Skip to content

Commit 4662bab

Browse files
committed
Update "Incremental chunk and player saving"
1 parent cb69628 commit 4662bab

1 file changed

Lines changed: 81 additions & 45 deletions

File tree

paper-server/patches/features_unapplied/0020-Incremental-chunk-and-player-saving.patch renamed to paper-server/patches/features/0021-Incremental-chunk-and-player-saving.patch

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,81 @@ Subject: [PATCH] Incremental chunk and player saving
55

66

77
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
8-
index a9751f4bda862ef597ba39700b83c434f7a457d9..90e23b96ed3fc5a84f52e6f94ad40bdb028fedf7 100644
8+
index 65a971379f35c4b1b519b93787f690d891e29523..dadad4106e774884bc32af0ce37591b08c6d9a4c 100644
99
--- a/net/minecraft/server/MinecraftServer.java
1010
+++ b/net/minecraft/server/MinecraftServer.java
11-
@@ -972,7 +972,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
12-
boolean var4;
11+
@@ -957,7 +957,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
12+
}
13+
public boolean saveAllChunks(final boolean silent, final boolean flush, final boolean force, final boolean close) {
14+
// Paper end - add close param
15+
- this.scoreboard.storeToSaveDataIfDirty(this.getDataStorage().computeIfAbsent(ScoreboardSaveData.TYPE));
16+
+ this.saveGlobalData(flush); // Paper - move to saveGlobalData()
17+
boolean result = false;
18+
19+
for (ServerLevel level : this.getAllLevels()) {
20+
@@ -969,13 +969,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
21+
result = true;
22+
}
23+
24+
- GameProfile singleplayerProfile = this.getSingleplayerProfile();
25+
- this.storageSource.saveDataTag(this.worldData, singleplayerProfile == null ? null : singleplayerProfile.id());
26+
- if (flush) {
27+
- this.savedDataStorage.saveAndJoin();
28+
- } else {
29+
- this.savedDataStorage.scheduleSave();
30+
- }
31+
+ // Paper - move to saveGlobalData()
32+
33+
if (flush) {
34+
for (ServerLevel level : this.getAllLevels()) {
35+
@@ -989,11 +983,25 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
36+
return result;
37+
}
38+
39+
+ // Paper start - split out global level data
40+
+ public void saveGlobalData(final boolean flush) {
41+
+ this.scoreboard.storeToSaveDataIfDirty(this.getDataStorage().computeIfAbsent(ScoreboardSaveData.TYPE));
42+
+
43+
+ GameProfile singleplayerProfile = this.getSingleplayerProfile();
44+
+ this.storageSource.saveDataTag(this.worldData, singleplayerProfile == null ? null : singleplayerProfile.id());
45+
+ if (flush) {
46+
+ this.savedDataStorage.saveAndJoin();
47+
+ } else {
48+
+ this.savedDataStorage.scheduleSave();
49+
+ }
50+
+ }
51+
+ // Paper end - split out global level data
52+
+
53+
public boolean saveEverything(final boolean silent, final boolean flush, final boolean force) {
54+
boolean var5;
1355
try {
1456
this.isSaving = true;
1557
- this.getPlayerList().saveAll();
1658
+ this.getPlayerList().saveAll(); // Paper - Incremental chunk and player saving; diff on change
17-
var4 = this.saveAllChunks(suppressLogs, flush, force);
18-
} finally {
19-
this.isSaving = false;
20-
@@ -1615,9 +1615,29 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
59+
boolean result = this.saveAllChunks(silent, flush, force);
60+
this.warnOnLowDiskSpace();
61+
var5 = result;
62+
@@ -1640,9 +1648,31 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
2163
}
2264

2365
this.ticksUntilAutosave--;
2466
- if (this.autosavePeriod > 0 && this.ticksUntilAutosave <= 0) { // CraftBukkit
2567
- this.autoSave();
2668
+ // Paper start - Incremental chunk and player saving
27-
+ final ProfilerFiller profiler = Profiler.get();
2869
+ int playerSaveInterval = io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.rate;
2970
+ if (playerSaveInterval < 0) {
30-
+ playerSaveInterval = autosavePeriod;
71+
+ playerSaveInterval = this.autosavePeriod;
3172
+ }
32-
+ profiler.push("save");
33-
+ final boolean fullSave = autosavePeriod > 0 && this.tickCount % autosavePeriod == 0;
73+
+ Profiler.get().push("save");
74+
+ final boolean fullSave = this.autosavePeriod > 0 && this.tickCount % this.autosavePeriod == 0;
3475
+ try {
3576
+ this.isSaving = true;
3677
+ if (playerSaveInterval > 0) {
3778
+ this.playerList.saveAll(playerSaveInterval);
3879
+ }
80+
+ if (fullSave) {
81+
+ this.saveGlobalData(false);
82+
+ }
3983
+ for (final ServerLevel level : this.getAllLevels()) {
4084
+ if (level.paperConfig().chunks.autoSaveInterval.value() > 0) {
4185
+ level.saveIncrementally(fullSave);
@@ -44,47 +88,36 @@ index a9751f4bda862ef597ba39700b83c434f7a457d9..90e23b96ed3fc5a84f52e6f94ad40bdb
4488
+ } finally {
4589
+ this.isSaving = false;
4690
}
47-
+ profiler.pop();
91+
+ Profiler.get().pop();
4892
+ // Paper end - Incremental chunk and player saving
4993

50-
ProfilerFiller profilerFiller = Profiler.get();
94+
ProfilerFiller profiler = Profiler.get();
5195
this.server.spark.executeMainThreadTasks(); // Paper - spark
5296
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
53-
index ef7e24716c2fc6a643d107cadcf743f80b39af41..45550619778b6a6b7f1f03467ece6bfe3d7b1e51 100644
97+
index 18eb79f76fb558a1ba9f989f59d2f273975be3a1..7a55657f9fb106dc3e95ef808d103a66cf2e56bd 100644
5498
--- a/net/minecraft/server/level/ServerLevel.java
5599
+++ b/net/minecraft/server/level/ServerLevel.java
56-
@@ -1416,6 +1416,26 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
100+
@@ -1441,6 +1441,15 @@ public class ServerLevel extends Level implements WorldGenLevel, ServerEntityGet
101+
public boolean mayInteract(final Entity entity, final BlockPos pos) {
57102
return !(entity instanceof Player player && (this.server.isUnderSpawnProtection(this, pos, player) || !this.getWorldBorder().isWithinBounds(pos)));
58103
}
59-
60104
+ // Paper start - Incremental chunk and player saving
61-
+ public void saveIncrementally(boolean doFull) {
105+
+ public void saveIncrementally(final boolean doFull) {
62106
+ if (doFull) {
63107
+ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld()));
64-
+ }
65-
+
66-
+ if (doFull) {
67108
+ this.saveLevelData(false);
68109
+ }
69110
+ // chunk autosave is already called by the ChunkSystem during unload processing (ChunkMap#processUnloads)
70-
+ // Copied from save()
71-
+ // CraftBukkit start - moved from MinecraftServer.saveChunks
72-
+ if (doFull) { // Paper
73-
+ this.serverLevelData.setCustomBossEvents(this.server.getCustomBossEvents().save(this.registryAccess()));
74-
+ this.levelStorageAccess.saveDataTag(this.server.registryAccess(), this.serverLevelData, this.server.getPlayerList().getSingleplayerData());
75-
+ }
76-
+ // CraftBukkit end
77111
+ }
78112
+ // Paper end - Incremental chunk and player saving
79-
+
80-
public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) {
113+
114+
public void save(final @Nullable ProgressListener progressListener, final boolean flush, final boolean noSave) {
81115
// Paper start - add close param
82-
this.save(progress, flush, skipSave, false);
83116
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
84-
index 1776f98636ca53a7cdbd160fbf6c22526fdb26a4..ea0853d09f17ee6dab3f063fd3abf10248d92ccd 100644
117+
index 41816ca8d4ef3d959d2b88cd4b2eedaaa541e612..82e87270d1ad89ad7aa56e028ced6b998ea0eca5 100644
85118
--- a/net/minecraft/server/level/ServerPlayer.java
86119
+++ b/net/minecraft/server/level/ServerPlayer.java
87-
@@ -203,6 +203,7 @@ import org.slf4j.Logger;
120+
@@ -205,6 +205,7 @@ import org.slf4j.Logger;
88121

89122
public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
90123
private static final Logger LOGGER = LogUtils.getLogger();
@@ -93,39 +126,42 @@ index 1776f98636ca53a7cdbd160fbf6c22526fdb26a4..ea0853d09f17ee6dab3f063fd3abf102
93126
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
94127
private static final int FLY_STAT_RECORDING_SPEED = 25;
95128
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
96-
index 38c30d98a200dd2a5c888cc080e9c77795f0e0c4..dec9dd8e42f90ccf7e5e3ad945e459d07159250d 100644
129+
index 0613b053f4a75c0884280011ee092d9d108b3857..b69bcaa1e27a4fbe9a9568f3c9e1843167abe1f5 100644
97130
--- a/net/minecraft/server/players/PlayerList.java
98131
+++ b/net/minecraft/server/players/PlayerList.java
99-
@@ -412,6 +412,7 @@ public abstract class PlayerList {
132+
@@ -418,6 +418,7 @@ public abstract class PlayerList {
100133

101-
protected void save(ServerPlayer player) {
134+
protected void save(final ServerPlayer player) {
102135
if (!player.getBukkitEntity().isPersistent()) return; // CraftBukkit
103136
+ player.lastSave = MinecraftServer.currentTick; // Paper - Incremental chunk and player saving
104137
this.playerIo.save(player);
105-
ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit
106-
if (serverStatsCounter != null) {
107-
@@ -941,9 +942,23 @@ public abstract class PlayerList {
138+
ServerStatsCounter stats = player.getStats(); // CraftBukkit
139+
if (stats != null) {
140+
@@ -951,10 +952,24 @@ public abstract class PlayerList {
108141
}
109142

110143
public void saveAll() {
111144
+ // Paper start - Incremental chunk and player saving
112145
+ this.saveAll(-1);
113146
+ }
114-
+
115147
+ public void saveAll(final int interval) {
148+
+ // Paper end - Incremental chunk and player saving
116149
io.papermc.paper.util.MCUtil.ensureMain("Save Players" , () -> { // Paper - Ensure main
117-
+ int numSaved = 0;
118-
+ final long now = MinecraftServer.currentTick;
119-
for (int i = 0; i < this.players.size(); i++) {
150+
- for (int i = 0; i < this.players.size(); i++) {
120151
- this.save(this.players.get(i));
121-
+ final ServerPlayer player = this.players.get(i);
152+
- }
153+
+ // Paper start - Incremental chunk and player saving
154+
+ int numSaved = 0;
155+
+ final long now = MinecraftServer.currentTick;
156+
+ for (final ServerPlayer player : this.players) {
122157
+ if (interval == -1 || now - player.lastSave >= interval) {
123158
+ this.save(player);
124159
+ if (interval != -1 && ++numSaved >= io.papermc.paper.configuration.GlobalConfiguration.get().playerAutoSave.maxPerTick()) {
125160
+ break;
126161
+ }
127162
+ }
128-
+ // Paper end - Incremental chunk and player saving
129-
}
163+
+ }
164+
+ // Paper end - Incremental chunk and player saving
130165
return null; }); // Paper - ensure main
131166
}
167+

0 commit comments

Comments
 (0)