From 67830d0d9821e3e34b23a44a3377d6ee0e15d580 Mon Sep 17 00:00:00 2001 From: HRudyPlayZ Date: Fri, 19 Nov 2021 20:42:25 +0100 Subject: [PATCH] Fixed compatibility with recent 1.7.10 Optifine versions - Added the getLocalVarIndex method to look for the correct index (necessary since Optifine changed it along with names in E7) - Replaced the static 14 index with the dynamic "var14" (or "frustrum") one inside the if checks - Upped the version number to 1.4.1 Basically ported what i did with Betweenlands so it works with any version of Optifine or even without it. Again, huge thanks to makamys for helping me understand how variable adresses work. --- build.gradle | 2 +- .../core/FairyLightsClassTransformer.java | 29 +++++++++++++------ 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index 7571b389..e4747b7d 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ buildscript { apply plugin: 'forge' -version = "1.4.0" +version = "1.4.1" group= "com.pau101.fairylights" archivesBaseName = "fairylights" diff --git a/src/main/java/com/pau101/fairylights/core/FairyLightsClassTransformer.java b/src/main/java/com/pau101/fairylights/core/FairyLightsClassTransformer.java index 10f57848..62bce2f5 100644 --- a/src/main/java/com/pau101/fairylights/core/FairyLightsClassTransformer.java +++ b/src/main/java/com/pau101/fairylights/core/FairyLightsClassTransformer.java @@ -8,13 +8,7 @@ import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.FieldNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.VarInsnNode; +import org.objectweb.asm.tree.*; public class FairyLightsClassTransformer implements IClassTransformer { private Logger logger = Logger.getLogger("FairyLightsClassTransformer"); @@ -46,9 +40,25 @@ public byte[] transform(String name, String transformedName, byte[] basicClass) return basicClass; } + private int getLocalVarIndex(List list, String name, String name2) { + // Returns the index of a specific local variable name from the method. This is required for compatibility with any Optifine version. + // It uses a list which you can create in the specific method using method.localVariables, and two names since for some dumb reasons, + // The game can access varX fine with the latest Optifine but not the internal name, and the opposite otherwise. + + for (int i = 0; i < list.size(); i += 1) { + LocalVariableNode object = list.get(i); + if (object.name.equals(name) || object.name.equals(name2)) return object.index; + } + return -1; + + } + private boolean transformFrustumStore(boolean obf, List methods, String entityRendererOwner, String frustumDesc) { boolean replacedASTORE8 = false; for (MethodNode method : methods) { + List localVarList = method.localVariables; + int var14index = getLocalVarIndex(localVarList, "var14", "frustrum"); + if ("(FJ)V".equals(method.desc)) { InsnList instructions = method.instructions; for (int i = 0; i < instructions.size(); i++) { @@ -57,15 +67,16 @@ private boolean transformFrustumStore(boolean obf, List methods, Str // replace all things trying to get the frustum from the // stack frame to getting the frustum from the class // field - if (instruction.getOpcode() == Opcodes.ALOAD && ((VarInsnNode) instruction).var == 14) { + if (instruction.getOpcode() == Opcodes.ALOAD && ((VarInsnNode) instruction).var == var14index) { ((VarInsnNode) instruction).var = 0; instructions.insert(instruction, new FieldInsnNode(Opcodes.GETFIELD, entityRendererOwner, fieldNameAddition, frustumDesc)); } + } else { // instead of storing the newly created frustum into // slot 14 of the method stack frame, put in the added // class field for external access - if (instruction.getOpcode() == Opcodes.ASTORE && ((VarInsnNode) instruction).var == 14) { + if (instruction.getOpcode() == Opcodes.ASTORE && ((VarInsnNode) instruction).var == var14index) { InsnList newInsn = new InsnList(); instructions.insertBefore(instructions.get(i - 3), new VarInsnNode(Opcodes.ALOAD, 0)); instructions.set(instruction, new FieldInsnNode(Opcodes.PUTFIELD, entityRendererOwner, fieldNameAddition, frustumDesc));