private 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 );
}
if ( unban ) {
if ( target.Info.BannedUntil > DateTime.UtcNow ) {
player.Message( "&SBypassed BannedUntil field for {0}&S, target is no longer tempbanned" );
target.Info.BannedUntil = DateTime.MinValue;
}
}
// 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" );
}
}
}
}