Exception that is thrown when a player's action or command could not be completed.
Inheritance: System.Exception
        static void CopyCallback([NotNull] Player player, [NotNull] Vector3I[] marks, [NotNull] object tag)
        {
            int         sx     = Math.Min(marks[0].X, marks[1].X);
            int         ex     = Math.Max(marks[0].X, marks[1].X);
            int         sy     = Math.Min(marks[0].Y, marks[1].Y);
            int         ey     = Math.Max(marks[0].Y, marks[1].Y);
            int         sz     = Math.Min(marks[0].Z, marks[1].Z);
            int         ez     = Math.Max(marks[0].Z, marks[1].Z);
            BoundingBox bounds = new BoundingBox(sx, sy, sz, ex, ey, ez);

            int volume = bounds.Volume;

            if (!player.CanDraw(volume))
            {
                player.MessageNow(
                    "You are only allowed to run commands that affect up to {0} blocks. This one would affect {1} blocks.",
                    player.Info.Rank.DrawLimit,
                    volume);
                return;
            }

            // remember dimensions and orientation
            CopyState copyInfo = new CopyState(marks[0], marks[1]);

            Map   map         = player.WorldMap;
            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            for (int x = sx; x <= ex; x++)
            {
                for (int y = sy; y <= ey; y++)
                {
                    for (int z = sz; z <= ez; z++)
                    {
                        copyInfo.Blocks[x - sx, y - sy, z - sz] = map.GetBlock(x, y, z);
                    }
                }
            }

            copyInfo.OriginWorld = playerWorld.Name;
            copyInfo.CopyTime    = DateTime.UtcNow;
            player.SetCopyState(copyInfo);

            player.MessageNow("{0} blocks copied into slot #{1}, origin at {2} corner. You can now &H/Paste",
                              volume,
                              player.CopySlot + 1,
                              copyInfo.OriginCorner);

            Logger.Log(LogType.UserActivity,
                       "{0} copied {1} blocks from world {2} (between {3} and {4}).",
                       player.Name,
                       volume,
                       playerWorld.Name,
                       bounds.MinVertex,
                       bounds.MaxVertex);
        }
Beispiel #2
0
        private static void ZoneAddCallback(Player player, Vector3I[] marks, object tag)
        {
            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            if (!player.Info.Rank.AllowSecurityCircumvention)
            {
                SecurityCheckResult buildCheck = playerWorld.BuildSecurity.CheckDetailed(player.Info);
                switch (buildCheck)
                {
                case SecurityCheckResult.BlackListed:
                    player.Message("Cannot add zones to world {0}&S: You are barred from building here.",
                                   playerWorld.ClassyName);
                    return;

                case SecurityCheckResult.RankTooLow:
                    player.Message("Cannot add zones to world {0}&S: You are not allowed to build here.",
                                   playerWorld.ClassyName);
                    return;
                    //case SecurityCheckResult.RankTooHigh:
                }
            }

            Zone zone  = (Zone)tag;
            var  zones = player.WorldMap.Zones;

            lock (zones.SyncRoot)
            {
                Zone dupeZone = zones.FindExact(zone.Name);
                if (dupeZone != null)
                {
                    player.Message("A zone named \"{0}\" has just been created by {1}",
                                   dupeZone.Name, dupeZone.CreatedBy);
                    return;
                }

                zone.Create(new BoundingBox(marks[0], marks[1]), player.Info);

                player.Message("Zone \"{0}\" created, {1} blocks total.",
                               zone.Name, zone.Bounds.Volume);
                Logger.Log(LogType.UserActivity,
                           "Player {0} created a new zone \"{1}\" containing {2} blocks.",
                           player.Name,
                           zone.Name,
                           zone.Bounds.Volume);

                zones.Add(zone);
            }
        }
        static void RedoHandler([NotNull] Player player, [NotNull] CommandReader cmd)
        {
            if (cmd.HasNext)
            {
                CdRedo.PrintUsage(player);
                return;
            }

            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            UndoState redoState = player.RedoPop();

            if (redoState == null)
            {
                player.MessageNow("There is currently nothing to redo.");
                return;
            }

            string msg = "Redo: ";

            if (redoState.Op != null && !redoState.Op.IsDone)
            {
                redoState.Op.Cancel();
                msg += String.Format("Cancelled {0} (was {1}% done). ",
                                     redoState.Op.Description,
                                     redoState.Op.PercentDone);
            }

            // no need to set player.drawingInProgress here because this is done on the user thread
            Logger.Log(LogType.UserActivity,
                       "Player {0} initiated /Redo affecting {1} blocks (on world {2})",
                       player.Name,
                       redoState.Buffer.Count,
                       playerWorld.Name);

            msg += String.Format("Restoring {0} blocks. Type &H/Undo&S to reverse.",
                                 redoState.Buffer.Count);
            player.MessageNow(msg);

            var op = new UndoDrawOperation(player, redoState, true);

            op.Prepare(new Vector3I[0]);
            op.Begin();
        }
