Example usage for org.objectweb.asm.tree ClassNode accept

List of usage examples for org.objectweb.asm.tree ClassNode accept

Introduction

In this page you can find the example usage for org.objectweb.asm.tree ClassNode accept.

Prototype

public void accept(final ClassVisitor classVisitor) 

Source Link

Document

Makes the given class visitor visit this class.

Usage

From source file:net.minecraftforge.gradle.tasks.MergeJars.java

License:Open Source License

private void copyClass(ZipFile inJar, ZipEntry entry, ZipOutputStream outJar, boolean isClientOnly)
        throws IOException {
    ClassReader reader = new ClassReader(readEntry(inJar, entry));
    ClassNode classNode = new ClassNode();

    reader.accept(classNode, 0);/*  w w  w . j a  va2 s.c  o m*/

    if (classNode.visibleAnnotations == null) {
        classNode.visibleAnnotations = new ArrayList<AnnotationNode>();
    }
    classNode.visibleAnnotations.add(getSideAnn(isClientOnly));

    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    byte[] data = writer.toByteArray();

    ZipEntry newEntry = new ZipEntry(entry.getName());
    if (outJar != null) {
        outJar.putNextEntry(newEntry);
        outJar.write(data);
    }
}

From source file:net.minecraftforge.gradle.tasks.MergeJars.java

License:Open Source License

