Search in sources :

Example 61 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Random-Things by lumien231.

the class ClassTransformer method patchVertexLighterFlat.

private byte[] patchVertexLighterFlat(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found VertexLighterFlat Class: " + classNode.name);
    MethodNode processQuad = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals("processQuad")) {
            processQuad = mn;
            break;
        }
    }
    if (processQuad != null) {
        logger.log(Level.DEBUG, " - Found processQuad");
        InsnList resetList = new InsnList();
        resetList.add(new VarInsnNode(ALOAD, 0));
        resetList.add(new InsnNode(ICONST_0));
        resetList.add(new FieldInsnNode(PUTFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "rtFullBright", "Z"));
        processQuad.instructions.insert(resetList);
        AbstractInsnNode tintTarget = null;
        int lightMapTarget = 0;
        AbstractInsnNode updateColorTarget = null;
        LabelNode firstLabel = null;
        LabelNode lastLabel = null;
        for (int i = 0; i < processQuad.instructions.size(); i++) {
            AbstractInsnNode ain = processQuad.instructions.get(i);
            if (ain instanceof VarInsnNode) {
                VarInsnNode vin = (VarInsnNode) ain;
                if (vin.var == 5 && (processQuad.instructions.get(i - 1) instanceof MethodInsnNode)) {
                    tintTarget = vin;
                }
            } else if (ain instanceof LabelNode) {
                LabelNode ln = (LabelNode) ain;
                if (firstLabel == null) {
                    firstLabel = ln;
                }
                lastLabel = ln;
            } else if (ain instanceof MethodInsnNode) {
                MethodInsnNode min = (MethodInsnNode) ain;
                if (min.name.equals(MCPNames.method("func_177369_e"))) {
                    lightMapTarget = i;
                } else if (min.name.equals("updateColor")) {
                    updateColorTarget = min;
                }
            }
        }
        FieldNode fullBrightField = new FieldNode(ACC_PRIVATE, "rtFullBright", "Z", null, false);
        classNode.fields.add(fullBrightField);
        if (lightMapTarget != 0) {
            logger.log(Level.DEBUG, " - Found patch target (lightmap) (1/4)");
            for (int i = lightMapTarget; i < processQuad.instructions.size(); i++) {
                AbstractInsnNode ain = processQuad.instructions.get(i);
                if (ain instanceof InsnNode) {
                    InsnNode in = (InsnNode) ain;
                    if (in.getOpcode() == AALOAD) {
                        logger.log(Level.DEBUG, " - Found lightmap array (2/4)");
                        LabelNode l0 = new LabelNode(new Label());
                        InsnList toInsert = new InsnList();
                        toInsert.add(new VarInsnNode(ALOAD, 0));
                        toInsert.add(new FieldInsnNode(GETFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "rtFullBright", "Z"));
                        toInsert.add(new JumpInsnNode(IFEQ, l0));
                        toInsert.add(new InsnNode(POP));
                        toInsert.add(new FieldInsnNode(GETSTATIC, "lumien/randomthings/lib/Constants", "FULLBRIGHT_OVERRIDE", "[F"));
                        toInsert.add(l0);
                        processQuad.instructions.insert(in, toInsert);
                        break;
                    }
                }
            }
        }
        if (tintTarget != null) {
            logger.log(Level.DEBUG, " - Found tintTarget (3/4");
            LabelNode l0 = new LabelNode(new Label());
            LabelNode l1 = new LabelNode(new Label());
            InsnList toInsert = new InsnList();
            toInsert.add(new VarInsnNode(ALOAD, 0));
            toInsert.add(new FieldInsnNode(GETFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "blockInfo", "Lnet/minecraftforge/client/model/pipeline/BlockInfo;"));
            toInsert.add(new MethodInsnNode(INVOKEVIRTUAL, "net/minecraftforge/client/model/pipeline/BlockInfo", "getState", "()Lnet/minecraft/block/state/IBlockState;", false));
            toInsert.add(new MethodInsnNode(INVOKEINTERFACE, "net/minecraft/block/state/IBlockState", MCPNames.method("func_177230_c"), "()Lnet/minecraft/block/Block;", true));
            toInsert.add(new TypeInsnNode(INSTANCEOF, "lumien/randomthings/lib/ILuminousBlock"));
            toInsert.add(new JumpInsnNode(IFEQ, l0));
            toInsert.add(new VarInsnNode(ALOAD, 0));
            toInsert.add(new FieldInsnNode(GETFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "blockInfo", "Lnet/minecraftforge/client/model/pipeline/BlockInfo;"));
            toInsert.add(new MethodInsnNode(INVOKEVIRTUAL, "net/minecraftforge/client/model/pipeline/BlockInfo", "getState", "()Lnet/minecraft/block/state/IBlockState;", false));
            toInsert.add(new InsnNode(DUP));
            toInsert.add(new MethodInsnNode(INVOKEINTERFACE, "net/minecraft/block/state/IBlockState", MCPNames.method("func_177230_c"), "()Lnet/minecraft/block/Block;", true));
            toInsert.add(new InsnNode(SWAP));
            toInsert.add(new VarInsnNode(ALOAD, 0));
            toInsert.add(new FieldInsnNode(GETFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "tint", "I"));
            toInsert.add(new MethodInsnNode(INVOKEINTERFACE, "lumien/randomthings/lib/ILuminousBlock", "shouldGlow", "(Lnet/minecraft/block/state/IBlockState;I)Z", true));
            toInsert.add(new JumpInsnNode(IFEQ, l0));
            toInsert.add(new VarInsnNode(ALOAD, 0));
            toInsert.add(new InsnNode(ICONST_0));
            toInsert.add(new FieldInsnNode(PUTFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "diffuse", "Z"));
            toInsert.add(new VarInsnNode(ALOAD, 0));
            toInsert.add(new InsnNode(ICONST_1));
            toInsert.add(new FieldInsnNode(PUTFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "rtFullBright", "Z"));
            toInsert.add(l0);
            processQuad.instructions.insertBefore(tintTarget, toInsert);
        }
        if (updateColorTarget != null) {
            logger.log(Level.DEBUG, " - Found updateColor target (tint) (4/4)");
            LabelNode l0 = new LabelNode(new Label());
            LabelNode l1 = new LabelNode(new Label());
            InsnList toInsert = new InsnList();
            toInsert.add(new VarInsnNode(ALOAD, 0));
            toInsert.add(new FieldInsnNode(GETFIELD, "net/minecraftforge/client/model/pipeline/VertexLighterFlat", "rtFullBright", "Z"));
            toInsert.add(new JumpInsnNode(IFEQ, l1));
            toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "updateColor", "([F[FFFFFI)V", false));
            toInsert.add(new InsnNode(POP));
            toInsert.add(new JumpInsnNode(GOTO, l0));
            toInsert.add(l1);
            processQuad.instructions.insertBefore(updateColorTarget, toInsert);
            processQuad.instructions.insert(updateColorTarget, l0);
        }
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    try {
        byte[] result = writer.toByteArray();
        return result;
    } catch (Exception e) {
        e.printStackTrace();
        return basicClass;
    }
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) FieldNode(org.objectweb.asm.tree.FieldNode) Label(org.objectweb.asm.Label) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) InsnList(org.objectweb.asm.tree.InsnList) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) ClassReader(org.objectweb.asm.ClassReader) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 62 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Random-Things by lumien231.

