diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java index 0c0b841..8030bdf 100644 --- a/src/main/java/net/minecraft/server/MinecraftServer.java +++ b/src/main/java/net/minecraft/server/MinecraftServer.java @@ -570,13 +570,14 @@ this.field_147147_p.func_151318_b().func_151330_a(agameprofile); } - if (this.tickCounter % 900 == 0) - { +// if (this.tickCounter % 900 == 0) +// { this.theProfiler.startSection("save"); - this.serverConfigManager.saveAllPlayerData(); - this.saveAllWorlds(true); + this.serverConfigManager.saveOnePlayerData(tickCounter); + for(WorldServer world : worldServers) + world.theChunkProviderServer.saveOneChunk(tickCounter); this.theProfiler.endSection(); - } +// } this.theProfiler.startSection("tallying"); this.tickTimeArray[this.tickCounter % 100] = System.nanoTime() - i; diff --git a/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java b/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java index 0348b3b..a3ca810 100644 --- a/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java +++ b/src/main/java/net/minecraft/server/management/ServerConfigurationManager.java @@ -1157,4 +1157,13 @@ { return playerNBTManagerObj; } + + public void saveOnePlayerData(int tick) + { + int ind = tick % Math.max(900, playerEntityList.size()); //Может ведь быть более 900 игроков, не правда ли?) + if(ind < playerEntityList.size()) + { + writePlayerData((EntityPlayerMP)playerEntityList.get(ind)); + } + } } diff --git a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java index f684bf4..f57589e 100644 --- a/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java +++ b/src/main/java/net/minecraft/world/gen/ChunkProviderServer.java @@ -1,6 +1,7 @@ package net.minecraft.world.gen; import gnu.trove.iterator.TIntIterator; +import gnu.trove.iterator.TIntObjectIterator; import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.set.TIntSet; @@ -413,7 +414,10 @@ /* ======================================== ULTRAMINE START =====================================*/ private static final int MAX_SAVE_QUEUE_SIZE = 20; + private static final int FULL_SAVE_INTERVAL = 10*60*20; //10 min private static final boolean isServer = FMLCommonHandler.instance().getSide().isServer(); + private final TIntSet possibleSaves = new TIntHashSet(); + private int lastFullSaveTick; @SideOnly(Side.SERVER) private ChunkGC chunkGC; @@ -459,8 +463,48 @@ public void unbindChunk(Chunk chunk) { if(isServer) + { chunk.unbind(); + possibleSaves.add(ChunkHash.chunkToKey(chunk.xPosition, chunk.zPosition)); + } else + { unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); + } + } + + public void saveOneChunk(int tick) + { + if(tick - lastFullSaveTick >= FULL_SAVE_INTERVAL) + { + for(TIntObjectIterator it = loadedChunkHashMap.iterator(); it.hasNext();) + { + it.advance(); + int key = it.key(); + if(it.value().needsSaving(false) && !chunksToUnload.contains(key)) + possibleSaves.add(key); + } + + lastFullSaveTick = tick; + } + + if(!possibleSaves.isEmpty()) + { + int count = Math.min(10, Math.max(1, possibleSaves.size()/(FULL_SAVE_INTERVAL - tick + lastFullSaveTick))); + + for(TIntIterator it = possibleSaves.iterator(); it.hasNext();) + { + int key = it.next(); + it.remove(); + Chunk chunk = loadedChunkHashMap.get(key); + if(chunk != null && chunk.needsSaving(false) && !chunksToUnload.contains(key)) + { + safeSaveChunk(chunk); + chunk.isModified = false; + chunk.postSave(); + if(--count == 0) break; + } + } + } } } \ No newline at end of file