package eu.the5zig.mod.asm.transformers; import eu.the5zig.mod.asm.LogUtil; import eu.the5zig.mod.asm.Names; import net.minecraft.launchwrapper.IClassTransformer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import static org.objectweb.asm.Opcodes.*; /** * Created by 5zig. * All rights reserved © 2015 */ public class PatchGuiTextfield implements IClassTransformer { @Override public byte[] transform(String s, String s1, byte[] bytes) { LogUtil.startClass("GuiTextfield (%s)", Names.guiTextfield.getName()); ClassReader reader = new ClassReader(bytes); ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); ClassPatcher visitor = new ClassPatcher(writer); reader.accept(visitor, 0); LogUtil.endClass(); return writer.toByteArray(); } public class ClassPatcher extends ClassVisitor { public ClassPatcher(ClassVisitor visitor) { super(ASM5, visitor); } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals("<init>") && desc.equals(Names.guiTextfield.getDesc())) { LogUtil.startMethod(Names.guiTextfield.getName() + "(%s)", Names.guiTextfield.getDesc()); return new PatchInit(cv.visitMethod(access, name, desc, signature, exceptions)); } LogUtil.endMethod(); return super.visitMethod(access, name, desc, signature, exceptions); } } public class PatchInit extends MethodVisitor { public PatchInit(MethodVisitor methodVisitor) { super(ASM5, methodVisitor); } @Override public void visitInsn(int opcode) { if (opcode == RETURN) { LogUtil.log("init"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESTATIC, "BytecodeHook", "onTextfieldInit", "(Ljava/lang/Object;)V", false); } super.visitInsn(opcode); } } }