static void LoadMainLevel(SchedulerTask task) { try { mainLevel = LevelActions.Load(Player.Console, Server.Config.MainLevel, false); if (mainLevel == null) { GenerateMain(); } } catch (Exception ex) { Logger.LogError("Error loading main level", ex); } }
public static void ReloadAll(Level lvl, Player src, bool announce) { Player[] players = PlayerInfo.Online.Items; foreach (Player p in players) { if (p.level != lvl) { continue; } LevelActions.ReloadFor(src, p, true); } }
static void LoadAutoloadMaps(SchedulerTask task) { AutoloadMaps = PlayerExtList.Load("text/autoload.txt", '='); List <string> maps = AutoloadMaps.AllNames(); foreach (string map in maps) { if (map.CaselessEq(Server.Config.MainLevel)) { continue; } LevelActions.Load(Player.Console, map, false); } }
/// <summary> Saves a backup of the map and associated files. (like bots, .properties) </summary> /// <param name="force"> Whether to save a backup, even if nothing changed since last one. </param> /// <param name="backup"> Specific name of the backup, or "" to automatically pick a name. </param> /// <returns> The name of the backup, or null if no backup was saved. </returns> public string Backup(bool force = false, string backup = "") { if (ChangedSinceBackup || force) { if (backup.Length == 0) { backup = LevelInfo.NextBackup(name); } if (!LevelActions.Backup(name, backup)) { Logger.Log(LogType.Warning, "FAILED TO INCREMENTAL BACKUP :" + name); return(null); } return(backup); } Logger.Log(LogType.SystemActivity, "Level unchanged, skipping backup"); return(null); }
static void SetMotd(Player p, Level lvl, string value) { lvl.Config.MOTD = value.Length == 0 ? "ignore" : value; lvl.Message("Map's MOTD was changed to: &b" + lvl.Config.MOTD); Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { // Some clients will freeze or crash if we send a MOTD packet, but don't follow it up by a new map. // Although checking for CPE extension support is preferred, also send to whitelisted clients for maximum compatibility bool motdOnly = pl.Supports(CpeExt.InstantMOTD) || (pl.appName != null && pl.appName.CaselessStarts("classicalsharp")); if (motdOnly) { pl.SendMapMotd(); } else { LevelActions.ReloadFor(p, pl, false); } } }
public static bool SetMainLevel(string map) { string main = mainLevel != null ? mainLevel.name : Server.Config.MainLevel; if (map.CaselessEq(main)) { return(false); } Level lvl = LevelInfo.FindExact(map); if (lvl == null) { lvl = LevelActions.Load(Player.Console, map, false); } if (lvl == null) { return(false); } SetMainLevel(lvl); return(true); }
public static bool Backup(Player p, Level lvl, string backup) { string map = lvl.name; bool auto = backup.Length == 0; if (auto) { backup = LevelInfo.NextBackup(map); } TimeSpan delta = lvl.lastBackup - DateTime.UtcNow; if (delta.TotalSeconds >= 0) { p.Message("You must wait another {0} to backup {1} &Sagain", delta.Shorten(true, true), lvl.ColoredName); return(false); } lvl.lastBackup = DateTime.UtcNow.AddSeconds(10); if (!LevelActions.Backup(map, backup)) { p.Message("&WFailed to backup {0}", lvl.ColoredName); return(false); } if (auto) { Logger.Log(LogType.SystemActivity, "Backup {1} saved for {0}", map, backup); lvl.Message("Backup " + backup + " saved for " + lvl.ColoredName); } else { Logger.Log(LogType.SystemActivity, "{0} had a backup created named &b{1}", map, backup); lvl.Message(lvl.ColoredName + " &Shad a backup created named &b" + backup); } return(true); }
public static void UpdateFallback(bool global, byte block, Level level) { Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (!global && pl.level != level) { continue; } if (pl.hasBlockDefs) { continue; } // if custom block is replacing core block, need to always reload for fallback if (block >= Block.CpeCount && !pl.level.MayHaveCustomBlocks) { continue; } LevelActions.ReloadMap(pl, pl, false); } }
public static void Resize(ref Level lvl, int width, int height, int length) { Level res = new Level(lvl.name, (ushort)width, (ushort)height, (ushort)length); res.hasPortals = lvl.hasPortals; res.hasMessageBlocks = lvl.hasMessageBlocks; byte[] src = lvl.blocks, dst = res.blocks; // Copy blocks in bulk width = Math.Min(lvl.Width, res.Width); height = Math.Min(lvl.Height, res.Height); length = Math.Min(lvl.Length, res.Length); for (int y = 0; y < height; y++) { for (int z = 0; z < length; z++) { int srcI = lvl.Width * (z + y * lvl.Length); int dstI = res.Width * (z + y * res.Length); Buffer.BlockCopy(src, srcI, dst, dstI, width); } } // Copy extended blocks in bulk width = Math.Min(lvl.ChunksX, res.ChunksX); height = Math.Min(lvl.ChunksY, res.ChunksY); length = Math.Min(lvl.ChunksZ, res.ChunksZ); for (int cy = 0; cy < height; cy++) { for (int cz = 0; cz < length; cz++) { for (int cx = 0; cx < width; cx++) { src = lvl.CustomBlocks[(cy * lvl.ChunksZ + cz) * lvl.ChunksX + cx]; if (src == null) { continue; } dst = new byte[16 * 16 * 16]; res.CustomBlocks[(cy * res.ChunksZ + cz) * res.ChunksX + cx] = dst; Buffer.BlockCopy(src, 0, dst, 0, 16 * 16 * 16); } } } // TODO: This copying is really ugly and probably not 100% right res.spawnx = lvl.spawnx; res.spawny = lvl.spawny; res.spawnz = lvl.spawnz; res.rotx = lvl.rotx; res.roty = lvl.roty; lock (lvl.saveLock) { lvl.Backup(true); // Make sure zones are kept res.Zones = lvl.Zones; lvl.Zones = new VolatileArray <Zone>(false); IMapExporter.Formats[0].Write(LevelInfo.MapPath(lvl.name), res); lvl.SaveChanges = false; } res.backedup = true; Level.LoadMetadata(res); BotsFile.Load(res); LevelActions.Replace(lvl, res); lvl = res; }