e07e0cb3ca
There is no reason for the light queue to even be an option. This enables the light queue for everyone. This also improves the "can we still tick" time logic to always check before running a light operation. previously, we always executed at least 10 on the first world (but not other worlds...), but we are seeing light take up some heavy time, so improving that for now. I've now also improved recheck gaps logic to happen at the end of all single block updates This also prevents multiple gap checks, as previously if a tick skipped the gaps check, the next tick would end up re-adding the entry again, resulting in multiple gap checks. This now just sets a marker "We need to recheck gaps" and will only occur once. This also should reduce chunk loads, as previously, we checked if the neighbor chunks were loaded for the gap check, however those neighbor chunks might of unloaded before the light queue operation actually ran. Now, the neighbor chunk is done when the gap check is being done, so it should avoid loading chunks. Fixes #1466 Fixes #1431
235 Zeilen
12 KiB
Diff
235 Zeilen
12 KiB
Diff
From dff8b771c79b65f0225427e0fa0ca4d6f9c38feb Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Mon, 19 Sep 2016 23:16:39 -0400
|
|
Subject: [PATCH] Auto Save Improvements
|
|
|
|
Makes Auto Save Rate setting configurable per-world. If the auto save rate is left -1, the global bukkit.yml value will be used.
|
|
|
|
Process auto save every tick instead of once per auto tick interval, so that chunk saves will distribute over many ticks instead of all at once.
|
|
|
|
Re-introduce a cap per tick for auto save (Spigot disabled the vanilla cap) and make it configurable.
|
|
|
|
Adds incremental player auto saving too
|
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
index aa0e3c757d..c1845d6811 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
@@ -255,4 +255,15 @@ public class PaperConfig {
|
|
flyingKickPlayerMessage = getString("messages.kick.flying-player", flyingKickPlayerMessage);
|
|
flyingKickVehicleMessage = getString("messages.kick.flying-vehicle", flyingKickVehicleMessage);
|
|
}
|
|
+
|
|
+ public static int playerAutoSaveRate = -1;
|
|
+ public static int maxPlayerAutoSavePerTick = 10;
|
|
+ private static void playerAutoSaveRate() {
|
|
+ playerAutoSaveRate = getInt("settings.player-auto-save-rate", -1);
|
|
+ maxPlayerAutoSavePerTick = getInt("settings.max-player-auto-save-per-tick", -1);
|
|
+ if (maxPlayerAutoSavePerTick == -1) { // -1 Automatic / "Recommended"
|
|
+ // 10 should be safe for everyone unless your mass spamming player auto save
|
|
+ maxPlayerAutoSavePerTick = (playerAutoSaveRate == -1 || playerAutoSaveRate > 100) ? 10 : 20;
|
|
+ }
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
index 8918bbf7da..015d7fcb5c 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
@@ -2,6 +2,7 @@ package com.destroystokyo.paper;
|
|
|
|
import java.util.List;
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
import org.bukkit.configuration.file.YamlConfiguration;
|
|
import org.spigotmc.SpigotWorldConfig;
|
|
|
|
@@ -302,4 +303,19 @@ public class PaperWorldConfig {
|
|
private void skipEntityTickingInChunksScheduledForUnload() {
|
|
skipEntityTickingInChunksScheduledForUnload = getBoolean("skip-entity-ticking-in-chunks-scheduled-for-unload", skipEntityTickingInChunksScheduledForUnload);
|
|
}
|
|
+
|
|
+ public int autoSavePeriod = -1;
|
|
+ private void autoSavePeriod() {
|
|
+ autoSavePeriod = getInt("auto-save-interval", -1);
|
|
+ if (autoSavePeriod > 0) {
|
|
+ log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)");
|
|
+ } else if (autoSavePeriod < 0) {
|
|
+ autoSavePeriod = MinecraftServer.getServer().autosavePeriod;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public int maxAutoSaveChunksPerTick = 24;
|
|
+ private void maxAutoSaveChunksPerTick() {
|
|
+ maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
|
|
+ }
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
|
index 7f1d0b39cf..5285bfb409 100644
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
|
@@ -50,9 +50,9 @@ public class Chunk implements IChunkAccess {
|
|
private final TickList<Block> s;
|
|
private final TickList<FluidType> t;
|
|
private boolean u;
|
|
- private boolean v;
|
|
+ private boolean v;public boolean hasEntities() { return v; } // Paper - OBFHELPER
|
|
private long lastSaved;
|
|
- private boolean x;
|
|
+ private boolean x; public boolean isModified() { return x; } // Paper - OBFHELPER
|
|
private int y;
|
|
private long z;
|
|
private int A;
|
|
@@ -1022,11 +1022,11 @@ public class Chunk implements IChunkAccess {
|
|
if (this.v && this.world.getTime() != this.lastSaved || this.x) {
|
|
return true;
|
|
}
|
|
- } else if (this.v && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification
|
|
- return true;
|
|
}
|
|
-
|
|
- return this.x;
|
|
+ // Paper start - Make world configurable and incremental
|
|
+ // This !flag section should say if isModified or hasEntities, then check auto save
|
|
+ return ((isModified() || hasEntities()) && this.world.getTime() >= this.lastSaved + world.paperConfig.autoSavePeriod);
|
|
+ // Paper end
|
|
}
|
|
|
|
public boolean isEmpty() {
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
index 9739288b53..a35eac043c 100644
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
@@ -241,7 +241,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
|
this.saveChunk(chunk, false); // Spigot
|
|
chunk.a(false);
|
|
++i;
|
|
- if (i == 24 && !flag && false) { // Spigot
|
|
+ if (!flag && i >= world.paperConfig.maxAutoSaveChunksPerTick) { // Spigot - // Paper - Incremental Auto Save - cap max
|
|
return false;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
index 3d83900298..690cff8828 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
@@ -37,6 +37,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
|
|
|
private static final Logger cc = LogManager.getLogger();
|
|
public String locale = null; // CraftBukkit - lowercase // Paper - default to null
|
|
+ public long lastSave = MinecraftServer.currentTick; // Paper
|
|
public PlayerConnection playerConnection;
|
|
public final MinecraftServer server;
|
|
public final PlayerInteractManager playerInteractManager;
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
index 04d8c108b4..a547ee5ca1 100644
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
@@ -148,6 +148,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
|
public org.bukkit.command.RemoteConsoleCommandSender remoteConsole;
|
|
public ConsoleReader reader;
|
|
public static int currentTick = 0; // Paper - Further improve tick loop
|
|
+ public boolean serverAutoSave = false; // Paper
|
|
public final Thread primaryThread;
|
|
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
|
public int autosavePeriod;
|
|
@@ -942,22 +943,30 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
|
this.m.b().a(agameprofile);
|
|
}
|
|
|
|
- if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
|
|
this.methodProfiler.a("save");
|
|
- this.s.savePlayers();
|
|
+
|
|
+ serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper
|
|
+ int playerSaveInterval = com.destroystokyo.paper.PaperConfig.playerAutoSaveRate;
|
|
+ if (playerSaveInterval < 0) {
|
|
+ playerSaveInterval = autosavePeriod;
|
|
+ }
|
|
+ if (playerSaveInterval > 0) { // CraftBukkit // Paper
|
|
+ this.s.savePlayers(playerSaveInterval);
|
|
// Spigot Start
|
|
+ } // Paper - Incremental Auto Saving
|
|
+
|
|
// We replace this with saving each individual world as this.saveChunks(...) is broken,
|
|
// and causes the main thread to sleep for random amounts of time depending on chunk activity
|
|
// Also pass flag to only save modified chunks
|
|
server.playerCommandState = true;
|
|
for (World world : getWorlds()) {
|
|
- world.getWorld().save(false);
|
|
+ if (world.paperConfig.autoSavePeriod > 0) world.getWorld().save(false); // Paper - Incremental / Configurable Auto Saving
|
|
}
|
|
server.playerCommandState = false;
|
|
// this.saveChunks(true);
|
|
// Spigot End
|
|
this.methodProfiler.e();
|
|
- }
|
|
+ //} // Paper - Incremental Auto Saving
|
|
|
|
this.methodProfiler.a("snooper");
|
|
if (getSnooperEnabled() && !this.i.d() && this.ticks > 100) { // Spigot
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
|
index 02dbb8c6c3..73d72ef7e3 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
|
@@ -341,6 +341,7 @@ public abstract class PlayerList {
|
|
}
|
|
|
|
protected void savePlayerFile(EntityPlayer entityplayer) {
|
|
+ entityplayer.lastSave = MinecraftServer.currentTick; // Paper
|
|
this.playerFileData.save(entityplayer);
|
|
ServerStatisticManager serverstatisticmanager = (ServerStatisticManager) entityplayer.getStatisticManager(); // CraftBukkit
|
|
|
|
@@ -1207,13 +1208,25 @@ public abstract class PlayerList {
|
|
|
|
}
|
|
|
|
+ // Paper start
|
|
public void savePlayers() {
|
|
+ savePlayers(null);
|
|
+ }
|
|
+
|
|
+ public void savePlayers(Integer interval) {
|
|
+ long now = MinecraftServer.currentTick;
|
|
MinecraftTimings.savePlayers.startTiming(); // Paper
|
|
+ int numSaved = 0; // Paper
|
|
for (int i = 0; i < this.players.size(); ++i) {
|
|
- this.savePlayerFile((EntityPlayer) this.players.get(i));
|
|
+ EntityPlayer entityplayer = this.players.get(i);
|
|
+ if (interval == null || now - entityplayer.lastSave >= interval) {
|
|
+ this.savePlayerFile(entityplayer);
|
|
+ if (interval != null && ++numSaved <= com.destroystokyo.paper.PaperConfig.maxPlayerAutoSavePerTick) { break; } // Paper
|
|
+ }
|
|
}
|
|
MinecraftTimings.savePlayers.stopTiming(); // Paper
|
|
}
|
|
+ // Paper end
|
|
|
|
public WhiteList getWhitelist() {
|
|
return this.whitelist;
|
|
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
index c5201697d5..ca2e027cda 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -872,8 +872,9 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
|
ChunkProviderServer chunkproviderserver = this.getChunkProviderServer();
|
|
|
|
if (chunkproviderserver.d()) {
|
|
- org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
|
|
+ if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit // Paper - Incremental Auto Saving - Only fire event on full save
|
|
timings.worldSave.startTiming(); // Paper
|
|
+ if (flag || server.serverAutoSave) { // Paper
|
|
if (iprogressupdate != null) {
|
|
iprogressupdate.a(new ChatMessage("menu.savingLevel", new Object[0]));
|
|
}
|
|
@@ -882,6 +883,7 @@ public class WorldServer extends World implements IAsyncTaskHandler {
|
|
if (iprogressupdate != null) {
|
|
iprogressupdate.c(new ChatMessage("menu.savingChunks", new Object[0]));
|
|
}
|
|
+ } // Paper
|
|
|
|
timings.worldSaveChunks.startTiming(); // Paper
|
|
chunkproviderserver.a(flag);
|
|
--
|
|
2.19.0
|
|
|