papermc/patches/server/0860-Fix-save-problems-on-shutdown.patch

75 lines
3.3 KiB
Diff
Raw Normal View History

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 5 Mar 2022 17:12:52 -0800
Subject: [PATCH] Fix save problems on shutdown
- Save level.dat first, in case the shutdown is killed later
- Force run minecraftserver tasks and the chunk source tasks
while waiting for the chunk system to empty, as there's simply
too much trash that could prevent them from executing during
the chunk source tick (i.e "time left in tick" logic).
- Set forceTicks to true, so that player packets are always
processed so that the main process queue can be drained
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index dca520534feac302b8e0f389ee9286bd719e31a6..33cf037bf8ed5ea88f52ee3731cde63c70e813ef 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -957,6 +957,13 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
+ // Paper start - let's be a little more intelligent around crashes
+ // make sure level.dat saves
+ for (ServerLevel level : this.getAllLevels()) {
+ level.saveLevelDat();
+ }
+ // Paper end - let's be a little more intelligent around crashes
+
while (this.levels.values().stream().anyMatch((worldserver1) -> {
return worldserver1.getChunkSource().chunkMap.hasWork();
})) {
@@ -969,9 +976,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
worldserver.getChunkSource().tick(() -> {
return true;
}, false);
+ while (worldserver.getChunkSource().pollTask()); // Paper - drain tasks
}
- this.waitUntilNextTick();
+ this.forceTicks = true; // Paper
+ while (this.pollTask()); // Paper - drain tasks
}
this.saveAllChunks(false, true, false);
@@ -1266,6 +1275,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
private boolean haveTime() {
+ // Paper start
+ if (this.forceTicks) {
+ return true;
+ }
+ // Paper end
// CraftBukkit start
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
return this.forceTicks || this.runningTask() || Util.getMillis() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTime : this.nextTickTime);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
2022-07-27 21:32:15 +00:00
index 836841987ff5dd4901f75f47028a60d8d1b6e04a..802b929a16b6a8aeee608caeb524e268f8df53bd 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
2022-07-27 21:32:15 +00:00
@@ -1279,7 +1279,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
}
+ // Paper start
+ this.saveLevelDat();
+ }
+ public void saveLevelDat() {
+ this.saveLevelData();
+ // Paper end
// CraftBukkit start - moved from MinecraftServer.saveChunks
ServerLevel worldserver1 = this;