-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rewrote the remapper again, hopefully for the last time :)
- Loading branch information
Showing
7 changed files
with
253 additions
and
334 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 98 additions & 13 deletions
111
src/main/kotlin/net/minecraftforge/fml/util/ObfuscationReflectionHelper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
src/main/kotlin/xyz/bluspring/kilt/loader/remap/DevMappingRenamer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(".", "/") | ||
} | ||
} |
Oops, something went wrong.