forked from openrs2/openrs2
parent
113820a9a2
commit
9b1f0c6886
@ -0,0 +1,64 @@ |
||||
package dev.openrs2.deob.remap |
||||
|
||||
import dev.openrs2.asm.classpath.ClassMetadata |
||||
import dev.openrs2.asm.classpath.ClassPath |
||||
import dev.openrs2.asm.filter.ClassFilter |
||||
import org.objectweb.asm.Opcodes |
||||
|
||||
class ClassMappingGenerator( |
||||
private val classPath: ClassPath, |
||||
private val excludedClasses: ClassFilter |
||||
) { |
||||
private val nameGenerator = NameGenerator() |
||||
private val mapping = mutableMapOf<String, String>() |
||||
|
||||
fun generate(): Map<String, String> { |
||||
for (clazz in classPath.libraryClasses) { |
||||
populateMapping(clazz) |
||||
} |
||||
return mapping |
||||
} |
||||
|
||||
private fun populateMapping(clazz: ClassMetadata): String { |
||||
val name = clazz.name |
||||
if (mapping.containsKey(name) || !isRenamable(clazz)) { |
||||
return mapping.getOrDefault(name, name) |
||||
} |
||||
|
||||
val mappedName = generateName(clazz) |
||||
mapping[name] = mappedName |
||||
return mappedName |
||||
} |
||||
|
||||
private fun isRenamable(clazz: ClassMetadata): Boolean { |
||||
if (excludedClasses.matches(clazz.name) || clazz.dependency) { |
||||
return false |
||||
} |
||||
|
||||
for (method in clazz.methods) { |
||||
if (clazz.getMethodAccess(method)!! and Opcodes.ACC_NATIVE != 0) { |
||||
return false |
||||
} |
||||
} |
||||
|
||||
return true |
||||
} |
||||
|
||||
private fun generateName(clazz: ClassMetadata): String { |
||||
val name = clazz.name |
||||
var mappedName = name.substring(0, name.lastIndexOf('/') + 1) |
||||
|
||||
val superClass = clazz.superClass |
||||
if (superClass != null && superClass.name != "java/lang/Object") { |
||||
var superName = populateMapping(superClass) |
||||
superName = superName.substring(superName.lastIndexOf('/') + 1) |
||||
mappedName += nameGenerator.generate(superName + "_Sub") |
||||
} else if (clazz.`interface`) { |
||||
mappedName += nameGenerator.generate("Interface") |
||||
} else { |
||||
mappedName += nameGenerator.generate("Class") |
||||
} |
||||
|
||||
return mappedName |
||||
} |
||||
} |
@ -0,0 +1,71 @@ |
||||
package dev.openrs2.deob.remap |
||||
|
||||
import dev.openrs2.asm.MemberRef |
||||
import dev.openrs2.asm.classpath.ClassPath |
||||
import dev.openrs2.asm.filter.MemberFilter |
||||
import dev.openrs2.util.collect.DisjointSet |
||||
import dev.openrs2.util.indefiniteArticle |
||||
import org.objectweb.asm.Type |
||||
|
||||
class FieldMappingGenerator( |
||||
private val classPath: ClassPath, |
||||
private val excludedFields: MemberFilter, |
||||
private val classMapping: Map<String, String> |
||||
) { |
||||
private val inheritedFieldSets = classPath.createInheritedFieldSets() |
||||
private val nameGenerator = NameGenerator() |
||||
private val mapping = mutableMapOf<MemberRef, String>() |
||||
|
||||
fun generate(): Map<MemberRef, String> { |
||||
for (partition in inheritedFieldSets) { |
||||
if (!isRenamable(partition)) { |
||||
continue |
||||
} |
||||
|
||||
val type = Type.getType(partition.first().desc) |
||||
val mappedName = generateName(type) |
||||
for (field in partition) { |
||||
mapping[field] = mappedName |
||||
} |
||||
} |
||||
|
||||
return mapping |
||||
} |
||||
|
||||
private fun isRenamable(partition: DisjointSet.Partition<MemberRef>): Boolean { |
||||
for (field in partition) { |
||||
val clazz = classPath[field.owner]!! |
||||
|
||||
if (excludedFields.matches(field) || clazz.dependency) { |
||||
return false |
||||
} |
||||
} |
||||
|
||||
return true |
||||
} |
||||
|
||||
private fun generateName(type: Type): String { |
||||
val dimensions: String |
||||
val elementType: Type |
||||
if (type.sort == Type.ARRAY) { |
||||
dimensions = "Array".repeat(type.dimensions) |
||||
elementType = type.elementType |
||||
} else { |
||||
dimensions = "" |
||||
elementType = type |
||||
} |
||||
|
||||
val prefix = when (elementType.sort) { |
||||
Type.BOOLEAN, Type.BYTE, Type.CHAR, Type.SHORT, Type.INT, Type.LONG, Type.FLOAT, Type.DOUBLE -> { |
||||
elementType.className + dimensions |
||||
} |
||||
Type.OBJECT -> { |
||||
val className = classMapping.getOrDefault(elementType.internalName, elementType.internalName) |
||||
className.substring(className.lastIndexOf('/') + 1) + dimensions |
||||
} |
||||
else -> throw IllegalArgumentException("Unknown field type $elementType") |
||||
} |
||||
|
||||
return nameGenerator.generate(prefix.indefiniteArticle() + prefix.capitalize()) |
||||
} |
||||
} |
@ -0,0 +1,58 @@ |
||||
package dev.openrs2.deob.remap |
||||
|
||||
import dev.openrs2.asm.MemberDesc |
||||
import dev.openrs2.asm.MemberRef |
||||
import dev.openrs2.asm.classpath.ClassPath |
||||
import dev.openrs2.asm.filter.MemberFilter |
||||
import dev.openrs2.util.collect.DisjointSet |
||||
import org.objectweb.asm.Opcodes |
||||
|
||||
class MethodMappingGenerator( |
||||
private val classPath: ClassPath, |
||||
private val excludedMethods: MemberFilter |
||||
) { |
||||
private val inheritedMethodSets = classPath.createInheritedMethodSets() |
||||
private var index = 0 |
||||
|
||||
fun generate(): Map<MemberRef, String> { |
||||
val mapping = mutableMapOf<MemberRef, String>() |
||||
|
||||
for (partition in inheritedMethodSets) { |
||||
@Suppress("DEPRECATION") |
||||
if (!isRenamable(classPath, excludedMethods, partition)) { |
||||
continue |
||||
} |
||||
|
||||
val mappedName = "method" + ++index |
||||
for (method in partition) { |
||||
mapping[method] = mappedName |
||||
} |
||||
} |
||||
|
||||
return mapping |
||||
} |
||||
|
||||
companion object { |
||||
@Deprecated("No replacement yet") |
||||
fun isRenamable( |
||||
classPath: ClassPath, |
||||
excludedMethods: MemberFilter, |
||||
partition: DisjointSet.Partition<MemberRef> |
||||
): Boolean { |
||||
for (method in partition) { |
||||
val clazz = classPath[method.owner]!! |
||||
|
||||
if (excludedMethods.matches(method) || clazz.dependency) { |
||||
return false |
||||
} |
||||
|
||||
val access = clazz.getMethodAccess(MemberDesc(method)) |
||||
if (access != null && access and Opcodes.ACC_NATIVE != 0) { |
||||
return false |
||||
} |
||||
} |
||||
|
||||
return true |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,19 @@ |
||||
package dev.openrs2.deob.remap |
||||
|
||||
class NameGenerator { |
||||
private val prefixes = mutableMapOf<String, Int>() |
||||
|
||||
fun generate(prefix: String): String { |
||||
require(prefix.isNotEmpty()) |
||||
|
||||
val separator = if (prefix.last().isDigit()) { |
||||
"_" |
||||
} else { |
||||
"" |
||||
} |
||||
|
||||
val index = prefixes.merge(prefix, 1, Integer::sum) |
||||
|
||||
return prefix + separator + index |
||||
} |
||||
} |
Loading…
Reference in new issue