diff --git a/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java b/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java deleted file mode 100644 index dd14e8cb8c..0000000000 --- a/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.java +++ /dev/null @@ -1,124 +0,0 @@ -package dev.openrs2.deob.transform; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import dev.openrs2.asm.InsnMatcher; -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.tree.AbstractInsnNode; -import org.objectweb.asm.tree.ClassNode; -import org.objectweb.asm.tree.FieldInsnNode; -import org.objectweb.asm.tree.MethodNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public final class CounterTransformer extends Transformer { - private static final Logger logger = LoggerFactory.getLogger(CounterTransformer.class); - - private static final InsnMatcher RESET_PATTERN = InsnMatcher.compile("ICONST_0 PUTSTATIC"); - private static final InsnMatcher INCREMENT_PATTERN = InsnMatcher.compile("GETSTATIC ICONST_1 IADD PUTSTATIC"); - - private final Set counters = new HashSet<>(); - - @Override - public void preTransform(ClassPath classPath) { - counters.clear(); - - var references = new HashMap(); - var resets = new HashMap(); - var increments = new HashMap(); - - for (var library : classPath.getLibraries()) { - for (var clazz : library) { - for (var method : clazz.methods) { - if (MethodNodeUtilsKt.hasCode(method)) { - findCounters(method, references, resets, increments); - } - } - } - } - - deleteCounters(classPath, references, resets, increments); - } - - private void findCounters(MethodNode method, Map references, Map resets, Map increments) { - for (var it = method.instructions.iterator(); it.hasNext(); ) { - var insn = it.next(); - if (insn.getType() != AbstractInsnNode.FIELD_INSN) { - continue; - } - - var fieldInsn = (FieldInsnNode) insn; - references.merge(new MemberRef(fieldInsn), 1, Integer::sum); - } - - RESET_PATTERN.match(method).forEach(match -> { - var putstatic = (FieldInsnNode) match.get(1); - resets.merge(new MemberRef(putstatic), 1, Integer::sum); - }); - - INCREMENT_PATTERN.match(method).forEach(match -> { - var getstatic = (FieldInsnNode) match.get(0); - var putstatic = (FieldInsnNode) match.get(3); - if (getstatic.owner.equals(putstatic.owner) && getstatic.name.equals(putstatic.name) && getstatic.desc.equals(putstatic.desc)) { - increments.merge(new MemberRef(putstatic), 1, Integer::sum); - } - }); - } - - private void deleteCounters(ClassPath classPath, Map references, Map resets, Map increments) { - for (Map.Entry entry : references.entrySet()) { - var counter = entry.getKey(); - - if (entry.getValue() != 3) { /* one for the reset, two for the increment */ - continue; - } - - if (resets.getOrDefault(counter, 0) != 1) { - continue; - } - - if (increments.getOrDefault(counter, 0) != 1) { - continue; - } - - ClassNode owner = classPath.getNode(counter.getOwner()); - owner.fields.removeIf(f -> f.name.equals(counter.getName()) && f.desc.equals(counter.getDesc())); - - counters.add(counter); - } - } - - @Override - public boolean transformCode(ClassPath classPath, Library library, ClassNode clazz, MethodNode method) { - RESET_PATTERN.match(method).forEach(match -> { - var putstatic = (FieldInsnNode) match.get(1); - if (counters.contains(new MemberRef(putstatic))) { - match.forEach(method.instructions::remove); - } - }); - - INCREMENT_PATTERN.match(method).forEach(match -> { - var getstatic = (FieldInsnNode) match.get(0); - var putstatic = (FieldInsnNode) match.get(3); - - if (getstatic.owner.equals(putstatic.owner) && getstatic.name.equals(putstatic.name) && getstatic.desc.equals(putstatic.desc) && - counters.contains(new MemberRef(putstatic))) { - match.forEach(method.instructions::remove); - } - }); - - return false; - } - - @Override - public void postTransform(ClassPath classPath) { - logger.info("Removed {} counters", counters.size()); - } -} diff --git a/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.kt b/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.kt new file mode 100644 index 0000000000..8d792eb9e3 --- /dev/null +++ b/deob/src/main/java/dev/openrs2/deob/transform/CounterTransformer.kt @@ -0,0 +1,122 @@ +package dev.openrs2.deob.transform + +import com.github.michaelbull.logging.InlineLogger +import dev.openrs2.asm.InsnMatcher +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.transform.Transformer +import org.objectweb.asm.tree.ClassNode +import org.objectweb.asm.tree.FieldInsnNode +import org.objectweb.asm.tree.MethodNode + +class CounterTransformer : Transformer() { + private val counters = mutableSetOf() + + override fun preTransform(classPath: ClassPath) { + counters.clear() + + val references = mutableMapOf() + val resets = mutableMapOf() + val increments = mutableMapOf() + + for (library in classPath.libraries) { + for (clazz in library) { + for (method in clazz.methods) { + if (method.hasCode()) { + findCounters(method, references, resets, increments) + } + } + } + } + + deleteCounters(classPath, references, resets, increments) + } + + private fun findCounters( + method: MethodNode, + references: MutableMap, + resets: MutableMap, + increments: MutableMap + ) { + for (insn in method.instructions) { + if (insn is FieldInsnNode) { + references.merge(MemberRef(insn), 1, Integer::sum) + } + } + + RESET_PATTERN.match(method).forEach { + val putstatic = MemberRef(it[1] as FieldInsnNode) + resets.merge(putstatic, 1, Integer::sum) + } + + INCREMENT_PATTERN.match(method).forEach { + val getstatic = MemberRef(it[0] as FieldInsnNode) + val putstatic = MemberRef(it[3] as FieldInsnNode) + if (getstatic == putstatic) { + increments.merge(putstatic, 1, Integer::sum) + } + } + } + + private fun deleteCounters( + classPath: ClassPath, + references: Map, + resets: Map, + increments: Map + ) { + for ((counter, value) in references) { + // one for the reset, two for the increment + if (value != 3) { + continue + } + + if (resets[counter] != 1) { + continue + } + + if (increments[counter] != 1) { + continue + } + + val owner = classPath.getNode(counter.owner)!! + owner.fields.removeIf { it.name == counter.name && it.desc == counter.desc } + counters.add(counter) + } + } + + override fun transformCode( + classPath: ClassPath, + library: Library, + clazz: ClassNode, + method: MethodNode + ): Boolean { + RESET_PATTERN.match(method).forEach { + val putstatic = it[1] as FieldInsnNode + if (counters.contains(MemberRef(putstatic))) { + it.forEach(method.instructions::remove) + } + } + + INCREMENT_PATTERN.match(method).forEach { + val getstatic = MemberRef(it[0] as FieldInsnNode) + val putstatic = MemberRef(it[3] as FieldInsnNode) + if (getstatic == putstatic && counters.contains(putstatic)) { + it.forEach(method.instructions::remove) + } + } + + return false + } + + override fun postTransform(classPath: ClassPath) { + logger.info { "Removed ${counters.size} counters" } + } + + companion object { + private val logger = InlineLogger() + private val RESET_PATTERN = InsnMatcher.compile("ICONST_0 PUTSTATIC") + private val INCREMENT_PATTERN = InsnMatcher.compile("GETSTATIC ICONST_1 IADD PUTSTATIC") + } +}