diff --git a/src/main/java/net/minecraft/world/WorldServer.java b/src/main/java/net/minecraft/world/WorldServer.java index e91b6d7..cd47fd3 100644 --- a/src/main/java/net/minecraft/world/WorldServer.java +++ b/src/main/java/net/minecraft/world/WorldServer.java @@ -336,6 +336,7 @@ this.theProfiler.startSection("getChunk"); Chunk chunk = this.getChunkFromChunkCoords(chunkX, chunkZ); + chunk.setActive(); this.theProfiler.startSection("updatePending"); this.updatePendingOf(chunk); this.func_147467_a(k, l, chunk); diff --git a/src/main/java/net/minecraft/world/chunk/Chunk.java b/src/main/java/net/minecraft/world/chunk/Chunk.java index 23c5c85..8c33822 100644 --- a/src/main/java/net/minecraft/world/chunk/Chunk.java +++ b/src/main/java/net/minecraft/world/chunk/Chunk.java @@ -929,6 +929,7 @@ MinecraftForge.EVENT_BUS.post(new ChunkEvent.Load(this)); loadTime = unbindTime = ((WorldServer)worldObj).func_73046_m().getTickCounter(); + lastsavePendingCount = pendingUpdatesSet.size(); } public void onChunkUnload() @@ -1018,12 +1019,9 @@ { if (par1) { - if (this.hasEntities && this.worldObj.getTotalWorldTime() != this.lastSaveTime || this.isModified) - { - return true; - } + return shouldSaveOnUnload(); } - else if (this.hasEntities && this.worldObj.getTotalWorldTime() >= this.lastSaveTime + 600L) + else if (wasActive && this.hasEntities && this.worldObj.getTotalWorldTime() >= this.lastSaveTime + 600L) { return true; } @@ -1544,6 +1542,8 @@ private ChunkBindState bindState = ChunkBindState.NONE; private int loadTime; private int unbindTime; + private boolean wasActive; + private int lastsavePendingCount; public PendingBlockUpdate pollPending(long time) { @@ -1613,4 +1613,20 @@ { return unbindTime; } + + public void setActive() + { + wasActive = true; + } + + public void postSave() + { + wasActive = false; + lastsavePendingCount = pendingUpdatesSet.size(); + } + + public boolean shouldSaveOnUnload() + { + return isModified || lastsavePendingCount != pendingUpdatesSet.size() || wasActive && hasEntities; + } } diff --git a/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java b/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java index 913ceab..95c979f 100644 --- a/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java +++ b/src/main/java/net/minecraft/world/chunk/storage/AnvilChunkLoader.java @@ -254,10 +254,11 @@ public void saveExtraData() { - while (this.writeNextIO()) - { - ; - } + //Async only +// while (this.writeNextIO()) +// { +// ; +// } } private void writeChunkToNBT(Chunk par1Chunk, World par2World, NBTTagCompound par3NBTTagCompound) @@ -502,6 +503,14 @@ } } + public int getSaveQueueSize() + { + synchronized(syncLockObject) + { + return pendingSaves.size(); + } + } + static class PendingChunk { public final ChunkCoordIntPair chunkCoordinate; diff --git a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java index a30e8ca..a216998 100644 --- a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java @@ -287,6 +287,7 @@ { this.safeSaveChunk(chunk); chunk.isModified = false; + chunk.postSave(); ++i; if (i == 24 && !par1) @@ -313,11 +314,6 @@ { if(isServer) chunkGC.onTick(); - - for (ChunkCoordIntPair forced : this.worldObj.getPersistentChunks().keySet()) - { - this.chunksToUnload.remove(ChunkHash.chunkToKey(forced.chunkXPos, forced.chunkZPos)); - } /* for (int i = 0; i < 100; ++i) @@ -341,31 +337,27 @@ } */ - int processed = 0; - for(TIntIterator it = chunksToUnload.iterator(); it.hasNext();) + Set persistentChunks = worldObj.getPersistentChunks().keySet(); + int savequeueSize = ((AnvilChunkLoader)currentChunkLoader).getSaveQueueSize(); + + for(TIntIterator it = chunksToUnload.iterator(); it.hasNext() && savequeueSize < MAX_SAVE_QUEUE_SIZE;) { - if(processed >= 20) break; int hash = it.next(); Chunk chunk = loadedChunkHashMap.get(hash); if(chunk != null) { - if(chunk.getBindState().canUnload()) + if(chunk.getBindState().canUnload() && !persistentChunks.contains(chunk.getChunkCoordIntPair())) { chunk.onChunkUnload(); - if(true/*chunk.shouldSaveOnUnload()*/) + if(chunk.shouldSaveOnUnload()) { - processed++; + savequeueSize++; safeSaveChunk(chunk); } this.safeSaveExtraChunkData(chunk); this.loadedChunkHashMap.remove(hash); - //chunk.postChunkUnload(); } } - else - { - logger.warn("Not existing chunk was queued for unload (" + ChunkHash.keyToX(hash) + ", " + ChunkHash.keyToZ(hash) + ")"); - } it.remove(); } @@ -409,6 +401,7 @@ /* ======================================== ULTRAMINE START =====================================*/ + private static final int MAX_SAVE_QUEUE_SIZE = 20; private static final boolean isServer = FMLCommonHandler.instance().getSide().isServer(); @SideOnly(Side.SERVER)