diff --git a/patches/minecraft/net/minecraft/entity/Entity.java.patch b/patches/minecraft/net/minecraft/entity/Entity.java.patch index 0487ad426c..d2bf89097c 100644 --- a/patches/minecraft/net/minecraft/entity/Entity.java.patch +++ b/patches/minecraft/net/minecraft/entity/Entity.java.patch @@ -155,7 +155,7 @@ } public boolean func_174816_a(Explosion p_174816_1_, World p_174816_2_, BlockPos p_174816_3_, IBlockState p_174816_4_, float p_174816_5_) -@@ -2862,6 +2889,184 @@ +@@ -2862,6 +2889,185 @@ EnchantmentHelper.func_151385_b(p_174815_1_, p_174815_2_); } @@ -248,6 +248,7 @@ + /** + * Reset the entity ID to a new value. Not to be used from Mod code + */ ++ @Deprecated + public final void resetEntityId() + { + this.field_145783_c = field_70152_a++; diff --git a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch b/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch index 302a93089c..b62e082676 100644 --- a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch +++ b/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch @@ -97,17 +97,18 @@ } } } -@@ -121,7 +180,9 @@ +@@ -121,7 +180,10 @@ NBTTagCompound nbttagcompound1 = new NBTTagCompound(); nbttagcompound.func_74782_a("Level", nbttagcompound1); nbttagcompound.func_74768_a("DataVersion", 922); + net.minecraftforge.fml.common.FMLCommonHandler.instance().getDataFixer().writeVersionData(nbttagcompound); this.func_75820_a(p_75816_2_, p_75816_1_, nbttagcompound1); ++ net.minecraftforge.common.ForgeChunkManager.storeChunkNBT(p_75816_2_, nbttagcompound1); + net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.world.ChunkDataEvent.Save(p_75816_2_, nbttagcompound)); this.func_75824_a(p_75816_2_.func_76632_l(), nbttagcompound); } catch (Exception exception) -@@ -305,11 +366,19 @@ +@@ -305,11 +367,19 @@ { NBTTagCompound nbttagcompound2 = new NBTTagCompound(); @@ -127,7 +128,7 @@ } } -@@ -318,8 +387,16 @@ +@@ -318,8 +388,16 @@ for (TileEntity tileentity : p_75820_1_.func_177434_r().values()) { @@ -144,7 +145,7 @@ } p_75820_3_.func_74782_a("TileEntities", nbttaglist2); -@@ -388,6 +465,12 @@ +@@ -388,6 +466,12 @@ chunk.func_76616_a(p_75823_2_.func_74770_j("Biomes")); } @@ -157,7 +158,7 @@ NBTTagList nbttaglist1 = p_75823_2_.func_150295_c("Entities", 10); for (int j1 = 0; j1 < nbttaglist1.func_74745_c(); ++j1) -@@ -431,8 +514,6 @@ +@@ -431,8 +515,6 @@ p_75823_1_.func_180497_b(new BlockPos(nbttagcompound3.func_74762_e("x"), nbttagcompound3.func_74762_e("y"), nbttagcompound3.func_74762_e("z")), block, nbttagcompound3.func_74762_e("t"), nbttagcompound3.func_74762_e("p")); } } diff --git a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch index 0e2273daae..913382a6ce 100644 --- a/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ b/patches/minecraft/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -72,11 +72,15 @@ Iterator iterator = this.field_73248_b.iterator(); for (int i = 0; i < 100 && iterator.hasNext(); iterator.remove()) -@@ -239,6 +272,11 @@ +@@ -235,10 +268,15 @@ + if (chunk != null && chunk.field_189550_d) + { + chunk.func_76623_d(); ++ net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.func_77272_a(chunk.field_76635_g, chunk.field_76647_h), chunk); + this.func_73242_b(chunk); this.func_73243_a(chunk); this.field_73244_f.remove(olong); ++i; -+ net.minecraftforge.common.ForgeChunkManager.putDormantChunk(ChunkPos.func_77272_a(chunk.field_76635_g, chunk.field_76647_h), chunk); + if (field_73244_f.size() == 0 && net.minecraftforge.common.ForgeChunkManager.getPersistentChunksFor(this.field_73251_h).size() == 0 && !this.field_73251_h.field_73011_w.func_186058_p().shouldLoadSpawn()){ + net.minecraftforge.common.DimensionManager.unloadWorld(this.field_73251_h.field_73011_w.getDimension()); + break; diff --git a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java index 8dbbc07f6d..c94a82a8a1 100644 --- a/src/main/java/net/minecraftforge/common/ForgeChunkManager.java +++ b/src/main/java/net/minecraftforge/common/ForgeChunkManager.java @@ -40,12 +40,14 @@ import net.minecraft.entity.Entity; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ClassInheritanceMultiMap; import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.AnvilChunkLoader; import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Property; @@ -112,7 +114,7 @@ public class ForgeChunkManager private static Map> forcedChunks = new MapMaker().weakKeys().makeMap(); private static BiMap pendingEntities = HashBiMap.create(); - private static Map> dormantChunkCache = new MapMaker().weakKeys().makeMap(); + private static Map> dormantChunkCache = new MapMaker().weakKeys().makeMap(); private static File cfgFile; private static Configuration config; @@ -129,6 +131,18 @@ public class ForgeChunkManager MOD_PROP_ORDER.add("maximumChunksPerTicket"); } + private static class ChunkEntry + { + public final Chunk chunk; + public final NBTTagCompound nbt; + + public ChunkEntry(Chunk chunk) + { + this.chunk = chunk; + this.nbt = new NBTTagCompound(); + } + } + public static Iterator getPersistentChunksIterableFor(final World world, Iterator chunkIterator) { final ImmutableSetMultimap persistentChunksFor = getPersistentChunksFor(world); @@ -472,7 +486,7 @@ public class ForgeChunkManager if (dormantChunkCacheSize != 0) { // only put into cache if we're using dormant chunk caching - dormantChunkCache.put(world, CacheBuilder.newBuilder().maximumSize(dormantChunkCacheSize).build()); + dormantChunkCache.put(world, CacheBuilder.newBuilder().maximumSize(dormantChunkCacheSize).build()); } WorldServer worldServer = (WorldServer) world; File chunkDir = worldServer.getChunkSaveLocation(); @@ -968,10 +982,32 @@ public class ForgeChunkManager public static void putDormantChunk(long coords, Chunk chunk) { if (dormantChunkCacheSize == 0) return; // Skip if we're not dormant caching chunks - Cache cache = dormantChunkCache.get(chunk.getWorld()); + Cache cache = dormantChunkCache.get(chunk.getWorld()); if (cache != null) { - cache.put(coords, chunk); + cache.put(coords, new ChunkEntry(chunk)); + } + } + + public static void storeChunkNBT(Chunk chunk, NBTTagCompound nbt) + { + if (dormantChunkCacheSize == 0) return; + + Cache cache = dormantChunkCache.get(chunk.getWorld()); + if (cache == null) return; + + ChunkEntry entry = cache.getIfPresent(ChunkPos.asLong(chunk.xPosition, chunk.zPosition)); + if (entry != null) + { + entry.nbt.setTag("Entities", nbt.getTagList("Entities", Constants.NBT.TAG_COMPOUND)); + entry.nbt.setTag("TileEntities", nbt.getTagList("TileEntities", Constants.NBT.TAG_COMPOUND)); + + ClassInheritanceMultiMap[] entityLists = chunk.getEntityLists(); + for (int i = 0; i < entityLists.length; ++i) + { + entityLists[i] = new ClassInheritanceMultiMap(Entity.class); + } + chunk.getTileEntityMap().clear(); } } @@ -979,24 +1015,33 @@ public class ForgeChunkManager public static Chunk fetchDormantChunk(long coords, World world) { if (dormantChunkCacheSize == 0) return null; // Don't bother with maps at all if its never gonna get a response - Cache cache = dormantChunkCache.get(world); - if (cache == null) + + Cache cache = dormantChunkCache.get(world); + if (cache == null) return null; + + ChunkEntry entry = cache.getIfPresent(coords); + if (entry == null) return null; + + loadChunkEntities(entry.chunk, entry.nbt, world); + + return entry.chunk; + } + + private static void loadChunkEntities(Chunk chunk, NBTTagCompound nbt, World world) + { + NBTTagList entities = nbt.getTagList("Entities", Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < entities.tagCount(); ++i) { - return null; + AnvilChunkLoader.readChunkEntity(entities.getCompoundTagAt(i), world, chunk); + chunk.setHasEntities(true); } - Chunk chunk = cache.getIfPresent(coords); - if (chunk != null) + + NBTTagList tileEntities = nbt.getTagList("TileEntities", Constants.NBT.TAG_COMPOUND); + for (int i = 0; i < tileEntities.tagCount(); ++i) { - for (ClassInheritanceMultiMap eList : chunk.getEntityLists()) - { - Iterator itr = eList.iterator(); - while (itr.hasNext()) - { - (itr.next()).resetEntityId(); - } - } + TileEntity tileentity = TileEntity.create(world, tileEntities.getCompoundTagAt(i)); + if (tileentity != null) chunk.addTileEntity(tileentity); } - return chunk; } static void captureConfig(File configDir)