the class ClassTransformer method patchOceanMonument.

private byte[] patchOceanMonument(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found MonumentCoreRoom Class: " + classNode.name);
    MethodNode addComponentParts = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals(MCPNames.method("func_74875_a"))) {
            addComponentParts = mn;
        }
    }
    if (addComponentParts != null) {
        logger.log(Level.DEBUG, " - Found addComponentParts");
        for (int i = 0; i < addComponentParts.instructions.size(); i++) {
            AbstractInsnNode ain = addComponentParts.instructions.get(i);
            if (ain instanceof InsnNode) {
                InsnNode in = (InsnNode) ain;
                if (in.getOpcode() == Opcodes.IRETURN) {
                    logger.log(Level.DEBUG, " - Patched addComponentParts");
                    AbstractInsnNode before = addComponentParts.instructions.get(i - 1);
                    InsnList toInsert = new InsnList();
                    toInsert.add(new VarInsnNode(Opcodes.ALOAD, 1));
                    toInsert.add(new VarInsnNode(Opcodes.ALOAD, 2));
                    toInsert.add(new VarInsnNode(Opcodes.ALOAD, 3));
                    toInsert.add(new VarInsnNode(Opcodes.ALOAD, 0));
                    toInsert.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "lumien/randomthings/worldgen/WorldGenOceanChest", "addComponentParts", "(Lnet/minecraft/world/World;Ljava/util/Random;Lnet/minecraft/world/gen/structure/StructureBoundingBox;Lnet/minecraft/world/gen/structure/StructureOceanMonumentPieces$MonumentCoreRoom;)V", false));
                    i += 5;
                    addComponentParts.instructions.insertBefore(before, toInsert);
                }
            }
        }
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) ClassReader(org.objectweb.asm.ClassReader) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 63 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Random-Things by lumien231.

the class ClassTransformer method patchRenderLivingBase.

