Esempio n. 1
0
        void Update(Level lvl)
        {
            cfg.SaveFor(lvlName);
            if (lvl == null)
            {
                return;
            }
            if (isVisit && lvl == Server.mainLevel)
            {
                return;
            }
            Player[] players = PlayerInfo.Online.Items;

            foreach (Player p in players)
            {
                if (p.level != lvl)
                {
                    continue;
                }
                bool allowed = CheckAllowed(p);

                if (!isVisit)
                {
                    p.AllowBuild = allowed;
                }
                else if (!allowed)
                {
                    p.Message("&WNo longer allowed to visit %S{0}", ColoredName);
                    PlayerActions.ChangeMap(p, Server.mainLevel);
                }
            }
        }
Esempio n. 2
0
        public void Goto(string warp, Player p)
        {
            Warp wp = Find(warp);

            if (wp == null)
            {
                return;
            }

            Level lvl = LevelInfo.FindExact(wp.lvlname);

            if (p.level != lvl)
            {
                PlayerActions.ChangeMap(p, lvl);
            }

            if (p.level.name.CaselessEq(wp.lvlname))
            {
                p.SendPos(Entities.SelfID, wp.x, wp.y, wp.z, wp.rotx, wp.roty);
                Player.Message(p, "Sent you to waypoint/warp");
            }
            else
            {
                Player.Message(p, "Unable to send you to the warp as the map it is on is not loaded.");
            }
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        void UpdateAllowVisit()
        {
            if (!IsVisit || lvl == Server.mainLevel)
            {
                return;
            }
            Player[] players = PlayerInfo.Online.Items;
            foreach (Player p in players)
            {
                if (p.level != lvl)
                {
                    continue;
                }

                LevelAccess access     = Check(p);
                bool        allowVisit = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed;
                if (allowVisit)
                {
                    continue;
                }

                Player.Message(p, "&cNo longer allowed to visit %S{0}", lvl.ColoredName);
                PlayerActions.ChangeMap(p, Server.mainLevel, false);
            }
        }
Esempio n. 5
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);
        }
Esempio n. 6
0
 void MovePlayersToMain()
 {
     Player[] players = PlayerInfo.Online.Items;
     foreach (Player p in players)
     {
         if (p.level == this)
         {
             p.Message("You were moved to the main level as " + ColoredName + " &Swas unloaded.");
             PlayerActions.ChangeMap(p, Server.mainLevel);
         }
     }
 }
Esempio n. 7
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);
        }
