diff --git a/src/main/java/net/runelite/deob/deobfuscators/UnusedFields.java b/src/main/java/net/runelite/deob/deobfuscators/UnusedFields.java index 392c6125af..110bd97df0 100644 --- a/src/main/java/net/runelite/deob/deobfuscators/UnusedFields.java +++ b/src/main/java/net/runelite/deob/deobfuscators/UnusedFields.java @@ -1,6 +1,8 @@ package net.runelite.deob.deobfuscators; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; @@ -10,59 +12,46 @@ import net.runelite.asm.Method; import net.runelite.asm.attributes.Code; import net.runelite.asm.attributes.code.Instruction; import net.runelite.asm.attributes.code.instruction.types.FieldInstruction; -import net.runelite.asm.attributes.code.instruction.types.GetFieldInstruction; -import net.runelite.asm.attributes.code.instruction.types.SetFieldInstruction; public class UnusedFields implements Deobfuscator { - private static boolean isUnused(ClassGroup group, Field field) + private final Set used = new HashSet<>(); + + private void checkForFieldUsage(ClassGroup group) { - int get = 0, set = 0; for (ClassFile cf : group.getClasses()) for (Method m : cf.getMethods().getMethods()) { Code code = m.getCode(); if (code == null) continue; - + for (Instruction ins : code.getInstructions().getInstructions()) { if (ins instanceof FieldInstruction) { FieldInstruction fi = (FieldInstruction) ins; - - if (fi.getMyField() != field) - continue; - if (ins instanceof GetFieldInstruction) - ++get; - if (ins instanceof SetFieldInstruction) - ++set; + used.add(fi.getMyField()); } } } - - // for only checking 'get' wed need a way to remove field initialization in constructors/class initializers - return get + set == 0; -// if (get == 0) -// return true; -// -// return false; } @Override public void run(ClassGroup group) { + checkForFieldUsage(group); + int count = 0; for (ClassFile cf : group.getClasses()) for (Field f : new ArrayList<>(cf.getFields().getFields())) - { - if (isUnused(group, f)) + if (!used.contains(f)) { cf.getFields().getFields().remove(f); ++count; } - } + System.out.println("Removed " + count + " unused fields"); } } diff --git a/src/test/java/net/runelite/deob/deobfuscators/UnusedFieldsTest.java b/src/test/java/net/runelite/deob/deobfuscators/UnusedFieldsTest.java new file mode 100644 index 0000000000..ffddd89bfa --- /dev/null +++ b/src/test/java/net/runelite/deob/deobfuscators/UnusedFieldsTest.java @@ -0,0 +1,40 @@ +package net.runelite.deob.deobfuscators; + +import java.io.File; +import java.io.IOException; +import net.runelite.asm.ClassGroup; +import net.runelite.deob.util.JarUtil; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +public class UnusedFieldsTest +{ + private static final File GAMEPACK = new File(RenameUniqueTest.class.getResource("/gamepack_v16.jar").getFile()); + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private ClassGroup group; + + @Before + public void before() throws IOException + { + group = JarUtil.loadJar(GAMEPACK); + } + + @After + public void after() throws IOException + { + JarUtil.saveJar(group, folder.newFile()); + } + + @Test + public void testRun() + { + UnusedFields uf = new UnusedFields(); + uf.run(group); + } +}