From 50c2140734ded53bbfa89fa10c2b90e726db0a7c Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Tue, 24 Apr 2018 23:01:18 +1000 Subject: [PATCH] Backups also save associated file with map (bots/blockdefs/env) --- MCGalaxy/Commands/Information/CmdMapInfo.cs | 2 +- MCGalaxy/Commands/Information/CmdWorlds.cs | 2 +- MCGalaxy/Levels/AccessController.cs | 2 +- MCGalaxy/Levels/Level.cs | 21 ++---- MCGalaxy/Levels/LevelActions.cs | 83 +++++++++++++-------- MCGalaxy/Levels/LevelInfo.cs | 4 +- MCGalaxy/Player/PlayerActions.cs | 2 +- MCGalaxy/Server/Tasks/UpgradeTasks.cs | 4 +- 8 files changed, 67 insertions(+), 53 deletions(-) diff --git a/MCGalaxy/Commands/Information/CmdMapInfo.cs b/MCGalaxy/Commands/Information/CmdMapInfo.cs index 37b5c0b99..a29c036af 100644 --- a/MCGalaxy/Commands/Information/CmdMapInfo.cs +++ b/MCGalaxy/Commands/Information/CmdMapInfo.cs @@ -215,7 +215,7 @@ namespace MCGalaxy.Commands.Info { Width = dims.X; Height = dims.Y; Length = dims.Z; BlockDBEntries = BlockDBFile.CountEntries(name); - path = LevelInfo.PropertiesPath(name); + path = LevelInfo.PropsPath(name); LevelConfig cfg = new LevelConfig(); cfg.Reset(Height); LevelConfig.Load(path, cfg); diff --git a/MCGalaxy/Commands/Information/CmdWorlds.cs b/MCGalaxy/Commands/Information/CmdWorlds.cs index c6a737bef..5af1b2c2b 100644 --- a/MCGalaxy/Commands/Information/CmdWorlds.cs +++ b/MCGalaxy/Commands/Information/CmdWorlds.cs @@ -53,7 +53,7 @@ namespace MCGalaxy.Commands.Info { build = LevelPermission.Guest; loadOnGoto = true; - string propsPath = LevelInfo.PropertiesPath(level); + string propsPath = LevelInfo.PropsPath(level); SearchArgs args = new SearchArgs(); if (!PropertiesFile.Read(propsPath, ref args, ProcessLine)) return; diff --git a/MCGalaxy/Levels/AccessController.cs b/MCGalaxy/Levels/AccessController.cs index 83df7bf2d..72eff8a25 100644 --- a/MCGalaxy/Levels/AccessController.cs +++ b/MCGalaxy/Levels/AccessController.cs @@ -264,7 +264,7 @@ namespace MCGalaxy { } void Update(Level lvl) { - cfg.Save(LevelInfo.PropertiesPath(lvlName)); + cfg.Save(LevelInfo.PropsPath(lvlName)); if (lvl == null) return; if (IsVisit && lvl == Server.mainLevel) return; Player[] players = PlayerInfo.Online.Items; diff --git a/MCGalaxy/Levels/Level.cs b/MCGalaxy/Levels/Level.cs index 3c4653b01..52510312b 100644 --- a/MCGalaxy/Levels/Level.cs +++ b/MCGalaxy/Levels/Level.cs @@ -219,7 +219,7 @@ namespace MCGalaxy { public static void SaveSettings(Level lvl) { if (lvl.IsMuseum) return; // museums do not save properties - string path = LevelInfo.PropertiesPath(lvl.MapName); + string path = LevelInfo.PropsPath(lvl.MapName); lvl.Config.Save(path); } @@ -278,24 +278,15 @@ namespace MCGalaxy { public int Backup(bool Forced = false, string backupName = "") { if (!backedup || Forced) { string backupPath = LevelInfo.BackupBasePath(name); - if (!Directory.Exists(backupPath)) Directory.CreateDirectory(backupPath); + if (!Directory.Exists(backupPath)) Directory.CreateDirectory(backupPath); int next = LevelInfo.LatestBackup(name) + 1; + if (backupName.Length == 0) backupName = next.ToString(); - string path = Path.Combine(backupPath, next.ToString()); - if (backupName.Length > 0) path = Path.Combine(backupPath, backupName); - Directory.CreateDirectory(path); - - string backup = Path.Combine(path, name + ".lvl"); - string current = LevelInfo.MapPath(name); - try { - File.Copy(current, backup, true); - backedup = true; - return next; - } catch (Exception e) { - Logger.LogError(e); + if (!LevelActions.Backup(name, backupName)) { Logger.Log(LogType.Warning, "FAILED TO INCREMENTAL BACKUP :" + name); return -1; } + return next; } Logger.Log(LogType.SystemActivity, "Level unchanged, skipping backup"); return -1; @@ -343,7 +334,7 @@ namespace MCGalaxy { public static void LoadMetadata(Level lvl) { try { - string propsPath = LevelInfo.PropertiesPath(lvl.MapName); + string propsPath = LevelInfo.PropsPath(lvl.MapName); bool propsExisted = LevelConfig.Load(propsPath, lvl.Config); if (propsExisted) { diff --git a/MCGalaxy/Levels/LevelActions.cs b/MCGalaxy/Levels/LevelActions.cs index 22c211041..341b0a207 100644 --- a/MCGalaxy/Levels/LevelActions.cs +++ b/MCGalaxy/Levels/LevelActions.cs @@ -17,6 +17,7 @@ */ using System; using System.IO; +using MCGalaxy.Blocks; using MCGalaxy.Bots; using MCGalaxy.DB; using MCGalaxy.SQL; @@ -26,6 +27,26 @@ namespace MCGalaxy { public static class LevelActions { + static string BlockPropsLvlPath(string map) { return BlockProps.PropsPath("_" + map); } + static string BlockPropsOldPath(string map) { return BlockProps.PropsPath("lvl" + map); } + static string BlockDefsPath(string map) { return "blockdefs/lvl_" + map + ".json"; } + + public static bool Backup(string map, string backupName) { + string basePath = LevelInfo.BackupBasePath(map); + if (!Directory.Exists(basePath)) Directory.CreateDirectory(basePath); + string path = Path.Combine(basePath, backupName); + Directory.CreateDirectory(path); + + bool lvl = DoAction(LevelInfo.MapPath(map), Path.Combine(path, map + ".lvl"), action_copy); + bool props = DoAction(LevelInfo.PropsPath(map), Path.Combine(path, "map.properties"), action_copy); + bool defs = DoAction(BlockDefsPath(map), Path.Combine(path, "blockdefs.json"), action_copy); + bool blkOld = DoAction(BlockPropsOldPath(map), Path.Combine(path, "blockprops.txt"), action_copy); + bool blkCur = DoAction(BlockPropsLvlPath(map), Path.Combine(path, "blockprops.txt"), action_copy); + bool bots = DoAction(BotsFile.BotsPath(map), Path.Combine(path, "bots.json"), action_copy); + + return lvl && props && defs && blkOld && blkCur && bots; + } + /// Renames the .lvl (and related) files and database tables. Does not unload. public static void Rename(string src, string dst) { File.Move(LevelInfo.MapPath(src), LevelInfo.MapPath(dst)); @@ -88,42 +109,42 @@ namespace MCGalaxy { public const string DeleteFailedMessage = "Unable to delete the level, because it could not be unloaded. A game may currently be running on it."; /// Deletes the .lvl (and related) files and database tables. Unloads level if it is loaded. - public static bool Delete(string name) { - Level lvl = LevelInfo.FindExact(name); + public static bool Delete(string map) { + Level lvl = LevelInfo.FindExact(map); if (lvl != null && !lvl.Unload()) return false; if (!Directory.Exists("levels/deleted")) Directory.CreateDirectory("levels/deleted"); - if (File.Exists(LevelInfo.DeletedPath(name))) { + if (File.Exists(LevelInfo.DeletedPath(map))) { int num = 0; - while (File.Exists(LevelInfo.DeletedPath(name + num))) num++; + while (File.Exists(LevelInfo.DeletedPath(map + num))) num++; - File.Move(LevelInfo.MapPath(name), LevelInfo.DeletedPath(name + num)); + File.Move(LevelInfo.MapPath(map), LevelInfo.DeletedPath(map + num)); } else { - File.Move(LevelInfo.MapPath(name), LevelInfo.DeletedPath(name)); + File.Move(LevelInfo.MapPath(map), LevelInfo.DeletedPath(map)); } - DoAll(name, "", action_delete); - DeleteDatabaseTables(name); - BlockDBFile.DeleteBackingFile(name); + DoAll(map, "", action_delete); + DeleteDatabaseTables(map); + BlockDBFile.DeleteBackingFile(map); return true; } - static void DeleteDatabaseTables(string name) { - if (Database.Backend.TableExists("Block" + name)) - Database.Backend.DeleteTable("Block" + name); + static void DeleteDatabaseTables(string map) { + if (Database.Backend.TableExists("Block" + map)) + Database.Backend.DeleteTable("Block" + map); - object locker = ThreadSafeCache.DBCache.GetLocker(name); + object locker = ThreadSafeCache.DBCache.GetLocker(map); lock (locker) { - if (Database.TableExists("Portals" + name)) { - Database.Backend.DeleteTable("Portals" + name); + if (Database.TableExists("Portals" + map)) { + Database.Backend.DeleteTable("Portals" + map); } - if (Database.TableExists("Messages" + name)) { - Database.Backend.DeleteTable("Messages" + name); + if (Database.TableExists("Messages" + map)) { + Database.Backend.DeleteTable("Messages" + map); } - if (Database.TableExists("Zone" + name)) { - Database.Backend.DeleteTable("Zone" + name); + if (Database.TableExists("Zone" + map)) { + Database.Backend.DeleteTable("Zone" + map); } } } @@ -203,22 +224,22 @@ namespace MCGalaxy { static void DoAll(string src, string dst, byte action) { DoAction(LevelInfo.MapPath(src) + ".backup", LevelInfo.MapPath(dst) + ".backup", action); - DoAction("levels/level properties/" + src + ".properties", - "levels/level properties/" + dst + ".properties", action); + DoAction(LevelInfo.PropsPath(src), + LevelInfo.PropsPath(dst), action); DoAction("levels/level properties/" + src, - "levels/level properties/" + dst + ".properties", action); - DoAction("blockdefs/lvl_" + src + ".json", - "blockdefs/lvl_" + dst + ".json", action); - DoAction("blockprops/lvl_" + src + ".txt", - "blockprops/lvl_" + dst + ".txt", action); - DoAction("blockprops/_" + src + ".txt", "" + - "blockprops/_" + dst + ".txt", action); + LevelInfo.PropsPath(dst), action); + DoAction(BlockDefsPath(src), + BlockDefsPath(dst), action); + DoAction(BlockPropsOldPath(src), + BlockPropsOldPath(dst), action); + DoAction(BlockPropsLvlPath(src), + BlockPropsLvlPath(dst), action); DoAction(BotsFile.BotsPath(src), BotsFile.BotsPath(dst), action); } - static void DoAction(string src, string dst, byte action) { - if (!File.Exists(src)) return; + static bool DoAction(string src, string dst, byte action) { + if (!File.Exists(src)) return true; try { if (action == action_delete) { File.Delete(src); @@ -227,8 +248,10 @@ namespace MCGalaxy { } else if (action == action_copy) { File.Copy(src, dst, true); } + return true; } catch (Exception ex) { Logger.LogError(ex); + return false; } } } diff --git a/MCGalaxy/Levels/LevelInfo.cs b/MCGalaxy/Levels/LevelInfo.cs index 5e8f3bf0f..5a86c0efa 100644 --- a/MCGalaxy/Levels/LevelInfo.cs +++ b/MCGalaxy/Levels/LevelInfo.cs @@ -113,7 +113,7 @@ namespace MCGalaxy { /// Relative path of a level's property file - public static string PropertiesPath(string name) { + public static string PropsPath(string name) { return "levels/level properties/" + name + ".properties"; } @@ -121,7 +121,7 @@ namespace MCGalaxy { lvl = FindExact(map); if (lvl != null) return lvl.Config; - string propsPath = PropertiesPath(map); + string propsPath = PropsPath(map); LevelConfig cfg = new LevelConfig(); cfg.Reset(0); LevelConfig.Load(propsPath, cfg); diff --git a/MCGalaxy/Player/PlayerActions.cs b/MCGalaxy/Player/PlayerActions.cs index 6e90ecabe..23096c374 100644 --- a/MCGalaxy/Player/PlayerActions.cs +++ b/MCGalaxy/Player/PlayerActions.cs @@ -79,7 +79,7 @@ namespace MCGalaxy { } static bool LoadOfflineLevel(Player p, string name) { - string propsPath = LevelInfo.PropertiesPath(name); + string propsPath = LevelInfo.PropsPath(name); LevelConfig cfg = new LevelConfig(); LevelConfig.Load(propsPath, cfg); diff --git a/MCGalaxy/Server/Tasks/UpgradeTasks.cs b/MCGalaxy/Server/Tasks/UpgradeTasks.cs index ab439080f..1a931b23d 100644 --- a/MCGalaxy/Server/Tasks/UpgradeTasks.cs +++ b/MCGalaxy/Server/Tasks/UpgradeTasks.cs @@ -44,7 +44,7 @@ namespace MCGalaxy.Tasks { if (names.Count > 0) { string lvlName = Path.GetFileNameWithoutExtension(files[i]); - string propsPath = LevelInfo.PropertiesPath(lvlName); + string propsPath = LevelInfo.PropsPath(lvlName); using (StreamWriter w = new StreamWriter(propsPath, true)) { w.WriteLine("VisitBlacklist = " + names.Join()); } @@ -116,7 +116,7 @@ namespace MCGalaxy.Tasks { static void Combine(string envFile) { string name = Path.GetFileNameWithoutExtension(envFile); - string propsPath = LevelInfo.PropertiesPath(name); + string propsPath = LevelInfo.PropsPath(name); List lines = new List(); if (File.Exists(propsPath)) {