@ -5,6 +5,9 @@ import dev.openrs2.asm.MemberDesc
import dev.openrs2.asm.MemberRef
import dev.openrs2.asm.MemberRef
import dev.openrs2.asm.classpath.ClassMetadata
import dev.openrs2.asm.classpath.ClassMetadata
import dev.openrs2.asm.classpath.ClassPath
import dev.openrs2.asm.classpath.ClassPath
import dev.openrs2.asm.filter.ClassFilter
import dev.openrs2.asm.filter.MemberFilter
import dev.openrs2.deob.Profile
import dev.openrs2.util.collect.DisjointSet
import dev.openrs2.util.collect.DisjointSet
import dev.openrs2.util.indefiniteArticle
import dev.openrs2.util.indefiniteArticle
import org.objectweb.asm.Opcodes
import org.objectweb.asm.Opcodes
@ -31,57 +34,38 @@ class TypedRemapper private constructor(
companion object {
companion object {
private val logger = InlineLogger ( )
private val logger = InlineLogger ( )
val EXCLUDED _CLASSES = setOf (
" client " ,
" jagex3/jagmisc/jagmisc " ,
" loader " ,
" unpack " ,
" unpackclass "
)
val EXCLUDED _METHODS = setOf (
" <clinit> " ,
" <init> " ,
" main " ,
" providesignlink " ,
" quit "
)
val EXCLUDED _FIELDS = setOf (
" cache "
)
private val LIBRARY _PREFIX _REGEX = Regex ( " ^(?:loader|unpackclass)_ " )
private val LIBRARY _PREFIX _REGEX = Regex ( " ^(?:loader|unpackclass)_ " )
private const val MAX _OBFUSCATED _NAME _LEN = 2
fun create ( classPath : ClassPath ) : TypedRemapper {
fun create ( classPath : ClassPath , profile : Profile ) : TypedRemapper {
val inheritedFieldSets = classPath . createInheritedFieldSets ( )
val inheritedFieldSets = classPath . createInheritedFieldSets ( )
val inheritedMethodSets = classPath . createInheritedMethodSets ( )
val inheritedMethodSets = classPath . createInheritedMethodSets ( )
val classes = createClassMapping ( classPath )
val classes = createClassMapping ( classPath , profile . excludedClasses )
val fields = createFieldMapping ( classPath , inheritedFieldSets , classes )
val fields = createFieldMapping ( classPath , profile . excludedFields , inheritedFieldSets , classes )
val methods = createMethodMapping ( classPath , inheritedMethodSets )
val methods = createMethodMapping ( classPath , profile . excludedMethods , inheritedMethodSets )
verifyMapping ( classes )
verifyMapping ( classes , profile . maxObfuscatedNameLen )
verifyMemberMapping ( fields )
verifyMemberMapping ( fields , profile . maxObfuscatedNameLen )
verifyMemberMapping ( methods )
verifyMemberMapping ( methods , profile . maxObfuscatedNameLen )
return TypedRemapper ( classes , fields , methods )
return TypedRemapper ( classes , fields , methods )
}
}
private fun verifyMapping ( mapping : Map < String , String > ) {
private fun verifyMapping ( mapping : Map < String , String > , maxObfuscatedNameLen : Int ) {
for ( ( key , value ) in mapping ) {
for ( ( key , value ) in mapping ) {
verifyMapping ( key , value )
verifyMapping ( key , value , maxObfuscatedNameLen )
}
}
}
}
private fun verifyMemberMapping ( mapping : Map < MemberRef , String > ) {
private fun verifyMemberMapping ( mapping : Map < MemberRef , String > , maxObfuscatedNameLen : Int ) {
for ( ( key , value ) in mapping ) {
for ( ( key , value ) in mapping ) {
verifyMapping ( key . name , value )
verifyMapping ( key . name , value , maxObfuscatedNameLen )
}
}
}
}
private fun verifyMapping ( name : String , mappedName : String ) {
private fun verifyMapping ( name : String , mappedName : String , maxObfuscatedNameLen : Int ) {
val originalName = name . replace ( LIBRARY _PREFIX _REGEX , " " )
val originalName = name . replace ( LIBRARY _PREFIX _REGEX , " " )
if ( originalName . length > MAX _OBFUSCATED _NAME _LEN && originalName != mappedName ) {
if ( originalName . length > maxObfuscatedNameLen && originalName != mappedName ) {
logger . warn { " Remapping probably unobfuscated name $originalName to $mappedName " }
logger . warn { " Remapping probably unobfuscated name $originalName to $mappedName " }
}
}
}
}
@ -95,32 +79,33 @@ class TypedRemapper private constructor(
return prefix + separator + prefixes . merge ( prefix , 1 , Integer :: sum )
return prefix + separator + prefixes . merge ( prefix , 1 , Integer :: sum )
}
}
private fun createClassMapping ( classPath : ClassPath ) : Map < String , String > {
private fun createClassMapping ( classPath : ClassPath , excludedClasses : ClassFilter ) : Map < String , String > {
val mapping = mutableMapOf < String , String > ( )
val mapping = mutableMapOf < String , String > ( )
val prefixes = mutableMapOf < String , Int > ( )
val prefixes = mutableMapOf < String , Int > ( )
for ( clazz in classPath . libraryClasses ) {
for ( clazz in classPath . libraryClasses ) {
populateClassMapping ( mapping , prefixes , clazz )
populateClassMapping ( excludedClasses , mapping , prefixes , clazz )
}
}
return mapping
return mapping
}
}
private fun populateClassMapping (
private fun populateClassMapping (
excludedClasses : ClassFilter ,
mapping : MutableMap < String , String > ,
mapping : MutableMap < String , String > ,
prefixes : MutableMap < String , Int > ,
prefixes : MutableMap < String , Int > ,
clazz : ClassMetadata
clazz : ClassMetadata
) : String {
) : String {
val name = clazz . name
val name = clazz . name
if ( mapping . containsKey ( name ) || !is ClassRenamable ( clazz ) ) {
if ( mapping . containsKey ( name ) || !is ClassRenamable ( clazz , excludedClasses ) ) {
return mapping . getOrDefault ( name , name )
return mapping . getOrDefault ( name , name )
}
}
val mappedName = generateClassName ( mapping , prefixes , clazz )
val mappedName = generateClassName ( excludedClasses , mapping , prefixes , clazz )
mapping [ name ] = mappedName
mapping [ name ] = mappedName
return mappedName
return mappedName
}
}
private fun isClassRenamable ( clazz : ClassMetadata ) : Boolean {
private fun isClassRenamable ( clazz : ClassMetadata , excludedClasses : ClassFilter ) : Boolean {
if ( clazz . name in EXCLUDED _CLASSES || clazz . dependency ) {
if ( excludedClasses . matches ( clazz . name ) || clazz . dependency ) {
return false
return false
}
}
@ -134,6 +119,7 @@ class TypedRemapper private constructor(
}
}
private fun generateClassName (
private fun generateClassName (
excludedClasses : ClassFilter ,
mapping : MutableMap < String , String > ,
mapping : MutableMap < String , String > ,
prefixes : MutableMap < String , Int > ,
prefixes : MutableMap < String , Int > ,
clazz : ClassMetadata
clazz : ClassMetadata
@ -143,7 +129,7 @@ class TypedRemapper private constructor(
val superClass = clazz . superClass
val superClass = clazz . superClass
if ( superClass != null && superClass . name != " java/lang/Object " ) {
if ( superClass != null && superClass . name != " java/lang/Object " ) {
var superName = populateClassMapping ( mapping , prefixes , superClass )
var superName = populateClassMapping ( excludedClasses , mapping , prefixes , superClass )
superName = superName . substring ( superName . lastIndexOf ( '/' ) + 1 )
superName = superName . substring ( superName . lastIndexOf ( '/' ) + 1 )
mappedName += generateName ( prefixes , superName + " _Sub " )
mappedName += generateName ( prefixes , superName + " _Sub " )
} else if ( clazz . `interface` ) {
} else if ( clazz . `interface` ) {
@ -157,6 +143,7 @@ class TypedRemapper private constructor(
private fun createFieldMapping (
private fun createFieldMapping (
classPath : ClassPath ,
classPath : ClassPath ,
excludedFields : MemberFilter ,
disjointSet : DisjointSet < MemberRef > ,
disjointSet : DisjointSet < MemberRef > ,
classMapping : Map < String , String >
classMapping : Map < String , String >
) : Map < MemberRef , String > {
) : Map < MemberRef , String > {
@ -164,7 +151,7 @@ class TypedRemapper private constructor(
val prefixes = mutableMapOf < String , Int > ( )
val prefixes = mutableMapOf < String , Int > ( )
for ( partition in disjointSet ) {
for ( partition in disjointSet ) {
if ( !is FieldRenamable ( classPath , partition ) ) {
if ( !is FieldRenamable ( classPath , excludedFields , partition ) ) {
continue
continue
}
}
@ -178,11 +165,15 @@ class TypedRemapper private constructor(
return mapping
return mapping
}
}
private fun isFieldRenamable ( classPath : ClassPath , partition : DisjointSet . Partition < MemberRef > ) : Boolean {
private fun isFieldRenamable (
classPath : ClassPath ,
excludedFields : MemberFilter ,
partition : DisjointSet . Partition < MemberRef >
) : Boolean {
for ( field in partition ) {
for ( field in partition ) {
val clazz = classPath [ field . owner ] !!
val clazz = classPath [ field . owner ] !!
if ( field . name in EXCLUDED _FIELDS || clazz . dependency ) {
if ( excludedFields . matches ( field ) || clazz . dependency ) {
return false
return false
}
}
}
}
@ -221,13 +212,14 @@ class TypedRemapper private constructor(
private fun createMethodMapping (
private fun createMethodMapping (
classPath : ClassPath ,
classPath : ClassPath ,
excludedMethods : MemberFilter ,
disjointSet : DisjointSet < MemberRef >
disjointSet : DisjointSet < MemberRef >
) : Map < MemberRef , String > {
) : Map < MemberRef , String > {
val mapping = mutableMapOf < MemberRef , String > ( )
val mapping = mutableMapOf < MemberRef , String > ( )
var id = 0
var id = 0
for ( partition in disjointSet ) {
for ( partition in disjointSet ) {
if ( !is MethodRenamable ( classPath , partition ) ) {
if ( !is MethodRenamable ( classPath , excludedMethods , partition ) ) {
continue
continue
}
}
@ -240,11 +232,15 @@ class TypedRemapper private constructor(
return mapping
return mapping
}
}
fun isMethodRenamable ( classPath : ClassPath , partition : DisjointSet . Partition < MemberRef > ) : Boolean {
fun isMethodRenamable (
classPath : ClassPath ,
excludedMethods : MemberFilter ,
partition : DisjointSet . Partition < MemberRef >
) : Boolean {
for ( method in partition ) {
for ( method in partition ) {
val clazz = classPath [ method . owner ] !!
val clazz = classPath [ method . owner ] !!
if ( method . name in EXCLUDED _METHODS || clazz . dependency ) {
if ( excludedMethods . matches ( method ) || clazz . dependency ) {
return false
return false
}
}