static bool ChangeMap(Player p, Level lvl, string name) { if (Interlocked.CompareExchange(ref p.UsingGoto, 1, 0) == 1) { p.Message("Cannot use /goto, already joining a map."); return(false); } Level oldLevel = p.level; bool didJoin = false; try { MCGalaxy.Commands.Misc.CmdTp.SavePreTeleportState(p); didJoin = name == null?GotoLevel(p, lvl) : GotoMap(p, name); } finally { Interlocked.Exchange(ref p.UsingGoto, 0); Server.DoGC(); } if (!didJoin) { return(false); } oldLevel.AutoUnload(); return(true); }
bool SendRawMapCore(Level prev, Level level) { bool success = true; try { if (level.blocks == null) { throw new InvalidOperationException("Tried to join unloaded level"); } useCheckpointSpawn = false; lastCheckpointIndex = -1; AFKCooldown = DateTime.UtcNow.AddSeconds(2); ZoneIn = null; AllowBuild = level.BuildAccess.CheckAllowed(this); SendMapMotd(); Session.SendLevel(prev, level); Loading = false; OnSentMapEvent.Call(this, prev, level); } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); Message("&WThere was an error sending the map, you have been sent to the main level."); Logger.LogError(ex); } finally { Server.DoGC(); } return(success); }
bool SendRawMapCore(Level oldLevel, Level level) { if (level.blocks == null) { return(false); } bool success = true; useCheckpointSpawn = false; lastCheckpointIndex = -1; AFKCooldown = DateTime.UtcNow.AddSeconds(2); SendMapMotd(); AccessResult access = level.BuildAccess.Check(this); AllowBuild = access == AccessResult.Whitelisted || access == AccessResult.Allowed; try { Send(Packet.LevelInitalise()); if (hasBlockDefs) { if (oldLevel != null && oldLevel != level) { RemoveOldLevelCustomBlocks(oldLevel); } BlockDefinition.SendLevelCustomBlocks(this); if (Supports(CpeExt.InventoryOrder)) { BlockDefinition.SendLevelInventoryOrder(this); } } using (LevelChunkStream s = new LevelChunkStream(this)) LevelChunkStream.CompressMap(this, s); // Force players to read the MOTD (clamped to 3 seconds at most) if (level.Config.LoadDelay > 0) { System.Threading.Thread.Sleep(level.Config.LoadDelay); } byte[] buffer = Packet.LevelFinalise(level.Width, level.Height, level.Length); Send(buffer); Loading = false; OnJoinedLevelEvent.Call(this, oldLevel, level); } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); SendMessage("There was an error sending the map data, you have been sent to the main level."); Logger.LogError(ex); } finally { Server.DoGC(); } return(success); }
void Cleanup() { // TODO: don't thread.Abort(), properly stop physics thread try { physThread.Abort(); physThread.Join(); } catch { } Dispose(); Server.DoGC(); }
public bool Unload(bool silent = false, bool save = true) { if (Server.mainLevel == this || IsMuseum) { return(false); } OnLevelUnloadEvent.Call(this); if (cancelunload) { Logger.Log(LogType.SystemActivity, "Unload canceled by Plugin! (Map: {0})", name); cancelunload = false; return(false); } MovePlayersToMain(); if (save && SaveChanges && Changed) { Save(false, true); } if (save && SaveChanges) { SaveBlockDBChanges(); } MovePlayersToMain(); LevelInfo.Remove(this); try { if (!unloadedBots) { unloadedBots = true; BotsFile.Save(this); PlayerBot.RemoveLoadedBots(this, false); } } catch (Exception ex) { Logger.LogError("Error saving bots", ex); } try { physThread.Abort(); physThread.Join(); } catch { } Dispose(); Server.DoGC(); if (!silent) { Chat.MessageOps(ColoredName + " %Swas unloaded."); } Logger.Log(LogType.SystemActivity, name + " was unloaded."); return(true); }
public bool Save(bool force = false, bool clearPhysics = false) { if (blocks == null || IsMuseum) { return(false); // museums do not save properties } string path = LevelInfo.MapPath(MapName); OnLevelSaveEvent.Call(this); if (cancelsave) { cancelsave = false; return(false); } try { if (!Directory.Exists("levels")) { Directory.CreateDirectory("levels"); } if (!Directory.Exists("levels/level properties")) { Directory.CreateDirectory("levels/level properties"); } if (!Directory.Exists("levels/prev")) { Directory.CreateDirectory("levels/prev"); } if (Changed || !File.Exists(path) || force || (physicschanged && clearPhysics)) { lock (saveLock) SaveCore(path); if (clearPhysics) { ClearPhysics(); } } else { Logger.Log(LogType.SystemActivity, "Skipping level save for " + name + "."); } } catch (Exception e) { Logger.Log(LogType.Warning, "FAILED TO SAVE :" + name); Chat.MessageGlobal("FAILED TO SAVE {0}", ColoredName); Logger.LogError(e); return(false); } Server.DoGC(); return(true); }
void Cleanup() { Physicsint = 0; try { // Wake up physics thread from Thread.Sleep physThread.Interrupt(); // Wait up to 1 second for physics thread to finish physThread.Join(1000); } catch { // No physics thread at all } Dispose(); Server.DoGC(); }
public static Level Load(Player p, string map, bool announce) { map = map.ToLower(); if (!LevelInfo.MapExists(map)) { p.Message("Level \"{0}\" does not exist", map); return(null); } Level cur = LevelInfo.FindExact(map); if (cur != null) { p.Message("%WLevel {0} %Wis already loaded.", cur.ColoredName); return(null); } try { Level lvl = ReadLevel(p, map); if (lvl == null || !lvl.CanJoin(p)) { return(null); } cur = LevelInfo.FindExact(map); if (cur != null) { p.Message("%WLevel {0} %Wis already loaded.", cur.ColoredName); return(null); } LevelInfo.Add(lvl); if (!announce) { return(lvl); } string autoloadMsg = "Level " + lvl.ColoredName + " %Sloaded."; Chat.Message(ChatScope.All, autoloadMsg, null, Chat.FilterVisible(p)); return(lvl); } finally { Server.DoGC(); } }
static bool ChangeMap(Player p, Level lvl, string name) { if (Interlocked.CompareExchange(ref p.UsingGoto, 1, 0) == 1) { Player.Message(p, "Cannot use /goto, already joining a map."); return(false); } Level oldLevel = p.level; bool didJoin = false; try { didJoin = name == null?GotoLevel(p, lvl) : GotoMap(p, name); } finally { Interlocked.Exchange(ref p.UsingGoto, 0); Server.DoGC(); } if (!didJoin) { return(false); } Unload(oldLevel); return(true); }
void Cleanup() { Physicsint = 0; Thread t; try { t = physThread; // Wake up physics thread from Thread.Sleep if (t != null) { t.Interrupt(); } // Wait up to 1 second for physics thread to finish if (t != null) { t.Join(1000); } } catch { // No physics thread at all } Dispose(); Server.DoGC(); }
bool SendRawMapCore(Level prev, Level level) { bool success = true; try { if (level.blocks == null) { throw new InvalidOperationException("Tried to join unloaded level"); } useCheckpointSpawn = false; lastCheckpointIndex = -1; AFKCooldown = DateTime.UtcNow.AddSeconds(2); ZoneIn = null; SendMapMotd(); AllowBuild = level.BuildAccess.CheckAllowed(this); int volume = level.blocks.Length; if (Supports(CpeExt.FastMap)) { Send(Packet.LevelInitaliseExt(volume)); } else { Send(Packet.LevelInitalise()); } if (hasBlockDefs) { if (prev != null && prev != level) { RemoveOldLevelCustomBlocks(prev); } BlockDefinition.SendLevelCustomBlocks(this); if (Supports(CpeExt.InventoryOrder)) { BlockDefinition.SendLevelInventoryOrder(this); } } using (LevelChunkStream dst = new LevelChunkStream(this)) using (Stream stream = LevelChunkStream.CompressMapHeader(this, volume, dst)) { if (level.MightHaveCustomBlocks()) { LevelChunkStream.CompressMap(this, stream, dst); } else { LevelChunkStream.CompressMapSimple(this, stream, dst); } } // Force players to read the MOTD (clamped to 3 seconds at most) if (level.Config.LoadDelay > 0) { System.Threading.Thread.Sleep(level.Config.LoadDelay); } byte[] buffer = Packet.LevelFinalise(level.Width, level.Height, level.Length); Send(buffer); Loading = false; OnSentMapEvent.Call(this, prev, level); } catch (Exception ex) { success = false; PlayerActions.ChangeMap(this, Server.mainLevel); Message("&WThere was an error sending the map, you have been sent to the main level."); Logger.LogError(ex); } finally { Server.DoGC(); } return(success); }
public bool Unload(bool silent = false, bool save = true) { if (Server.mainLevel == this || IsMuseum) { return(false); } if (Server.lava.active && Server.lava.map == this) { return(false); } OnLevelUnloadEvent.Call(this); if (cancelunload) { Logger.Log(LogType.SystemActivity, "Unload canceled by Plugin! (Map: {0})", name); cancelunload = false; return(false); } MovePlayersToMain(); if (save && Changed && ShouldSaveChanges()) { Save(false, true); } if (save && ShouldSaveChanges()) { SaveBlockDBChanges(); } if (TntWarsGame.Find(this) != null) { foreach (TntWarsGame.player pl in TntWarsGame.Find(this).Players) { pl.p.CurrentTntGameNumber = -1; Player.Message(pl.p, "TNT Wars: The TNT Wars game you are currently playing has been deleted!"); pl.p.PlayingTntWars = false; pl.p.canBuild = true; TntWarsGame.SetTitlesAndColor(pl, true); } Logger.Log(LogType.GameActivity, "TNT Wars: Game deleted on " + name); TntWarsGame.GameList.Remove(TntWarsGame.Find(this)); } MovePlayersToMain(); LevelInfo.Loaded.Remove(this); try { if (!unloadedBots) { unloadedBots = true; BotsFile.Save(this); PlayerBot.RemoveLoadedBots(this, false); } physThread.Abort(); physThread.Join(); } catch { } finally { Dispose(); Server.DoGC(); if (!silent) { Chat.MessageOps(ColoredName + " %Swas unloaded."); } Logger.Log(LogType.SystemActivity, name + " was unloaded."); } return(true); }