Skip to content

Commit

Permalink
Rewrote the remapper again, hopefully for the last time :)
Browse files Browse the repository at this point in the history
  • Loading branch information
BluSpring committed Oct 21, 2023
1 parent 4e01282 commit 48fab1e
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 334 deletions.
7 changes: 7 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ repositories {
maven("https://maven.terraformersmc.com/") {
name = "TerraformersMC"
}

maven("https://maven.su5ed.dev/releases") {
name = "Su5ed"
}
}

dependencies {
Expand Down Expand Up @@ -150,6 +154,9 @@ dependencies {
// Remapping SRG to Intermediary
implementation(include("net.minecraftforge:srgutils:0.4.13")!!)

// Use Sinytra Connector's fork of ForgeAutoRenamingTool
implementation(include("dev.su5ed.sinytra:ForgeAutoRenamingTool:${property("forgerenamer_version")}")!!)

// Runtime mods for testing
modRuntimeOnly ("com.terraformersmc:modmenu:4.1.0") {
exclude("net.fabricmc", "fabric-loader")
Expand Down
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,8 @@ eventbus_version=6.0.4
# https://files.minecraftforge.net/net/minecraftforge/forgespi/index.html
forgespi_version=6.0.2

# https://maven.su5ed.dev/#/releases/dev/su5ed/sinytra/ForgeAutoRenamingTool
forgerenamer_version=1.0.8

# https://files.minecraftforge.net/cpw/mods/securejarhandler/index.html
securejarhandler_version=2.1.4
Original file line number Diff line number Diff line change
@@ -1,30 +1,115 @@
package net.minecraftforge.fml.util

import cpw.mods.modlauncher.api.INameMappingService
import net.fabricmc.loader.impl.FabricLoaderImpl
import net.fabricmc.loader.api.FabricLoader
import org.slf4j.LoggerFactory
import xyz.bluspring.kilt.loader.remap.KiltRemapper
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Method
import java.util.*

object ObfuscationReflectionHelper {
private val srgIntermediaryTree = KiltRemapper.srgIntermediaryTree
private val LOGGER = LoggerFactory.getLogger(ObfuscationReflectionHelper::class.java)

private val fabricRemapper = FabricLoader.getInstance().mappingResolver
private val srgIntermediaryTree = KiltRemapper.srgIntermediaryMapping
private val srgMappedFields =
srgIntermediaryTree.classes.flatMap { it.fields }.associateBy { it.getName("searge") }
srgIntermediaryTree.classes.flatMap { it.fields.map { f -> f.original to fabricRemapper.mapFieldName("intermediary", it.mapped, f.mapped, f.mappedDescriptor) } }.associateBy { it.first }
private val srgMappedMethods =
srgIntermediaryTree.classes.flatMap { it.methods }.associateBy { it.getName("searge") }
private val mappingEnvironment = FabricLoaderImpl.INSTANCE
srgIntermediaryTree.classes.flatMap { it.methods.map { f -> f.original to fabricRemapper.mapMethodName("intermediary", it.mapped, f.mapped, f.mappedDescriptor) } }.associateBy { it.first }

@JvmStatic
fun remapName(domain: INameMappingService.Domain, name: String): String {
// TODO: Make this remap from MojMap to Intermediary.
// We might have to package MojMap alongside Kilt, however that would very much
// violate the redistribution part of MojMaps.
return name
return when (domain) {
INameMappingService.Domain.CLASS -> {
fabricRemapper.mapClassName("intermediary", srgIntermediaryTree.remapClass(name))
}

INameMappingService.Domain.FIELD -> {
srgMappedFields[name]?.second ?: name
}

INameMappingService.Domain.METHOD -> {
srgMappedMethods[name]?.second ?: name
}
}
}

@JvmStatic
fun <T, E> getPrivateValue(classToAccess: Class<in E>, instance: E, fieldName: String): T {
return try {
findField(classToAccess, fieldName).get(instance) as T
} catch (e: UnableToFindFieldException) {
LOGGER.error("Unable to locate field $fieldName (${remapName(INameMappingService.Domain.FIELD, fieldName)}) on type ${classToAccess.name}", e)
throw e
} catch (e: IllegalAccessException) {
LOGGER.error("Unable to access field $fieldName (${remapName(INameMappingService.Domain.FIELD, fieldName)}) on type ${classToAccess.name}", e)
throw UnableToAccessFieldException(e)
}
}

@JvmStatic
fun <T, E> setPrivateValue(classToAccess: Class<in T>, instance: T, value: E, fieldName: String) {
try {
findField(classToAccess, fieldName).set(instance, value)
} catch (e: UnableToFindFieldException) {
LOGGER.error("Unable to locate any field $fieldName on type ${classToAccess.name}", e)
throw e
} catch (e: IllegalAccessException) {
LOGGER.error("Unable to access any field $fieldName on type ${classToAccess.name}", e)
throw UnableToAccessFieldException(e)
}
}

@JvmStatic
fun findMethod(clazz: Class<*>, methodName: String, vararg parameterTypes: Class<*>): Method {
return try {
val m = clazz.getDeclaredMethod(remapName(INameMappingService.Domain.METHOD, methodName), *parameterTypes)
m.isAccessible = true
m
} catch (e: Exception) {
throw UnableToFindMethodException(e)
}
}

@JvmStatic
fun <T> findConstructor(clazz: Class<T>, vararg parameterTypes: Class<*>): Constructor<T> {
return try {
val constructor = clazz.getDeclaredConstructor(*parameterTypes)
constructor.isAccessible = true
constructor
} catch (e: NoSuchMethodException) {
val desc = StringBuilder()
desc.append(clazz.simpleName)

val joiner = StringJoiner(", ", "(", ")")
for (type in parameterTypes) {
joiner.add(type.simpleName)
}

desc.append(joiner)

throw UnknownConstructorException("Could not find constructor '$desc' in $clazz")
}
}

@JvmStatic
fun <T> findField(clazz: Class<in T>, fieldName: String): Field {
return try {
val f = clazz.getDeclaredField(remapName(INameMappingService.Domain.FIELD, fieldName))
f.isAccessible = true
f
} catch (e: Exception) {
throw UnableToFindFieldException(e)
}
}

class UnableToAccessFieldException private constructor(e: Exception) : RuntimeException(e)
open class UnableToAccessFieldException internal constructor(e: Exception) : RuntimeException(e)

class UnableToFindFieldException private constructor(e: Exception) : RuntimeException(e)
open class UnableToFindFieldException internal constructor(e: Exception) : RuntimeException(e)

class UnableToFindMethodException(failed: Throwable?) : RuntimeException(failed)
open class UnableToFindMethodException(failed: Throwable?) : RuntimeException(failed)

class UnknownConstructorException(message: String?) : RuntimeException(message)
open class UnknownConstructorException(message: String?) : RuntimeException(message)
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ object AccessTransformerLoader {
private val whitespace = Pattern.compile("[ \t]+")

private val classTransformInfo = mutableMapOf<String, ClassTransformInfo>()
private val mc = KiltRemapper.mcRemapper
private val mappingResolver = FabricLoader.getInstance().mappingResolver

private fun println(info: String) {
Expand Down Expand Up @@ -54,8 +53,8 @@ object AccessTransformerLoader {
else Final.DEFAULT

// class name
val srgClassName = split[1]
val intermediaryClassName = KiltRemapper.remapClass(srgClassName.replace(".", "/"))
val srgClassName = split[1].replace(".", "/")
val intermediaryClassName = KiltRemapper.remapClass(srgClassName)

// field / method
if (split.size > 2 && !split[2].startsWith("#")) {
Expand All @@ -80,7 +79,7 @@ object AccessTransformerLoader {
val intermediaryDescriptor = KiltRemapper.remapDescriptor(descriptor, toIntermediary = true)
val mappedDescriptor = KiltRemapper.remapDescriptor(descriptor)

val methodName = mappingResolver.mapMethodName("intermediary", intermediaryClassName.replace("/", "."), mc.mapFieldName(srgClassName, name, descriptor), intermediaryDescriptor)
val methodName = mappingResolver.mapMethodName("intermediary", intermediaryClassName.replace("/", "."), KiltRemapper.srgIntermediaryMapping.getClass(srgClassName)?.remapField(name) ?: name, intermediaryDescriptor)
val transformInfo = classTransformInfo[intermediaryClassName] ?: ClassTransformInfo(AccessType.DEFAULT, Final.DEFAULT)
val pair = Pair(methodName, mappedDescriptor)

Expand All @@ -105,8 +104,8 @@ object AccessTransformerLoader {
} else { // field
val name = split[2]

val fieldInfo = KiltRemapper.srgIntermediaryTree.classes.firstOrNull { it.getName("searge") == srgClassName }?.fields?.firstOrNull { it.getName("searge") == name } ?: continue
val fieldName = mappingResolver.mapMethodName("intermediary", intermediaryClassName.replace("/", "."), mc.mapFieldName(srgClassName, name, fieldInfo.getDescriptor("searge")), fieldInfo.getDescriptor("intermediary"))
val fieldInfo = KiltRemapper.srgIntermediaryMapping.getClass(srgClassName)?.fields?.firstOrNull { it.original == name } ?: continue
val fieldName = mappingResolver.mapMethodName("intermediary", intermediaryClassName.replace("/", "."), KiltRemapper.srgIntermediaryMapping.getClass(srgClassName)?.remapField(name) ?: name, fieldInfo.mappedDescriptor)

val transformInfo = classTransformInfo[intermediaryClassName] ?: ClassTransformInfo(AccessType.DEFAULT, Final.DEFAULT)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package xyz.bluspring.kilt.loader.remap

import net.fabricmc.loader.api.FabricLoader
import net.minecraftforge.srgutils.IMappingFile
import net.minecraftforge.srgutils.IRenamer

class DevMappingRenamer : IRenamer {
private val resolver = FabricLoader.getInstance().mappingResolver

override fun rename(value: IMappingFile.IField): String {
return resolver.mapFieldName("intermediary", value.parent.mapped.replace("/", "."), value.mapped, value.mappedDescriptor)
}

override fun rename(value: IMappingFile.IMethod): String {
return resolver.mapMethodName("intermediary", value.parent.mapped.replace("/", "."), value.mapped, value.mappedDescriptor)
}

override fun rename(value: IMappingFile.IClass): String {
return resolver.mapClassName("intermediary", value.mapped.replace("/", ".")).replace(".", "/")
}
}
Loading

0 comments on commit 48fab1e

Please sign in to comment.