Beispiel #4
0
        /// <summary> Sends world/local chat message. </summary>
        /// <param name="player"> Player writing the message. </param>
        /// <param name="rawMessage"> Message text. </param>
        /// <returns> True if message was sent, false if it was canceled by an event callback. </returns>
        /// <exception cref="ArgumentNullException"> If player or rawMessage is null. </exception>
        public static bool SendWorld([NotNull] Player player, [NotNull] string rawMessage)
        {
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (rawMessage == null)
            {
                throw new ArgumentNullException("rawMessage");
            }
            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            var recipientList = playerWorld.Players
                                .NotIgnoring(player);

            string formattedMessage = String.Format("({0}&F){1}: {2}",
                                                    playerWorld.ClassyName,
                                                    player.ClassyName,
                                                    rawMessage);

            var e = new ChatSendingEventArgs(player,
                                             rawMessage,
                                             formattedMessage,
                                             ChatMessageType.World,
                                             recipientList);

            if (!SendInternal(e))
            {
                return(false);
            }

            Logger.Log(LogType.GlobalChat,
                       "(world {0}){1}: {2}",
                       playerWorld.Name, player.Name, rawMessage);
            return(true);
        }
Beispiel #5
0
        /// <summary> Unbans given IP address and all accounts on that IP. </summary>
        /// <param name="targetAddress"> IP address that is being unbanned. </param>
        /// <param name="player"> Player who is unbanning. </param>
        /// <param name="reason"> Reason for unban. May be null or empty, if permitted by server configuration. </param>
        /// <param name="announce"> Whether unban should be publicly announced on the server. </param>
        /// <param name="raiseEvents"> Whether RemovingIPBan, RemovedIPBan, BanChanging, and BanChanged events should be raised. </param>
        /// <exception cref="ArgumentNullException"> targetAddress or player is null. </exception>
        /// <exception cref="PlayerOpException"> Permission or configuration issues arise, or if everyone has already been unbanned. </exception>
        public static void UnbanAll([NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason,
                                    bool announce, bool raiseEvents)
        {
            if (targetAddress == null)
            {
                throw new ArgumentNullException("targetAddress");
            }
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (reason != null && reason.Trim().Length == 0)
            {
                reason = null;
            }

            if (!player.Can(Permission.Ban, Permission.BanIP, Permission.BanAll))
            {
                PlayerOpException.ThrowPermissionMissing(player, null, "unban-all",
                                                         Permission.Ban, Permission.BanIP, Permission.BanAll);
            }

            // Check if player is trying to unban self
            if (targetAddress.Equals(player.IP) && !player.IsSuper)
            {
                PlayerOpException.ThrowCannotTargetSelf(player, null, "unban-all");
            }

            // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255)
            if (targetAddress.Equals(IPAddress.None) || targetAddress.Equals(IPAddress.Any))
            {
                PlayerOpException.ThrowInvalidIP(player, null, targetAddress);
            }

            PlayerOpException.CheckBanReason(reason, player, null, true);
            bool somethingGotUnbanned = false;

            lock ( BanListLock ) {
                CheckIfLoaded();
                // Unban the IP
                if (Contains(targetAddress))
                {
                    if (Remove(targetAddress, raiseEvents))
                    {
                        Logger.Log(LogType.UserActivity,
                                   "{0} unbanned {1} (UnbanAll {1}). Reason: {2}",
                                   player.Name, targetAddress, reason ?? "");

                        // Announce unban on the server
                        if (announce)
                        {
                            var can = Server.Players.Can(Permission.ViewPlayerIPs);
                            can.Message("&W{0} was unbanned by {1}", targetAddress, player.ClassyName);
                            var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                            cant.Message("&WAn IP was unbanned by {0}", player.ClassyName);
                        }

                        somethingGotUnbanned = true;
                    }
                }

                // Unban individual players
                PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers(targetAddress);
                foreach (PlayerInfo targetAlt in allPlayersOnIP)
                {
                    if (targetAlt.BanStatus != BanStatus.Banned)
                    {
                        continue;
                    }

                    // Raise PlayerInfo.BanChanging event
                    PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs(targetAlt, player, true,
                                                                                          reason, announce);
                    if (raiseEvents)
                    {
                        PlayerInfo.RaiseBanChangingEvent(e);
                        if (e.Cancel)
                        {
                            continue;
                        }
                        reason = e.Reason;
                    }

                    // Do the ban
                    if (targetAlt.ProcessUnban(player.Name, reason))
                    {
                        if (raiseEvents)
                        {
                            PlayerInfo.RaiseBanChangedEvent(e);
                        }

                        // Log and announce ban
                        Logger.Log(LogType.UserActivity,
                                   "{0} unbanned {1} (UnbanAll {2}). Reason: {3}",
                                   player.Name, targetAlt.Name, targetAddress, reason ?? "");
                        if (announce)
                        {
                            Server.Message("&WPlayer {0}&W was unbanned by {1}&W (UnbanAll)",
                                           targetAlt.ClassyName, player.ClassyName);
                        }
                        somethingGotUnbanned = true;
                    }
                }
            }

            // If no one ended up getting unbanned, quit here
            if (!somethingGotUnbanned)
            {
                PlayerOpException.ThrowNoOneToUnban(player, null, targetAddress);
            }

            // Announce UnbanAll reason towards the end of all unbans
            if (announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null)
            {
                Server.Message("&WUnbanAll reason: {0}", reason);
            }
        }
Beispiel #6
0
        /// <summary> Bans given IP address and all accounts on that IP. All players from IP are kicked.
        /// Throws PlayerOpException on problems. </summary>
        /// <param name="targetAddress"> IP address that is being banned. </param>
        /// <param name="player"> Player who is banning. </param>
        /// <param name="reason"> Reason for ban. May be empty, if permitted by server configuration. </param>
        /// <param name="announce"> Whether ban should be publicly announced on the server. </param>
        /// <param name="raiseEvents"> Whether AddingIPBan, AddedIPBan, BanChanging, and BanChanged events should be raised. </param>
        /// <exception cref="ArgumentNullException"> targetAddress or player is null. </exception>
        /// <exception cref="PlayerOpException"> Permission or configuration issues arise, or if everyone has already been banned. </exception>
        public static void BanAll([NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason,
                                  bool announce, bool raiseEvents)
        {
            if (targetAddress == null)
            {
                throw new ArgumentNullException("targetAddress");
            }
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (reason != null && reason.Trim().Length == 0)
            {
                reason = null;
            }

            if (!player.Can(Permission.Ban, Permission.BanIP, Permission.BanAll))
            {
                PlayerOpException.ThrowPermissionMissing(player, null, "ban-all",
                                                         Permission.Ban, Permission.BanIP, Permission.BanAll);
            }

            // Check if player is trying to ban self
            if (targetAddress.Equals(player.IP) && !player.IsSuper)
            {
                PlayerOpException.ThrowCannotTargetSelf(player, null, "ban-all");
            }

            // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255)
            if (targetAddress.Equals(IPAddress.None) || targetAddress.Equals(IPAddress.Any))
            {
                PlayerOpException.ThrowInvalidIP(player, null, targetAddress);
            }

            // Check if any high-ranked players use this address
            PlayerInfo[] allPlayersOnIP        = PlayerDB.FindPlayers(targetAddress);
            PlayerInfo   infoWhomPlayerCantBan = allPlayersOnIP.FirstOrDefault(info => !player.Can(Permission.Ban, info.Rank));

            if (infoWhomPlayerCantBan != null)
            {
                PlayerOpException.ThrowPermissionLimitIP(player, infoWhomPlayerCantBan, targetAddress);
            }

            PlayerOpException.CheckBanReason(reason, player, null, false);
            bool somethingGotBanned = false;

            lock ( BanListLock ) {
                CheckIfLoaded();
                // Ban the IP
                if (!Contains(targetAddress))
                {
                    IPBanInfo banInfo = new IPBanInfo(targetAddress, null, player.Name, reason);
                    if (Add(banInfo, raiseEvents))
                    {
                        Logger.Log(LogType.UserActivity,
                                   "{0} banned {1} (BanAll {1}). Reason: {2}",
                                   player.Name, targetAddress, reason ?? "");

                        // Announce ban on the server
                        if (announce)
                        {
                            var can = Server.Players.Can(Permission.ViewPlayerIPs);
                            can.Message("&W{0} was banned by {1}", targetAddress, player.ClassyName);
                            var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                            cant.Message("&WAn IP was banned by {0}", player.ClassyName);
                        }
                        somethingGotBanned = true;
                    }
                }

                // Ban individual players
                foreach (PlayerInfo targetAlt in allPlayersOnIP)
                {
                    if (targetAlt.BanStatus != BanStatus.NotBanned)
                    {
                        continue;
                    }

                    // Raise PlayerInfo.BanChanging event
                    PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs(targetAlt, player, false,
                                                                                          reason, announce);
                    if (raiseEvents)
                    {
                        PlayerInfo.RaiseBanChangingEvent(e);
                        if (e.Cancel)
                        {
                            continue;
                        }
                        reason = e.Reason;
                    }

                    // Do the ban
                    if (targetAlt.ProcessBan(player, player.Name, reason))
                    {
                        if (raiseEvents)
                        {
                            PlayerInfo.RaiseBanChangedEvent(e);
                        }

                        // Log and announce ban
                        Logger.Log(LogType.UserActivity,
                                   "{0} banned {1} (BanAll {2}). Reason: {3}",
                                   player.Name, targetAlt.Name, targetAddress, reason ?? "");
                        if (announce)
                        {
                            Server.Message("&WPlayer {0}&W was banned by {1}&W (BanAll)",
                                           targetAlt.ClassyName, player.ClassyName);
                        }
                        somethingGotBanned = true;
                    }
                }
            }

            // If no one ended up getting banned, quit here
            if (!somethingGotBanned)
            {
                PlayerOpException.ThrowNoOneToBan(player, null, targetAddress);
            }

            // Announce BanAll reason towards the end of all bans
            if (announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null)
            {
                Server.Message("&WBanAll reason: {0}", reason);
            }

            // Kick all players from IP
            Player[] targetsOnline = Server.Players.FromIP(targetAddress).ToArray();
            if (targetsOnline.Length > 0)
            {
                string kickReason;
                if (reason != null)
                {
                    kickReason = String.Format("Banned by {0}: {1}", player.Name, reason);
                }
                else
                {
                    kickReason = String.Format("Banned by {0}", player.Name);
                }
                for (int i = 0; i < targetsOnline.Length; i++)
                {
                    if (targetsOnline[i].Info.BanStatus != BanStatus.IPBanExempt)
                    {
                        targetsOnline[i].Kick(kickReason, LeaveReason.BanAll);
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary> Unbans an IP address. If an associated PlayerInfo is known,
        /// use a different overload of this method instead. Throws PlayerOpException on problems. </summary>
        /// <param name="targetAddress"> IP address that is being unbanned. </param>
        /// <param name="player"> Player who is unbanning. </param>
        /// <param name="reason"> Reason for unban. May be empty, if permitted by server configuration. </param>
        /// <param name="announce"> Whether unban should be publicly announced on the server. </param>
        /// <param name="raiseEvents"> Whether RemovingIPBan and RemovedIPBan events should be raised. </param>
        /// <exception cref="ArgumentNullException"> targetAddress or player is null. </exception>
        /// <exception cref="PlayerOpException"> Permission or configuration issues arise, or if IP is already unbanned. </exception>
        public static void UnbanIP([NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason,
                                   bool announce, bool raiseEvents)
        {
            if (targetAddress == null)
            {
                throw new ArgumentNullException("targetAddress");
            }
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (reason != null && reason.Trim().Length == 0)
            {
                reason = null;
            }

            // Check if player can unban IPs in general
            if (!player.Can(Permission.Ban, Permission.BanIP))
            {
                PlayerOpException.ThrowPermissionMissing(player, null, "IP-unban", Permission.Ban, Permission.BanIP);
            }

            // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255)
            if (targetAddress.Equals(IPAddress.None) || targetAddress.Equals(IPAddress.Any))
            {
                PlayerOpException.ThrowInvalidIP(player, null, targetAddress);
            }

            // Check if player is trying to unban self
            if (targetAddress.Equals(player.IP) && !player.IsSuper)
            {
                PlayerOpException.ThrowCannotTargetSelf(player, null, "IP-unban");
            }

            PlayerOpException.CheckBanReason(reason, player, null, true);

            lock ( BanListLock ) {
                CheckIfLoaded();
                // Actually unban
                bool result = Remove(targetAddress, raiseEvents);

                if (result)
                {
                    Logger.Log(LogType.UserActivity,
                               "{0} unbanned {1} (UnbanIP {1}). Reason: {2}",
                               player.Name, targetAddress, reason ?? "");
                    if (announce)
                    {
                        var can = Server.Players.Can(Permission.ViewPlayerIPs);
                        can.Message("&W{0} was unbanned by {1}", targetAddress, player.ClassyName);
                        var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                        cant.Message("&WAn IP was unbanned by {0}", player.ClassyName);
                        if (ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null)
                        {
                            Server.Message("&WUnbanIP reason: {0}", reason);
                        }
                    }
                }
                else
                {
                    string msg;
                    if (player.Can(Permission.ViewPlayerIPs))
                    {
                        msg = String.Format("IP address {0} is not currently banned.", targetAddress);
                    }
                    else
                    {
                        msg = String.Format("Given IP address is not currently banned.");
                    }
                    string colorMsg = "&S" + msg;
                    throw new PlayerOpException(player, null, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg);
                }
            }
        }
Beispiel #8
0
        /// <summary> Bans given IP address. All players from IP are kicked. If an associated PlayerInfo is known,
        /// use a different overload of this method instead. Throws PlayerOpException on problems. </summary>
        /// <param name="targetAddress"> IP address that is being banned. </param>
        /// <param name="player"> Player who is banning. </param>
        /// <param name="reason"> Reason for ban. May be empty, if permitted by server configuration. </param>
        /// <param name="announce"> Whether ban should be publicly announced on the server. </param>
        /// <param name="raiseEvents"> Whether AddingIPBan and AddedIPBan events should be raised. </param>
        /// <exception cref="ArgumentNullException"> targetAddress or player is null. </exception>
        /// <exception cref="PlayerOpException"> Permission or configuration issues arise, or if IP is already banned. </exception>
        public static void BanIP([NotNull] this IPAddress targetAddress, [NotNull] Player player, [CanBeNull] string reason,
                                 bool announce, bool raiseEvents)
        {
            if (targetAddress == null)
            {
                throw new ArgumentNullException("targetAddress");
            }
            if (player == null)
            {
                throw new ArgumentNullException("player");
            }
            if (reason != null && reason.Trim().Length == 0)
            {
                reason = null;
            }

            // Check if player can ban IPs in general
            if (!player.Can(Permission.Ban, Permission.BanIP))
            {
                PlayerOpException.ThrowPermissionMissing(player, null, "IP-ban", Permission.Ban, Permission.BanIP);
            }

            // Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255)
            if (targetAddress.Equals(IPAddress.None) || targetAddress.Equals(IPAddress.Any))
            {
                PlayerOpException.ThrowInvalidIP(player, null, targetAddress);
            }

            // Check if player is trying to ban self
            if (targetAddress.Equals(player.IP) && !player.IsSuper)
            {
                PlayerOpException.ThrowCannotTargetSelf(player, null, "IP-ban");
            }

            lock ( BanListLock ) {
                CheckIfLoaded();
                // Check if target is already banned
                IPBanInfo existingBan = Get(targetAddress);
                if (existingBan != null)
                {
                    string msg;
                    if (player.Can(Permission.ViewPlayerIPs))
                    {
                        msg = String.Format("IP address {0} is already banned.", targetAddress);
                    }
                    else
                    {
                        msg = String.Format("Given IP address is already banned.");
                    }
                    string colorMsg = "&S" + msg;
                    throw new PlayerOpException(player, null, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg);
                }

                // Check if any high-ranked players use this address
                PlayerInfo infoWhomPlayerCantBan = PlayerDB.FindPlayers(targetAddress)
                                                   .FirstOrDefault(info => !player.Can(Permission.Ban, info.Rank));
                if (infoWhomPlayerCantBan != null)
                {
                    PlayerOpException.ThrowPermissionLimitIP(player, infoWhomPlayerCantBan, targetAddress);
                }

                PlayerOpException.CheckBanReason(reason, player, null, false);

                // Actually ban
                IPBanInfo banInfo = new IPBanInfo(targetAddress, null, player.Name, reason);
                bool      result  = Add(banInfo, raiseEvents);

                if (result)
                {
                    Logger.Log(LogType.UserActivity,
                               "{0} banned {1} (BanIP {1}). Reason: {2}",
                               player.Name, targetAddress, reason ?? "");
                    if (announce)
                    {
                        // Announce ban on the server
                        var can = Server.Players.Can(Permission.ViewPlayerIPs);
                        can.Message("&W{0} was banned by {1}", targetAddress, player.ClassyName);
                        var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                        cant.Message("&WAn IP was banned by {0}", player.ClassyName);
                        if (ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null)
                        {
                            Server.Message("&WBanIP reason: {0}", reason);
                        }
                    }

                    // Kick all players connected from address
                    string kickReason;
                    if (reason != null)
                    {
                        kickReason = String.Format("IP-Banned by {0}: {1}", player.Name, reason);
                    }
                    else
                    {
                        kickReason = String.Format("IP-Banned by {0}", player.Name);
                    }
                    foreach (Player other in Server.Players.FromIP(targetAddress))
                    {
                        if (other.Info.BanStatus != BanStatus.IPBanExempt)
                        {
                            other.Kick(kickReason, LeaveReason.BanIP);   // TODO: check side effects of not using DoKick
                        }
                    }
                }
                else
                {
                    // address is already banned
                    string msg;
                    if (player.Can(Permission.ViewPlayerIPs))
                    {
                        msg = String.Format("{0} is already banned.", targetAddress);
                    }
                    else
                    {
                        msg = "Given IP address is already banned.";
                    }
                    string colorMsg = "&S" + msg;
                    throw new PlayerOpException(player, null, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg);
                }
            }
        }
Beispiel #9
0
        static void ZoneRenameHandler(Player player, CommandReader cmd)
        {
            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            // make sure that both parameters are given
            string oldName = cmd.Next();
            string newName = cmd.Next();

            if (oldName == null || newName == null)
            {
                CdZoneRename.PrintUsage(player);
                return;
            }

            // make sure that the new name is valid
            if (!World.IsValidName(newName))
            {
                player.Message("\"{0}\" is not a valid zone name", newName);
                return;
            }

            // find the old zone
            var  zones   = player.WorldMap.Zones;
            Zone oldZone = zones.Find(oldName);

            if (oldZone == null)
            {
                player.MessageNoZone(oldName);
                return;
            }

            // Check if a zone with "newName" name already exists
            Zone newZone = zones.FindExact(newName);

            if (newZone != null && newZone != oldZone)
            {
                player.Message("A zone with the name \"{0}\" already exists.", newName);
                return;
            }

            // check if any change is needed
            string fullOldName = oldZone.Name;

            if (fullOldName == newName)
            {
                player.Message("The zone is already named \"{0}\"", fullOldName);
                return;
            }

            // actually rename the zone
            zones.Rename(oldZone, newName);

            // announce the rename
            playerWorld.Players.Message("&SZone \"{0}\" was renamed to \"{1}&S\" by {2}",
                                        fullOldName, oldZone.ClassyName, player.ClassyName);
            Logger.Log(LogType.UserActivity,
                       "Player {0} renamed zone \"{1}\" to \"{2}\" on world {3}",
                       player.Name, fullOldName, newName, playerWorld.Name);
        }
Beispiel #10
0
        static void ZoneRemoveHandler(Player player, CommandReader cmd)
        {
            if (player.World == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            string zoneName = cmd.Next();

            if (zoneName == null || cmd.HasNext)
            {
                CdZoneRemove.PrintUsage(player);
                return;
            }

            if (zoneName == "*")
            {
                if (!cmd.IsConfirmed)
                {
                    Logger.Log(LogType.UserActivity,
                               "ZRemove: Asked {0} to confirm removing all zones on world {1}",
                               player.Name, player.World.Name);
                    player.Confirm(cmd,
                                   "&WRemove ALL zones on this world ({0}&W)? This cannot be undone.&S",
                                   player.World.ClassyName);
                    return;
                }
                player.WorldMap.Zones.Clear();
                Logger.Log(LogType.UserActivity,
                           "Player {0} removed all zones on world {1}",
                           player.Name, player.World.Name);
                Server.Message("Player {0}&S removed all zones on world {1}",
                               player.ClassyName, player.World.ClassyName);
                return;
            }

            ZoneCollection zones = player.WorldMap.Zones;
            Zone           zone  = zones.Find(zoneName);

            if (zone != null)
            {
                if (!player.Info.Rank.AllowSecurityCircumvention)
                {
                    switch (zone.Controller.CheckDetailed(player.Info))
                    {
                    case SecurityCheckResult.BlackListed:
                        player.Message("You are not allowed to remove zone {0}: you are blacklisted.", zone.ClassyName);
                        return;

                    case SecurityCheckResult.RankTooLow:
                        player.Message("You are not allowed to remove zone {0}.", zone.ClassyName);
                        return;
                    }
                }
                if (!cmd.IsConfirmed)
                {
                    Logger.Log(LogType.UserActivity,
                               "ZRemove: Asked {0} to confirm removing zone {1} from world {2}",
                               player.Name, zone.Name, player.World.Name);
                    player.Confirm(cmd, "Remove zone {0}&S?", zone.ClassyName);
                    return;
                }

                if (zones.Remove(zone.Name))
                {
                    Logger.Log(LogType.UserActivity,
                               "Player {0} removed zone {1} from world {2}",
                               player.Name, zone.Name, player.World.Name);
                    player.Message("Zone \"{0}\" removed.", zone.Name);
                }
            }
            else
            {
                player.MessageNoZone(zoneName);
            }
        }
Beispiel #11
0
        static void ZoneAddHandler(Player player, CommandReader cmd)
        {
            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }

            string givenZoneName = cmd.Next();

            if (givenZoneName == null)
            {
                CdZoneAdd.PrintUsage(player);
                return;
            }

            if (!player.Info.Rank.AllowSecurityCircumvention)
            {
                SecurityCheckResult buildCheck = playerWorld.BuildSecurity.CheckDetailed(player.Info);
                switch (buildCheck)
                {
                case SecurityCheckResult.BlackListed:
                    player.Message("Cannot add zones to world {0}&S: You are barred from building here.",
                                   playerWorld.ClassyName);
                    return;

                case SecurityCheckResult.RankTooLow:
                    player.Message("Cannot add zones to world {0}&S: You are not allowed to build here.",
                                   playerWorld.ClassyName);
                    return;
                }
            }

            Zone           newZone        = new Zone();
            ZoneCollection zoneCollection = player.WorldMap.Zones;

            if (givenZoneName.StartsWith("+"))
            {
                // personal zone (/ZAdd +Name)
                givenZoneName = givenZoneName.Substring(1);

                // Find the target player
                PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, givenZoneName);
                if (info == null)
                {
                    return;
                }

                // Make sure that the name is not taken already.
                // If a zone named after the player already exists, try adding a number after the name (e.g. "Notch2")
                newZone.Name = info.Name;
                for (int i = 2; zoneCollection.Contains(newZone.Name); i++)
                {
                    newZone.Name = givenZoneName + i;
                }

                newZone.Controller.MinRank = info.Rank.NextRankUp ?? info.Rank;
                newZone.Controller.Include(info);
                player.Message("ZoneAdd: Creating a {0}+&S zone for player {1}&S. Click or &H/Mark&S 2 blocks.",
                               newZone.Controller.MinRank.ClassyName, info.ClassyName);
                player.SelectionStart(2, ZoneAddCallback, newZone, CdZoneAdd.Permissions);
            }
            else
            {
                // Adding an ordinary, rank-restricted zone.
                if (!World.IsValidName(givenZoneName))
                {
                    player.Message("\"{0}\" is not a valid zone name", givenZoneName);
                    return;
                }

                if (zoneCollection.Contains(givenZoneName))
                {
                    player.Message("A zone with this name already exists. Use &H/ZEdit&S to edit.");
                    return;
                }

                newZone.Name = givenZoneName;

                string rankName = cmd.Next();
                if (rankName == null)
                {
                    player.Message("No rank was specified. See &H/Help zone");
                    return;
                }

                Rank minRank = RankManager.FindRank(rankName);
                if (minRank == null)
                {
                    player.MessageNoRank(rankName);
                    return;
                }

                string name;
                while ((name = cmd.Next()) != null)
                {
                    if (name.Length < 1)
                    {
                        CdZoneAdd.PrintUsage(player);
                        return;
                    }
                    PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, name.Substring(1));
                    if (info == null)
                    {
                        return;
                    }

                    if (name.StartsWith("+"))
                    {
                        newZone.Controller.Include(info);
                    }
                    else if (name.StartsWith("-"))
                    {
                        newZone.Controller.Exclude(info);
                    }
                }

                newZone.Controller.MinRank = minRank;
                player.SelectionStart(2, ZoneAddCallback, newZone, CdZoneAdd.Permissions);
                player.Message("ZoneAdd: Creating zone {0}&S. Click or &H/Mark&S 2 blocks.",
                               newZone.ClassyName);
            }
        }
Beispiel #12
0
        static void ZoneEditHandler(Player player, CommandReader cmd)
        {
            if (player.World == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }
            bool   changesWereMade = false;
            string zoneName        = cmd.Next();

            if (zoneName == null)
            {
                player.Message("No zone name specified. See &H/Help ZEdit");
                return;
            }

            Zone zone = player.WorldMap.Zones.Find(zoneName);

            if (zone == null)
            {
                player.MessageNoZone(zoneName);
                return;
            }

            string nextToken;

            while ((nextToken = cmd.Next()) != null)
            {
                // Clear whitelist
                if (nextToken.Equals("-*"))
                {
                    PlayerInfo[] oldWhitelist = zone.Controller.ExceptionList.Included;
                    if (oldWhitelist.Length > 0)
                    {
                        zone.Controller.ResetIncludedList();
                        player.Message("Whitelist of zone {0}&S cleared: {1}",
                                       zone.ClassyName, oldWhitelist.JoinToClassyString());
                        Logger.Log(LogType.UserActivity,
                                   "Player {0} cleared whitelist of zone {1} on world {2}: {3}",
                                   player.Name, zone.Name, player.World.Name,
                                   oldWhitelist.JoinToString(pi => pi.Name));
                    }
                    else
                    {
                        player.Message("Whitelist of zone {0}&S is empty.",
                                       zone.ClassyName);
                    }
                    continue;
                }

                // Clear blacklist
                if (nextToken.Equals("+*"))
                {
                    PlayerInfo[] oldBlacklist = zone.Controller.ExceptionList.Excluded;
                    if (oldBlacklist.Length > 0)
                    {
                        zone.Controller.ResetExcludedList();
                        player.Message("Blacklist of zone {0}&S cleared: {1}",
                                       zone.ClassyName, oldBlacklist.JoinToClassyString());
                        Logger.Log(LogType.UserActivity,
                                   "Player {0} cleared blacklist of zone {1} on world {2}: {3}",
                                   player.Name, zone.Name, player.World.Name,
                                   oldBlacklist.JoinToString(pi => pi.Name));
                    }
                    else
                    {
                        player.Message("Blacklist of zone {0}&S is empty.",
                                       zone.ClassyName);
                    }
                    continue;
                }

                if (nextToken.StartsWith("+"))
                {
                    PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, nextToken.Substring(1));
                    if (info == null)
                    {
                        return;
                    }

                    // prevent players from whitelisting themselves to bypass protection
                    if (!player.Info.Rank.AllowSecurityCircumvention && player.Info == info)
                    {
                        switch (zone.Controller.CheckDetailed(info))
                        {
                        case SecurityCheckResult.BlackListed:
                            player.Message("You are not allowed to remove yourself from the blacklist of zone {0}",
                                           zone.ClassyName);
                            continue;

                        case SecurityCheckResult.RankTooLow:
                            player.Message("You must be {0}+&S to add yourself to the whitelist of zone {1}",
                                           zone.Controller.MinRank.ClassyName, zone.ClassyName);
                            continue;
                        }
                    }

                    switch (zone.Controller.Include(info))
                    {
                    case PermissionOverride.Deny:
                        player.Message("{0}&S is no longer excluded from zone {1}",
                                       info.ClassyName, zone.ClassyName);
                        changesWereMade = true;
                        break;

                    case PermissionOverride.None:
                        player.Message("{0}&S is now included in zone {1}",
                                       info.ClassyName, zone.ClassyName);
                        changesWereMade = true;
                        break;

                    case PermissionOverride.Allow:
                        player.Message("{0}&S is already included in zone {1}",
                                       info.ClassyName, zone.ClassyName);
                        break;
                    }
                }
                else if (nextToken.StartsWith("-"))
                {
                    PlayerInfo info = PlayerDB.FindPlayerInfoOrPrintMatches(player, nextToken.Substring(1));
                    if (info == null)
                    {
                        return;
                    }

                    switch (zone.Controller.Exclude(info))
                    {
                    case PermissionOverride.Deny:
                        player.Message("{0}&S is already excluded from zone {1}",
                                       info.ClassyName, zone.ClassyName);
                        break;

                    case PermissionOverride.None:
                        player.Message("{0}&S is now excluded from zone {1}",
                                       info.ClassyName, zone.ClassyName);
                        changesWereMade = true;
                        break;

                    case PermissionOverride.Allow:
                        player.Message("{0}&S is no longer included in zone {1}",
                                       info.ClassyName, zone.ClassyName);
                        changesWereMade = true;
                        break;
                    }
                }
                else
                {
                    Rank minRank = RankManager.FindRank(nextToken);

                    if (minRank != null)
                    {
                        // prevent players from lowering rank so bypass protection
                        if (!player.Info.Rank.AllowSecurityCircumvention &&
                            zone.Controller.MinRank > player.Info.Rank && minRank <= player.Info.Rank)
                        {
                            player.Message("You are not allowed to lower the zone's rank.");
                            continue;
                        }

                        if (zone.Controller.MinRank != minRank)
                        {
                            zone.Controller.MinRank = minRank;
                            player.Message("Permission for zone \"{0}\" changed to {1}+",
                                           zone.Name,
                                           minRank.ClassyName);
                            changesWereMade = true;
                        }
                    }
                    else
                    {
                        player.MessageNoRank(nextToken);
                    }
                }

                if (changesWereMade)
                {
                    zone.Edit(player.Info);
                }
                else
                {
                    player.Message("No changes were made to the zone.");
                }
            }
        }
        static void UndoHandler([NotNull] Player player, [NotNull] CommandReader cmd)
        {
            World playerWorld = player.World;

            if (playerWorld == null)
            {
                PlayerOpException.ThrowNoWorld(player);
            }
            if (cmd.HasNext)
            {
                player.Message("Undo command takes no parameters. Did you mean to do &H/UndoPlayer&S or &H/UndoArea&S?");
                return;
            }

            string    msg       = "Undo: ";
            UndoState undoState = player.UndoPop();

            if (undoState == null)
            {
                player.MessageNow("There is currently nothing to undo.");
                return;
            }

            // Cancel the last DrawOp, if still in progress
            if (undoState.Op != null && !undoState.Op.IsDone && !undoState.Op.IsCancelled)
            {
                undoState.Op.Cancel();
                msg += String.Format("Cancelled {0} (was {1}% done). ",
                                     undoState.Op.Description,
                                     undoState.Op.PercentDone);
            }

            // Check if command was too massive.
            if (undoState.IsTooLargeToUndo)
            {
                if (undoState.Op != null)
                {
                    player.MessageNow("Cannot undo {0}: too massive.", undoState.Op.Description);
                }
                else
                {
                    player.MessageNow("Cannot undo: too massive.");
                }
                return;
            }

            // no need to set player.drawingInProgress here because this is done on the user thread
            Logger.Log(LogType.UserActivity,
                       "Player {0} initiated /Undo affecting {1} blocks (on world {2})",
                       player.Name,
                       undoState.Buffer.Count,
                       playerWorld.Name);

            msg += String.Format("Restoring {0} blocks. Type &H/Redo&S to reverse.",
                                 undoState.Buffer.Count);
            player.MessageNow(msg);

            var op = new UndoDrawOperation(player, undoState, false);

            op.Prepare(new Vector3I[0]);
            op.Begin();
        }
        internal static void Init()
        {
            CommandManager.RegisterCommand(CdMassRank);
            CommandManager.RegisterCommand(CdSetInfo);

            CommandManager.RegisterCommand(CdReload);

            CommandManager.RegisterCommand(CdShutdown);
            CommandManager.RegisterCommand(CdRestart);

            //CommandManager.RegisterCommand( CdPruneDB );

            CommandManager.RegisterCommand(CdImport);

            CommandManager.RegisterCommand(CdInfoSwap);

#if DEBUG
            CommandManager.RegisterCommand(new CommandDescriptor {
                Name     = "BUM",
                IsHidden = true,
                Category = CommandCategory.Maintenance | CommandCategory.Debug,
                Help     = "Bandwidth Use Mode statistics.",
                Handler  = delegate(Player player, CommandReader cmd) {
                    string newModeName = cmd.Next();
                    if (newModeName == null)
                    {
                        player.Message("{0}: S: {1}  R: {2}  S/s: {3:0.0}  R/s: {4:0.0}",
                                       player.BandwidthUseMode,
                                       player.BytesSent,
                                       player.BytesReceived,
                                       player.BytesSentRate,
                                       player.BytesReceivedRate);
                    }
                    else
                    {
                        var newMode                  = (BandwidthUseMode)Enum.Parse(typeof(BandwidthUseMode), newModeName, true);
                        player.BandwidthUseMode      = newMode;
                        player.Info.BandwidthUseMode = newMode;
                    }
                }
            });

            CommandManager.RegisterCommand(new CommandDescriptor {
                Name     = "BDBDB",
                IsHidden = true,
                Category = CommandCategory.Maintenance | CommandCategory.Debug,
                Help     = "BlockDB Debug",
                Handler  = delegate(Player player, CommandReader cmd) {
                    if (player.World == null)
                    {
                        PlayerOpException.ThrowNoWorld(player);
                    }
                    BlockDB db = player.World.BlockDB;
                    lock (db.SyncRoot) {
                        player.Message("BlockDB: CAP={0} SZ={1} FI={2}",
                                       db.CacheCapacity, db.CacheSize, db.LastFlushedIndex);
                    }
                }
            });
#endif
        }