public byte[] processClass(byte[] cIn, byte[] sIn) {
    ClassNode cClassNode = getClassNode(cIn);
    ClassNode sClassNode = getClassNode(sIn);

    processFields(cClassNode, sClassNode);
    processMethods(cClassNode, sClassNode);

    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cClassNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecraftforge.gradle.user.patcherUser.forge.McVersionTransformer.java

License:Open Source License

@Override
public byte[] transform(byte[] data) {
    String mcVersion = Constants.resolveString(this.mcVersion);

    ClassReader reader = new ClassReader(data);
    ClassNode node = new ClassNode();

    reader.accept(node, 0);/* ww w .  j a v  a  2 s .  c  o m*/
    List<AnnotationNode> annots = node.visibleAnnotations;

    if (annots == null || annots.isEmpty()) // annotations
        return data;

    for (AnnotationNode mod : annots) {
        if (mod.desc.endsWith("fml/common/Mod;")) {
            int index = mod.values.indexOf("acceptedMinecraftVersions");
            if (index == -1) {
                mod.values.add("acceptedMinecraftVersions");
                mod.values.add("[" + mcVersion + "]");
            }

            break; // break out, im done. There cant be 2 @Mods in a file... can there?
        }
    }

    ClassWriter writer = new ClassWriter(0);
    node.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecrell.ice.launch.transformers.AccessTransformer.java

License:Open Source License

@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
    if (bytes == null || !modifiers.containsKey(transformedName)) {
        return bytes;
    }/*from   ww  w  .j a  va2s  . co m*/

    ClassNode classNode = new ClassNode();
    ClassReader reader = new ClassReader(bytes);
    reader.accept(classNode, 0);

    for (Modifier m : modifiers.get(transformedName)) {
        if (m.isClass) { // Class
            classNode.access = m.transform(classNode.access);
        } else if (m.desc == null) { // Field
            for (FieldNode fieldNode : classNode.fields) {
                if (m.wildcard || fieldNode.name.equals(m.name)) {
                    fieldNode.access = m.transform(fieldNode.access);
                    if (!m.wildcard)
                        break;
                }
            }
        } else {
            List<MethodNode> overridable = null;

            for (MethodNode methodNode : classNode.methods) {
                if (m.wildcard || (methodNode.name.equals(m.name) && methodNode.desc.equals(m.desc))) {
                    boolean wasPrivate = (methodNode.access & ACC_PRIVATE) != 0;
                    methodNode.access = m.transform(methodNode.access);

                    // Constructors always use INVOKESPECIAL
                    // if we changed from private to something else we need to replace all INVOKESPECIAL calls to this method with INVOKEVIRTUAL
                    // so that overridden methods will be called. Only need to scan this class, because obviously the method was private.
                    if (!methodNode.name.equals("<init>") && wasPrivate
                            && (methodNode.access & ACC_PRIVATE) == 0) {
                        if (overridable == null) {
                            overridable = new ArrayList<>(3);
                        }

                        overridable.add(methodNode);
                    }

                    if (!m.wildcard)
                        break;
                }
            }

            if (overridable != null) {
                for (MethodNode methodNode : classNode.methods) {
                    for (Iterator<AbstractInsnNode> itr = methodNode.instructions.iterator(); itr.hasNext();) {
                        AbstractInsnNode insn = itr.next();
                        if (insn.getOpcode() == INVOKESPECIAL) {
                            MethodInsnNode mInsn = (MethodInsnNode) insn;
                            for (MethodNode replace : overridable) {
                                if (replace.name.equals(mInsn.name) && replace.desc.equals(mInsn.desc)) {
                                    mInsn.setOpcode(INVOKEVIRTUAL);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    ClassWriter writer = new ClassWriter(0);
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecrell.quartz.launch.transformers.MappingTreeTransformer.java

License:MIT License

@Override
public byte[] transform(String name, String transformedName, byte[] basicClass) {
    if (basicClass == null) {
        return null;
    }/*ww w.jav  a 2 s  . c  om*/

    if (!transform(name, transformedName)) {
        return basicClass;
    }

    ClassNode classNode = new ClassNode();
    ClassReader reader = new ClassReader(basicClass);
    reader.accept(classNode, readerFlags());

    transform(name, transformedName, classNode);

    ClassWriter writer = new ClassWriter(writerFlags());
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.minecrell.quartz.mappings.transformer.context.SimpleTransformerContext.java

License:Open Source License

@Override
public ClassReader getTransformed(ClassReader reader) {
    if (reader == null) {
        return null;
    }/*from  w w  w .j  a  va2s. c o  m*/

    String name = reader.getClassName();
    String transformedName = this.renamer.map(name);
    name = name.replace('/', '.');
    transformedName = transformedName.replace('/', '.');

    List<CoreClassTransformer> coreTransformers = new ArrayList<>(this.coreTransformers.size());

    int readerFlags = 0;
    int writerFlags = 0;

    for (CoreClassTransformer transformer : this.coreTransformers) {
        if (transformer.transform(name, transformedName)) {
            readerFlags |= transformer.readerFlags();
            writerFlags |= transformer.writerFlags();
            coreTransformers.add(transformer);
        }
    }

    List<TreeClassTransformer> treeTransformers = new ArrayList<>(this.treeTransformers.size());

    for (TreeClassTransformer transformer : this.treeTransformers) {
        if (transformer.transform(name, transformedName)) {
            readerFlags |= transformer.readerFlags();
            writerFlags |= transformer.writerFlags();
            treeTransformers.add(transformer);
        }
    }

    ClassWriter writer = new ClassWriter(writerFlags);
    ClassVisitor visitor;
    ClassNode classNode = null;

    if (!treeTransformers.isEmpty()) {
        classNode = new ClassNode();
        visitor = classNode;
    } else {
        visitor = writer;
    }

    for (CoreClassTransformer transformer : coreTransformers) {
        visitor = transformer.transform(name, transformedName, reader, visitor);
    }

    reader.accept(visitor, readerFlags);

    if (!treeTransformers.isEmpty()) {
        for (TreeClassTransformer transformer : treeTransformers) {
            classNode = transformer.transform(name, transformedName, classNode);
        }

        classNode.accept(writer);
    }

    return new ClassReader(writer.toByteArray());
}

From source file:net.petercashel.jmsDd.util.ASMTransformer.java

License:Apache License

public static byte[] transform(String name, byte[] bytes) {
    if (debug)// www  .j a  va2s .  c om
        System.out.println(bytes.length);
    ClassNode classNode = new ClassNode();
    String classNameASM = name.replace('.', '/');
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);
    boolean DoModInit = false;
    boolean HasInit = false;
    String initDesc = "()V";
    boolean lockDesc = false;

    try {
        try {
            for (int i = 0; i < classNode.visibleAnnotations.size(); i++) {
                AnnotationNode ann = (AnnotationNode) classNode.visibleAnnotations.get(i);
                if (ann.desc.equalsIgnoreCase("Lnet/petercashel/jmsDd/module/Module;")) {
                    try {
                        if (debug)
                            System.out.println("ANNOTE!");
                        DoModInit = true;
                        Map<String, Object> values = asmList2Map(ann.values);
                        ModuleSystem.modulesToLoad.put(
                                values.get("ModuleName").toString().replace("[", "").replace("]", ""),
                                classNode.name.replace("/", "."));
                    } catch (Exception e) {
                        e.printStackTrace();

                    }
                }
            }
        } catch (Exception e) {
        }

        try {
            if (DoModInit) {

                for (int i = 0; i < classNode.methods.size(); i++) {
                    MethodNode m = (MethodNode) classNode.methods.get(i);
                    if (m.name.contentEquals("<init>")) {
                        initDesc = m.desc;
                        if (m.desc.contentEquals("()V")) {
                            HasInit = true;
                            if (debug)
                                System.out.println("Found <init>");
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (debug)
        System.out.println("Still alive?");
    try {

        //          L0
        //             LINENUMBER 43 L0
        //             ALOAD 0
        //             INVOKESPECIAL // CLASSNAME FOR ASM  // ()V    ////// This is effectically a super() call but to the discovered constructor
        //            L1
        //             LINENUMBER 44 L1
        //             INVOKESTATIC net/petercashel/jmsDd/API/API$Impl.getAPI ()Lnet/petercashel/jmsDd/API/API;
        //             ALOAD 0
        //             INVOKEINTERFACE net/petercashel/jmsDd/API/API.registerEventBus (Ljava/lang/Object;)V
        //            L2
        //             LINENUMBER 46 L2
        //             RETURN
        //            L3
        //             LOCALVARIABLE this // "L" + CLASSNAME FOR ASM + ";" // L0 L3 0
        //             LOCALVARIABLE e Lnet/petercashel/jmsDd/event/module/DummyEvent; L0 L3 1
        //             MAXSTACK = 2
        //             MAXLOCALS = 2
        if (DoModInit) {
            if (HasInit) {
                if (debug)
                    System.out.println("Adding Extra Constructor to " + name);
                MethodNode constructor = new MethodNode(Opcodes.ACC_PUBLIC, "<init>",
                        "(Lnet/petercashel/jmsDd/event/module/DummyEvent;)V", null, null);

                Label L0 = new Label();
                constructor.visitLabel(L0);
                constructor.visitVarInsn(Opcodes.ALOAD, 0);
                constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, classNameASM, "<init>", initDesc);

                Label L1 = new Label();
                constructor.visitLabel(L1);
                constructor.visitMethodInsn(Opcodes.INVOKESTATIC, "net/petercashel/jmsDd/API/API$Impl",
                        "getAPI", "()Lnet/petercashel/jmsDd/API/API;");
                constructor.visitVarInsn(Opcodes.ALOAD, 0);
                constructor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "net/petercashel/jmsDd/API/API",
                        "registerEventBus", "(Ljava/lang/Object;)V");

                Label L2 = new Label();
                constructor.visitLabel(L2);
                constructor.visitInsn(Opcodes.RETURN);

                Label L3 = new Label();
                constructor.visitLabel(L3);
                constructor.visitLocalVariable("this", "L" + classNameASM + ";", null, L0, L3, 0);
                constructor.visitLocalVariable("e", "Lnet/petercashel/jmsDd/event/module/DummyEvent;", null, L0,
                        L3, 1);
                constructor.visitMaxs(2, 2);
                constructor.visitEnd();
                classNode.methods.add(constructor);

            } else {
                System.err.println("WARNING! " + name
                        + " Doesn't have a default no-args constructor.  Module loader cannot chain load the constructor. \n If you are recieving this error and your module has no constructors defined, or a no-args constructor defined, \n please report the bug to the author of JMSDd.");
                MethodNode constructor = new MethodNode(Opcodes.ACC_PUBLIC, "<init>",
                        "(Lnet/petercashel/jmsDd/event/module/DummyEvent;)V", null, null);

                Label L0 = new Label();
                constructor.visitLabel(L0);
                constructor.visitVarInsn(Opcodes.ALOAD, 0);
                //INVOKESPECIAL java/lang/Object.<init> ()V ////// There is no other constructor, call super() to Object.
                constructor.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");

                Label L1 = new Label();
                constructor.visitLabel(L1);
                constructor.visitMethodInsn(Opcodes.INVOKESTATIC, "net/petercashel/jmsDd/API/API$Impl",
                        "getAPI", "()Lnet/petercashel/jmsDd/API/API;");
                constructor.visitVarInsn(Opcodes.ALOAD, 0);
                constructor.visitMethodInsn(Opcodes.INVOKEINTERFACE, "net/petercashel/jmsDd/API/API",
                        "registerEventBus", "(Ljava/lang/Object;)V");

                Label L2 = new Label();
                constructor.visitLabel(L2);
                constructor.visitInsn(Opcodes.RETURN);

                Label L3 = new Label();
                constructor.visitLabel(L3);
                constructor.visitLocalVariable("this", "L" + classNameASM + ";", null, L0, L3, 0);
                constructor.visitLocalVariable("e", "Lnet/petercashel/jmsDd/event/module/DummyEvent;", null, L0,
                        L3, 1);
                constructor.visitMaxs(2, 2);
                constructor.visitEnd();
                classNode.methods.add(constructor);
            }
            classNode.visitEnd();
            ClassWriter wr = new ClassWriter(0);
            classNode.accept(wr);

            bytes = wr.toByteArray();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (debug)
        System.out.println("Still alive.");
    if (debug)
        System.out.println(bytes.length);
    if (plugins.size() > 0) {
        for (ASMPlugin p : plugins) {
            try {
                bytes = p.transform(name, bytes);
            } catch (Exception e) {

            }
        }
    }

    return bytes;
}

From source file:net.roryclaasen.asm.rorysmodcore.transformer.EntityPlayerTransformer.java

License:Apache License

public byte[] patchOnUpdate(String name, byte[] bytes, boolean obfuscated) {
    RMLog.info("[EntityPlayer] [onUpdate] Patching", true);
    String targetMethodName = "";

    if (obfuscated == true)
        targetMethodName = "h";
    else/*from  w w  w.  j  a  v  a2 s .co m*/
        targetMethodName = "onUpdate";
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        MethodNode method = methods.next();
        int invok_index = -1;
        if ((method.name.equals(targetMethodName) && method.desc.equals("()V"))) {
            AbstractInsnNode currentNode = null;
            AbstractInsnNode targetNode = null;

            Iterator<AbstractInsnNode> iter = method.instructions.iterator();

            int index = -1;

            int GETFIELD_COUNT = 0;
            while (iter.hasNext()) {
                index++;
                currentNode = iter.next();
                if (currentNode.getOpcode() == Opcodes.GETFIELD) {
                    GETFIELD_COUNT++;
                    if (GETFIELD_COUNT == 13) {
                        targetNode = currentNode;
                        invok_index = index;
                        break;
                    }
                }
            }
            if (targetNode == null || invok_index == -1) {
                RMLog.info("[EntityPlayer] Did not find all necessary target nodes! ABANDON CLASS!", true);
                return bytes;
            }
            /*
             * mv.visitLineNumber(305, l19);
             * mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
             * mv.visitVarInsn(ALOAD, 0);
             * -- mv.visitFieldInsn(GETFIELD, "net/minecraft/entity/player/EntityPlayer", "worldObj", "Lnet/minecraft/world/World;");
             * mv.visitFieldInsn(GETFIELD, "net/minecraft/world/World", "isRemote", "Z");
             * Label l21 = new Label();
             * mv.visitJumpInsn(IFNE, l21);
             */
            @SuppressWarnings("unused")
            AbstractInsnNode p1, p2, p3;
            p1 = method.instructions.get(invok_index - 1); // mv.visitVarInsn(ALOAD, 0);
            p2 = method.instructions.get(invok_index); // mv.visitFieldInsn(GETFIELD, "net/minecraft/entity/player/EntityPlayer", "worldObj", "Lnet/minecraft/world/World;");
            p3 = method.instructions.get(invok_index + 1); // mv.visitFieldInsn(GETFIELD, "net/minecraft/world/World", "isRemote", "Z");

            //method.instructions.remove(p1);
            //method.instructions.remove(p2);
            //method.instructions.remove(p3);

            MethodInsnNode m1 = new MethodInsnNode(Opcodes.INVOKESTATIC,
                    "net/roryclaasen/asm/rorysmodcore/transformer/StaticClass", "shouldWakeUp",
                    "(Lnet/minecraft/entity/player/EntityPlayer;)Z", false);

            method.instructions.set(p2, m1);
            method.instructions.remove(p3);
            break;
        }
    }
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.roryclaasen.asm.rorysmodcore.transformer.WorldServerTransformer.java

License:Apache License

public byte[] patchTick(String name, byte[] bytes, boolean obfuscated) {
    RMLog.info("[WorldServer] [tick] Patching", true);
    String targetMethodName = "";

    if (obfuscated == true)
        targetMethodName = "b";
    else//from ww w  .  ja  v a  2  s. c om
        targetMethodName = "tick";
    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        MethodNode method = methods.next();
        int invok_index = -1;
        if ((method.name.equals(targetMethodName) && method.desc.equals("()V"))) {
            AbstractInsnNode currentNode = null;
            AbstractInsnNode targetNode = null;

            Iterator<AbstractInsnNode> iter = method.instructions.iterator();

            int index = -1;

            int INVOKEVIRTUAL_COUNT = 0;
            while (iter.hasNext()) {
                index++;
                currentNode = iter.next();
                if (currentNode.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                    INVOKEVIRTUAL_COUNT++;
                    if (INVOKEVIRTUAL_COUNT == 9) {
                        targetNode = currentNode;
                        invok_index = index;
                        break;
                    }
                }
            }
            if (targetNode == null || invok_index == -1) {
                RMLog.info("[WorldServer] Did not find all necessary target nodes! ABANDON CLASS!", true);
                return bytes;
            }
            AbstractInsnNode p1 = method.instructions.get(invok_index);
            MethodInsnNode a1 = new MethodInsnNode(Opcodes.INVOKESPECIAL, "net/minecraft/world/WorldServer",
                    "resetRainAndThunder", "()V", false);

            method.instructions.set(p1, a1);
            break;
        }
    }
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
}

From source file:net.roryclaasen.asm.rorysmodcore.transformer.WorldServerTransformer.java

License:Apache License

public byte[] patchWakeAllPlayers(String name, byte[] bytes, boolean obfuscated) {
    RMLog.info("[WorldServer] [wakeAllPlayers] Patching", true);
    String targetMethodName = "";

    if (obfuscated == true)
        targetMethodName = "d";
    else//w  w w  . j  ava2s.  c  o m
        targetMethodName = "wakeAllPlayers";

    ClassNode classNode = new ClassNode();
    ClassReader classReader = new ClassReader(bytes);
    classReader.accept(classNode, 0);

    Iterator<MethodNode> methods = classNode.methods.iterator();
    while (methods.hasNext()) {
        MethodNode method = methods.next();
        int invok_index = -1;
        if ((method.name.equals(targetMethodName) && method.desc.equals("()V"))) {
            AbstractInsnNode currentNode = null;
            AbstractInsnNode targetNode = null;

            Iterator<AbstractInsnNode> iter = method.instructions.iterator();
            int index = -1;
            while (iter.hasNext()) {
                index++;
                currentNode = iter.next();
                if (currentNode.getOpcode() == Opcodes.INVOKEVIRTUAL) {
                    invok_index = index;
                    targetNode = currentNode;
                    break;
                }
            }
            if (targetNode == null || invok_index == -1) {
                RMLog.info("[WorldServer] Did not find all necessary target nodes! ABANDON CLASS!", true);
                return bytes;
            }
            AbstractInsnNode p1 = method.instructions.get(invok_index);
            MethodInsnNode p2 = new MethodInsnNode(Opcodes.INVOKESTATIC,
                    "net/roryclaasen/asm/rorysmodcore/transformer/StaticClass", "shouldWakeUp", "()Z", false);

            method.instructions.set(p1, p2);
            method.instructions.remove(method.instructions.get(invok_index - 1));
            break;
        }
    }
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    classNode.accept(writer);
    return writer.toByteArray();
}