75 lines
3.4 KiB
Diff
75 lines
3.4 KiB
Diff
|
From 1726fd02fac28834745b15aac24be4c8f050de5b Mon Sep 17 00:00:00 2001
|
||
|
From: md_5 <git@md-5.net>
|
||
|
Date: Sun, 12 Jan 2014 21:07:18 +1100
|
||
|
Subject: [PATCH] Improve AutoSave Mechanism
|
||
|
|
||
|
The problem here is that MinecraftServer.save(..), will attempt to sleep whilst all pending chunks are written to disk.
|
||
|
however due to various and complicated bugs, it will wait for an incorrect amount of chunks, which may cause it to sleep for an overly long amount of time.
|
||
|
|
||
|
Instead we will mimic the save-all command in its behaviour, which is both safe and performant.
|
||
|
|
||
|
Also, only save modified chunks, or chunks with entities after 4 auto save passes
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||
|
index e664e55..1412616 100644
|
||
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||
|
@@ -917,7 +917,7 @@ public class Chunk {
|
||
|
if (this.r && this.world.getTime() != this.lastSaved || this.q) {
|
||
|
return true;
|
||
|
}
|
||
|
- } else if (this.r && this.world.getTime() >= this.lastSaved + 600L) {
|
||
|
+ } else if (this.r && this.world.getTime() >= this.lastSaved + MinecraftServer.getServer().autosavePeriod * 4) { // Spigot - Only save if we've passed 2 auto save intervals without modification
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||
|
index 7ce37c0..4a2f084 100644
|
||
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||
|
@@ -623,7 +623,17 @@ public abstract class MinecraftServer implements ICommandListener, Runnable, IAs
|
||
|
SpigotTimings.worldSaveTimer.startTiming(); // Spigot
|
||
|
this.methodProfiler.a("save");
|
||
|
this.v.savePlayers();
|
||
|
- this.saveChunks(true);
|
||
|
+ // Spigot Start
|
||
|
+ // 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 : worlds) {
|
||
|
+ world.getWorld().save(false);
|
||
|
+ }
|
||
|
+ server.playerCommandState = false;
|
||
|
+ // this.saveChunks(true);
|
||
|
+ // Spigot End
|
||
|
this.methodProfiler.b();
|
||
|
SpigotTimings.worldSaveTimer.stopTiming(); // Spigot
|
||
|
}
|
||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||
|
index 2545b38..d61c1de 100644
|
||
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||
|
@@ -688,12 +688,17 @@ public class CraftWorld implements World {
|
||
|
}
|
||
|
|
||
|
public void save() {
|
||
|
+ // Spigot start
|
||
|
+ save(true);
|
||
|
+ }
|
||
|
+ public void save(boolean forceSave) {
|
||
|
+ // Spigot end
|
||
|
this.server.checkSaveState();
|
||
|
try {
|
||
|
boolean oldSave = world.savingDisabled;
|
||
|
|
||
|
world.savingDisabled = false;
|
||
|
- world.save(true, null);
|
||
|
+ world.save(forceSave, null); // Spigot
|
||
|
|
||
|
world.savingDisabled = oldSave;
|
||
|
} catch (ExceptionWorldConflict ex) {
|
||
|
--
|
||
|
2.1.0
|
||
|
|