mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
Save/restore dormant chunk entity data from NBT (#3940)
This commit is contained in:
1 parent
4d02491374
commit
7d60ce788b
4 files changed
+77
-26
No files matched your search
@@ -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++;
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,11 +72,15 @@
|
||||
Iterator<Long> 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;
|
||||
|
||||
@@ -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<World, ImmutableSetMultimap<ChunkPos,Ticket>> forcedChunks = new MapMaker().weakKeys().makeMap();
|
||||
private static BiMap<UUID,Ticket> pendingEntities = HashBiMap.create();
|
||||
|
||||
private static Map<World,Cache<Long, Chunk>> dormantChunkCache = new MapMaker().weakKeys().makeMap();
|
||||
private static Map<World,Cache<Long, ChunkEntry>> 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<Chunk> getPersistentChunksIterableFor(final World world, Iterator<Chunk> chunkIterator)
|
||||
{
|
||||
final ImmutableSetMultimap<ChunkPos, Ticket> 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).<Long, Chunk>build());
|
||||
dormantChunkCache.put(world, CacheBuilder.newBuilder().maximumSize(dormantChunkCacheSize).<Long, ChunkEntry>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<Long, Chunk> cache = dormantChunkCache.get(chunk.getWorld());
|
||||
Cache<Long, ChunkEntry> 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<Long, ChunkEntry> 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<Entity>[] entityLists = chunk.getEntityLists();
|
||||
for (int i = 0; i < entityLists.length; ++i)
|
||||
{
|
||||
entityLists[i] = new ClassInheritanceMultiMap<Entity>(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<Long, Chunk> cache = dormantChunkCache.get(world);
|
||||
if (cache == null)
|
||||
|
||||
Cache<Long, ChunkEntry> 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<Entity> eList : chunk.getEntityLists())
|
||||
{
|
||||
Iterator<Entity> 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)
|
||||
|
||||
Reference in new issue
Block a user