List of usage examples for org.objectweb.asm.tree ClassNode ClassNode
public ClassNode()
From source file:net.minecraftforge.fml.common.asm.transformers.SoundEngineFixTransformer.java
License:Open Source License
@Override public byte[] transform(String name, String transformedName, byte[] basicClass) { if (transformedName.equals("paulscode.sound.Source")) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); classNode.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "removed", "Z", null, null)); // adding field 'public boolean removed;' ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer);/*from ww w .ja va2 s .c o m*/ return writer.toByteArray(); } else if (transformedName.equals("paulscode.sound.Library")) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); MethodNode method = null; for (MethodNode m : classNode.methods) { if (m.name.equals("removeSource") && m.desc.equals("(Ljava/lang/String;)V")) // trying to find paulscode.sound.Library.removeSource(String) { method = m; break; } } if (method == null) throw new RuntimeException( "Error processing " + transformedName + " - no removeSource method found"); AbstractInsnNode referenceNode = null; for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) { AbstractInsnNode insn = iterator.next(); if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("paulscode/sound/Source") // searching for mySource.cleanup() node (line 1086) && ((MethodInsnNode) insn).name.equals("cleanup")) { referenceNode = insn; break; } } if (referenceNode != null) { LabelNode after = (LabelNode) referenceNode.getNext(); AbstractInsnNode beginning = referenceNode.getPrevious(); int varIndex = ((VarInsnNode) beginning).var; method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // adding extra if (mySource.toStream) method.instructions.insertBefore(beginning, new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "toStream", "Z")); LabelNode elseNode = new LabelNode(); method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.IFEQ, elseNode)); // if fails (else) -> go to mySource.cleanup(); method.instructions.insertBefore(beginning, new VarInsnNode(Opcodes.ALOAD, varIndex)); // if (mySource.toStream) { mySource.removed = true; } method.instructions.insertBefore(beginning, new InsnNode(Opcodes.ICONST_1)); method.instructions.insertBefore(beginning, new FieldInsnNode(Opcodes.PUTFIELD, "paulscode/sound/Source", "removed", "Z")); method.instructions.insertBefore(beginning, new JumpInsnNode(Opcodes.GOTO, after)); // still inside if -> jump to sourceMap.remove( sourcename ); method.instructions.insertBefore(beginning, elseNode); } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } else if (transformedName.equals("paulscode.sound.StreamThread")) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(basicClass); classReader.accept(classNode, 0); MethodNode method = null; for (MethodNode m : classNode.methods) { if (m.name.equals("run") && m.desc.equals("()V")) // trying to find paulscode.sound.StreamThread.run(); { method = m; break; } } if (method == null) throw new RuntimeException("Error processing " + transformedName + " - no run method found"); AbstractInsnNode referenceNode = null; for (Iterator<AbstractInsnNode> iterator = method.instructions.iterator(); iterator.hasNext();) { AbstractInsnNode insn = iterator.next(); if (insn instanceof MethodInsnNode && ((MethodInsnNode) insn).owner.equals("java/util/ListIterator") // searching for 'src = iter.next();' node (line 110) && ((MethodInsnNode) insn).name.equals("next")) { referenceNode = insn.getNext().getNext(); break; } } if (referenceNode != null) { int varIndex = ((VarInsnNode) referenceNode).var; LabelNode after = (LabelNode) referenceNode.getNext(); method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // add if(removed) method.instructions.insertBefore(after, new FieldInsnNode(Opcodes.GETFIELD, "paulscode/sound/Source", "removed", "Z")); method.instructions.insertBefore(after, new JumpInsnNode(Opcodes.IFEQ, after)); // if the source has been marked as removed, clean it up and set the variable to null so it will be removed from the list method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ALOAD, varIndex)); // src.cleanup(); method.instructions.insertBefore(after, new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "paulscode/sound/Source", "cleanup", "()V", false)); method.instructions.insertBefore(after, new InsnNode(Opcodes.ACONST_NULL)); // src = null; method.instructions.insertBefore(after, new VarInsnNode(Opcodes.ASTORE, varIndex)); } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); classNode.accept(writer); return writer.toByteArray(); } return basicClass; }
From source file:net.minecraftforge.gradle.tasks.DeobfuscateJar.java
License:Open Source License
private byte[] stripSynthetics(String name, byte[] data) { ClassReader reader = new ClassReader(data); ClassNode node = new ClassNode(); reader.accept(node, 0);/*from ww w . j a v a 2 s .com*/ if ((node.access & Opcodes.ACC_ENUM) == 0 && !node.superName.equals("java/lang/Enum") && (node.access & Opcodes.ACC_SYNTHETIC) == 0) { // ^^ is for ignoring enums. for (FieldNode f : ((List<FieldNode>) node.fields)) { f.access = f.access & (0xffffffff - Opcodes.ACC_SYNTHETIC); //getLogger().lifecycle("Stripping field: "+f.name); } for (MethodNode m : ((List<MethodNode>) node.methods)) { m.access = m.access & (0xffffffff - Opcodes.ACC_SYNTHETIC); //getLogger().lifecycle("Stripping method: "+m.name); } } ClassWriter writer = new ClassWriter(0); node.accept(writer); return writer.toByteArray(); }
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);/*from w w w . j a v a 2s.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
private ClassNode getClassNode(byte[] data) { ClassReader reader = new ClassReader(data); ClassNode classNode = new ClassNode(); reader.accept(classNode, 0);/*ww w.j a v a 2s . c om*/ return classNode; }
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);/*from w w 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 w ww . j av a 2 s .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.ice.launch.transformers.DeobfuscationTransformer.java
License:Open Source License
private String getFieldType(String owner, String name) { Map<String, String> fieldDescriptions = this.fieldDescriptions.get(owner); if (fieldDescriptions != null) return fieldDescriptions.get(name); byte[] bytes = getBytes(owner); if (bytes == null) return null; ClassReader reader = new ClassReader(bytes); ClassNode classNode = new ClassNode(); reader.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); String result = null;// ww w.jav a 2 s .c o m fieldDescriptions = Maps.newHashMapWithExpectedSize(classNode.fields.size()); for (FieldNode fieldNode : classNode.fields) { fieldDescriptions.put(fieldNode.name, fieldNode.desc); if (fieldNode.name.equals(name)) { result = fieldNode.desc; } } this.fieldDescriptions.put(owner, fieldDescriptions); return result; }
From source file:net.minecrell.quartz.launch.mappings.MappingsParser.java
License:MIT License
public static ClassNode loadClassStructure(ClassReader reader) { ClassNode classNode = new ClassNode(); reader.accept(classNode, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); return classNode; }
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; }//from w w w . j a va 2 s . co m 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; }// w w w .j a v a 2s . co 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()); }