예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
            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);
            }
예제 #6
0
        /*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);
        }
예제 #7
0
            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);
            }
예제 #8
0
        /// <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);
        }
예제 #9
0
        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);
                    }
                }
            }
        }
예제 #10
0
        /// <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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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);
                }
            }
        }