示例#1
0
        private void SetPlayerInfoText(PlayerInfo info)
        {
            textBox1.Text    = "";
            PlayerLabel.Text = player.Name;
            SetTextRankColor(Color.GetName(player.Rank.Color));
            if (info.LastIP.Equals(System.Net.IPAddress.None))
            {
                textBox1.Text += String.Format("About {0}&S: Never seen before.\r\n", info.ClassyName);
            }
            else
            {
                if (info != null)
                {
                    TimeSpan idle = info.PlayerObject.IdleTime;
                    if (info.IsHidden)
                    {
                        if (idle.TotalMinutes > 2)
                        {
                            if (player.Can(Permission.ViewPlayerIPs))
                            {
                                textBox1.Text += String.Format("About {0}&S: HIDDEN from {1} (idle {2})\r\n",
                                                               info.ClassyName,
                                                               info.LastIP,
                                                               idle.ToMiniString());
                            }
                            else
                            {
                                textBox1.Text += String.Format("About {0}&S: HIDDEN (idle {1})\r\n",
                                                               info.ClassyName,
                                                               idle.ToMiniString());
                            }
                        }
                        else
                        {
                            if (player.Can(Permission.ViewPlayerIPs))
                            {
                                textBox1.Text += String.Format("About {0}&S: HIDDEN. Online from {1}\r\n",
                                                               info.ClassyName,
                                                               info.LastIP);
                            }
                            else
                            {
                                textBox1.Text += String.Format("About {0}&S: HIDDEN.\r\n",
                                                               info.ClassyName);
                            }
                        }
                    }
                    else
                    {
                        if (idle.TotalMinutes > 1)
                        {
                            if (player.Can(Permission.ViewPlayerIPs))
                            {
                                textBox1.Text += String.Format("About {0}&S: Online now from {1} (idle {2})\r\n",
                                                               info.ClassyName,
                                                               info.LastIP,
                                                               idle.ToMiniString());
                            }
                            else
                            {
                                textBox1.Text += String.Format("About {0}&S: Online now (idle {1})\r\n",
                                                               info.ClassyName,
                                                               idle.ToMiniString());
                            }
                        }
                        else
                        {
                            if (player.Can(Permission.ViewPlayerIPs))
                            {
                                textBox1.Text += String.Format("About {0}&S: Online now from {1}\r\n",
                                                               info.ClassyName,
                                                               info.LastIP);
                            }
                            else
                            {
                                textBox1.Text += String.Format("About {0}&S: Online now.\r\n",
                                                               info.ClassyName);
                            }
                        }
                    }
                }
                else
                {
                    if (player.Can(Permission.ViewPlayerIPs))
                    {
                        if (info.LeaveReason != LeaveReason.Unknown)
                        {
                            textBox1.Text += String.Format("About {0}&S: Last seen {1} ago from {2} ({3}).\r\n",
                                                           info.ClassyName,
                                                           info.TimeSinceLastSeen.ToMiniString(),
                                                           info.LastIP,
                                                           info.LeaveReason);
                        }
                        else
                        {
                            textBox1.Text += String.Format("About {0}&S: Last seen {1} ago from {2}.\r\n",
                                                           info.ClassyName,
                                                           info.TimeSinceLastSeen.ToMiniString(),
                                                           info.LastIP);
                        }
                    }
                    else
                    {
                        if (info.LeaveReason != LeaveReason.Unknown)
                        {
                            textBox1.Text += String.Format("About {0}&S: Last seen {1} ago ({2}).\r\n",
                                                           info.ClassyName,
                                                           info.TimeSinceLastSeen.ToMiniString(),
                                                           info.LeaveReason);
                        }
                        else
                        {
                            textBox1.Text += String.Format("About {0}&S: Last seen {1} ago.\r\n",
                                                           info.ClassyName,
                                                           info.TimeSinceLastSeen.ToMiniString());
                        }
                    }
                }
                // Show login information
                textBox1.Text += String.Format("  Logged in {0} time(s) since {1:d MMM yyyy}.\r\n",
                                               info.TimesVisited,
                                               info.FirstLoginDate);
            }

            if (info.IsFrozen)
            {
                textBox1.Text += String.Format("  Frozen {0} ago by {1}\r\n",
                                               info.TimeSinceFrozen.ToMiniString(),
                                               info.FrozenByClassy);
            }

            if (info.IsMuted)
            {
                textBox1.Text += String.Format("  Muted for {0} by {1}\r\n",
                                               info.TimeMutedLeft.ToMiniString(),
                                               info.MutedByClassy);
                float blocks = ((info.BlocksBuilt + info.BlocksDrawn) - info.BlocksDeleted);
                if (blocks < 0)
                {
                    textBox1.Text += String.Format("  &CWARNING! {0}&S has deleted more than built!\r\n", info.ClassyName);  //<---- GlennMR on Au70 Galaxy
                }
            }

            // Show ban information
            IPBanInfo ipBan = IPBanList.Get(info.LastIP);

            switch (info.BanStatus)
            {
            case BanStatus.Banned:
                if (ipBan != null)
                {
                    textBox1.Text += String.Format("  Account and IP are &CBANNED&S. See &H/BanInfo\r\n");
                }
                else
                {
                    textBox1.Text += String.Format("  Account is &CBANNED&S. See &H/BanInfo\r\n");
                }
                break;

            case BanStatus.IPBanExempt:
                if (ipBan != null)
                {
                    textBox1.Text += String.Format("  IP is &CBANNED&S, but account is exempt. See &H/BanInfo\r\n");
                }
                else
                {
                    textBox1.Text += String.Format("  IP is not banned, and account is exempt. See &H/BanInfo\r\n");
                }
                break;

            case BanStatus.NotBanned:
                if (ipBan != null)
                {
                    textBox1.Text += String.Format("  IP is &CBANNED&S. See &H/BanInfo\r\n");
                }
                break;
            }

            if (!info.LastIP.Equals(System.Net.IPAddress.None))
            {
                // Show alts
                List <PlayerInfo> altNames = new List <PlayerInfo>();
                int bannedAltCount         = 0;
                foreach (PlayerInfo playerFromSameIP in PlayerDB.FindPlayers(info.LastIP))
                {
                    if (playerFromSameIP == info)
                    {
                        continue;
                    }
                    altNames.Add(playerFromSameIP);
                    if (playerFromSameIP.IsBanned)
                    {
                        bannedAltCount++;
                    }
                }

                // Stats
                if (info.BlocksDrawn > 500000000)
                {
                    textBox1.Text += String.Format("  Built {0} and deleted {1} blocks, drew {2}M blocks, wrote {3} messages.\r\n",
                                                   info.BlocksBuilt,
                                                   info.BlocksDeleted,
                                                   info.BlocksDrawn / 1000000,
                                                   info.MessagesWritten);
                }
                else if (info.BlocksDrawn > 500000)
                {
                    textBox1.Text += String.Format("  Built {0} and deleted {1} blocks, drew {2}K blocks, wrote {3} messages.\r\n",
                                                   info.BlocksBuilt,
                                                   info.BlocksDeleted,
                                                   info.BlocksDrawn / 1000,
                                                   info.MessagesWritten);
                }
                else if (info.BlocksDrawn > 0)
                {
                    textBox1.Text += String.Format("  Built {0} and deleted {1} blocks, drew {2} blocks, wrote {3} messages.\r\n",
                                                   info.BlocksBuilt,
                                                   info.BlocksDeleted,
                                                   info.BlocksDrawn,
                                                   info.MessagesWritten);
                }
                else
                {
                    textBox1.Text += String.Format("  Built {0} and deleted {1} blocks, wrote {2} messages.\r\n",
                                                   info.BlocksBuilt,
                                                   info.BlocksDeleted,
                                                   info.MessagesWritten);
                }

                // More stats
                if (info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0 || info.PromoCount > 0)
                {
                    textBox1.Text += String.Format("  Kicked {0}, Promoted {1} and banned {2} players.\r\n", info.TimesKickedOthers, info.PromoCount, info.TimesBannedOthers);
                }

                if (info.TimesKicked > 0)
                {
                    if (info.LastKickDate != DateTime.MinValue)
                    {
                        textBox1.Text += String.Format("  Got kicked {0} times. Last kick {1} ago by {2}\r\n",
                                                       info.TimesKicked,
                                                       info.TimeSinceLastKick.ToMiniString(),
                                                       info.LastKickByClassy);
                    }
                    else
                    {
                        textBox1.Text += String.Format("  Got kicked {0} times.\r\n", info.TimesKicked);
                    }
                    if (info.LastKickReason != null)
                    {
                        textBox1.Text += String.Format("  Kick reason: {0}\r\n", info.LastKickReason);
                    }
                }

                // Promotion/demotion
                if (info.PreviousRank == null)
                {
                    if (info.RankChangedBy == null)
                    {
                        textBox1.Text += String.Format("  Rank is {0}&S (default).\r\n",
                                                       info.Rank.ClassyName);
                    }
                    else
                    {
                        textBox1.Text += String.Format("  Promoted to {0}&S by {1}&S {2} ago.\r\n",
                                                       info.Rank.ClassyName,
                                                       info.RankChangedByClassy,
                                                       info.TimeSinceRankChange.ToMiniString());
                        if (info.RankChangeReason != null)
                        {
                            textBox1.Text += String.Format("  Promotion reason: {0}\r\n", info.RankChangeReason);
                        }
                    }
                }
                else if (info.PreviousRank <= info.Rank)
                {
                    textBox1.Text += String.Format("  Promoted from {0}&S to {1}&S by {2}&S {3} ago.\r\n",
                                                   info.PreviousRank.ClassyName,
                                                   info.Rank.ClassyName,
                                                   info.RankChangedByClassy,
                                                   info.TimeSinceRankChange.ToMiniString());
                    if (info.RankChangeReason != null)
                    {
                        textBox1.Text += String.Format("  Promotion reason: {0}\r\n", info.RankChangeReason);
                    }
                }
                else
                {
                    textBox1.Text += String.Format("  Demoted from {0}&S to {1}&S by {2}&S {3} ago.\r\n",
                                                   info.PreviousRank.ClassyName,
                                                   info.Rank.ClassyName,
                                                   info.RankChangedByClassy,
                                                   info.TimeSinceRankChange.ToMiniString());
                    if (info.RankChangeReason != null)
                    {
                        textBox1.Text += String.Format("  Demotion reason: {0}\r\n", info.RankChangeReason);
                    }
                }

                if (!info.LastIP.Equals(System.Net.IPAddress.None))
                {
                    // Time on the server
                    TimeSpan totalTime = info.TotalTime;
                    totalTime      = totalTime.Add(info.TimeSinceLastLogin);
                    textBox1.Text += String.Format("  Spent a total of {0:F1} hours ({1:F1} minutes) here.\r\n",
                                                   totalTime.TotalHours,
                                                   totalTime.TotalMinutes);
                }
                textBox1.Text = Color.StripColors(textBox1.Text);
            }
        }
示例#2
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>
        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;

            // 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}", MessageType.Announcement, targetAddress, player.ClassyName);
                        var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                        cant.Message("&WAn IP was banned by {0}", MessageType.Announcement, 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)
            {
                return;
            }
            var kickReason = reason != null ? $"Banned by {player.Name}: {reason}" : $"Banned by {player.Name}";

            foreach (var t in targetsOnline)
            {
                t.Kick(kickReason, LeaveReason.BanAll);
            }
        }
示例#3
0
        /// <summary> Unbans given IP address and all accounts on that IP. 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 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>
        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;

            // 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}", 0, targetAddress, player.ClassyName);
                        var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                        cant.Message("&WAn IP was unbanned by {0}", 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);
            }
        }
示例#4
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>
        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");
            }

            // 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}", 0, targetAddress, player.ClassyName);
                    var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
                    cant.Message("&WAn IP was banned by {0}", 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);
            }
        }