Skip to content

Instantly share code, notes, and snippets.

@boq
Last active December 27, 2015 05:09
Show Gist options
  • Save boq/7272206 to your computer and use it in GitHub Desktop.
Save boq/7272206 to your computer and use it in GitHub Desktop.
package cpw.mods.fml.common.asm.transformers;
import java.util.Map;
import java.util.Set;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.*;
import org.objectweb.asm.commons.Method;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
public class TestTransformer implements IClassTransformer {
private final static String bedHookCls = "openblocks/BedHook";
private static class HookMethodVisitor extends MethodVisitor {
private final String methodName;
public HookMethodVisitor(MethodVisitor mv, String methodName) {
super(Opcodes.ASM4, mv);
this.methodName = methodName;
}
@Override
public void visitCode() {
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0); //EntityPlayer this
mv.visitMethodInsn(Opcodes.INVOKESTATIC, bedHookCls, "hook", "(Lnet/minecraft/entity/player/EntityPlayer;)Z");
Label skipReturn = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, skipReturn);
mv.visitLdcInsn(true);
mv.visitInsn(Opcodes.IRETURN);
mv.visitLabel(skipReturn);
}
}
public class HookClassVistor extends ClassVisitor {
private final Set<Method> methods;
public HookClassVistor(ClassVisitor cv, Set<Method> methods) {
super(Opcodes.ASM4, cv);
this.methods = ImmutableSet.copyOf(methods);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
Method type = new Method(name, desc);
MethodVisitor parent = super.visitMethod(access, name, desc, signature, exceptions);
return methods.contains(type) ? new HookMethodVisitor(parent, name) : parent;
}
}
private Map<String, Set<Method>> classes = Maps.newHashMap();
{
classes.put("net.minecraft.entity.player.EntityPlayer", ImmutableSet.<Method>of(new Method("isInBed", "()Z")));
}
@Override
public byte[] transform(String name, String transformedName, byte[] bytes) {
Set<Method> methodsToModify = classes.get(transformedName);
if (methodsToModify == null)
return bytes;
ClassReader cr = new ClassReader(bytes);
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
HookClassVistor mod = new HookClassVistor(cw, methodsToModify);
cr.accept(mod, 0);
return cw.toByteArray();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment