public void BanIP( [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 ) ) {
PlayerOpException.ThrowPermissionMissing( player, this, "IP-ban", Permission.Ban, Permission.BanIP );
}
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, "IP-ban" );
}
// 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 unbannable = PlayerDB.FindPlayers( address )
.FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) );
if ( unbannable != null ) {
PlayerOpException.ThrowPermissionLimitIP( player, unbannable, address );
}
// Check existing ban statuses
bool needNameBan = !IsBanned;
bool needIPBan = !IPBanList.Contains( address );
if ( !needIPBan && !needNameBan ) {
string msg, colorMsg;
if ( player.Can( Permission.ViewPlayerIPs ) ) {
msg = String.Format( "Given player ({0}) and their IP address ({1}) are both already banned.",
Name, address );
colorMsg = String.Format( "&SGiven player ({0}&S) and their IP address ({1}) are both already banned.",
ClassyName, address );
} else {
msg = String.Format( "Given player ({0}) and their IP address are both already banned.",
Name );
colorMsg = String.Format( "&SGiven player ({0}&S) and their IP address are both already banned.",
ClassyName );
}
throw new PlayerOpException( player, this, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg );
}
// Check if target is IPBan-exempt
bool targetIsExempt = ( BanStatus == BanStatus.IPBanExempt );
if ( !needIPBan && targetIsExempt ) {
string msg = String.Format( "Given player ({0}) is exempt from IP bans. Remove the exemption and retry.",
Name );
string colorMsg = String.Format( "&SGiven player ({0}&S) is exempt from IP bans. Remove the exemption and retry.",
ClassyName );
throw new PlayerOpException( player, this, PlayerOpExceptionCode.TargetIsExempt, msg, colorMsg );
}
// Ban the name
if ( needNameBan ) {
Ban( player, reason, announce, raiseEvents );
}
PlayerOpException.CheckBanReason( reason, player, this, false );
// Ban the IP
if ( needIPBan ) {
IPBanInfo banInfo = new IPBanInfo( address, Name, player.Name, reason );
if ( IPBanList.Add( banInfo, raiseEvents ) ) {
Logger.Log( LogType.UserActivity,
"{0} banned {1} (BanIP {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 );
if ( ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null ) {
Server.Message( "&WBanIP reason: {0}", reason );
}
}
} else {
// IP is already banned
string msg, colorMsg;
if ( player.Can( Permission.ViewPlayerIPs ) ) {
msg = String.Format( "IP of player {0} ({1}) is already banned.",
Name, address );
colorMsg = String.Format( "&SIP of player {0}&S ({1}) is already banned.",
Name, address );
} else {
msg = String.Format( "IP of player {0} is already banned.",
Name );
colorMsg = String.Format( "&SIP of player {0}&S is already banned.",
ClassyName );
}
throw new PlayerOpException( player, null, PlayerOpExceptionCode.NoActionNeeded, msg, colorMsg );
}
}
}
}