diff options
Diffstat (limited to 'paper-server/patches/features/0025-Incremental-chunk-and-player-saving.patch')
-rw-r--r-- | paper-server/patches/features/0025-Incremental-chunk-and-player-saving.patch | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/paper-server/patches/features/0025-Incremental-chunk-and-player-saving.patch b/paper-server/patches/features/0025-Incremental-chunk-and-player-saving.patch new file mode 100644 index 0000000000..9d7ae4524f --- /dev/null +++ b/paper-server/patches/features/0025-Incremental-chunk-and-player-saving.patch @@ -0,0 +1,133 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Shane Freeder <[email protected]> +Date: Sun, 9 Jun 2019 03:53:22 +0100 +Subject: [PATCH] Incremental chunk and player saving + + +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index d967d605c2e4227ae980c30f1c8b86edbc680d6d..6dbae12bbfd47cd4e75bc3089561e8e226e9e604 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -960,7 +960,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa + boolean var4; + try { + this.isSaving = true; +- this.getPlayerList().saveAll(); ++ this.getPlayerList().saveAll(); // Paper - Incremental chunk and player saving; diff on change + var4 = this.saveAllChunks(suppressLog, flush, forced); + } finally { + this.isSaving = false; +@@ -1533,9 +1533,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa + } + + this.ticksUntilAutosave--; +- if (this.autosavePeriod > 0 && this.ticksUntilAutosave <= 0) { // CraftBukkit +- this.autoSave(); ++ // Paper start - Incremental chunk and player saving ++ final ProfilerFiller profiler = Profiler.get(); ++ int playerSaveInterval = io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.rate; ++ if (playerSaveInterval < 0) { ++ playerSaveInterval = autosavePeriod; ++ } ++ profiler.push("save"); ++ final boolean fullSave = autosavePeriod > 0 && this.tickCount % autosavePeriod == 0; ++ try { ++ this.isSaving = true; ++ if (playerSaveInterval > 0) { ++ this.playerList.saveAll(playerSaveInterval); ++ } ++ for (final ServerLevel level : this.getAllLevels()) { ++ if (level.paperConfig().chunks.autoSaveInterval.value() > 0) { ++ level.saveIncrementally(fullSave); ++ } ++ } ++ } finally { ++ this.isSaving = false; + } ++ profiler.pop(); ++ // Paper end - Incremental chunk and player saving + + ProfilerFiller profilerFiller = Profiler.get(); + this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings) +diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java +index 46dfaed12c998c219a20c711a06531aed2c68012..ebeeb63c3dca505a3ce8b88feaa5d2ca20ec24a2 100644 +--- a/net/minecraft/server/level/ServerLevel.java ++++ b/net/minecraft/server/level/ServerLevel.java +@@ -1316,6 +1316,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + return !this.server.isUnderSpawnProtection(this, pos, player) && this.getWorldBorder().isWithinBounds(pos); + } + ++ // Paper start - Incremental chunk and player saving ++ public void saveIncrementally(boolean doFull) { ++ if (doFull) { ++ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); ++ } ++ ++ if (doFull) { ++ this.saveLevelData(true); ++ } ++ // chunk autosave is already called by the ChunkSystem during unload processing (ChunkMap#processUnloads) ++ // Copied from save() ++ // CraftBukkit start - moved from MinecraftServer.saveChunks ++ if (doFull) { // Paper ++ ServerLevel serverLevel1 = this; ++ this.serverLevelData.setWorldBorder(serverLevel1.getWorldBorder().createSettings()); ++ this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save(this.registryAccess())); ++ this.levelStorageAccess.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData()); ++ } ++ // CraftBukkit end ++ } ++ // Paper end - Incremental chunk and player saving ++ + public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) { + // Paper start - add close param + this.save(progress, flush, skipSave, false); +diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java +index e61fe83479f095e8addbd3e8f1d5179c998ae1eb..0a7e5106a1d39150326e7c323030df5d32ecef1e 100644 +--- a/net/minecraft/server/level/ServerPlayer.java ++++ b/net/minecraft/server/level/ServerPlayer.java +@@ -180,6 +180,7 @@ import org.slf4j.Logger; + + public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system + private static final Logger LOGGER = LogUtils.getLogger(); ++ public long lastSave = MinecraftServer.currentTick; // Paper - Incremental chunk and player saving + private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; + private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; + private static final int FLY_STAT_RECORDING_SPEED = 25; +diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java +index 6abe5fd39583663af0feb98607cff75c42d96729..65c16eddff43c875be72b08f61d6f321a6876a48 100644 +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -482,6 +482,7 @@ public abstract class PlayerList { + + protected void save(ServerPlayer player) { + if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit ++ player.lastSave = MinecraftServer.currentTick; // Paper - Incremental chunk and player saving + this.playerIo.save(player); + ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit + if (serverStatsCounter != null) { +@@ -1069,9 +1070,23 @@ public abstract class PlayerList { + } + + public void saveAll() { ++ // Paper start - Incremental chunk and player saving ++ this.saveAll(-1); ++ } ++ ++ public void saveAll(final int interval) { + io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main ++ int numSaved = 0; ++ final long now = MinecraftServer.currentTick; + for (int i = 0; i < this.players.size(); i++) { +- this.save(this.players.get(i)); ++ final ServerPlayer player = this.players.get(i); ++ if (interval == -1 || now - player.lastSave >= interval) { ++ this.save(player); ++ if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) { ++ break; ++ } ++ } ++ // Paper end - Incremental chunk and player saving + } + return null; }); // Paper - ensure main + } |