package io.gitlab.jfronny.quickmeth; import io.gitlab.jfronny.libjf.unsafe.asm.AsmConfig; import io.gitlab.jfronny.libjf.unsafe.asm.AsmTransformer; import io.gitlab.jfronny.libjf.unsafe.asm.patch.Patch; import io.gitlab.jfronny.libjf.unsafe.asm.patch.PatchUtil; import org.objectweb.asm.Opcodes; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import java.util.Set; public class BytecodeTransformer implements AsmConfig, Patch { private static final String math = "java/lang/Math"; private static final String mathUtil = "io/gitlab/jfronny/quickmeth/MathUtil"; private static final String mathHelper = PatchUtil.getRemappedInternal("net/minecraft/class_3532"); private static final String mathHelperSin = mapMathHelper("method_15374", "(F)F"); private static final String mathHelperCos = mapMathHelper("method_15362", "(F)F"); private static final String mathHelperSqrt = mapMathHelper("method_15355", "(F)F"); private static final String mathHelperFloor = mapMathHelper("method_15375", "(F)F"); private static String mapMathHelper(String method, String descriptor) { return AsmTransformer.MAPPING_RESOLVER.mapMethodName(AsmTransformer.INTERMEDIARY, mathHelper.replace('/', '.'), method, descriptor); } @Override public Set skipClasses() { return null; } @Override public Set getPatches() { return Cfg.rewriteMath ? Set.of(this) : Set.of(); } @Override public void apply(ClassNode klazz) { if (klazz.name.equals(mathUtil)) return; for (MethodNode method : klazz.methods) { for (AbstractInsnNode insn : method.instructions.toArray()) { if (insn.getOpcode() == Opcodes.INVOKESTATIC) { MethodInsnNode mIns = (MethodInsnNode) insn; String insNew = null; if (Cfg.corruptTrigonometry) { if (mIns.owner.equals(math)) { if (mIns.name.equals("sin")) insNew = "sin"; else if (mIns.name.equals("cos")) insNew = "cos"; } else if (mIns.owner.equals(mathHelper)) { if (mIns.name.equals(mathHelperSin)) insNew = "sin"; else if (mIns.name.equals(mathHelperCos)) insNew = "cos"; } } if (Cfg.corruptGenericMath) { if (mIns.owner.equals(math)) { if (mIns.name.equals("sqrt")) insNew = "sqrt"; } else if (mIns.owner.equals(mathHelper)) { if (mIns.name.equals(mathHelperSqrt)) insNew = "sqrt"; } } if (Cfg.corruptGenericMath2) { if (mIns.owner.equals(math)) { if (mIns.name.equals("floor")) insNew = "floor"; } else if (mIns.owner.equals(mathHelper)) { if (mIns.name.equals(mathHelperFloor)) insNew = "floor"; } } if (insNew != null) { method.instructions.insertBefore(mIns, new MethodInsnNode(Opcodes.INVOKESTATIC, mathUtil, insNew, mIns.desc)); method.instructions.remove(mIns); } } } } } }