/// <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}", 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> 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}", 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++ ) { targetsOnline[i].Kick( kickReason, LeaveReason.BanAll ); } } }
void BanPlayerInfoInternal( [NotNull] Player player, [CanBeNull] string reason, bool unban, bool announce, bool raiseEvents ) { if( player == null ) throw new ArgumentNullException( "player" ); if( reason != null && reason.Trim().Length == 0 ) reason = null; lock( actionLock ) { // Check if player can ban/unban in general if( !player.Can( Permission.Ban ) ) { PlayerOpException.ThrowPermissionMissing( player, this, unban ? "unban" : "ban", Permission.Ban ); } // Check if player is trying to ban/unban self if( player.Info == this ) { PlayerOpException.ThrowCannotTargetSelf( player, this, unban ? "unban" : "ban" ); } // See if target is already banned/unbanned if( unban && BanStatus != BanStatus.Banned ) { PlayerOpException.ThrowPlayerNotBanned( player, this, "banned" ); } else if( !unban && BanStatus == BanStatus.Banned ) { PlayerOpException.ThrowPlayerAlreadyBanned( player, this, "banned" ); } // Check if player has sufficient rank permissions if( !unban && !player.Can( Permission.Ban, Rank ) ) { PlayerOpException.ThrowPermissionLimit( player, this, "ban", Permission.Ban ); } PlayerOpException.CheckBanReason( reason, player, this, unban ); // Raise PlayerInfo.BanChanging event PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( this, player, unban, reason, announce ); if( raiseEvents ) { RaiseBanChangingEvent( e ); if( e.Cancel ) PlayerOpException.ThrowCancelled( player, this ); reason = e.Reason; } // Actually ban bool result; if( unban ) { result = ProcessUnban( player.Name, reason ); } else { result = ProcessBan( player, player.Name, reason ); } // Check what happened if( result ) { if( raiseEvents ) { RaiseBanChangedEvent( e ); } Player target = PlayerObject; string verb = (unban ? "unbanned" : "banned"); Logger.Log( LogType.UserActivity, "{0} {1} {2}. Reason: {3}", player.Name, verb, Name, reason ?? "" ); if( target != null ) { // Log and announce ban/unban if( announce ) { Server.Message( target, "{0}&W was {1} by {2}", target.ClassyName, verb, player.ClassyName ); } // Kick the target if( !unban ) { string kickReason; if( reason != null ) { kickReason = String.Format( "Banned by {0}: {1}", player.Name, reason ); } else { kickReason = String.Format( "Banned by {0}", player.Name ); } // TODO: check side effects of not using DoKick target.Kick( kickReason, LeaveReason.Ban ); } } else { if( announce ) { Server.Message( "{0}&W (offline) was {1} by {2}", ClassyName, verb, player.ClassyName ); } } // Announce ban/unban reason if( announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) { if( unban ) { Server.Message( "&WUnban reason: {0}", reason ); } else { Server.Message( "&WBan reason: {0}", reason ); } } } else { // Player is already banned/unbanned if( unban ) { PlayerOpException.ThrowPlayerNotBanned( player, this, "banned" ); } else { PlayerOpException.ThrowPlayerAlreadyBanned( player, this, "banned" ); } } } }