private byte[] patchRenderLivingBase(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found RenderLivingBase Class: " + classNode.name);
    MethodNode canRenderName = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals(MCPNames.method("func_177070_b"))) {
            canRenderName = mn;
            break;
        }
    }
    if (canRenderName != null) {
        logger.log(Level.DEBUG, "- Found canRenderName (1/1)");
        LabelNode l1 = new LabelNode(new Label());
        InsnList toInsert = new InsnList();
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "canRenderName", "(Lnet/minecraft/entity/EntityLivingBase;)Z", false));
        toInsert.add(new JumpInsnNode(IFGT, l1));
        toInsert.add(new InsnNode(ICONST_0));
        toInsert.add(new InsnNode(IRETURN));
        toInsert.add(l1);
        canRenderName.instructions.insert(toInsert);
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Label(org.objectweb.asm.Label) ClassReader(org.objectweb.asm.ClassReader) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Example 64 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Random-Things by lumien231.

the class ClassTransformer method patchDummyClass.

private byte[] patchDummyClass(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found Dummy Class: " + classNode.name);
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) ClassReader(org.objectweb.asm.ClassReader)

Example 65 with ClassNode

use of org.objectweb.asm.tree.ClassNode in project Random-Things by lumien231.

the class ClassTransformer method patchLiquidBlock.

private byte[] patchLiquidBlock(byte[] basicClass) {
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(basicClass);
    classReader.accept(classNode, 0);
    logger.log(Level.DEBUG, "Found BlockLiquid Class: " + classNode.name);
    MethodNode shouldSideBeRendered = null;
    for (MethodNode mn : classNode.methods) {
        if (mn.name.equals(MCPNames.method("func_176225_a"))) {
            shouldSideBeRendered = mn;
            break;
        }
    }
    if (shouldSideBeRendered != null) {
        logger.log(Level.DEBUG, " - Found shouldSideBeRendered (1/1)");
        LabelNode l1 = new LabelNode(new Label());
        InsnList toInsert = new InsnList();
        toInsert.add(new VarInsnNode(ALOAD, 0));
        toInsert.add(new VarInsnNode(ALOAD, 1));
        toInsert.add(new VarInsnNode(ALOAD, 2));
        toInsert.add(new VarInsnNode(ALOAD, 3));
        toInsert.add(new MethodInsnNode(INVOKESTATIC, asmHandler, "shouldLiquidSideBeRendered", "(Lnet/minecraft/block/BlockLiquid;Lnet/minecraft/world/IBlockAccess;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)I", false));
        toInsert.add(new InsnNode(DUP));
        toInsert.add(new JumpInsnNode(IFLT, l1));
        toInsert.add(new InsnNode(IRETURN));
        toInsert.add(l1);
        toInsert.add(new InsnNode(POP));
        shouldSideBeRendered.instructions.insert(toInsert);
    }
    CustomClassWriter writer = new CustomClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    classNode.accept(writer);
    return writer.toByteArray();
}
Also used : LabelNode(org.objectweb.asm.tree.LabelNode) ClassNode(org.objectweb.asm.tree.ClassNode) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) VarInsnNode(org.objectweb.asm.tree.VarInsnNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) TypeInsnNode(org.objectweb.asm.tree.TypeInsnNode) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) LdcInsnNode(org.objectweb.asm.tree.LdcInsnNode) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) InsnNode(org.objectweb.asm.tree.InsnNode) MethodNode(org.objectweb.asm.tree.MethodNode) MethodInsnNode(org.objectweb.asm.tree.MethodInsnNode) Label(org.objectweb.asm.Label) ClassReader(org.objectweb.asm.ClassReader) JumpInsnNode(org.objectweb.asm.tree.JumpInsnNode) InsnList(org.objectweb.asm.tree.InsnList) VarInsnNode(org.objectweb.asm.tree.VarInsnNode)

Aggregations

ClassNode (org.objectweb.asm.tree.ClassNode)323 ClassReader (org.objectweb.asm.ClassReader)148 MethodNode (org.objectweb.asm.tree.MethodNode)120 ClassWriter (org.objectweb.asm.ClassWriter)70 IOException (java.io.IOException)44 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)37 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)34 InsnList (org.objectweb.asm.tree.InsnList)29 FieldNode (org.objectweb.asm.tree.FieldNode)28 ArrayList (java.util.ArrayList)27 Test (org.junit.Test)26 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)26 Label (org.objectweb.asm.Label)21 InputStream (java.io.InputStream)20 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)18 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)18 InnerClassNode (org.objectweb.asm.tree.InnerClassNode)17 InsnNode (org.objectweb.asm.tree.InsnNode)17 Method (java.lang.reflect.Method)16 List (java.util.List)16