package com.austinv11.peripheralsplusplus.asm; import com.austinv11.peripheralsplusplus.PeripheralsPlusPlus; import net.minecraft.launchwrapper.IClassTransformer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.*; import java.util.Iterator; public class Transformer implements IClassTransformer, Opcodes { @Override public byte[] transform(String className, String newClassName, byte[] byteCode) { if (className.equals("dan200.computercraft.shared.pocket.items.ItemPocketComputer")) { PeripheralsPlusPlus.LOGGER.info("Adding pocket computer peripherals"); return transformPocketComputerCreateServerComputer(byteCode); } return byteCode; } private byte[] transformPocketComputerCreateServerComputer(byte[] byteCode) { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(byteCode); classReader.accept(classNode, 0); for (MethodNode m : classNode.methods) if (m.name.equals("createServerComputer")) { Iterator<AbstractInsnNode> nodes = m.instructions.iterator(); int i = 0; while (nodes.hasNext()) { AbstractInsnNode node = nodes.next(); if (node.getOpcode() == INVOKEVIRTUAL) { if (i != 10) { i++; continue; } InsnList instructions = new InsnList(); instructions.add(new VarInsnNode(ALOAD, 7)); instructions.add(new VarInsnNode(ALOAD, 3)); instructions.add(new VarInsnNode(ALOAD, 2)); instructions.add(new MethodInsnNode(INVOKESTATIC, "com/austinv11/peripheralsplusplus/hooks/ComputerCraftHooks", "onPocketComputerCreate", "(Ldan200/computercraft/shared/computer/core/ServerComputer;Lnet/minecraft/item/ItemStack;Lnet/minecraft/inventory/IInventory;)V", false)); m.instructions.insert(node, instructions); break; } } } else if (m.name.equals("func_77653_i") || m.name.equals("getItemStackDisplayName")) { Iterator<AbstractInsnNode> nodes = m.instructions.iterator(); while (nodes.hasNext()) { AbstractInsnNode node = nodes.next(); if (node.getOpcode() == ASTORE) { InsnList instructions = new InsnList(); instructions.add(new VarInsnNode(ALOAD, 2)); instructions.add(new VarInsnNode(ALOAD, 1)); instructions.add(new MethodInsnNode(INVOKESTATIC, "com/austinv11/peripheralsplusplus/hooks/ComputerCraftHooks", "getName", "(Ljava/lang/String;Lnet/minecraft/item/ItemStack;)Ljava/lang/String;", false)); instructions.add(new InsnNode(ARETURN)); m.instructions.insert(node, instructions); break; } } } else if (m.name.equals("func_77663_a") || m.name.equals("onUpdate")) { Iterator<AbstractInsnNode> nodes = m.instructions.iterator(); int i = 0; while (nodes.hasNext()) { AbstractInsnNode node = nodes.next(); if (node.getOpcode() == ASTORE) { if (i != 1) { i++; continue; } InsnList instructions = new InsnList(); instructions.add(new VarInsnNode(ALOAD, 3)); instructions.add(new VarInsnNode(ALOAD, 1)); instructions.add(new VarInsnNode(ALOAD, 7)); instructions.add(new MethodInsnNode(INVOKESTATIC, "com/austinv11/peripheralsplusplus/hooks/ComputerCraftHooks", "update", "(Lnet/minecraft/entity/Entity;Lnet/minecraft/item/ItemStack;Ldan200/computercraft/shared/computer/core/ServerComputer;)V", false)); m.instructions.insert(node, instructions); break; } } } ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); classNode.accept(writer); return writer.toByteArray(); } }