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}", 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 );
}
}