예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
파일: Level.cs 프로젝트: 8cta/MCGalaxy
        void Cleanup()
        {
            // TODO: don't thread.Abort(), properly stop physics thread
            try {
                physThread.Abort();
                physThread.Join();
            } catch {
            }

            Dispose();
            Server.DoGC();
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        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();
        }
예제 #8
0
        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();
            }
        }
예제 #9
0
        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);
        }
예제 #10
0
        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();
        }
예제 #11
0
        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);
        }
예제 #12
0
파일: Level.cs 프로젝트: ProtheanGod/KingMC
        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);
        }