Esempio n. 8
0
        public void Goto(Warp warp, Player p)
        {
            if (!p.level.name.CaselessEq(warp.Level))
            {
                PlayerActions.ChangeMap(p, warp.Level);
            }

            if (p.level.name.CaselessEq(warp.Level))
            {
                p.SendPosition(warp.Pos, new Orientation(warp.Yaw, warp.Pitch));
                p.Message("Sent you to waypoint/warp");
            }
            else
            {
                p.Message("Unable to send you to the warp as the map it is on is not loaded.");
            }
        }
            void Goto(Player p, string playerName = null, ushort page = 0)
            {
                bool all = false;

                if (playerName != null)
                {
                    playerName = playerName.ToLower();
                    if (playerName == "all")
                    {
                        all = true;
                    }
                    else if (playerName == "public")
                    {
                        playerName = null;
                    }
                    else
                    {
                        playerName = StoredCustomModel.GetPlayerName(playerName) ?? StoredCustomModel.GetPlayerName(playerName + "+");
                    }
                }

                List <string> modelNames;

                if (all)
                {
                    var dict = GetAllModels(p);
                    modelNames = dict
                                 // public ones first
                                 .OrderByDescending(pair => pair.Key == "Public")
                                 // then by player name A-Z
                                 .ThenBy(pair => pair.Key)
                                 .Select(pair => pair.Value)
                                 .SelectMany(x => x)
                                 .ToList();
                }
                else
                {
                    modelNames = GetModels(playerName, p);
                }
                if (modelNames == null)
                {
                    return;
                }

                // - 1 for our self player
                var partitionSize = Packet.MaxCustomModels - 1;
                var partitions    = modelNames.Partition(partitionSize).ToList();

                if (page >= partitions.Count)
                {
                    p.Message(
                        "%WPage doesn't exist"
                        );
                    return;
                }
                var total = modelNames.Count;

                modelNames = partitions[page];
                p.Message(
                    "%HViewing %T{0} %Hmodels{1}",
                    total,
                    partitions.Count > 1
                        ? string.Format(
                        " %S(page %T{0}%S/%T{1}%S)",
                        page + 1,
                        partitions.Count
                        )
                        : ""
                    );
                if (partitions.Count > 1 && page < (partitions.Count - 1))
                {
                    p.Message(
                        "%SUse \"%H/cm goto {0} {1}%S\" to go to the next page",
                        playerName,
                        page + 2
                        );
                }

                var mapName = string.Format(
                    "&f{0} Custom Models{1}",
                    all ? "All" : (
                        playerName == null
                            ? "Public"
                            : GetNameWithoutPlus(playerName) + "'s"
                        ),
                    page != 0 ? string.Format(" ({0})", page + 1) : ""
                    );

                ushort spacing = 4;
                ushort width   = (ushort)(
                    // edges
                    (spacing * 2) +
                    // grass blocks
                    modelNames.Count +
                    // inbetween blocks
                    ((modelNames.Count - 1) * (spacing - 1))
                    );
                ushort height = 1;
                ushort length = 16;

                byte[] blocks = new byte[width * height * length];

                Level lvl = new Level(mapName, width, height, length, blocks);

                for (int i = 0; i < blocks.Length; i++)
                {
                    blocks[i] = 1;
                }

                lvl.SaveChanges        = false;
                lvl.ChangedSinceBackup = false;

                lvl.IsMuseum        = true;
                lvl.BuildAccess.Min = LevelPermission.Nobody;
                lvl.Config.Physics  = 0;

                lvl.spawnx = spacing;
                lvl.spawny = 2;
                lvl.Config.HorizonBlock = 1;
                lvl.Config.EdgeLevel    = 1;
                lvl.Config.CloudsHeight = -0xFFFFFF;
                lvl.Config.SidesOffset  = 0;
                lvl.Config.Buildable    = false;
                lvl.Config.Deletable    = false;

                for (ushort i = 0; i < modelNames.Count; i++)
                {
                    ushort x = (ushort)(spacing + (i * spacing));
                    ushort y = 0;
                    ushort z = spacing;

                    blocks[lvl.PosToInt(x, y, z)] = 2;

                    var modelName = modelNames[i];

                    var storedModel = new StoredCustomModel(modelName);
                    if (storedModel.Exists())
                    {
                        storedModel.LoadFromFile();
                    }

                    var skinName = p.SkinName;
                    if (
                        !storedModel.usesHumanSkin &&
                        storedModel.defaultSkin != null
                        )
                    {
                        skinName = storedModel.defaultSkin;
                    }

                    // hack because clients strip + at the end
                    var botName = "&f" + (modelName.EndsWith("+") ? modelName + "&0+" : modelName);
                    var bot     = new PlayerBot(botName, lvl)
                    {
                        id       = (byte)i,
                        Model    = modelName,
                        SkinName = skinName,
                    };
                    bot.SetInitialPos(Position.FromFeetBlockCoords(x, y + 1, z));
                    bot.SetYawPitch(Orientation.DegreesToPacked(180), Orientation.DegreesToPacked(0));
                    bot.ClickedOnText = "/CustomModel wear " + modelName;

                    _ = lvl.Bots.Add(bot);
                }

                if (!PlayerActions.ChangeMap(p, lvl))
                {
                    return;
                }
            }
Esempio n. 10
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);
        }
Esempio n. 11
0
        bool SendRawMapCore(Level oldLevel, Level level)
        {
            if (level.blocks == null)
            {
                return(false);
            }
            bool success = true;

            useCheckpointSpawn  = false;
            lastCheckpointIndex = -1;

            LevelAccess access = level.BuildAccess.Check(this);

            AllowBuild = access == LevelAccess.Whitelisted || access == LevelAccess.Allowed;

            try {
                if (hasBlockDefs)
                {
                    if (oldLevel != null && oldLevel != level)
                    {
                        RemoveOldLevelCustomBlocks(oldLevel);
                    }
                    BlockDefinition.SendLevelCustomBlocks(this);
                }

                SendRaw(Opcode.LevelInitialise);
                using (LevelChunkStream s = new LevelChunkStream(this))
                    LevelChunkStream.CompressMap(this, s);

                byte[] buffer = new byte[7];
                buffer[0] = Opcode.LevelFinalise;
                NetUtils.WriteI16((short)level.Width, buffer, 1);
                NetUtils.WriteI16((short)level.Height, buffer, 3);
                NetUtils.WriteI16((short)level.Length, buffer, 5);
                Send(buffer);
                AFKCooldown = DateTime.UtcNow.AddSeconds(2);
                Loading     = false;

                if (HasCpeExt(CpeExt.EnvWeatherType))
                {
                    Send(Packet.EnvWeatherType((byte)level.Weather));
                }
                if (HasCpeExt(CpeExt.EnvColors))
                {
                    SendCurrentEnvColors();
                }
                SendCurrentMapAppearance();
                if (HasCpeExt(CpeExt.BlockPermissions))
                {
                    SendCurrentBlockPermissions();
                }

                if (OnSendMap != null)
                {
                    OnSendMap(this, buffer);
                }
                if (!level.guns && aiming)
                {
                    aiming = false;
                    ClearBlockchange();
                }
            } 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.");
                Server.ErrorLog(ex);
            } finally {
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            return(success);
        }
