public void BanAll( [NotNull] Player player, [CanBeNull] string reason, bool announce, bool raiseEvents )
{
if ( player == null )
throw new ArgumentNullException( "player" );
if ( reason != null && reason.Trim().Length == 0 )
reason = null;
lock ( actionLock ) {
if ( !player.Can( Permission.Ban, Permission.BanIP, Permission.BanAll ) ) {
PlayerOpException.ThrowPermissionMissing( player, this, "ban-all",
Permission.Ban, Permission.BanIP, Permission.BanAll );
}
IPAddress address = LastIP;
// Check if player is trying to ban self
if ( player.Info == this || address.Equals( player.IP ) && !player.IsSuper ) {
PlayerOpException.ThrowCannotTargetSelf( player, this, "ban-all" );
}
// Check if a non-bannable address was given (0.0.0.0 or 255.255.255.255)
if ( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) {
PlayerOpException.ThrowInvalidIP( player, this, address );
}
// Check if any high-ranked players use this address
PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers( address );
PlayerInfo infoWhomPlayerCantBan = allPlayersOnIP.FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) );
if ( infoWhomPlayerCantBan != null ) {
PlayerOpException.ThrowPermissionLimitIP( player, infoWhomPlayerCantBan, address );
}
PlayerOpException.CheckBanReason( reason, player, this, false );
bool somethingGotBanned = false;
// Ban the IP
if ( !IPBanList.Contains( address ) ) {
IPBanInfo banInfo = new IPBanInfo( address, Name, player.Name, reason );
if ( IPBanList.Add( banInfo, raiseEvents ) ) {
Logger.Log( LogType.UserActivity,
"{0} banned {1} (BanAll {2}). Reason: {3}",
player.Name, address, Name, reason ?? "" );
// Announce ban on the server
if ( announce ) {
var can = Server.Players.Can( Permission.ViewPlayerIPs );
can.Message( "&WPlayer {0}&W was IP-banned ({1}) by {2}",
ClassyName, address, player.ClassyName );
var cant = Server.Players.Cant( Permission.ViewPlayerIPs );
cant.Message( "&WPlayer {0}&W was IP-banned by {1}",
ClassyName, 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 ) {
RaiseBanChangingEvent( e );
if ( e.Cancel )
continue;
reason = e.Reason;
}
// Do the ban
if ( targetAlt.ProcessBan( player, player.Name, reason ) ) {
if ( raiseEvents ) {
RaiseBanChangedEvent( e );
}
// Log and announce ban
Logger.Log( LogType.UserActivity,
"{0} banned {1} (BanAll {2}). Reason: {3}",
player.Name, targetAlt.Name, Name, reason ?? "" );
if ( announce ) {
if ( targetAlt == this ) {
Server.Message( "&WPlayer {0}&W was banned by {1}&W (BanAll)",
targetAlt.ClassyName, player.ClassyName );
} else {
Server.Message( "&WPlayer {0}&W was banned by {1}&W by association with {2}",
targetAlt.ClassyName, player.ClassyName, ClassyName );
}
}
somethingGotBanned = true;
}
}
// If no one ended up getting banned, quit here
if ( !somethingGotBanned ) {
PlayerOpException.ThrowNoOneToBan( player, this, address );
}
// 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( address ).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 );
}
}
}
}