From 8ffca417fb8126577e20cc9789ef90ede1ec454c Mon Sep 17 00:00:00 2001 From: octarine-noise Date: Sun, 9 Apr 2017 11:30:35 +0200 Subject: [PATCH] get rid of obfuscated namespace support, rely on FML deobfuscation instead --- .../kotlin/mods/betterfoliage/loader/Refs.kt | 60 +++++++++---------- .../mods/octarinecore/metaprog/Reflection.kt | 46 ++++++-------- .../octarinecore/metaprog/Transformation.kt | 20 +++---- 3 files changed, 56 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/mods/betterfoliage/loader/Refs.kt b/src/main/kotlin/mods/betterfoliage/loader/Refs.kt index 8398e0e..ae9376e 100644 --- a/src/main/kotlin/mods/betterfoliage/loader/Refs.kt +++ b/src/main/kotlin/mods/betterfoliage/loader/Refs.kt @@ -16,50 +16,50 @@ object Refs { val Random = ClassRef("java.util.Random") // Minecraft - val IBlockAccess = ClassRef("net.minecraft.world.IBlockAccess", "aih") - val IBlockState = ClassRef("net.minecraft.block.state.IBlockState", "ars") - val BlockStateBase = ClassRef("net.minecraft.block.state.BlockStateBase", "arp") - val BlockPos = ClassRef("net.minecraft.util.math.BlockPos", "cm") - val MutableBlockPos = ClassRef("net.minecraft.util.math.BlockPos\$MutableBlockPos", "cm\$a") - val BlockRenderLayer = ClassRef("net.minecraft.util.BlockRenderLayer", "ahv") - val EnumFacing = ClassRef("net.minecraft.util.EnumFacing", "ct") + val IBlockAccess = ClassRef("net.minecraft.world.IBlockAccess") + val IBlockState = ClassRef("net.minecraft.block.state.IBlockState") + val BlockStateBase = ClassRef("net.minecraft.block.state.BlockStateBase") + val BlockPos = ClassRef("net.minecraft.util.math.BlockPos") + val MutableBlockPos = ClassRef("net.minecraft.util.math.BlockPos\$MutableBlockPos") + val BlockRenderLayer = ClassRef("net.minecraft.util.BlockRenderLayer") + val EnumFacing = ClassRef("net.minecraft.util.EnumFacing") - val World = ClassRef("net.minecraft.world.World", "aid") - val WorldClient = ClassRef("net.minecraft.client.multiplayer.WorldClient", "bln") - val showBarrierParticles = MethodRef(WorldClient, "showBarrierParticles", "func_184153_a", "a", ClassRef.void, ClassRef.int, ClassRef.int, ClassRef.int, ClassRef.int, Random, ClassRef.boolean, MutableBlockPos) + val World = ClassRef("net.minecraft.world.World") + val WorldClient = ClassRef("net.minecraft.client.multiplayer.WorldClient") + 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 StateImplementation = ClassRef("net.minecraft.block.state.BlockStateContainer\$StateImplementation", "art\$a") + val Block = ClassRef("net.minecraft.block.Block") + val StateImplementation = ClassRef("net.minecraft.block.state.BlockStateContainer\$StateImplementation") val canRenderInLayer = MethodRef(Block, "canRenderInLayer", ClassRef.boolean, IBlockState, BlockRenderLayer) - val getAmbientOcclusionLightValue = MethodRef(StateImplementation, "getAmbientOcclusionLightValue", "func_185892_j", "j", ClassRef.float) - val useNeighborBrightness = MethodRef(StateImplementation, "useNeighborBrightness", "func_185916_f", "f", ClassRef.boolean) + val getAmbientOcclusionLightValue = MethodRef(StateImplementation, "getAmbientOcclusionLightValue", "func_185892_j", ClassRef.float) + val useNeighborBrightness = MethodRef(StateImplementation, "useNeighborBrightness", "func_185916_f", ClassRef.boolean) val doesSideBlockRendering = MethodRef(StateImplementation, "doesSideBlockRendering", ClassRef.boolean, IBlockAccess, BlockPos, EnumFacing) - val isOpaqueCube = MethodRef(StateImplementation, "isOpaqueCube", "func_185914_p", "p", ClassRef.boolean) - val randomDisplayTick = MethodRef(Block, "randomDisplayTick", "func_180655_c", "a", ClassRef.void, IBlockState, World, BlockPos, Random) + val isOpaqueCube = MethodRef(StateImplementation, "isOpaqueCube", "func_185914_p", ClassRef.boolean) + val randomDisplayTick = MethodRef(Block, "randomDisplayTick", "func_180655_c", ClassRef.void, IBlockState, World, BlockPos, Random) - val BlockModelRenderer = ClassRef("net.minecraft.client.renderer.BlockModelRenderer", "box") - val AmbientOcclusionFace = ClassRef("net.minecraft.client.renderer.BlockModelRenderer\$AmbientOcclusionFace", "box\$b") - val ChunkCompileTaskGenerator = ClassRef("net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator", "bqs") - val VertexBuffer = ClassRef("net.minecraft.client.renderer.VertexBuffer", "bnt") + val BlockModelRenderer = ClassRef("net.minecraft.client.renderer.BlockModelRenderer") + val AmbientOcclusionFace = ClassRef("net.minecraft.client.renderer.BlockModelRenderer\$AmbientOcclusionFace") + val ChunkCompileTaskGenerator = ClassRef("net.minecraft.client.renderer.chunk.ChunkCompileTaskGenerator") + val VertexBuffer = ClassRef("net.minecraft.client.renderer.VertexBuffer") val AOF_constructor = MethodRef(AmbientOcclusionFace, "", ClassRef.void, BlockModelRenderer) - val RenderChunk = ClassRef("net.minecraft.client.renderer.chunk.RenderChunk", "bqy") - val rebuildChunk = MethodRef(RenderChunk, "rebuildChunk", "func_178581_b", "b", ClassRef.void, ClassRef.float, ClassRef.float, ClassRef.float, ChunkCompileTaskGenerator) + val RenderChunk = ClassRef("net.minecraft.client.renderer.chunk.RenderChunk") + 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 renderBlock = MethodRef(BlockRendererDispatcher, "renderBlock", "func_175018_a", "a", ClassRef.boolean, IBlockState, BlockPos, IBlockAccess, VertexBuffer) + val BlockRendererDispatcher = ClassRef("net.minecraft.client.renderer.BlockRendererDispatcher") + 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 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 ModelBlock = ClassRef("net.minecraft.client.renderer.block.model.ModelBlock", "bpd") - val ResourceLocation = ClassRef("net.minecraft.util.ResourceLocation", "kn") - val ModelResourceLocation = ClassRef("net.minecraft.client.renderer.block.model.ModelResourceLocation", "byq") + val ModelBlock = ClassRef("net.minecraft.client.renderer.block.model.ModelBlock") + val ResourceLocation = ClassRef("net.minecraft.util.ResourceLocation") + val ModelResourceLocation = ClassRef("net.minecraft.client.renderer.block.model.ModelResourceLocation") val VanillaModelWrapper = ClassRef("net.minecraftforge.client.model.ModelLoader\$VanillaModelWrapper") val model_VMW = FieldRef(VanillaModelWrapper, "model", ModelBlock) val location_VMW = FieldRef(VanillaModelWrapper, "location", ModelBlock) diff --git a/src/main/kotlin/mods/octarinecore/metaprog/Reflection.kt b/src/main/kotlin/mods/octarinecore/metaprog/Reflection.kt index b6c9f1e..debe1fc 100644 --- a/src/main/kotlin/mods/octarinecore/metaprog/Reflection.kt +++ b/src/main/kotlin/mods/octarinecore/metaprog/Reflection.kt @@ -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) } } .filterNotNull() -enum class Namespace { OBF, SRG, MCP } +enum class Namespace { MCP, SRG } abstract class Resolvable { abstract fun resolve(): T? @@ -56,11 +56,9 @@ fun allAvailable(vararg codeElement: Resolvable<*>) = codeElement.all { it.eleme /** * Reference to a class. * - * @param[mcpName] MCP name of the class - * @param[obfName] obfuscated name of the class + * @param[name] MCP name of the class */ -open class ClassRef(val mcpName: String, val obfName: String) : Resolvable>() { - constructor(mcpName: String) : this(mcpName, mcpName) +open class ClassRef(val name: String) : Resolvable>() { companion object { val int = ClassRefPrimitive("I", Int::class.java) @@ -70,10 +68,9 @@ open class ClassRef(val mcpName: String, val obfName: String) : Resolvable?) : ClassRef(name) { - override fun asmDescriptor(namespace: Namespace) = mcpName + override fun asmDescriptor(namespace: Namespace) = name override fun resolve() = clazz } -class ClassRefArray(mcpName: String, obfName: String) : ClassRef(mcpName, obfName) { - constructor(mcpName: String) : this(mcpName, mcpName) +class ClassRefArray(name: String) : ClassRef(name) { 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. @@ -103,30 +99,26 @@ fun ClassRef.array() = ClassRefArray(mcpName, obfName) * @param[parentClass] reference to the class containing the method * @param[mcpName] MCP 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] references to the argument types */ class MethodRef(val parentClass: ClassRef, val mcpName: String, - val srgName: String?, - val obfName: String?, + val srgName: String, val returnType: ClassRef, - vararg argTypes: ClassRef + vararg val argTypes: ClassRef ) : Resolvable() { 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) { OBF -> obfName!!; SRG -> srgName!!; MCP -> mcpName } + fun name(namespace: Namespace) = when(namespace) { SRG -> srgName; MCP -> mcpName } fun asmDescriptor(namespace: Namespace) = "(${argTypes.map { it.asmDescriptor(namespace) }.fold(""){ s1, s2 -> s1 + s2 } })${returnType.asmDescriptor(namespace)}" override fun resolve(): Method? = if (parentClass.element == null || argTypes.any { it.element == null }) null else { val args = argTypes.map { it.element!! }.toTypedArray() - listOf(srgName!!, mcpName).map { tryDefault(null) { + listOf(srgName, mcpName).map { tryDefault(null) { parentClass.element!!.getDeclaredMethod(it, *args) }}.filterNotNull().firstOrNull() ?.apply { isAccessible = true } @@ -146,24 +138,22 @@ class MethodRef(val parentClass: ClassRef, * @param[parentClass] reference to the class containing the field * @param[mcpName] MCP 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 */ class FieldRef(val parentClass: ClassRef, val mcpName: String, - val srgName: String?, - val obfName: String?, + val srgName: String, val type: ClassRef? ) : Resolvable() { - 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) override fun resolve(): Field? = if (parentClass.element == null) null else { - listOf(srgName!!, mcpName).map { tryDefault(null) { + listOf(srgName, mcpName).map { tryDefault(null) { parentClass.element!!.getDeclaredField(it) }}.filterNotNull().firstOrNull() ?.apply{ isAccessible = true } diff --git a/src/main/kotlin/mods/octarinecore/metaprog/Transformation.kt b/src/main/kotlin/mods/octarinecore/metaprog/Transformation.kt index 454c504..3fdf620 100644 --- a/src/main/kotlin/mods/octarinecore/metaprog/Transformation.kt +++ b/src/main/kotlin/mods/octarinecore/metaprog/Transformation.kt @@ -1,6 +1,6 @@ package mods.octarinecore.metaprog -import mods.octarinecore.metaprog.Namespace.MCP +import mods.octarinecore.metaprog.Namespace.* import net.minecraft.launchwrapper.IClassTransformer import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin import org.apache.logging.log4j.LogManager @@ -45,19 +45,15 @@ open class Transformer : IClassTransformer { synchronized(this) { methodTransformers.forEach { (targetMethod, transform) -> - if (transformedName != targetMethod.parentClass.name(MCP)) return@forEach - if (name == transformedName) - log.debug("Found class $name") - else - log.debug("Found class $name matching $transformedName") + if (transformedName != targetMethod.parentClass.name) return@forEach 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) } ?: continue when (namespace) { - MCP -> log.debug("Found method ${targetMethod.parentClass.name(MCP)}.${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") + MCP -> log.info("Found method ${targetMethod.parentClass.name}.${targetMethod.name(MCP)} ${targetMethod.asmDescriptor(MCP)}") + SRG -> log.info("Found method ${targetMethod.parentClass.name}.${targetMethod.name(namespace)} ${targetMethod.asmDescriptor(namespace)} (matching ${targetMethod.name(MCP)})") } MethodTransformContext(method, namespace).transform() workDone = true @@ -161,7 +157,7 @@ class MethodTransformContext(val method: MethodNode, val environment: Namespace) fun invokeRef(ref: MethodRef): (AbstractInsnNode)->Boolean = { insn -> (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 } } @@ -194,7 +190,7 @@ class InstructionList(val environment: Namespace) { */ fun invokeStatic(target: MethodRef, isInterface: Boolean = false) = list.add(MethodInsnNode( Opcodes.INVOKESTATIC, - target.parentClass.name(environment).replace(".", "/"), + target.parentClass.name.replace(".", "/"), target.name(environment), target.asmDescriptor(environment), isInterface @@ -207,7 +203,7 @@ class InstructionList(val environment: Namespace) { */ fun getField(target: FieldRef) = list.add(FieldInsnNode( Opcodes.GETFIELD, - target.parentClass.name(environment).replace(".", "/"), + target.parentClass.name.replace(".", "/"), target.name(environment), target.asmDescriptor(environment) ))