Esempio n. 12
0
        void CompleteLoginProcess()
        {
            Player clone = null;

            OnPlayerFinishConnectingEvent.Call(this);
            if (cancelconnecting)
            {
                cancelconnecting = false; return;
            }

            lock (PlayerInfo.Online.locker) {
                // Check if any players online have same name
                Player[] players = PlayerInfo.Online.Items;
                foreach (Player pl in players)
                {
                    if (pl.truename == truename)
                    {
                        clone = pl; break;
                    }
                }

                // Remove clone from list (hold lock for as short time as possible)
                if (clone != null && Server.Config.VerifyNames)
                {
                    PlayerInfo.Online.Remove(clone);
                }
                id = NextFreeId();
                PlayerInfo.Online.Add(this);
            }

            if (clone != null && Server.Config.VerifyNames)
            {
                string reason = ip == clone.ip ? "(Reconnecting)" : "(Reconnecting from a different IP)";
                clone.Leave(reason);
            }
            else if (clone != null)
            {
                Leave(null, "Already logged in!", true);
                return;
            }

            SendRawMap(null, level);
            if (Socket.Disconnected)
            {
                return;
            }
            loggedIn = true;

            SessionStartTime = DateTime.UtcNow;
            LastLogin        = DateTime.Now;
            TotalTime        = TimeSpan.FromSeconds(1);
            GetPlayerStats();
            ShowWelcome();

            Server.Background.QueueOnce(ShowAltsTask, name, TimeSpan.Zero);
            CheckState();

            if (!Directory.Exists("players"))
            {
                Directory.CreateDirectory("players");
            }
            PlayerDB.Load(this);
            Game.Team = Team.TeamIn(this);
            SetPrefix();
            LoadCpeData();

            if (Server.Config.verifyadmins && Rank >= Server.Config.VerifyAdminsRank)
            {
                adminpen = true;
            }
            if (Server.noEmotes.Contains(name))
            {
                parseEmotes = !Server.Config.ParseEmotes;
            }

            hideRank = Rank;
            hidden   = CanUse("Hide") && Server.hidden.Contains(name);
            if (hidden)
            {
                Message("&8Reminder: You are still hidden.");
            }

            if (Chat.AdminchatPerms.UsableBy(Rank) && Server.Config.AdminsJoinSilently)
            {
                hidden    = true;
                adminchat = true;
            }

            OnPlayerConnectEvent.Call(this);
            if (cancellogin)
            {
                cancellogin = false; return;
            }

            string joinMsg = "&a+ λFULL %S" + PlayerDB.GetLoginMessage(this);

            if (hidden)
            {
                joinMsg = "&8(hidden)" + joinMsg;
            }

            if (Server.Config.GuestJoinsNotify || Rank > LevelPermission.Guest)
            {
                Chat.MessageFrom(ChatScope.All, this, joinMsg, null, Chat.FilterVisible(this), !hidden);
            }

            if (Server.Config.AgreeToRulesOnEntry && Rank == LevelPermission.Guest && !Server.agreed.Contains(name))
            {
                Message("&9You must read the &c/Rules &9and &c/Agree &9to them before you can build and use commands!");
                agreed = false;
            }

            if (Server.Config.verifyadmins && Rank >= Server.Config.VerifyAdminsRank)
            {
                if (!Directory.Exists("extra/passwords") || !File.Exists("extra/passwords/" + name + ".dat"))
                {
                    Message("%WPlease set your admin verification password with %T/SetPass [password]!");
                }
                else
                {
                    Message("%WPlease complete admin verification with %T/Pass [password]!");
                }
            }

            if (CanUse("Inbox") && Database.TableExists("Inbox" + name))
            {
                int count = Database.CountRows("Inbox" + name);
                if (count > 0)
                {
                    Message("You have &a" + count + " %Smessages in %T/Inbox");
                }
            }

            if (Server.Config.PositionUpdateInterval > 1000)
            {
                Message("Lowlag mode is currently &aON.");
            }

            if (String.IsNullOrEmpty(appName))
            {
                Logger.Log(LogType.UserActivity, "{0} [{1}] connected.", name, ip);
            }
            else
            {
                Logger.Log(LogType.UserActivity, "{0} [{1}] connected using {2}.", name, ip, appName);
            }

            PlayerActions.PostSentMap(this, null, level, false);
            Loading = false;


            if (RestoreLastMap.ContainsKey(truename))
            {
                string levelName = RestoreLastMap[truename];
                if (Formatter.ValidMapName(this, levelName) && (levelName != Server.mainLevel.name))
                {
                    Logger.Log(LogType.UserActivity, "{0} Restoring last map {1}", truename, levelName);
                    PlayerActions.ChangeMap(this, levelName);
                }
            }
        }