diff --git a/deob/src/main/java/dev/openrs2/deob/transform/ResetTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/ResetTransformer.java deleted file mode 100644 index bc8be3ea..00000000 --- a/deob/src/main/java/dev/openrs2/deob/transform/ResetTransformer.java +++ /dev/null @@ -1,128 +0,0 @@ -package dev.openrs2.deob.transform; - -import java.util.HashSet; -import java.util.Set; - -import dev.openrs2.asm.InsnNodeUtilsKt; -import dev.openrs2.asm.MemberRef; -import dev.openrs2.asm.MethodNodeUtilsKt; -import dev.openrs2.asm.classpath.ClassPath; -import dev.openrs2.asm.classpath.Library; -import dev.openrs2.asm.transform.Transformer; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.InsnNode; -import org.objectweb.asm.tree.LdcInsnNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.VarInsnNode; -import org.objectweb.asm.tree.analysis.AnalyzerException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class ResetTransformer extends Transformer { - private static final Logger logger = LoggerFactory.getLogger(ResetTransformer.class); - - private static MemberRef findMasterReset(MethodNode method) { - AbstractInsnNode shutdownLdc = null; - - for (var insn : method.instructions) { - if (insn.getOpcode() != Opcodes.LDC) { - continue; - } - - var ldc = (LdcInsnNode) insn; - if (ldc.cst.equals("Shutdown complete - clean:")) { - shutdownLdc = ldc; - break; - } - } - - for (var insn = shutdownLdc; insn != null; insn = insn.getPrevious()) { - if (insn.getOpcode() != Opcodes.ALOAD) { - continue; - } - - var load = (VarInsnNode) insn; - if (load.var != 0) { - continue; - } - - var nextInsn = InsnNodeUtilsKt.getNextReal(insn); - if (nextInsn.getOpcode() != Opcodes.INVOKEVIRTUAL) { - continue; - } - - var invoke = (MethodInsnNode) nextInsn; - if (!invoke.desc.equals("()V")) { - continue; - } - - return new MemberRef(invoke); - } - - return null; - } - - private static void findResetMethods(Set resetMethods, ClassNode clazz, MethodNode method) throws AnalyzerException { - MethodNodeUtilsKt.removeDeadCode(method, clazz.name); - - for (var insn : method.instructions) { - if (insn.getOpcode() != Opcodes.INVOKESTATIC) { - continue; - } - - var invoke = (MethodInsnNode) insn; - resetMethods.add(new MemberRef(invoke)); - } - } - - private final Set resetMethods = new HashSet<>(); - - @Override - protected void preTransform(ClassPath classPath) throws AnalyzerException { - resetMethods.clear(); - - for (var library : classPath.getLibraries()) { - for (var clazz : library) { - for (var method : clazz.methods) { - if (!MethodNodeUtilsKt.hasCode(method)) { - continue; - } - - var masterReset = findMasterReset(method); - if (masterReset == null) { - continue; - } - - logger.info("Identified master reset method: {}", masterReset); - - var resetClass = classPath.getNode("client"); - var resetMethod = resetClass.methods.stream() - .filter(m -> m.name.equals(masterReset.getName()) && m.desc.equals(masterReset.getDesc())) - .findAny() - .orElseThrow(); - - findResetMethods(resetMethods, resetClass, resetMethod); - - resetMethod.instructions.clear(); - resetMethod.tryCatchBlocks.clear(); - - resetMethod.instructions.add(new InsnNode(Opcodes.RETURN)); - } - } - } - } - - @Override - protected boolean transformClass(ClassPath classPath, Library library, ClassNode clazz) { - clazz.methods.removeIf(m -> resetMethods.contains(new MemberRef(clazz, m))); - return false; - } - - @Override - protected void postTransform(ClassPath classPath) { - logger.info("Removed {} reset methods", resetMethods.size()); - } -} diff --git a/deob/src/main/java/dev/openrs2/deob/transform/ResetTransformer.kt b/deob/src/main/java/dev/openrs2/deob/transform/ResetTransformer.kt new file mode 100644 index 00000000..cf1e9a5a --- /dev/null +++ b/deob/src/main/java/dev/openrs2/deob/transform/ResetTransformer.kt @@ -0,0 +1,108 @@ +package dev.openrs2.deob.transform + +import com.github.michaelbull.logging.InlineLogger +import dev.openrs2.asm.MemberRef +import dev.openrs2.asm.classpath.ClassPath +import dev.openrs2.asm.classpath.Library +import dev.openrs2.asm.hasCode +import dev.openrs2.asm.nextReal +import dev.openrs2.asm.removeDeadCode +import dev.openrs2.asm.transform.Transformer +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* +import org.objectweb.asm.tree.analysis.AnalyzerException + +class ResetTransformer : Transformer() { + private val resetMethods = mutableSetOf() + + @Throws(AnalyzerException::class) + override fun preTransform(classPath: ClassPath) { + resetMethods.clear() + + for (library in classPath.libraries) { + for (clazz in library) { + for (method in clazz.methods) { + if (!method.hasCode()) { + continue + } + + val masterReset = findMasterReset(method) ?: continue + logger.info { "Identified master reset method: $masterReset" } + + val resetClass = classPath.getNode("client")!! + val resetMethod = resetClass.methods.first { + it.name == masterReset.name && it.desc == masterReset.desc + } + + findResetMethods(resetMethods, resetClass, resetMethod) + + resetMethod.instructions.clear() + resetMethod.tryCatchBlocks.clear() + resetMethod.instructions.add(InsnNode(Opcodes.RETURN)) + } + } + } + } + + override fun transformClass(classPath: ClassPath, library: Library, clazz: ClassNode): Boolean { + clazz.methods.removeIf { resetMethods.contains(MemberRef(clazz, it)) } + return false + } + + override fun postTransform(classPath: ClassPath) { + logger.info { "Removed ${resetMethods.size} reset methods" } + } + + companion object { + private val logger = InlineLogger() + + private fun findMasterReset(method: MethodNode): MemberRef? { + var shutdownLdc: AbstractInsnNode? = null + for (insn in method.instructions) { + if (insn is LdcInsnNode && insn.cst == "Shutdown complete - clean:") { + shutdownLdc = insn + break + } + } + + var insn = shutdownLdc + while (insn != null) { + if (insn !is VarInsnNode || insn.opcode != Opcodes.ALOAD) { + insn = insn.previous + continue + } + + if (insn.`var` != 0) { + insn = insn.previous + continue + } + + val nextInsn = insn.nextReal + if (nextInsn !is MethodInsnNode || nextInsn.opcode != Opcodes.INVOKEVIRTUAL) { + insn = insn.previous + continue + } + + if (nextInsn.desc != "()V") { + insn = insn.previous + continue + } + + return MemberRef(nextInsn) + } + + return null + } + + @Throws(AnalyzerException::class) + private fun findResetMethods(resetMethods: MutableSet, clazz: ClassNode, method: MethodNode) { + method.removeDeadCode(clazz.name) + + for (insn in method.instructions) { + if (insn is MethodInsnNode && insn.opcode == Opcodes.INVOKESTATIC) { + resetMethods.add(MemberRef(insn)) + } + } + } + } +}