I try to make a coremod on 1.12.2 Forge in order to patch some missing stuff in the Lost Cities mod. (Source: https://github.com/McJtyMods/LostCities/blob/1.12/src/main/java/mcjty/lostcities/dimensions/world/lost/BuildingInfo.java)
A friend and I have written this LostCitiesClassTransformer.java:
package com.seemdmax.lcpatches; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.IFEQ; import static org.objectweb.asm.Opcodes.IFGT; import static org.objectweb.asm.Opcodes.ILOAD; import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import java.util.Arrays; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AbstractInsnNode; import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.InsnList; import org.objectweb.asm.tree.JumpInsnNode; import org.objectweb.asm.tree.LabelNode; import org.objectweb.asm.tree.MethodInsnNode; import org.objectweb.asm.tree.MethodNode; import org.objectweb.asm.tree.VarInsnNode; import mcjty.lostcities.api.ILostCityBuilding; import mcjty.lostcities.dimensions.world.lost.BuildingInfo; import net.minecraft.launchwrapper.IClassTransformer; public class LostCitiesClassTransformer implements IClassTransformer { private static final String[] classesBeingTransformed = { "mcjty.lostcities.dimensions.world.lost.BuildingInfo" }; @Override public byte[] transform(String name, String transformedName, byte[] classBeingTransformed) { boolean isObfuscated = !name.equals(transformedName); int index = Arrays.asList(classesBeingTransformed).indexOf(transformedName); return index != -1 ? transform(index, classBeingTransformed, isObfuscated) : classBeingTransformed; } private static byte[] transform(int index, byte[] classBeingTransformed, boolean isObfuscated) { System.out.println("Transform " + classesBeingTransformed[index] + " got called!"); try { ClassNode classNode = new ClassNode(); ClassReader classReader = new ClassReader(classBeingTransformed); classReader.accept(classNode, 0); System.out.println("Transforming " + classesBeingTransformed[index] + " Is Obf: " + isObfuscated); switch (index) { case 0: transformLCCellars(classNode, isObfuscated); break; } ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); classNode.accept(classWriter); return classWriter.toByteArray(); } catch (Exception e) { e.printStackTrace(); } return classBeingTransformed; } private static void transformLCCellars(ClassNode buildingInfoClass, boolean isObfuscated) { final String BUILDING_INFO = isObfuscated ? "<init>" : "<init>"; final String BUILDING_INFO_DESC = isObfuscated ? "(IILmcjty/lostcities/dimensions/world/LostCityChunkGenerator;)V" : "(IILmcjty/lostcities/dimensions/world/LostCityChunkGenerator;)V"; for (MethodNode method : buildingInfoClass.methods) { if (method.name.equals(BUILDING_INFO) && method.desc.equals(BUILDING_INFO_DESC)) { System.out.println("Found method in BuildingInfo to transform"); AbstractInsnNode targetNode = null; for (AbstractInsnNode instruction : method.instructions.toArray()) { if (instruction.getOpcode() == ILOAD) { if (((VarInsnNode) instruction).var == 13 & instruction.getNext().getOpcode() == IFGT) { System.out.println("Matched"); targetNode = instruction; break; } } } if (targetNode != null) { System.out.println("Target Node valid"); LabelNode newLabelNode = new LabelNode(); InsnList toInsert = new InsnList(); toInsert.add(new VarInsnNode(ALOAD, 0)); toInsert.add(new MethodInsnNode(INVOKEVIRTUAL, Type.getInternalName(BuildingInfo.class), "getBuilding", "()Lmcjty/lostcities/api/ILostCityBuilding", false)); toInsert.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ILostCityBuilding.class), "getMinCellars", "()I", false)); toInsert.add( new MethodInsnNode(INVOKESTATIC, Type.getInternalName(Math.class), "max", "(II)I", false)); method.instructions.insertBefore(targetNode, toInsert); System.out.println("Transform done!"); } else { System.out.println("Something went wrong transforming BuildingInfo!"); } } } } }
The original code we want to patch (Bytecode Outline):
L101 LINENUMBER 764 L101 ALOAD 0 GETFIELD mcjty/lostcities/dimensions/world/lost/BuildingInfo.profile : Lmcjty/lostcities/config/LostCityProfile; GETFIELD mcjty/lostcities/config/LostCityProfile.BUILDING_MINCELLARS : I ILOAD 13 IFGT L102 ICONST_0 GOTO L103 L102 FRAME FULL [mcjty/lostcities/dimensions/world/lost/BuildingInfo I I mcjty/lostcities/dimensions/world/LostCityChunkGenerator mcjty/lostcities/api/LostChunkCharacteristics java/util/Random I mcjty/lostcities/dimensions/world/lost/cityassets/CityStyle mcjty/lostcities/dimensions/world/lost/cityassets/PredefinedCity$PredefinedBuilding F I I I I] [I] ALOAD 5 ILOAD 13 INVOKEVIRTUAL java/util/Random.nextInt (I)I L103 FRAME FULL [mcjty/lostcities/dimensions/world/lost/BuildingInfo I I mcjty/lostcities/dimensions/world/LostCityChunkGenerator mcjty/lostcities/api/LostChunkCharacteristics java/util/Random I mcjty/lostcities/dimensions/world/lost/cityassets/CityStyle mcjty/lostcities/dimensions/world/lost/cityassets/PredefinedCity$PredefinedBuilding F I I I I] [I I] IADD ISTORE 14 L104 LINENUMBER 765 L104 ALOAD 0 INVOKEVIRTUAL mcjty/lostcities/dimensions/world/lost/BuildingInfo.getMaxHighwayLevel ()I IFLT L105 L167 LOCALVARIABLE topleft Lmcjty/lostcities/dimensions/world/lost/BuildingInfo; L58 L73 8 LOCALVARIABLE reldest F L96 L94 13 LOCALVARIABLE predefinedBuilding Lmcjty/lostcities/dimensions/world/lost/cityassets/PredefinedCity$PredefinedBuilding; L75 L74 8 LOCALVARIABLE cityFactor F L85 L74 9 LOCALVARIABLE maxfloors I L86 L74 10 LOCALVARIABLE f I L87 L74 11 LOCALVARIABLE minfloors I L91 L74 12 LOCALVARIABLE maxcellars I L101 L74 13 LOCALVARIABLE fb I L104 L74 14 LOCALVARIABLE r F L115 L74 15 LOCALVARIABLE conditionContext Lmcjty/lostcities/dimensions/world/lost/cityassets/ConditionContext; L130 L140 10 LOCALVARIABLE randomPart Ljava/lang/String; L131 L140 11 LOCALVARIABLE i I L127 L128 9 LOCALVARIABLE this Lmcjty/lostcities/dimensions/world/lost/BuildingInfo; L0 L167 0 LOCALVARIABLE chunkX I L0 L167 1 LOCALVARIABLE chunkZ I L0 L167 2 LOCALVARIABLE provider Lmcjty/lostcities/dimensions/world/LostCityChunkGenerator; L0 L167 3 LOCALVARIABLE characteristics Lmcjty/lostcities/api/LostChunkCharacteristics; L31 L167 4 LOCALVARIABLE rand Ljava/util/Random; L37 L167 5 LOCALVARIABLE b Z L39 L167 6 LOCALVARIABLE cs Lmcjty/lostcities/dimensions/world/lost/cityassets/CityStyle; L55 L167 7 LOCALVARIABLE building Lmcjty/lostcities/dimensions/world/lost/cityassets/Building; L126 L167 8 MAXSTACK = 14 MAXLOCALS = 16
The Bytecode Outline containing our fix:
L101 LINENUMBER 764 L101 ALOAD 0 GETFIELD mcjty/lostcities/dimensions/world/lost/BuildingInfo.profile : Lmcjty/lostcities/config/LostCityProfile; GETFIELD mcjty/lostcities/config/LostCityProfile.BUILDING_MINCELLARS : I ALOAD 0 INVOKEVIRTUAL mcjty/lostcities/dimensions/world/lost/BuildingInfo.getBuilding ()Lmcjty/lostcities/api/ILostCityBuilding INVOKEINTERFACE mcjty/lostcities/api/ILostCityBuilding.getMinCellars ()I INVOKESTATIC java/lang/Math.max (II)I ILOAD 13 IFGT L102 ICONST_0 GOTO L103 L102 FRAME FULL [mcjty/lostcities/dimensions/world/lost/BuildingInfo I I mcjty/lostcities/dimensions/world/LostCityChunkGenerator mcjty/lostcities/api/LostChunkCharacteristics java/util/Random I mcjty/lostcities/dimensions/world/lost/cityassets/CityStyle mcjty/lostcities/dimensions/world/lost/cityassets/PredefinedCity$PredefinedBuilding F I I I I] [I] ALOAD 5 ILOAD 13 L104 LINENUMBER 765 L104 INVOKEVIRTUAL java/util/Random.nextInt (I)I L103 FRAME FULL [mcjty/lostcities/dimensions/world/lost/BuildingInfo I I mcjty/lostcities/dimensions/world/LostCityChunkGenerator mcjty/lostcities/api/LostChunkCharacteristics java/util/Random I mcjty/lostcities/dimensions/world/lost/cityassets/CityStyle mcjty/lostcities/dimensions/world/lost/cityassets/PredefinedCity$PredefinedBuilding F I I I I] [I I] IADD ISTORE 14 ... L168 LOCALVARIABLE topleft Lmcjty/lostcities/dimensions/world/lost/BuildingInfo; L58 L73 8 LOCALVARIABLE reldest F L96 L94 13 LOCALVARIABLE predefinedBuilding Lmcjty/lostcities/dimensions/world/lost/cityassets/PredefinedCity$PredefinedBuilding; L75 L74 8 LOCALVARIABLE cityFactor F L85 L74 9 LOCALVARIABLE maxfloors I L86 L74 10 LOCALVARIABLE f I L87 L74 11 LOCALVARIABLE minfloors I L91 L74 12 LOCALVARIABLE maxcellars I L101 L74 13 LOCALVARIABLE fb I L105 L74 14 LOCALVARIABLE r F L116 L74 15 LOCALVARIABLE conditionContext Lmcjty/lostcities/dimensions/world/lost/cityassets/ConditionContext; L131 L141 10 LOCALVARIABLE randomPart Ljava/lang/String; L132 L141 11 LOCALVARIABLE i I L128 L129 9 LOCALVARIABLE this Lmcjty/lostcities/dimensions/world/lost/BuildingInfo; L0 L168 0 LOCALVARIABLE chunkX I L0 L168 1 LOCALVARIABLE chunkZ I L0 L168 2 LOCALVARIABLE provider Lmcjty/lostcities/dimensions/world/LostCityChunkGenerator; L0 L168 3 LOCALVARIABLE characteristics Lmcjty/lostcities/api/LostChunkCharacteristics; L31 L168 4 LOCALVARIABLE rand Ljava/util/Random; L37 L168 5 LOCALVARIABLE b Z L39 L168 6 LOCALVARIABLE cs Lmcjty/lostcities/dimensions/world/lost/cityassets/CityStyle; L55 L168 7 LOCALVARIABLE building Lmcjty/lostcities/dimensions/world/lost/cityassets/Building; L127 L168 8 MAXSTACK = 14 MAXLOCALS = 16
The Stacktrace we get:
net.minecraft.util.ReportedException: Exception generating new chunk at net.minecraft.world.WorldServer.initialize(WorldServer.java:930) ~[WorldServer.class:?] at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(IntegratedServer.java:124) ~[IntegratedServer.class:?] at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:160) ~[IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:552) [MinecraftServer.class:?] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_281] Caused by: java.lang.NoClassDefFoundError: mcjty/lostcities/dimensions/world/lost/BuildingInfo at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more Caused by: java.lang.ClassNotFoundException: mcjty.lostcities.dimensions.world.lost.BuildingInfo at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) ~[launchwrapper-1.12.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_281] at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_281] at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more Caused by: net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerException: Exception in class transformer com.seemdmax.lcpatches.LostCitiesClassTransformer@1bec3ef7 from coremod Lost Cities Patches at net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerWrapper.transform(ASMTransformerWrapper.java:260) ~[forgeSrc-1.12.2-14.23.5.2847.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) ~[launchwrapper-1.12.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ~[launchwrapper-1.12.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_281] at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_281] at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more Caused by: java.lang.ClassCircularityError: mcjty/lostcities/dimensions/world/lost/BuildingInfo at com.seemdmax.lcpatches.LostCitiesClassTransformer.transformLCCellars(LostCitiesClassTransformer.java:100) ~[bin/:?] at com.seemdmax.lcpatches.LostCitiesClassTransformer.transform(LostCitiesClassTransformer.java:55) ~[bin/:?] at com.seemdmax.lcpatches.LostCitiesClassTransformer.transform(LostCitiesClassTransformer.java:39) ~[bin/:?] at net.minecraftforge.fml.common.asm.ASMTransformerWrapper$TransformerWrapper.transform(ASMTransformerWrapper.java:256) ~[forgeSrc-1.12.2-14.23.5.2847.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) ~[launchwrapper-1.12.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ~[launchwrapper-1.12.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_281] at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_281] at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more
What we tried: We tried to get the building using different ways, e.g. using GETFIELD. Error remain the same.
Any help would be appreciated. If you need to know more details, feel free to ask. Thanks in advance.
Edit: After hardcoding the String, I got another Stacktrace. Is this still related to me doing something wrong with ASM?
net.minecraft.util.ReportedException: Exception generating new chunk at net.minecraft.world.WorldServer.initialize(WorldServer.java:930) ~[WorldServer.class:?] at net.minecraft.server.integrated.IntegratedServer.loadAllWorlds(IntegratedServer.java:124) ~[IntegratedServer.class:?] at net.minecraft.server.integrated.IntegratedServer.init(IntegratedServer.java:160) ~[IntegratedServer.class:?] at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:552) [MinecraftServer.class:?] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_281] Caused by: java.lang.NoClassDefFoundError: mcjty/lostcities/dimensions/world/lost/BuildingInfo at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more Caused by: java.lang.ClassNotFoundException: mcjty.lostcities.dimensions.world.lost.BuildingInfo at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:191) ~[launchwrapper-1.12.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_281] at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_281] at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more Caused by: java.lang.ArrayIndexOutOfBoundsException: 41 at org.objectweb.asm.Type.getType(Type.java:490) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.Type.getReturnType(Type.java:384) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.commons.Remapper.mapMethodDesc(Remapper.java:125) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.commons.RemappingMethodAdapter.doVisitMethodInsn(RemappingMethodAdapter.java:157) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.commons.RemappingMethodAdapter.visitMethodInsn(RemappingMethodAdapter.java:143) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.ClassReader.readCode(ClassReader.java:1496) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.ClassReader.readMethod(ClassReader.java:1032) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.ClassReader.accept(ClassReader.java:708) ~[asm-debug-all-5.2.jar:5.2] at org.objectweb.asm.ClassReader.accept(ClassReader.java:521) ~[asm-debug-all-5.2.jar:5.2] at net.minecraftforge.fml.common.asm.transformers.DeobfuscationTransformer.transform(DeobfuscationTransformer.java:76) ~[forgeSrc-1.12.2-14.23.5.2847.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.runTransformers(LaunchClassLoader.java:279) ~[launchwrapper-1.12.jar:?] at net.minecraft.launchwrapper.LaunchClassLoader.findClass(LaunchClassLoader.java:176) ~[launchwrapper-1.12.jar:?] at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[?:1.8.0_281] at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[?:1.8.0_281] at mcjty.lostcities.dimensions.world.LostCityChunkGenerator.generateChunk(LostCityChunkGenerator.java:216) ~[LostCityChunkGenerator.class:?] at net.minecraft.world.gen.ChunkProviderServer.provideChunk(ChunkProviderServer.java:155) ~[ChunkProviderServer.class:?] at net.minecraft.world.World.getChunkFromChunkCoords(World.java:362) ~[World.class:?] at net.minecraft.world.World.getChunkFromBlockCoords(World.java:354) ~[World.class:?] at net.minecraft.world.World.getBlockState(World.java:995) ~[World.class:?] at net.minecraft.world.World.isAirBlock(World.java:279) ~[World.class:?] at net.minecraft.world.World.getGroundAboveSeaLevel(World.java:252) ~[World.class:?] at net.minecraft.world.WorldProvider.canCoordinateBeSpawn(WorldProvider.java:102) ~[WorldProvider.class:?] at net.minecraft.world.WorldServer.createSpawnPosition(WorldServer.java:989) ~[WorldServer.class:?] at net.minecraft.world.WorldServer.initialize(WorldServer.java:908) ~[WorldServer.class:?] ... 4 more
Advertisement
Answer
The problem is that you do Type.getInternalName(BuildingInfo.class)
. That’s the very class you’re trying to transform as it’s being loaded, so you created a circular reference by using it in a way that would need it to be loaded. You’ll need to hardcode the string "mcjty/lostcities/dimensions/world/lost/BuildingInfo"
there instead.
Also, in "()Lmcjty/lostcities/api/ILostCityBuilding"
, that’s supposed to have a semicolon at the end, so change it to "()Lmcjty/lostcities/api/ILostCityBuilding;"
.
Finally, you need to change false
to true
in new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ILostCityBuilding.class), "getMinCellars", "()I", false));
, since it is in fact an interface method.