From 8c4713c6d7bf8a0b5031b5f816c9e830335915bd Mon Sep 17 00:00:00 2001 From: Prototik Date: Thu, 14 May 2015 12:38:03 +0700 Subject: [PATCH] Patch ChunkProviderServer.loadedChunkHashMap in runtime, fix #1 --- build.gradle | 21 ++++---- .../fml/relauncher/CoreModManager.java.patch | 41 ++++++++++++-- .../world/gen/ChunkProviderServer.java.patch | 6 +-- .../common/chunkio/ChunkIOProvider.java.patch | 2 +- .../kcauldron/KCauldonClassTransformer.java | 53 +++++++++++++++++++ 5 files changed, 104 insertions(+), 19 deletions(-) create mode 100644 src/main/java/kcauldron/KCauldonClassTransformer.java diff --git a/build.gradle b/build.gradle index a908a50..2169cc2 100644 --- a/build.gradle +++ b/build.gradle @@ -41,17 +41,14 @@ minecraft { srgExtra "PK: org/bukkit/craftbukkit org/bukkit/craftbukkit/v1_7_R4" } -group = 'net.minecraftforge' -ext.mcVersion = "1.7.10" -ext.cauldronVersion = "2" -ext.forgeVersion = "1403" -ext.bukkitVersion = "1" -ext.revision = "54" -version = "${mcVersion}-${cauldronVersion}.${forgeVersion}.${bukkitVersion}.${revision}" +group = 'pw.prok.kcauldron' +archivesBaseName = 'kcauldron' -jenkins { - job = 'Cauldron' -} +ext.mcVersion = "1.7.10" +ext.cauldronVersion = "3" +ext.forgeVersion = "1403" +ext.revision = "57" +version = "${mcVersion}-${cauldronVersion}.${forgeVersion}.${revision}" launch4j { jreMinVersion = '1.6.0' @@ -63,8 +60,8 @@ tasks.packageUniversal { tasks.packageUniversal.manifest { attributes([ - 'Implementation-Vendor': 'Cauldron', - 'Implementation-Title': 'Cauldron', + 'Implementation-Vendor': 'Prototik', + 'Implementation-Title': 'KCauldron', 'Implementation-Version': 'KCauldron-'+project.version, 'Forge-Version': '10.13.3.1403', 'Specification-Vendor': 'Bukkit Team', diff --git a/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch b/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch index 75603cd..3f572fc 100644 --- a/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch +++ b/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch @@ -1,6 +1,41 @@ --- ../src-base/minecraft/cpw/mods/fml/relauncher/CoreModManager.java +++ ../src-work/minecraft/cpw/mods/fml/relauncher/CoreModManager.java -@@ -153,6 +153,9 @@ +@@ -27,10 +27,14 @@ + import java.util.Map; + import java.util.jar.Attributes; + import java.util.jar.JarFile; ++ ++import kcauldron.KCauldonClassTransformer; + import net.minecraft.launchwrapper.ITweaker; + import net.minecraft.launchwrapper.Launch; + import net.minecraft.launchwrapper.LaunchClassLoader; ++ + import org.apache.logging.log4j.Level; ++ + import com.google.common.base.Strings; + import com.google.common.base.Throwables; + import com.google.common.collect.ImmutableList; +@@ -38,6 +42,7 @@ + import com.google.common.collect.Maps; + import com.google.common.collect.ObjectArrays; + import com.google.common.primitives.Ints; ++ + import cpw.mods.fml.common.FMLLog; + import cpw.mods.fml.common.asm.transformers.ModAccessTransformer; + import cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker; +@@ -94,6 +99,11 @@ + @Override + public void injectIntoClassLoader(LaunchClassLoader classLoader) + { ++ // Cauldron start ++ // Register own ClassTransformer for some needs ++ classLoader.registerTransformer("kcauldron.KCauldonClassTransformer"); ++ KCauldonClassTransformer.DEV = deobfuscatedEnvironment; ++ // Cauldron end + FMLRelaunchLog.fine("Injecting coremod %s {%s} class transformers", name, coreModInstance.getClass().getName()); + if (coreModInstance.getASMTransformerClass() != null) for (String transformer : coreModInstance.getASMTransformerClass()) + { +@@ -153,6 +163,9 @@ } @@ -10,7 +45,7 @@ public static void handleLaunch(File mcDir, LaunchClassLoader classLoader, FMLTweaker tweaker) { CoreModManager.mcDir = mcDir; -@@ -212,6 +215,19 @@ +@@ -212,6 +225,19 @@ loadCoreMod(classLoader, coreModClassName, null); } discoverCoreMods(mcDir, classLoader); @@ -30,7 +65,7 @@ } -@@ -424,8 +440,11 @@ +@@ -424,8 +450,11 @@ MCVersion requiredMCVersion = coreModClazz.getAnnotation(IFMLLoadingPlugin.MCVersion.class); if (!Arrays.asList(rootPlugins).contains(coreModClass) && (requiredMCVersion == null || Strings.isNullOrEmpty(requiredMCVersion.value()))) { diff --git a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch index 93a7133..41ac8bc 100644 --- a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -38,7 +38,7 @@ + public List loadedChunks = new ArrayList(); // Cauldron - vanilla compatibility public WorldServer worldObj; private Set loadingChunks = com.google.common.collect.Sets.newHashSet(); -+ public LongHashMap field_73244_f = new LongHashMap(); // Cauldron - vanilla/mystcraft compatibility ++ public LongHashMap loadedChunkHashMap_vanilla = new LongHashMap(); // Cauldron - vanilla/mystcraft compatibility private static final String __OBFID = "CL_00001436"; public ChunkProviderServer(WorldServer p_i1520_1_, IChunkLoader p_i1520_2_, IChunkProvider p_i1520_3_) @@ -170,7 +170,7 @@ - chunk.onChunkLoad(); + this.loadedChunkHashMap.put(LongHash.toLong(p_73158_1_, p_73158_2_), chunk); // CraftBukkit + this.loadedChunks.add(chunk); // Cauldron - vanilla compatibility -+ this.field_73244_f.add(ChunkCoordIntPair.chunkXZ2Int(p_73158_1_, p_73158_2_), chunk); // Cauldron - vanilla/mystcraft compatibility ++ this.loadedChunkHashMap_vanilla.add(ChunkCoordIntPair.chunkXZ2Int(p_73158_1_, p_73158_2_), chunk); // Cauldron - vanilla/mystcraft compatibility + loadingChunks.remove(LongHash.toLong(p_73158_1_, p_73158_2_)); // Cauldron - LongHash + + if (chunk != null) @@ -408,7 +408,7 @@ + // this.unloadQueue.remove(olong); + this.loadedChunkHashMap.remove(chunkcoordinates); // CraftBukkit + this.loadedChunks.remove(chunk); // Cauldron - vanilla compatibility -+ this.field_73244_f.remove(ChunkCoordIntPair.chunkXZ2Int(LongHash.msw(chunkcoordinates), LongHash.lsw(chunkcoordinates))); // Cauldron - vanilla/mystcraft compatibility ++ this.loadedChunkHashMap_vanilla.remove(ChunkCoordIntPair.chunkXZ2Int(LongHash.msw(chunkcoordinates), LongHash.lsw(chunkcoordinates))); // Cauldron - vanilla/mystcraft compatibility + ForgeChunkManager.putDormantChunk(chunkcoordinates, chunk); + if(this.loadedChunkHashMap.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){ + DimensionManager.unloadWorld(this.worldObj.provider.dimensionId); diff --git a/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch b/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch index b73cee9..8779098 100644 --- a/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch +++ b/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch @@ -17,7 +17,7 @@ - queuedChunk.provider.loadedChunkHashMap.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk); + queuedChunk.provider.loadedChunkHashMap.put(LongHash.toLong(queuedChunk.x, queuedChunk.z), chunk); queuedChunk.provider.loadedChunks.add(chunk); -+ queuedChunk.provider.field_73244_f.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk); // Cauldron - vanilla/mystcraft compatibility ++ queuedChunk.provider.loadedChunkHashMap_vanilla.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk); // Cauldron - vanilla/mystcraft compatibility chunk.onChunkLoad(); if (queuedChunk.provider.currentChunkProvider != null) { diff --git a/src/main/java/kcauldron/KCauldonClassTransformer.java b/src/main/java/kcauldron/KCauldonClassTransformer.java new file mode 100644 index 0000000..aaa4354 --- /dev/null +++ b/src/main/java/kcauldron/KCauldonClassTransformer.java @@ -0,0 +1,53 @@ +package kcauldron; + +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; + +import net.minecraft.launchwrapper.IClassTransformer; +import static org.objectweb.asm.Opcodes.*; + +public class KCauldonClassTransformer implements IClassTransformer { + public static boolean DEV; + + @Override + public byte[] transform(String name, String transformedName, byte[] basicClass) { + if ("net.minecraft.world.gen.ChunkProviderServer".equals(transformedName) || "net.minecraftforge.common.chunkio.ChunkIOProvider".equals(transformedName)) { + return patchChunkCall(basicClass); + } + return basicClass; + } + + private byte[] patchChunkCall(byte[] bytes) { + ClassReader reader = new ClassReader(bytes); + ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); + reader.accept(new ClassVisitor(ASM5, writer) { + @Override + public FieldVisitor visitField(int access, String name, + String desc, String signature, Object value) { + if ("loadedChunkHashMap_vanilla".equals(name)) { + name = DEV ? "loadedChunkHashMap" : "field_73244_f"; + } + return super.visitField(access, name, desc, signature, value); + } + + @Override + public MethodVisitor visitMethod(int access, String name, + String desc, String signature, String[] exceptions) { + return new MethodVisitor(api, super.visitMethod(access, name, desc, signature, exceptions)) { + @Override + public void visitFieldInsn(int opcode, String owner, + String name, String desc) { + if ("loadedChunkHashMap_vanilla".equals(name)) { + name = DEV ? "loadedChunkHashMap" : "field_73244_f"; + } + super.visitFieldInsn(opcode, owner, name, desc); + } + }; + } + }, 0); + return writer.toByteArray(); + } +}