internal static void Unignore(Player player, Command cmd) { string name = cmd.Next(); if (name != null) { PlayerInfo targetInfo; if (!PlayerDB.FindPlayerInfo(name, out targetInfo)) { PlayerInfo[] infos = PlayerDB.FindPlayers(name); if (infos.Length == 1) { targetInfo = infos[0]; } else if (infos.Length > 1) { player.ManyMatchesMessage("player", infos); return; } else { player.NoPlayerMessage(name); return; } } else if (targetInfo == null) { player.NoPlayerMessage(name); return; } if (player.Unignore(targetInfo)) { player.MessageNow("You are no longer ignoring {0}", targetInfo.GetClassyName()); } else { player.MessageNow("You are not currently ignoring {0}", targetInfo.GetClassyName()); } } else { PlayerInfo[] ignoreList = player.GetIgnoreList(); if (ignoreList.Length > 0) { player.MessageNow("Ignored players: {0}", ignoreList.JoinToClassyString()); } else { player.MessageNow("You are not currently ignoring anyone."); } return; } }
/// <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); } }
/// <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); } } } }
/// <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); } } }
internal static void Info(Player player, Command cmd) { string name = cmd.Next(); if (name == null) { name = player.Name; } else if (!player.Can(Permission.ViewOthersInfo)) { player.NoAccessMessage(Permission.ViewOthersInfo); return; } IPAddress ip; PlayerInfo[] infos; if (Server.IsIP(name) && IPAddress.TryParse(name, out ip)) { // find players by IP infos = PlayerDB.FindPlayers(ip, PlayerDB.NumberOfMatchesToPrint); } else if (name.Contains("*") || name.Contains(".")) { // find players by regex/wildcard string regexString = "^" + RegexNonNameChars.Replace(name, "").Replace("*", ".*") + "$"; Regex regex = new Regex(regexString, RegexOptions.IgnoreCase | RegexOptions.Compiled); infos = PlayerDB.FindPlayers(regex, PlayerDB.NumberOfMatchesToPrint); } else { // find players by partial matching PlayerInfo tempInfo; if (!PlayerDB.FindPlayerInfo(name, out tempInfo)) { infos = PlayerDB.FindPlayers(name, PlayerDB.NumberOfMatchesToPrint); } else if (tempInfo == null) { player.NoPlayerMessage(name); return; } else { infos = new[] { tempInfo }; } } if (infos.Length == 1) { PrintPlayerInfo(player, infos[0]); } else if (infos.Length > 1) { player.ManyMatchesMessage("player", infos); if (infos.Length == PlayerDB.NumberOfMatchesToPrint) { player.Message("NOTE: Only first {0} matches are shown.", PlayerDB.NumberOfMatchesToPrint); } } else { player.NoPlayerMessage(name); } }
public static void PrintPlayerInfo(Player player, PlayerInfo info) { Player target = Server.FindPlayerExact(info.Name); // hide online status when hidden if (target != null && !player.CanSee(target)) { target = null; } if (info.LastIP.Equals(IPAddress.None)) { player.Message("About {0}&S: Never seen before.", info.GetClassyName()); } else { if (target != null) { if (target.IsHidden) { if (player.Can(Permission.ViewPlayerIPs)) { player.Message("About {0}&S: HIDDEN. Online from {1}", info.GetClassyName(), info.LastIP); } else { player.Message("About {0}&S: HIDDEN.", info.GetClassyName()); } } else { if (player.Can(Permission.ViewPlayerIPs)) { player.Message("About {0}&S: Online now from {1}", info.GetClassyName(), info.LastIP); } else { player.Message("About {0}&S: Online now.", info.GetClassyName()); } } } else { if (player.Can(Permission.ViewPlayerIPs)) { player.Message("About {0}&S: Last seen {1} ago from {2}", info.GetClassyName(), info.TimeSinceLastSeen.ToMiniString(), info.LastIP); } else { player.Message("About {0}&S: Last seen {1} ago.", info.GetClassyName(), info.TimeSinceLastSeen.ToMiniString()); } } // Show login information player.Message(" Logged in {0} time(s) since {1:d MMM yyyy}.", info.TimesVisited, info.FirstLoginDate); } // Show ban information IPBanInfo ipBan = IPBanList.Get(info.LastIP); if (ipBan != null && info.Banned) { player.Message(" Both name and IP are {0}BANNED&S. See &H/baninfo", Color.Red); } else if (ipBan != null) { player.Message(" IP is {0}BANNED&S (but nick isn't). See &H/baninfo", Color.Red); } else if (info.Banned) { player.Message(" Nick is {0}BANNED&S (but IP isn't). See &H/baninfo", Color.Red); } if (info.LastIP.ToString() != IPAddress.None.ToString()) { // Show alts List <PlayerInfo> altNames = new List <PlayerInfo>(); int bannedAltCount = 0; foreach (PlayerInfo playerFromSameIP in PlayerDB.FindPlayers(info.LastIP, 25)) { if (playerFromSameIP != info) { altNames.Add(playerFromSameIP); if (playerFromSameIP.Banned) { bannedAltCount++; } } } if (altNames.Count > 0) { if (bannedAltCount > 0) { player.Message(" {0} accounts ({1} banned) share this IP: {2}", altNames.Count, bannedAltCount, altNames.ToArray().JoinToClassyString()); } else { player.Message(" {0} accounts share this IP: {1}", altNames.Count, altNames.ToArray().JoinToClassyString()); } } } // Stats if (info.BlocksDrawn > 500000000) { player.Message(" Built {0} and deleted {1} blocks, drew {2}M blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000000, info.LinesWritten); } else if (info.BlocksDrawn > 500000) { player.Message(" Built {0} and deleted {1} blocks, drew {2}K blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000, info.LinesWritten); } else if (info.BlocksDrawn > 0) { player.Message(" Built {0} and deleted {1} blocks, drew {2} blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn, info.LinesWritten); } else { player.Message(" Built {0} and deleted {1} blocks, wrote {2} messages.", info.BlocksBuilt, info.BlocksDeleted, info.LinesWritten); } // More stats if (info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0) { player.Message(" Kicked {0} and banned {1} players.", info.TimesKickedOthers, info.TimesBannedOthers); } if (info.TimesKicked > 0) { if (info.LastKickDate != DateTime.MinValue) { player.Message(" Got kicked {0} times. Last kick {1} ago by {2}", info.TimesKicked, info.TimeSinceLastKick.ToMiniString(), info.LastKickBy); if (info.LastKickReason.Length > 0) { player.Message(" Last kick reason: {0}", info.LastKickReason); } } else { player.Message(" Got kicked {0} times", info.TimesKicked); } } // Promotion/demotion if (!String.IsNullOrEmpty(info.RankChangedBy)) { if (info.PreviousRank == null) { player.Message(" Promoted to {0}&S by {1} {2} ago.", info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString()); } else if (info.PreviousRank < info.Rank) { player.Message(" Promoted from {0}&S to {1}&S by {2} {3} ago.", info.PreviousRank.GetClassyName(), info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString()); if (!string.IsNullOrEmpty(info.RankChangeReason)) { player.Message(" Promotion reason: {0}", info.RankChangeReason); } } else { player.Message(" Demoted from {0}&S to {1}&S by {2} {3} ago.", info.PreviousRank.GetClassyName(), info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString()); if (info.RankChangeReason.Length > 0) { player.Message(" Demotion reason: {0}", info.RankChangeReason); } } } else { player.Message(" Rank is {0}&S (default).", info.Rank.GetClassyName()); } if (info.LastIP.ToString() != IPAddress.None.ToString()) { // Time on the server TimeSpan totalTime = info.TotalTime; if (target != null) { totalTime = totalTime.Add(info.TimeSinceLastLogin); } player.Message(" Spent a total of {0:F1} hours ({1:F1} minutes) here.", totalTime.TotalHours, totalTime.TotalMinutes); } }