diff options
Diffstat (limited to 'paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch')
-rw-r--r-- | paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch b/paper-server/patches/features/0032-Incremental-chunk-and-player-saving.patch new file mode 100644 index 0000000000..282b9eb257 --- /dev/null +++ b/paper-server/patches/features/0032-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 d077debf5936050484856e0b84f764967b5d3f5c..75efd8f11a42696319c0908b7cf911cf976a31b6 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -940,7 +940,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; +@@ -1530,9 +1530,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 9caa06f09409d36abf9e0a770ba004f4049e8e09..fc3b0db0f0a85fb42cb5fa8a1d78d4c4691ab519 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 bf4deeac50197eeb83c5b1e458b609aac5ad8a97..a97b0b177a1fb0557af2af4d1f192513d7c0390d 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 e5ae5e1161396280ffea1009f40dafa0398050bb..d74242a0d25c906d74b018c24d4b21d64415617d 100644 +--- a/net/minecraft/server/players/PlayerList.java ++++ b/net/minecraft/server/players/PlayerList.java +@@ -483,6 +483,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) { +@@ -1070,9 +1071,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 + } |