// Remove all bans
        public static void UnbanAll(MPBanMode mode = MPBanMode.Ban)
        {
            var banList = GetList(mode);

            banList.Clear();
            OnUpdate(mode, false);
        }
        // Remove all non-Permanent bans
        public static void UnbanAllNonPermanent(MPBanMode mode = MPBanMode.Ban)
        {
            var banList = GetList(mode);

            banList.RemoveAll(entry => entry.permanent == false);
            OnUpdate(mode, false);
        }
 // Reset the MPBanPlayers state
 // Removes all non-permanent bans of all modes
 public static void Reset()
 {
     Debug.Log("MPBanPlayers: resetting all non-permanent bans");
     for (MPBanMode mode = (MPBanMode)0; mode < MPBanMode.Count; mode++)
     {
         UnbanAllNonPermanent(mode);
     }
 }
        // Get the ban list
        public static List <MPBanEntry> GetList(MPBanMode mode = MPBanMode.Ban)
        {
            int m = (int)mode;

            if (banLists[m] == null)
            {
                banLists[m] = new List <MPBanEntry>();
            }
            return(banLists[m]);
        }
        // Remove all entries matching a candidate from the ban list
        public static int Unban(MPBanEntry candidate, MPBanMode mode = MPBanMode.Ban)
        {
            var banList = GetList(mode);
            int cnt     = banList.RemoveAll(entry => entry.matches(candidate, "UNBAN: "));

            if (cnt > 0)
            {
                OnUpdate(mode, false);
            }
            return(cnt);
        }
        // Check if this player is banned
        public static bool IsBanned(MPBanEntry candidate, MPBanMode mode = MPBanMode.Ban)
        {
            var banList = GetList(mode);

            foreach (var entry in banList)
            {
                if (entry.matches(candidate, "BAN CHECK: "))
                {
                    return(true);
                }
            }
            // no ban entry matches this player..
            return(false);
        }
 // The ban list was modified
 public static void OnUpdate(MPBanMode mode, bool added)
 {
     totalBanCount = 0;
     for (MPBanMode m = (MPBanMode)0; m < MPBanMode.Count; m++)
     {
         totalBanCount += GetList(m).Count;
     }
     if (added)
     {
         if (mode == MPBanMode.Annoy)
         {
             // apply Annoy bans directly, but not normal bans, as we have the specil KICK and KICKBAN commands
             // that way, we can ban players without having them to be immediately kicked
             AnnoyPlayers();
         }
     }
 }
        // Execute UNBAN or UNANNOY or UNBLOCKCHAT
        public bool DoUnban(MPBanMode banMode)
        {
            if (banMode == MPBanMode.Annoy)
            {
                // UNANNOY also implies UNBLOCKCHAT
                DoUnban(MPBanMode.BlockChat);
            }
            if (String.IsNullOrEmpty(arg))
            {
                MPBanPlayers.UnbanAll(banMode);
                ReturnTo(String.Format("ban list {0} cleared by {1}", banMode, senderEntry.name));
            }
            else
            {
                // check against names in ban list (may not be current player names)
                string pattern = arg.ToUpper();
                var    banList = MPBanPlayers.GetList(banMode);
                int    cnt     = banList.RemoveAll(entry => (MatchPlayerName(entry.name, pattern) != 0));
                if (cnt > 0)
                {
                    MPBanPlayers.OnUpdate(banMode, false);
                }
                else
                {
                    // check the currently connected players
                    if (SelectPlayer(arg))
                    {
                        cnt = MPBanPlayers.Unban(selectedPlayerEntry, banMode);
                    }
                }

                if (cnt > 0)
                {
                    ReturnTo(String.Format("{0} players UNBANNED from {1} list by {2}", cnt, banMode, senderEntry.name));
                }
                else
                {
                    ReturnToSender(String.Format("Un{0}: no player {1} found", banMode, arg));
                }
            }
            return(false);
        }
        // Add a player to the Ban List
        public static bool Ban(MPBanEntry candidate, MPBanMode mode = MPBanMode.Ban, bool permanent = false)
        {
            if (!candidate.IsValid())
            {
                return(false);
            }
            candidate.permanent = permanent;
            var banList = GetList(mode);

            foreach (var entry in banList)
            {
                if (entry.matches(candidate, "BAN already matched: "))
                {
                    // Update it
                    entry.Set(candidate);
                    OnUpdate(mode, true);
                    return(false);
                }
            }
            banList.Add(candidate);
            Debug.LogFormat("BAN: player {0} is NOW banned in mode: {1}", candidate.Describe(), mode);
            OnUpdate(mode, true);
            return(true);
        }
        // Execute KICK or BAN or KICKBAN or ANNOY or BLOCKCHAT command
        public bool DoKickBan(bool doKick, bool doBan, MPBanMode banMode)
        {
            string op;
            string banOp = banMode.ToString().ToUpper();

            if (doKick && doBan)
            {
                op = "KICK" + banOp;
            }
            else if (doKick)
            {
                op = "KICK";
            }
            else if (doBan)
            {
                op = banOp;
            }
            else
            {
                return(false);
            }

            Debug.LogFormat("{0} request for {1}", op, arg);
            if (!SelectPlayer(arg))
            {
                Debug.LogFormat("{0}: no player {1} found", op, arg);
                ReturnToSender(String.Format("{0}: player {1} not found", op, arg));
                return(false);
            }

            if (IsTrustedPlayer(selectedPlayerEntry))
            {
                ReturnToSender(String.Format("{0}: not on this server, dude!", op));
                return(false);
            }

            if (selectedPlayerConnectionId >= 0 && sender_conn == selectedPlayerConnectionId)
            {
                Debug.LogFormat("{0}: won't self-apply", op, arg);
                ReturnToSender(String.Format("{0}: won't self-apply", op, arg));
                return(false);
            }

            if (doBan)
            {
                MPBanPlayers.Ban(selectedPlayerEntry, banMode);
                if (banMode == MPBanMode.Annoy)
                {
                    // ANNOY also implies BLOCKCHAT
                    MPBanPlayers.Ban(selectedPlayerEntry, MPBanMode.BlockChat);
                }
                ReturnTo(String.Format("{0} player {1} by {2}", banOp, selectedPlayerEntry.name, senderEntry.name), -1, selectedPlayerConnectionId);
            }
            if (doKick)
            {
                ReturnTo(String.Format("KICK player {0} by {1}", selectedPlayerEntry.name, senderEntry.name), -1, selectedPlayerConnectionId);
                if (selectedPlayer != null)
                {
                    MPBanPlayers.KickPlayer(selectedPlayer);
                }
                else if (selectedPlayerLobbyData != null)
                {
                    MPBanPlayers.KickPlayer(selectedPlayerLobbyData);
                }
                else
                {
                    MPBanPlayers.KickPlayer(selectedPlayerConnectionId, selectedPlayerEntry.name);
                }
            }
            return(false);
        }