get rid of obfuscated namespace support, rely on FML deobfuscation instead

This commit is contained in:
octarine-noise
2017-04-09 11:30:35 +02:00
parent 8f9a35f40e
commit 8ffca417fb
3 changed files with 56 additions and 70 deletions

View File

@@ -16,50 +16,50 @@ object Refs {
val Random = ClassRef("java.util.Random") val Random = ClassRef("java.util.Random")
// Minecraft // Minecraft
val IBlockAccess = ClassRef("net.minecraft.world.IBlockAccess", "aih") val IBlockAccess = ClassRef("net.minecraft.world.IBlockAccess")
val IBlockState = ClassRef("net.minecraft.block.state.IBlockState", "ars") val IBlockState = ClassRef("net.minecraft.block.state.IBlockState")
val BlockStateBase = ClassRef("net.minecraft.block.state.BlockStateBase", "arp") val BlockStateBase = ClassRef("net.minecraft.block.state.BlockStateBase")
val BlockPos = ClassRef("net.minecraft.util.math.BlockPos", "cm") val BlockPos = ClassRef("net.minecraft.util.math.BlockPos")
val MutableBlockPos = ClassRef("net.minecraft.util.math.BlockPos\$MutableBlockPos", "cm\$a") val MutableBlockPos = ClassRef("net.minecraft.util.math.BlockPos\$MutableBlockPos")
val BlockRenderLayer = ClassRef("net.minecraft.util.BlockRenderLayer", "ahv") val BlockRenderLayer = ClassRef("net.minecraft.util.BlockRenderLayer")
val EnumFacing = ClassRef("net.minecraft.util.EnumFacing", "ct") val EnumFacing = ClassRef("net.minecraft.util.EnumFacing")
val World = ClassRef("net.minecraft.world.World", "aid") val World = ClassRef("net.minecraft.world.World")
val WorldClient = ClassRef("net.minecraft.client.multiplayer.WorldClient", "bln") val WorldClient = ClassRef("net.minecraft.client.multiplayer.WorldClient")
val showBarrierParticles = MethodRef(WorldClient, "showBarrierParticles", "func_184153_a", "a", ClassRef.void, ClassRef.int, ClassRef.int, ClassRef.int, ClassRef.int, Random, ClassRef.boolean, MutableBlockPos) val showBarrierParticles = MethodRef(WorldClient, "showBarrierParticles", "func_184153_a", ClassRef.void, ClassRef.int, ClassRef.int, ClassRef.int, ClassRef.int, Random, ClassRef.boolean, MutableBlockPos)
val Block = ClassRef("net.minecraft.block.Block", "akf") val Block = ClassRef("net.minecraft.block.Block")
val StateImplementation = ClassRef("net.minecraft.block.state.BlockStateContainer\$StateImplementation", "art\$a") val StateImplementation = ClassRef("net.minecraft.block.state.BlockStateContainer\$StateImplementation")
val canRenderInLayer = MethodRef(Block, "canRenderInLayer", ClassRef.boolean, IBlockState, BlockRenderLayer) val canRenderInLayer = MethodRef(Block, "canRenderInLayer", ClassRef.boolean, IBlockState, BlockRenderLayer)
val getAmbientOcclusionLightValue = MethodRef(StateImplementation, "getAmbientOcclusionLightValue", "func_185892_j", "j", ClassRef.float) val getAmbientOcclusionLightValue = MethodRef(StateImplementation, "getAmbientOcclusionLightValue", "func_185892_j", ClassRef.float)
val useNeighborBrightness = MethodRef(StateImplementation, "useNeighborBrightness", "func_185916_f", "f", ClassRef.boolean) val useNeighborBrightness = MethodRef(StateImplementation, "useNeighborBrightness", "func_185916_f", ClassRef.boolean)
val doesSideBlockRendering = MethodRef(StateImplementation, "doesSideBlockRendering", ClassRef.boolean, IBlockAccess, BlockPos, EnumFacing) val doesSideBlockRendering = MethodRef(StateImplementation, "doesSideBlockRendering", ClassRef.boolean, IBlockAccess, BlockPos, EnumFacing)
val isOpaqueCube = MethodRef(StateImplementation, "isOpaqueCube", "func_185914_p", "p", ClassRef.boolean) val isOpaqueCube = MethodRef(StateImplementation, "isOpaqueCube", "func_185914_p", ClassRef.boolean)
val randomDisplayTick = MethodRef(Block, "randomDisplayTick", "func_180655_c", "a", ClassRef.void, IBlockState, World, BlockPos, Random) val randomDisplayTick = MethodRef(Block, "randomDisplayTick", "func_180655_c", ClassRef.void, IBlockState, World, BlockPos, Random)
val BlockModelRenderer = ClassRef("net.minecraft.client.renderer.BlockModelRenderer", "box") val BlockModelRenderer = ClassRef("net.minecraft.client.renderer.BlockModelRenderer")
val AmbientOcclusionFace = ClassRef("net.minecraft.client.renderer.BlockModelRenderer\$AmbientOcclusionFace", "box\$b") val AmbientOcclusionFace = ClassRef("net.minecraft.client.renderer.BlockModelRenderer\$AmbientOcclusionFace")
val ChunkCompileTaskGenerator = ClassRef("net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator", "bqs") val ChunkCompileTaskGenerator = ClassRef("net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator")
val VertexBuffer = ClassRef("net.minecraft.client.renderer.VertexBuffer", "bnt") val VertexBuffer = ClassRef("net.minecraft.client.renderer.VertexBuffer")
val AOF_constructor = MethodRef(AmbientOcclusionFace, "<init>", ClassRef.void, BlockModelRenderer) val AOF_constructor = MethodRef(AmbientOcclusionFace, "<init>", ClassRef.void, BlockModelRenderer)
val RenderChunk = ClassRef("net.minecraft.client.renderer.chunk.RenderChunk", "bqy") val RenderChunk = ClassRef("net.minecraft.client.renderer.chunk.RenderChunk")
val rebuildChunk = MethodRef(RenderChunk, "rebuildChunk", "func_178581_b", "b", ClassRef.void, ClassRef.float, ClassRef.float, ClassRef.float, ChunkCompileTaskGenerator) val rebuildChunk = MethodRef(RenderChunk, "rebuildChunk", "func_178581_b", ClassRef.void, ClassRef.float, ClassRef.float, ClassRef.float, ChunkCompileTaskGenerator)
val BlockRendererDispatcher = ClassRef("net.minecraft.client.renderer.BlockRendererDispatcher", "bov") val BlockRendererDispatcher = ClassRef("net.minecraft.client.renderer.BlockRendererDispatcher")
val renderBlock = MethodRef(BlockRendererDispatcher, "renderBlock", "func_175018_a", "a", ClassRef.boolean, IBlockState, BlockPos, IBlockAccess, VertexBuffer) val renderBlock = MethodRef(BlockRendererDispatcher, "renderBlock", "func_175018_a", ClassRef.boolean, IBlockState, BlockPos, IBlockAccess, VertexBuffer)
val TextureAtlasSprite = ClassRef("net.minecraft.client.renderer.texture.TextureAtlasSprite", "bwe") val TextureAtlasSprite = ClassRef("net.minecraft.client.renderer.texture.TextureAtlasSprite")
val IRegistry = ClassRef("net.minecraft.util.registry.IRegistry", "de") val IRegistry = ClassRef("net.minecraft.util.registry.IRegistry")
val ModelLoader = ClassRef("net.minecraftforge.client.model.ModelLoader") val ModelLoader = ClassRef("net.minecraftforge.client.model.ModelLoader")
val stateModels = FieldRef(ModelLoader, "stateModels", Map) val stateModels = FieldRef(ModelLoader, "stateModels", Map)
val setupModelRegistry = MethodRef(ModelLoader, "setupModelRegistry", "func_177570_a", "a", IRegistry) val setupModelRegistry = MethodRef(ModelLoader, "setupModelRegistry", "func_177570_a", IRegistry)
val IModel = ClassRef("net.minecraftforge.client.model.IModel") val IModel = ClassRef("net.minecraftforge.client.model.IModel")
val ModelBlock = ClassRef("net.minecraft.client.renderer.block.model.ModelBlock", "bpd") val ModelBlock = ClassRef("net.minecraft.client.renderer.block.model.ModelBlock")
val ResourceLocation = ClassRef("net.minecraft.util.ResourceLocation", "kn") val ResourceLocation = ClassRef("net.minecraft.util.ResourceLocation")
val ModelResourceLocation = ClassRef("net.minecraft.client.renderer.block.model.ModelResourceLocation", "byq") val ModelResourceLocation = ClassRef("net.minecraft.client.renderer.block.model.ModelResourceLocation")
val VanillaModelWrapper = ClassRef("net.minecraftforge.client.model.ModelLoader\$VanillaModelWrapper") val VanillaModelWrapper = ClassRef("net.minecraftforge.client.model.ModelLoader\$VanillaModelWrapper")
val model_VMW = FieldRef(VanillaModelWrapper, "model", ModelBlock) val model_VMW = FieldRef(VanillaModelWrapper, "model", ModelBlock)
val location_VMW = FieldRef(VanillaModelWrapper, "location", ModelBlock) val location_VMW = FieldRef(VanillaModelWrapper, "location", ModelBlock)

View File

@@ -43,7 +43,7 @@ fun Any.reflectFieldsOfType(vararg types: Class<*>) = this.javaClass.declaredFie
.map { field -> field.name to field.let { it.isAccessible = true; it.get(this) } } .map { field -> field.name to field.let { it.isAccessible = true; it.get(this) } }
.filterNotNull() .filterNotNull()
enum class Namespace { OBF, SRG, MCP } enum class Namespace { MCP, SRG }
abstract class Resolvable<T> { abstract class Resolvable<T> {
abstract fun resolve(): T? abstract fun resolve(): T?
@@ -56,11 +56,9 @@ fun allAvailable(vararg codeElement: Resolvable<*>) = codeElement.all { it.eleme
/** /**
* Reference to a class. * Reference to a class.
* *
* @param[mcpName] MCP name of the class * @param[name] MCP name of the class
* @param[obfName] obfuscated name of the class
*/ */
open class ClassRef(val mcpName: String, val obfName: String) : Resolvable<Class<*>>() { open class ClassRef(val name: String) : Resolvable<Class<*>>() {
constructor(mcpName: String) : this(mcpName, mcpName)
companion object { companion object {
val int = ClassRefPrimitive("I", Int::class.java) val int = ClassRefPrimitive("I", Int::class.java)
@@ -70,10 +68,9 @@ open class ClassRef(val mcpName: String, val obfName: String) : Resolvable<Class
val void = ClassRefPrimitive("V", null) val void = ClassRefPrimitive("V", null)
} }
fun name(namespace: Namespace) = if (namespace == Namespace.OBF) obfName else mcpName open fun asmDescriptor(namespace: Namespace) = "L${name.replace(".", "/")};"
open fun asmDescriptor(namespace: Namespace) = "L${name(namespace).replace(".", "/")};"
override fun resolve() = listOf(mcpName, obfName).map { getJavaClass(it) }.filterNotNull().firstOrNull() override fun resolve() = getJavaClass(name)
fun isInstance(obj: Any) = element?.isInstance(obj) ?: false fun isInstance(obj: Any) = element?.isInstance(obj) ?: false
} }
@@ -85,17 +82,16 @@ open class ClassRef(val mcpName: String, val obfName: String) : Resolvable<Class
* @param[clazz] class of this primitive type * @param[clazz] class of this primitive type
*/ */
class ClassRefPrimitive(name: String, val clazz: Class<*>?) : ClassRef(name) { class ClassRefPrimitive(name: String, val clazz: Class<*>?) : ClassRef(name) {
override fun asmDescriptor(namespace: Namespace) = mcpName override fun asmDescriptor(namespace: Namespace) = name
override fun resolve() = clazz override fun resolve() = clazz
} }
class ClassRefArray(mcpName: String, obfName: String) : ClassRef(mcpName, obfName) { class ClassRefArray(name: String) : ClassRef(name) {
constructor(mcpName: String) : this(mcpName, mcpName)
override fun asmDescriptor(namespace: Namespace) = "[" + super.asmDescriptor(namespace) override fun asmDescriptor(namespace: Namespace) = "[" + super.asmDescriptor(namespace)
override fun resolve() = listOf(mcpName, obfName).map { getJavaClass("[L$it;") }.filterNotNull().firstOrNull() override fun resolve() = getJavaClass("[L$name;")
} }
fun ClassRef.array() = ClassRefArray(mcpName, obfName) fun ClassRef.array() = ClassRefArray(name)
/** /**
* Reference to a method. * Reference to a method.
@@ -103,30 +99,26 @@ fun ClassRef.array() = ClassRefArray(mcpName, obfName)
* @param[parentClass] reference to the class containing the method * @param[parentClass] reference to the class containing the method
* @param[mcpName] MCP name of the method * @param[mcpName] MCP name of the method
* @param[srgName] SRG name of the method * @param[srgName] SRG name of the method
* @param[obfName] obfuscated name of the method
* @param[returnType] reference to the return type * @param[returnType] reference to the return type
* @param[returnType] references to the argument types * @param[returnType] references to the argument types
*/ */
class MethodRef(val parentClass: ClassRef, class MethodRef(val parentClass: ClassRef,
val mcpName: String, val mcpName: String,
val srgName: String?, val srgName: String,
val obfName: String?,
val returnType: ClassRef, val returnType: ClassRef,
vararg argTypes: ClassRef vararg val argTypes: ClassRef
) : Resolvable<Method>() { ) : Resolvable<Method>() {
constructor(parentClass: ClassRef, mcpName: String, returnType: ClassRef, vararg argTypes: ClassRef) : constructor(parentClass: ClassRef, mcpName: String, returnType: ClassRef, vararg argTypes: ClassRef) :
this(parentClass, mcpName, mcpName, mcpName, returnType, *argTypes) this(parentClass, mcpName, mcpName, returnType, *argTypes)
val argTypes = argTypes fun name(namespace: Namespace) = when(namespace) { SRG -> srgName; MCP -> mcpName }
fun name(namespace: Namespace) = when(namespace) { OBF -> obfName!!; SRG -> srgName!!; MCP -> mcpName }
fun asmDescriptor(namespace: Namespace) = "(${argTypes.map { it.asmDescriptor(namespace) }.fold(""){ s1, s2 -> s1 + s2 } })${returnType.asmDescriptor(namespace)}" fun asmDescriptor(namespace: Namespace) = "(${argTypes.map { it.asmDescriptor(namespace) }.fold(""){ s1, s2 -> s1 + s2 } })${returnType.asmDescriptor(namespace)}"
override fun resolve(): Method? = override fun resolve(): Method? =
if (parentClass.element == null || argTypes.any { it.element == null }) null if (parentClass.element == null || argTypes.any { it.element == null }) null
else { else {
val args = argTypes.map { it.element!! }.toTypedArray() val args = argTypes.map { it.element!! }.toTypedArray()
listOf(srgName!!, mcpName).map { tryDefault(null) { listOf(srgName, mcpName).map { tryDefault(null) {
parentClass.element!!.getDeclaredMethod(it, *args) parentClass.element!!.getDeclaredMethod(it, *args)
}}.filterNotNull().firstOrNull() }}.filterNotNull().firstOrNull()
?.apply { isAccessible = true } ?.apply { isAccessible = true }
@@ -146,24 +138,22 @@ class MethodRef(val parentClass: ClassRef,
* @param[parentClass] reference to the class containing the field * @param[parentClass] reference to the class containing the field
* @param[mcpName] MCP name of the field * @param[mcpName] MCP name of the field
* @param[srgName] SRG name of the field * @param[srgName] SRG name of the field
* @param[obfName] obfuscated name of the field
* @param[type] reference to the field type * @param[type] reference to the field type
*/ */
class FieldRef(val parentClass: ClassRef, class FieldRef(val parentClass: ClassRef,
val mcpName: String, val mcpName: String,
val srgName: String?, val srgName: String,
val obfName: String?,
val type: ClassRef? val type: ClassRef?
) : Resolvable<Field>() { ) : Resolvable<Field>() {
constructor(parentClass: ClassRef, mcpName: String, type: ClassRef?) : this(parentClass, mcpName, mcpName, mcpName, type) constructor(parentClass: ClassRef, mcpName: String, type: ClassRef?) : this(parentClass, mcpName, mcpName, type)
fun name(namespace: Namespace) = when(namespace) { OBF -> obfName!!; SRG -> srgName!!; MCP -> mcpName } fun name(namespace: Namespace) = when(namespace) { SRG -> srgName; MCP -> mcpName }
fun asmDescriptor(namespace: Namespace) = type!!.asmDescriptor(namespace) fun asmDescriptor(namespace: Namespace) = type!!.asmDescriptor(namespace)
override fun resolve(): Field? = override fun resolve(): Field? =
if (parentClass.element == null) null if (parentClass.element == null) null
else { else {
listOf(srgName!!, mcpName).map { tryDefault(null) { listOf(srgName, mcpName).map { tryDefault(null) {
parentClass.element!!.getDeclaredField(it) parentClass.element!!.getDeclaredField(it)
}}.filterNotNull().firstOrNull() }}.filterNotNull().firstOrNull()
?.apply{ isAccessible = true } ?.apply{ isAccessible = true }

View File

@@ -1,6 +1,6 @@
package mods.octarinecore.metaprog package mods.octarinecore.metaprog
import mods.octarinecore.metaprog.Namespace.MCP import mods.octarinecore.metaprog.Namespace.*
import net.minecraft.launchwrapper.IClassTransformer import net.minecraft.launchwrapper.IClassTransformer
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
@@ -45,19 +45,15 @@ open class Transformer : IClassTransformer {
synchronized(this) { synchronized(this) {
methodTransformers.forEach { (targetMethod, transform) -> methodTransformers.forEach { (targetMethod, transform) ->
if (transformedName != targetMethod.parentClass.name(MCP)) return@forEach if (transformedName != targetMethod.parentClass.name) return@forEach
if (name == transformedName)
log.debug("Found class $name")
else
log.debug("Found class $name matching $transformedName")
for (method in classNode.methods) { for (method in classNode.methods) {
val namespace = Namespace.values().reversed().find { val namespace = Namespace.values().find {
method.name == targetMethod.name(it) && method.desc == targetMethod.asmDescriptor(it) method.name == targetMethod.name(it) && method.desc == targetMethod.asmDescriptor(it)
} ?: continue } ?: continue
when (namespace) { when (namespace) {
MCP -> log.debug("Found method ${targetMethod.parentClass.name(MCP)}.${targetMethod.name(MCP)} ${targetMethod.asmDescriptor(MCP)}") MCP -> log.info("Found method ${targetMethod.parentClass.name}.${targetMethod.name(MCP)} ${targetMethod.asmDescriptor(MCP)}")
else -> log.debug("Found method ${targetMethod.parentClass.name(namespace)}.${targetMethod.name(namespace)} ${targetMethod.asmDescriptor(namespace)} matching ${targetMethod.parentClass.name(MCP)}.${targetMethod.name(MCP)} ${targetMethod.asmDescriptor(MCP)} in namespace $namespace") SRG -> log.info("Found method ${targetMethod.parentClass.name}.${targetMethod.name(namespace)} ${targetMethod.asmDescriptor(namespace)} (matching ${targetMethod.name(MCP)})")
} }
MethodTransformContext(method, namespace).transform() MethodTransformContext(method, namespace).transform()
workDone = true workDone = true
@@ -161,7 +157,7 @@ class MethodTransformContext(val method: MethodNode, val environment: Namespace)
fun invokeRef(ref: MethodRef): (AbstractInsnNode)->Boolean = { insn -> fun invokeRef(ref: MethodRef): (AbstractInsnNode)->Boolean = { insn ->
(insn as? MethodInsnNode)?.let { (insn as? MethodInsnNode)?.let {
it.name == ref.name(environment) && it.owner == ref.parentClass.name(environment).replace(".", "/") it.name == ref.name(environment) && it.owner == ref.parentClass.name.replace(".", "/")
} ?: false } ?: false
} }
} }
@@ -194,7 +190,7 @@ class InstructionList(val environment: Namespace) {
*/ */
fun invokeStatic(target: MethodRef, isInterface: Boolean = false) = list.add(MethodInsnNode( fun invokeStatic(target: MethodRef, isInterface: Boolean = false) = list.add(MethodInsnNode(
Opcodes.INVOKESTATIC, Opcodes.INVOKESTATIC,
target.parentClass.name(environment).replace(".", "/"), target.parentClass.name.replace(".", "/"),
target.name(environment), target.name(environment),
target.asmDescriptor(environment), target.asmDescriptor(environment),
isInterface isInterface
@@ -207,7 +203,7 @@ class InstructionList(val environment: Namespace) {
*/ */
fun getField(target: FieldRef) = list.add(FieldInsnNode( fun getField(target: FieldRef) = list.add(FieldInsnNode(
Opcodes.GETFIELD, Opcodes.GETFIELD,
target.parentClass.name(environment).replace(".", "/"), target.parentClass.name.replace(".", "/"),
target.name(environment), target.name(environment),
target.asmDescriptor(environment) target.asmDescriptor(environment)
)) ))