diff --git a/deob/src/main/java/dev/openrs2/deob/classpath/ClassPath.java b/deob/src/main/java/dev/openrs2/deob/classpath/ClassPath.java index f04f13f7c4..5aea456aae 100644 --- a/deob/src/main/java/dev/openrs2/deob/classpath/ClassPath.java +++ b/deob/src/main/java/dev/openrs2/deob/classpath/ClassPath.java @@ -3,10 +3,16 @@ package dev.openrs2.deob.classpath; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import dev.openrs2.asm.Library; +import dev.openrs2.asm.MemberDesc; +import dev.openrs2.asm.MemberRef; +import dev.openrs2.util.collect.DisjointSet; +import dev.openrs2.util.collect.ForestDisjointSet; public final class ClassPath { private final ClassLoader runtime; @@ -68,4 +74,122 @@ public final class ClassPath { cache.put(name, metadata); return metadata; } + + public DisjointSet createInheritedFieldSets() { + var disjointSet = new ForestDisjointSet(); + var ancestorCache = new HashMap>(); + + for (var library : libraries) { + for (var clazz : library) { + populateInheritedFieldSets(ancestorCache, disjointSet, get(clazz.name)); + } + } + + return disjointSet; + } + + private Set populateInheritedFieldSets(Map> ancestorCache, DisjointSet disjointSet, ClassMetadata clazz) { + var ancestors = ancestorCache.get(clazz); + if (ancestors != null) { + return ancestors; + } + ancestors = new HashSet<>(); + + var superClass = clazz.getSuperClass(); + if (superClass != null) { + var fields = populateInheritedFieldSets(ancestorCache, disjointSet, superClass); + + for (var field : fields) { + var partition1 = disjointSet.add(new MemberRef(clazz.getName(), field)); + var partition2 = disjointSet.add(new MemberRef(superClass.getName(), field)); + disjointSet.union(partition1, partition2); + } + + ancestors.addAll(fields); + } + + for (var superInterface : clazz.getSuperInterfaces()) { + var fields = populateInheritedFieldSets(ancestorCache, disjointSet, superInterface); + + for (var field : fields) { + var partition1 = disjointSet.add(new MemberRef(clazz.getName(), field)); + var partition2 = disjointSet.add(new MemberRef(superInterface.getName(), field)); + disjointSet.union(partition1, partition2); + } + + ancestors.addAll(fields); + } + + for (var field : clazz.getFields()) { + if (TypedRemapper.EXCLUDED_FIELDS.contains(field.getName())) { + continue; + } + + disjointSet.add(new MemberRef(clazz.getName(), field)); + ancestors.add(field); + } + + ancestors = Collections.unmodifiableSet(ancestors); + ancestorCache.put(clazz, ancestors); + return ancestors; + } + + public DisjointSet createInheritedMethodSets() { + var disjointSet = new ForestDisjointSet(); + var ancestorCache = new HashMap>(); + + for (var library : libraries) { + for (var clazz : library) { + populateInheritedMethodSets(ancestorCache, disjointSet, get(clazz.name)); + } + } + + return disjointSet; + } + + private Set populateInheritedMethodSets(Map> ancestorCache, DisjointSet disjointSet, ClassMetadata clazz) { + var ancestors = ancestorCache.get(clazz); + if (ancestors != null) { + return ancestors; + } + ancestors = new HashSet<>(); + + var superClass = clazz.getSuperClass(); + if (superClass != null) { + var methods = populateInheritedMethodSets(ancestorCache, disjointSet, superClass); + + for (var method : methods) { + var partition1 = disjointSet.add(new MemberRef(clazz.getName(), method)); + var partition2 = disjointSet.add(new MemberRef(superClass.getName(), method)); + disjointSet.union(partition1, partition2); + } + + ancestors.addAll(methods); + } + + for (var superInterface : clazz.getSuperInterfaces()) { + var methods = populateInheritedMethodSets(ancestorCache, disjointSet, superInterface); + + for (var method : methods) { + var partition1 = disjointSet.add(new MemberRef(clazz.getName(), method)); + var partition2 = disjointSet.add(new MemberRef(superInterface.getName(), method)); + disjointSet.union(partition1, partition2); + } + + ancestors.addAll(methods); + } + + for (var method : clazz.getMethods()) { + if (TypedRemapper.EXCLUDED_METHODS.contains(method.getName())) { + continue; + } + + disjointSet.add(new MemberRef(clazz.getName(), method)); + ancestors.add(method); + } + + ancestors = Collections.unmodifiableSet(ancestors); + ancestorCache.put(clazz, ancestors); + return ancestors; + } } diff --git a/deob/src/main/java/dev/openrs2/deob/classpath/TypedRemapper.java b/deob/src/main/java/dev/openrs2/deob/classpath/TypedRemapper.java index 0bcafdd2ea..c91389af48 100644 --- a/deob/src/main/java/dev/openrs2/deob/classpath/TypedRemapper.java +++ b/deob/src/main/java/dev/openrs2/deob/classpath/TypedRemapper.java @@ -1,8 +1,6 @@ package dev.openrs2.deob.classpath; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -12,7 +10,6 @@ import dev.openrs2.asm.MemberDesc; import dev.openrs2.asm.MemberRef; import dev.openrs2.util.StringUtils; import dev.openrs2.util.collect.DisjointSet; -import dev.openrs2.util.collect.ForestDisjointSet; import org.objectweb.asm.Type; import org.objectweb.asm.commons.Remapper; import org.slf4j.Logger; @@ -41,12 +38,10 @@ public final class TypedRemapper extends Remapper { private static final int MAX_OBFUSCATED_NAME_LEN = 2; public static TypedRemapper create(ClassPath classPath) { - var libraryClasses = classPath.getLibraryClasses(); + var inheritedFieldSets = classPath.createInheritedFieldSets(); + var inheritedMethodSets = classPath.createInheritedMethodSets(); - var inheritedFieldSets = createInheritedFieldSets(libraryClasses); - var inheritedMethodSets = createInheritedMethodSets(libraryClasses); - - var classes = createClassMapping(libraryClasses); + var classes = createClassMapping(classPath.getLibraryClasses()); var fields = createFieldMapping(classPath, inheritedFieldSets, classes); var methods = createMethodMapping(classPath, inheritedMethodSets); @@ -76,120 +71,6 @@ public final class TypedRemapper extends Remapper { } } - private static DisjointSet createInheritedFieldSets(List classes) { - var disjointSet = new ForestDisjointSet(); - var ancestorCache = new HashMap>(); - - for (var clazz : classes) { - populateInheritedFieldSets(ancestorCache, disjointSet, clazz); - } - - return disjointSet; - } - - private static Set populateInheritedFieldSets(Map> ancestorCache, DisjointSet disjointSet, ClassMetadata clazz) { - var ancestors = ancestorCache.get(clazz); - if (ancestors != null) { - return ancestors; - } - ancestors = new HashSet<>(); - - var superClass = clazz.getSuperClass(); - if (superClass != null) { - var fields = populateInheritedFieldSets(ancestorCache, disjointSet, superClass); - - for (var field : fields) { - var partition1 = disjointSet.add(new MemberRef(clazz.getName(), field)); - var partition2 = disjointSet.add(new MemberRef(superClass.getName(), field)); - disjointSet.union(partition1, partition2); - } - - ancestors.addAll(fields); - } - - for (var superInterface : clazz.getSuperInterfaces()) { - var fields = populateInheritedFieldSets(ancestorCache, disjointSet, superInterface); - - for (var field : fields) { - var partition1 = disjointSet.add(new MemberRef(clazz.getName(), field)); - var partition2 = disjointSet.add(new MemberRef(superInterface.getName(), field)); - disjointSet.union(partition1, partition2); - } - - ancestors.addAll(fields); - } - - for (var field : clazz.getFields()) { - if (EXCLUDED_FIELDS.contains(field.getName())) { - continue; - } - - disjointSet.add(new MemberRef(clazz.getName(), field)); - ancestors.add(field); - } - - ancestors = Collections.unmodifiableSet(ancestors); - ancestorCache.put(clazz, ancestors); - return ancestors; - } - - private static DisjointSet createInheritedMethodSets(List classes) { - var disjointSet = new ForestDisjointSet(); - var ancestorCache = new HashMap>(); - - for (var clazz : classes) { - populateInheritedMethodSets(ancestorCache, disjointSet, clazz); - } - - return disjointSet; - } - - private static Set populateInheritedMethodSets(Map> ancestorCache, DisjointSet disjointSet, ClassMetadata clazz) { - var ancestors = ancestorCache.get(clazz); - if (ancestors != null) { - return ancestors; - } - ancestors = new HashSet<>(); - - var superClass = clazz.getSuperClass(); - if (superClass != null) { - var methods = populateInheritedMethodSets(ancestorCache, disjointSet, superClass); - - for (var method : methods) { - var partition1 = disjointSet.add(new MemberRef(clazz.getName(), method)); - var partition2 = disjointSet.add(new MemberRef(superClass.getName(), method)); - disjointSet.union(partition1, partition2); - } - - ancestors.addAll(methods); - } - - for (var superInterface : clazz.getSuperInterfaces()) { - var methods = populateInheritedMethodSets(ancestorCache, disjointSet, superInterface); - - for (var method : methods) { - var partition1 = disjointSet.add(new MemberRef(clazz.getName(), method)); - var partition2 = disjointSet.add(new MemberRef(superInterface.getName(), method)); - disjointSet.union(partition1, partition2); - } - - ancestors.addAll(methods); - } - - for (var method : clazz.getMethods()) { - if (EXCLUDED_METHODS.contains(method.getName())) { - continue; - } - - disjointSet.add(new MemberRef(clazz.getName(), method)); - ancestors.add(method); - } - - ancestors = Collections.unmodifiableSet(ancestors); - ancestorCache.put(clazz, ancestors); - return ancestors; - } - private static String generateName(Map prefixes, String prefix) { return prefix + prefixes.merge(prefix, 1, Integer::sum); }