mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 12:05:51 -04:00
Ensure level saving is threadsafe, avoids random loss of levels. (Thanks goodlyay)
This commit is contained in:
parent
85c4ae4199
commit
024cd71945
@ -110,7 +110,6 @@ namespace MCGalaxy.Commands.CPE {
|
||||
|
||||
if (index >= offset) {
|
||||
count++;
|
||||
Server.s.Log(col.Fallback.ToString());
|
||||
const string format = "{4}{0} &{1}({2}){4} - %{1}, falls back to &{3}%{3}.";
|
||||
Player.SendMessage(p, String.Format(format, col.Name, col.Code, col.Hex(), col.Fallback, Server.DefaultColor), false);
|
||||
|
||||
|
@ -238,6 +238,7 @@ namespace MCGalaxy
|
||||
|
||||
public bool bufferblocks = Server.bufferblocks;
|
||||
internal readonly object queueLock = new object();
|
||||
readonly object saveLock = new object();
|
||||
public List<BlockQueue.QueuedBlock> blockqueue = new List<BlockQueue.QueuedBlock>();
|
||||
private readonly object physThreadLock = new object();
|
||||
BufferedBlockSender bulkSender;
|
||||
@ -323,8 +324,7 @@ namespace MCGalaxy
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
public void Dispose() {
|
||||
Extras.Clear();
|
||||
liquids.Clear();
|
||||
leaves.Clear();
|
||||
@ -333,10 +333,13 @@ namespace MCGalaxy
|
||||
UndoBuffer.Clear();
|
||||
blockCache.Clear();
|
||||
ZoneList.Clear();
|
||||
|
||||
lock (queueLock)
|
||||
blockqueue.Clear();
|
||||
blocks = null;
|
||||
CustomBlocks = null;
|
||||
lock (saveLock) {
|
||||
blocks = null;
|
||||
CustomBlocks = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@ -559,23 +562,10 @@ namespace MCGalaxy
|
||||
if (!Directory.Exists("levels/prev")) Directory.CreateDirectory("levels/prev");
|
||||
|
||||
if (changed || !File.Exists(path) || Override || (physicschanged && clearPhysics)) {
|
||||
if (clearPhysics)
|
||||
ClearPhysics();
|
||||
if (clearPhysics) ClearPhysics();
|
||||
|
||||
if (File.Exists(path)) {
|
||||
string prevPath = LevelInfo.PrevPath(name);
|
||||
if (File.Exists(prevPath))
|
||||
File.Delete(prevPath);
|
||||
File.Copy(path, prevPath, true);
|
||||
File.Delete(path);
|
||||
}
|
||||
LvlFile.Save(this, path + ".backup");
|
||||
File.Copy(path + ".backup", path);
|
||||
SaveSettings(this);
|
||||
|
||||
Server.s.Log(string.Format("SAVED: Level \"{0}\". ({1}/{2}/{3})", name, players.Count,
|
||||
PlayerInfo.Online.Count, Server.players));
|
||||
changed = false;
|
||||
lock (saveLock)
|
||||
SaveCore(path);
|
||||
} else {
|
||||
Server.s.Log("Skipping level save for " + name + ".");
|
||||
}
|
||||
@ -587,6 +577,24 @@ namespace MCGalaxy
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
|
||||
void SaveCore(string path) {
|
||||
if (blocks == null) return;
|
||||
if (File.Exists(path)) {
|
||||
string prevPath = LevelInfo.PrevPath(name);
|
||||
if (File.Exists(prevPath)) File.Delete(prevPath);
|
||||
File.Copy(path, prevPath, true);
|
||||
File.Delete(path);
|
||||
}
|
||||
|
||||
LvlFile.Save(this, path + ".backup");
|
||||
File.Copy(path + ".backup", path);
|
||||
SaveSettings(this);
|
||||
|
||||
Server.s.Log(string.Format("SAVED: Level \"{0}\". ({1}/{2}/{3})", name, players.Count,
|
||||
PlayerInfo.Online.Count, Server.players));
|
||||
changed = false;
|
||||
}
|
||||
|
||||
public int Backup(bool Forced = false, string backupName = "") {
|
||||
if (!backedup || Forced) {
|
||||
|
@ -1198,6 +1198,10 @@ return;
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleCommands(List<string> cmds) {
|
||||
|
||||
}
|
||||
|
||||
bool CheckCommand(string cmd) {
|
||||
if (cmd == "") { SendMessage("No command entered."); return false; }
|
||||
if (Server.agreetorulesonentry && !agreed && !(cmd == "agree" || cmd == "rules" || cmd == "disagree")) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user