/// <summary> Renames the .lvl (and related) files and database tables. Does not unload. </summary> public static void Rename(string src, string dst) { File.Move(LevelInfo.MapPath(src), LevelInfo.MapPath(dst)); MoveIfExists(LevelInfo.MapPath(src) + ".backup", LevelInfo.MapPath(dst) + ".backup"); MoveIfExists("levels/level properties/" + src + ".properties", "levels/level properties/" + dst + ".properties"); MoveIfExists("levels/level properties/" + src, "levels/level properties/" + dst + ".properties"); MoveIfExists("blockdefs/lvl_" + src + ".json", "blockdefs/lvl_" + dst + ".json"); MoveIfExists("blockprops/lvl_" + src + ".txt", "blockprops/lvl_" + dst + ".txt"); MoveIfExists(BotsFile.BotsPath(src), BotsFile.BotsPath(dst)); // TODO: Should we move backups still try { //MoveBackups(src, dst); } catch { } RenameDatabaseTables(src, dst); BlockDBFile.MoveBackingFile(src, dst); }
/// <summary> Deletes the .lvl (and related) files and database tables. Unloads level if it is loaded. </summary> 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(map))) { int num = 0; while (File.Exists(LevelInfo.DeletedPath(map + num))) { num++; } File.Move(LevelInfo.MapPath(map), LevelInfo.DeletedPath(map + num)); } else { File.Move(LevelInfo.MapPath(map), LevelInfo.DeletedPath(map)); } DoAll(map, "", action_delete); DeleteDatabaseTables(map); BlockDBFile.DeleteBackingFile(map); return(true); }
/// <summary> Renames the given map and associated metadata. Does not unload. </summary> /// <remarks> Backups are NOT renamed. </remarks> public static bool Rename(Player p, string src, string dst) { if (LevelInfo.MapExists(dst)) { p.Message("&WLevel \"{0}\" already exists.", dst); return(false); } Level lvl = LevelInfo.FindExact(src); if (lvl == Server.mainLevel) { p.Message("Cannot rename the main level."); return(false); } List <Player> players = null; if (lvl != null) { players = lvl.getPlayers(); } if (lvl != null && !lvl.Unload()) { p.Message("Unable to rename the level, because it could not be unloaded. " + "A game may currently be running on it."); return(false); } File.Move(LevelInfo.MapPath(src), LevelInfo.MapPath(dst)); DoAll(src, dst, action_move); // TODO: Should we move backups still try { //MoveBackups(src, dst); } catch { } RenameDatabaseTables(p, src, dst); BlockDBFile.MoveBackingFile(src, dst); OnLevelRenamedEvent.Call(src, dst); if (players == null) { return(true); } // Move all the old players to the renamed map Load(p, dst, false); foreach (Player pl in players) { PlayerActions.ChangeMap(pl, dst); } return(true); }
/// <summary> Renames the .lvl (and related) files and database tables. Does not unload. </summary> public static void Rename(string src, string dst) { File.Move(LevelInfo.MapPath(src), LevelInfo.MapPath(dst)); DoAll(src, dst, action_move); // TODO: Should we move backups still try { //MoveBackups(src, dst); } catch { } RenameDatabaseTables(src, dst); BlockDBFile.MoveBackingFile(src, dst); }
public void FromMap(string map) { this.Name = map; MapName = map; string path = LevelInfo.MapPath(map); Vec3U16 dims = IMapImporter.GetFor(path).ReadDimensions(path); Width = dims.X; Height = dims.Y; Length = dims.Z; BlockDBEntries = BlockDBFile.CountEntries(map); path = LevelInfo.PropsPath(map); LevelConfig cfg = new LevelConfig(); cfg.Load(path); Config = cfg; Visit = new LevelAccessController(cfg, map, true); Build = new LevelAccessController(cfg, map, false); }
/*static void MoveBackups(string src, string dst) { * string srcBase = LevelInfo.BackupBasePath(src); * string dstBase = LevelInfo.BackupBasePath(dst); * if (!Directory.Exists(srcBase)) return; * Directory.CreateDirectory(dstBase); * * string[] backups = Directory.GetDirectories(srcBase); * for (int i = 0; i < backups.Length; i++) { * string name = LevelInfo.BackupNameFrom(backups[i]); * string srcFile = LevelInfo.BackupFilePath(src, name); * string dstFile = LevelInfo.BackupFilePath(dst, name); * string dstDir = LevelInfo.BackupDirPath(dst, name); * * Directory.CreateDirectory(dstDir); * File.Move(srcFile, dstFile); * Directory.Delete(backups[i]); * } * Directory.Delete(srcBase); * }*/ /// <summary> Deletes a map and associated metadata. </summary> public static bool Delete(Player p, string map) { Level lvl = LevelInfo.FindExact(map); if (lvl == Server.mainLevel) { p.Message("Cannot delete the main level."); return(false); } if (lvl != null && !lvl.Unload()) { p.Message("Unable to delete the level, because it could not be unloaded. " + "A game may currently be running on it."); return(false); } p.Message("Created backup."); if (!Directory.Exists("levels/deleted")) { Directory.CreateDirectory("levels/deleted"); } if (File.Exists(Paths.DeletedMapFile(map))) { int num = 0; while (File.Exists(Paths.DeletedMapFile(map + num))) { num++; } File.Move(LevelInfo.MapPath(map), Paths.DeletedMapFile(map + num)); } else { File.Move(LevelInfo.MapPath(map), Paths.DeletedMapFile(map)); } DoAll(map, "", action_delete); DeleteDatabaseTables(map); BlockDBFile.DeleteBackingFile(map); OnLevelDeletedEvent.Call(map); return(true); }
public void FromOfflineLevel(string name) { this.Name = name; MapName = name; string path = LevelInfo.MapPath(name); Vec3U16 dims = IMapImporter.Formats[0].ReadDimensions(path); Width = dims.X; Height = dims.Y; Length = dims.Z; BlockDBEntries = BlockDBFile.CountEntries(name); path = LevelInfo.PropsPath(name); LevelConfig cfg = new LevelConfig(); cfg.SetDefaults(Height); cfg.Load(path); Config = cfg; Visit = new LevelAccessController(cfg, name, true); Build = new LevelAccessController(cfg, name, false); }
/// <summary> Deletes the .lvl (and related) files and database tables. /// Unloads a level (if present) which exactly matches name. </summary> public static void Delete(string name) { Level lvl = LevelInfo.FindExact(name); if (lvl != null) { lvl.Unload(); } if (!Directory.Exists("levels/deleted")) { Directory.CreateDirectory("levels/deleted"); } if (File.Exists("levels/deleted/" + name + ".lvl")) { int num = 0; while (File.Exists("levels/deleted/" + name + num + ".lvl")) { num++; } File.Move(LevelInfo.LevelPath(name), "levels/deleted/" + name + num + ".lvl"); } else { File.Move(LevelInfo.LevelPath(name), "levels/deleted/" + name + ".lvl"); } try { File.Delete("levels/level properties/" + name + ".properties"); } catch { } try { File.Delete("levels/level properties/" + name); } catch { } try { if (File.Exists("blockdefs/lvl_" + name + ".json")) { File.Delete("blockdefs/lvl_" + name + ".json"); } } catch {} BotsFile.DeleteBots(name); DeleteDatabaseTables(name); BlockDBFile.DeleteBackingFile(name); }
static unsafe void Read(Stream s, BlockDBFile format, Action <BlockDBEntry> output) { byte[] bulk = new byte[BlockDBFile.BulkEntries * BlockDBFile.EntrySize]; fixed(byte *ptr = bulk) { while (true) { BlockDBEntry *e = (BlockDBEntry *)ptr; int count = format.ReadForward(s, bulk, e); if (count == 0) { break; } for (int i = 0; i < count; i++, e++) { output(*e); } } } }
/// <summary> Deletes the .lvl (and related) files and database tables. Unloads level if it is loaded. </summary> public static bool Delete(string name) { Level lvl = LevelInfo.FindExact(name); if (lvl != null && !lvl.Unload()) { return(false); } if (!Directory.Exists("levels/deleted")) { Directory.CreateDirectory("levels/deleted"); } if (File.Exists(LevelInfo.DeletedPath(name))) { int num = 0; while (File.Exists(LevelInfo.DeletedPath(name + num))) { num++; } File.Move(LevelInfo.MapPath(name), LevelInfo.DeletedPath(name + num)); } else { File.Move(LevelInfo.MapPath(name), LevelInfo.DeletedPath(name)); } DeleteIfExists(LevelInfo.MapPath(name) + ".backup"); DeleteIfExists("levels/level properties/" + name); DeleteIfExists("levels/level properties/" + name + ".properties"); DeleteIfExists("blockdefs/lvl_" + name + ".json"); DeleteIfExists("blockprops/lvl_" + name + ".txt"); DeleteIfExists(BotsFile.BotsPath(name)); DeleteDatabaseTables(name); BlockDBFile.DeleteBackingFile(name); return(true); }
/// <summary> Renames the .lvl (and related) files and database tables. /// Does not perform any unloading. </summary> public static void Rename(string src, string dst) { File.Move(LevelInfo.LevelPath(src), LevelInfo.LevelPath(dst)); try { File.Move(LevelInfo.LevelPath(src) + ".backup", LevelInfo.LevelPath(dst) + ".backup"); } catch { } try { File.Move("levels/level properties/" + src + ".properties", "levels/level properties/" + dst + ".properties"); } catch { } try { File.Move("levels/level properties/" + src, "levels/level properties/" + dst + ".properties"); } catch { } try { if (File.Exists("blockdefs/lvl_" + src + ".json")) { File.Move("blockdefs/lvl_" + src + ".json", "blockdefs/lvl_" + dst + ".json"); } } catch { } try { MoveBackups(src, dst); } catch { } BotsFile.MoveBots(src, dst); RenameDatabaseTables(src, dst); BlockDBFile.MoveBackingFile(src, dst); }
public override void Use(Player p, string message, CommandData data) { if (message.Length == 0) { p.Message("You need to provide a player name."); return; } string[] parts = message.SplitSpaces(), names = null; int[] ids = GetIds(p, data, parts, out names); if (ids == null) { return; } TimeSpan delta = GetDelta(p, parts[0], parts, 1); if (delta == TimeSpan.MinValue) { return; } BlockDB db = p.level.BlockDB; DateTime start = DateTime.UtcNow - delta; BlockDBCacheWriter w = new BlockDBCacheWriter(); w.start = (int)((start - BlockDB.Epoch).TotalSeconds); using (IDisposable locker = db.Locker.AccquireWrite()) { if (!File.Exists(db.FilePath)) { p.Message("%WBlockDB file for this map doesn't exist."); return; } Vec3U16 dims; FastList <BlockDBEntry> entries = new FastList <BlockDBEntry>(4096); using (Stream src = OpenRead(db.FilePath), dst = OpenWrite(db.FilePath + ".tmp")) { BlockDBFile format = BlockDBFile.ReadHeader(src, out dims); BlockDBFile.WriteHeader(dst, dims); w.dst = dst; w.format = format; w.ids = ids; Read(src, format, w.Output); // flush entries leftover if (w.entries.Count > 0) { format.WriteEntries(dst, w.entries); } } string namesStr = names.Join(name => p.FormatNick(name)); if (w.left > 0) { File.Delete(db.FilePath); File.Move(db.FilePath + ".tmp", db.FilePath); p.Message("Pruned {1}%S's changes ({2} entries left now) for the past &b{0}", delta.Shorten(true), namesStr, w.left); } else { File.Delete(db.FilePath + ".tmp"); p.Message("No changes found by {1} %Sin the past &b{0}", delta.Shorten(true), namesStr); } } }