mirror of
https://github.com/PaperMC/Paper.git
synced 2025-07-26 09:42:06 -07:00
This implements a solution that preemptively exits the tick loop if we have already marked the connection as disconnecting. This avoids changing the result of Connection#isConnected in order to avoid other possibly unintentional changes. Fundamentally it should be investigated if closing the connection async is really still needed. This also additionally removes the login disconnecting logic for server stopping, as this was also a possible issue in the config stage but also shouldn't be an issue as connections are closed on server stop very early. Additionally, do not check for isConnecting() on VERIFYING, as that seemed to be an old diff originally trying to resolve this code, however isConnected is not updated at this point so it pretty much was useless.
134 lines
6.8 KiB
Diff
134 lines
6.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Shane Freeder <theboyetronic@gmail.com>
|
|
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 338ef549efe82c250c74365c1c1071986920c8c9..39581095ccc69d113d954ed835bdfa32d25b5489 100644
|
|
--- a/net/minecraft/server/MinecraftServer.java
|
|
+++ b/net/minecraft/server/MinecraftServer.java
|
|
@@ -955,7 +955,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;
|
|
@@ -1534,9 +1534,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 34b7769663e235b93c6388ab0c92c00f0297e42f..dda8d38ef61672cc714d9e5a475f9b0412ed5ff9 100644
|
|
--- a/net/minecraft/server/level/ServerLevel.java
|
|
+++ b/net/minecraft/server/level/ServerLevel.java
|
|
@@ -1339,6 +1339,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
|
|
return !(entity instanceof Player player && (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(false);
|
|
+ }
|
|
+ // 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 ff2f4a0fd221c0b632066cdc93719ec6d66c2ff7..9cbadb677d2ab3e9e3ee45df6647a1cbd28fcfd7 100644
|
|
--- a/net/minecraft/server/level/ServerPlayer.java
|
|
+++ b/net/minecraft/server/level/ServerPlayer.java
|
|
@@ -195,6 +195,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 18aaa9bfb08ce36177a5f357644093630ce91264..fe3f36b3cd90766f026c6383cfedc42fa7ae5508 100644
|
|
--- a/net/minecraft/server/players/PlayerList.java
|
|
+++ b/net/minecraft/server/players/PlayerList.java
|
|
@@ -489,6 +489,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) {
|
|
@@ -1059,9 +1060,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
|
|
}
|