QuickMath/src/main/java/io/gitlab/jfronny/quickmeth/BytecodeTransformer.java
2021-10-25 15:16:47 +02:00

81 lines
3.6 KiB
Java

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<String> skipClasses() {
return null;
}
@Override
public Set<Patch> 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);
}
}
}
}
}
}