|
|
|
@ -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<MemberRef> createInheritedFieldSets(List<ClassMetadata> classes) { |
|
|
|
|
var disjointSet = new ForestDisjointSet<MemberRef>(); |
|
|
|
|
var ancestorCache = new HashMap<ClassMetadata, Set<MemberDesc>>(); |
|
|
|
|
|
|
|
|
|
for (var clazz : classes) { |
|
|
|
|
populateInheritedFieldSets(ancestorCache, disjointSet, clazz); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return disjointSet; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Set<MemberDesc> populateInheritedFieldSets(Map<ClassMetadata, Set<MemberDesc>> ancestorCache, DisjointSet<MemberRef> 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<MemberRef> createInheritedMethodSets(List<ClassMetadata> classes) { |
|
|
|
|
var disjointSet = new ForestDisjointSet<MemberRef>(); |
|
|
|
|
var ancestorCache = new HashMap<ClassMetadata, Set<MemberDesc>>(); |
|
|
|
|
|
|
|
|
|
for (var clazz : classes) { |
|
|
|
|
populateInheritedMethodSets(ancestorCache, disjointSet, clazz); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return disjointSet; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static Set<MemberDesc> populateInheritedMethodSets(Map<ClassMetadata, Set<MemberDesc>> ancestorCache, DisjointSet<MemberRef> 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<String, Integer> prefixes, String prefix) { |
|
|
|
|
return prefix + prefixes.merge(prefix, 1, Integer::sum); |
|
|
|
|
} |
|
|
|
|