private MethodNode fixMethod(MethodNode originalMethod) { CloneMap cloneMap = new CloneMap(); MethodNode result = cloneMethodWithoutInstructions(originalMethod, cloneMap); result.instructions = fixInstructions(originalMethod, cloneMap); return result; }
@Override boolean processMethods(List<MethodNode> methods) { int found = 0; for (MethodNode mn : methods) { if (mn.name.equals("<init>")) { logger.log(Level.INFO, "\tPatching constructor in EntityPlayer"); ListIterator<AbstractInsnNode> it = mn.instructions.iterator(); while (it.hasNext()) { AbstractInsnNode insn = it.next(); if (insn instanceof TypeInsnNode) { if (((TypeInsnNode) insn).desc.equals(inventoryClassName)) { ((TypeInsnNode) insn).desc = "mods/battlegear2/api/core/InventoryPlayerBattle"; } } else if (insn instanceof MethodInsnNode) { if (((MethodInsnNode) insn).owner.equals(inventoryClassName)) { ((MethodInsnNode) insn).owner = "mods/battlegear2/api/core/InventoryPlayerBattle"; } } } found++; } else if (mn.name.equals(onItemFinishMethodName) && mn.desc.equals(SIMPLEST_METHOD_DESC)) { sendPatchLog("onItemUseFinish"); InsnList newList = new InsnList(); ListIterator<AbstractInsnNode> it = mn.instructions.iterator(); while (it.hasNext()) { AbstractInsnNode next = it.next(); if (next instanceof MethodInsnNode && ((MethodInsnNode) next) .owner.equals("net/minecraftforge/event/ForgeEventFactory")) { found++; int index = ((MethodInsnNode) next).desc.indexOf(")"); String newDesc = ((MethodInsnNode) next).desc.substring(0, index) + "I" + ((MethodInsnNode) next).desc.substring(index); newList.add(new VarInsnNode(ILOAD, 1)); newList.add( new MethodInsnNode(INVOKESTATIC, UTILITY_CLASS, "beforeFinishUseEvent", newDesc)); } else { newList.add(next); } } mn.instructions = newList; } else if (mn.name.equals(onUpdateMethodName) && mn.desc.equals(SIMPLEST_METHOD_DESC)) { sendPatchLog("onUpdate"); InsnList newList = new InsnList(); ListIterator<AbstractInsnNode> it = mn.instructions.iterator(); while (it.hasNext()) { AbstractInsnNode next = it.next(); if (next instanceof FieldInsnNode && ((FieldInsnNode) next).owner.equals(entityPlayerClassName) && ((FieldInsnNode) next).name.equals(playerInventoryFieldName)) { found++; newList.add(new VarInsnNode(ALOAD, 0)); newList.add( new FieldInsnNode( GETFIELD, entityPlayerClassName, playerItemInUseField, "L" + itemStackClassName + ";")); newList.add( new MethodInsnNode( INVOKESTATIC, UTILITY_CLASS, "getCurrentItemOnUpdate", "(L" + entityPlayerClassName + ";L" + itemStackClassName + ";)L" + itemStackClassName + ";")); next = it.next(); } else { newList.add(next); } } mn.instructions = newList; } else if (mn.name.equals(setCurrentItemArmourMethodName) && mn.desc.equals(setCurrentItemArmourMethodDesc)) { sendPatchLog("setCurrentItemOrArmor"); replaceInventoryArrayAccess( mn, entityPlayerClassName, playerInventoryFieldName, mn.maxStack, mn.maxLocals); found++; } else if (mn.name.equals(interactWithMethodName) && mn.desc.equals(interactWithMethodDesc)) { sendPatchLog("interactWith"); MethodNode mv = new MethodNode(ACC_PUBLIC, interactWithMethodName, interactWithMethodDesc, null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKESTATIC, UTILITY_CLASS, "interactWith", "(L" + entityPlayerClassName + ";L" + entityClassName + ";)Z"); mv.visitInsn(IRETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "L" + entityPlayerClassName + ";", null, l0, l1, 0); mv.visitLocalVariable("p_70998_1_", "L" + entityClassName + ";", null, l0, l1, 1); mv.visitMaxs(2, 2); mv.visitEnd(); mn.instructions = mv.instructions; found++; } } logger.log(Level.INFO, "\tCreating new methods in EntityPlayer"); methods.add(methods.size(), generateAttackOffhandMethod()); methods.add(methods.size(), generateSwingOffhand()); methods.add(methods.size(), generateGetOffSwingMethod()); methods.add(methods.size(), generateUpdateSwingArm()); methods.add(methods.size(), generateIsBattleMode()); methods.add(methods.size(), generateIsBlockingWithShield()); methods.add(methods.size(), generateSetBlockingWithShield()); methods.add( methods.size(), generateGetter(entityPlayerClassName, "getSpecialActionTimer", "specialActionTimer", "I")); methods.add( methods.size(), generateSetter(entityPlayerClassName, "setSpecialActionTimer", "specialActionTimer", "I")); return found == 5; }