Created
September 24, 2011 12:10
-
-
Save mstefarov/1239257 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static void DoBan( [NotNull] Player player, string nameOrIP, [NotNull] string reason, | |
bool banIP, bool banAll, bool unban ) { | |
if( player == null ) throw new ArgumentNullException( "player" ); | |
if( nameOrIP == null ) { | |
player.Message( "Please specify player name or IP to ban." ); | |
return; | |
} | |
if( reason == null ) throw new ArgumentNullException( "reason" ); | |
IPAddress address; | |
Player target = Server.FindPlayerExact( nameOrIP ); | |
PlayerInfo targetInfo; | |
if( target != null ) { | |
targetInfo = target.Info; | |
} else { | |
targetInfo = PlayerDB.FindPlayerInfoExact( nameOrIP ); | |
} | |
if( ConfigKey.RequireBanReason.Enabled() && string.IsNullOrEmpty( reason ) ) { | |
player.Message( "&WPlease specify a ban/unban reason." ); | |
// freeze the target player to prevent further damage | |
if( !unban && target != null && !targetInfo.IsFrozen && | |
player.Can( Permission.Freeze ) && player.Can( Permission.Ban, target.Info.Rank ) ) { | |
player.Message( "{0}&S has been frozen while you retry.", | |
target.ClassyName ); | |
FreezeHandler( player, new Command( "/freeze " + target.Name ) ); | |
} | |
return; | |
} | |
// ban by IP address | |
if( banIP && Server.IsIP( nameOrIP ) && IPAddress.TryParse( nameOrIP, out address ) ) { | |
DoIPBan( player, address, reason, null, banAll, unban ); | |
// ban online players | |
} else if( !unban && target != null ) { | |
// check permissions | |
if( player.Can( Permission.Ban, target.Info.Rank ) ) { | |
address = target.Info.LastIP; | |
PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetInfo, player, false, reason ); | |
PlayerInfo.RaiseBanChangingEvent( e ); | |
if( e.Cancel ) return; | |
reason = e.Reason; | |
if( banIP ) DoIPBan( player, address, reason, target.Name, banAll, false ); | |
if( !banAll ) { | |
if( target.Info.ProcessBan( player, player.Name, reason ) ) { | |
PlayerInfo.RaiseBanChangedEvent( e ); | |
Logger.Log( "{0} was banned by {1}.", LogType.UserActivity, | |
target.Info.Name, player.Name ); | |
Server.Message( target, | |
"{0}&W was banned by {1}", | |
target.ClassyName, player.ClassyName ); | |
if( !string.IsNullOrEmpty( reason ) ) { | |
if( ConfigKey.AnnounceKickAndBanReasons.Enabled() ) { | |
Server.Message( target, "&WBan reason: {0}", reason ); | |
} | |
} | |
DoKick( player, target, reason, true, false, LeaveReason.Ban ); | |
if( !banIP ) { | |
PlayerInfo[] alts = PlayerDB.FindPlayers( target.Info.LastIP ); | |
PlayerInfo[] bannedAlts = alts.Where( t => (t.IsBanned && t != target.Info) ).ToArray(); | |
if( bannedAlts.Length > 0 ) { | |
player.Message( "Warning: {0}&S shares IP with other banned players: {1}&S. Consider adding an IP-ban.", | |
target.ClassyName, | |
bannedAlts.JoinToClassyString() ); | |
} | |
} | |
} else { | |
player.Message( "{0}&S is already banned.", target.ClassyName ); | |
} | |
} | |
} else { | |
player.Message( "You can only ban players ranked {0}&S or lower.", | |
player.Info.Rank.GetLimit( Permission.Ban ).ClassyName ); | |
player.Message( "{0}&S is ranked {1}", | |
target.ClassyName, target.Info.Rank.ClassyName ); | |
} | |
// ban or unban offline players | |
} else if( targetInfo != null ) { | |
if( player.Can( Permission.Ban, targetInfo.Rank ) || unban ) { | |
address = targetInfo.LastIP; | |
PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetInfo, player, unban, reason ); | |
PlayerInfo.RaiseBanChangingEvent( e ); | |
if( e.Cancel ) return; | |
reason = e.Reason; | |
if( banIP ) DoIPBan( player, address, reason, targetInfo.Name, banAll, unban ); | |
if( !banAll ) { | |
if( unban ) { | |
if( targetInfo.ProcessUnban( player.Name, reason ) ) { | |
PlayerInfo.RaiseBanChangedEvent( e ); | |
Logger.Log( "{0} (offline) was unbanned by {1}", LogType.UserActivity, | |
targetInfo.Name, player.Name ); | |
Server.Message( "{0}&W (offline) was unbanned by {1}", | |
targetInfo.ClassyName, player.ClassyName ); | |
if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && !string.IsNullOrEmpty( reason ) ) { | |
Server.Message( "&WUnban reason: {0}", reason ); | |
} | |
} else { | |
player.Message( "{0}&S (offline) is not currenty banned.", targetInfo.ClassyName ); | |
} | |
} else { | |
if( targetInfo.ProcessBan( player, player.Name, reason ) ) { | |
PlayerInfo.RaiseBanChangedEvent( e ); | |
Logger.Log( "{0} (offline) was banned by {1}.", LogType.UserActivity, | |
targetInfo.Name, player.Name ); | |
Server.Message( "{0}&W (offline) was banned by {1}", | |
targetInfo.ClassyName, player.ClassyName ); | |
if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && !string.IsNullOrEmpty( reason ) ) { | |
Server.Message( "&WBan reason: {0}", reason ); | |
} | |
} else { | |
player.Message( "{0}&S (offline) is already banned.", targetInfo.ClassyName ); | |
} | |
} | |
} | |
} else { | |
player.Message( "You can only ban players ranked {0}&S or lower.", | |
player.Info.Rank.GetLimit( Permission.Ban ).ClassyName ); | |
player.Message( "{0}&S is ranked {1}", | |
targetInfo.ClassyName, targetInfo.Rank.ClassyName ); | |
} | |
// ban players who are not in the database yet | |
} else if( Player.IsValidName( nameOrIP ) ) { | |
if( !player.Can( Permission.EditPlayerDB ) ) { | |
player.Message( "Player not found. Please specify valid name or IP." ); | |
return; | |
} | |
player.Message( "Warning: Player \"{0}\" is not in the database (possible typo)", nameOrIP ); | |
if( unban ) { | |
player.Message( "\"{0}\" (unrecognized) is not banned.", nameOrIP ); | |
} else { | |
targetInfo = PlayerDB.AddFakeEntry( nameOrIP, RankChangeType.Default ); | |
PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( targetInfo, player, false, reason ); | |
PlayerInfo.RaiseBanChangingEvent( e ); | |
if( e.Cancel ) return; // TODO: Remove fake player from DB | |
reason = e.Reason; | |
// this will never return false (player could not have been banned already) | |
targetInfo.ProcessBan( player, player.Name, reason ); | |
PlayerInfo.RaiseBanChangedEvent( e ); | |
player.Message( "Player \"{0}\" (unrecognized) was banned.", nameOrIP ); | |
Logger.Log( "{0} (unrecognized) was banned by {1}", LogType.UserActivity, | |
targetInfo.Name, player.Name ); | |
Server.Message( "{0}&W (unrecognized) was banned by {1}", | |
targetInfo.ClassyName, player.ClassyName ); | |
if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && !string.IsNullOrEmpty( reason ) ) { | |
Server.Message( "&WBan reason: {0}", reason ); | |
} | |
} | |
} else { | |
player.Message( "Please specify valid player name or IP." ); | |
} | |
} | |
internal static void DoIPBan( [NotNull] Player player, [NotNull] IPAddress address, | |
string reason, string targetName, bool all, bool unban ) { | |
if( player == null ) throw new ArgumentNullException( "player" ); | |
if( address == null ) throw new ArgumentNullException( "address" ); | |
if( address.Equals( IPAddress.None ) || address.Equals( IPAddress.Any ) ) { | |
player.Message( "Invalid IP: {0}", address ); | |
return; | |
} | |
if( unban ) { | |
IPBanInfo banInfo = IPBanList.Get( address ); | |
if( IPBanList.Remove( address, true ) ) { | |
Logger.Log( "{0} unbanned {1}", LogType.UserActivity, player.Name, address ); | |
if( player.Can( Permission.ViewPlayerIPs ) ) { | |
player.Message( "{0} has been removed from the IP ban list.", address ); | |
} else { | |
player.Message( "This IP has been removed from the ban list." ); | |
} | |
string ipAssociatedName = targetName; | |
if( !String.IsNullOrEmpty( banInfo.PlayerName ) ) { | |
ipAssociatedName = banInfo.PlayerName; | |
} | |
var can = Server.Players.Can( Permission.ViewPlayerIPs ).Except( player ); | |
var cant = Server.Players.Cant( Permission.ViewPlayerIPs ).Except( player ); | |
if( !String.IsNullOrEmpty( ipAssociatedName ) ) { | |
can.Message( "&W{0} (associated with {1}) was unbanned by {2}", | |
address, ipAssociatedName, player.ClassyName ); | |
cant.Message( "&WIP associated with {0} was unbanned by {1}", | |
ipAssociatedName, player.ClassyName ); | |
} else { | |
can.Message( "&W{0} was unbanned by {1}", | |
address, player.ClassyName ); | |
can.Message( "&WAn IP was unbanned by {0}", | |
player.ClassyName ); | |
} | |
if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && !String.IsNullOrEmpty( reason ) ) { | |
Server.Message( player, "&WUnban reason: {0}", reason ); | |
} | |
} else { | |
if( player.Can( Permission.ViewPlayerIPs ) ) { | |
player.Message( "{0} is not currently banned.", address ); | |
} else { | |
player.Message( "This IP is not currently banned." ); | |
} | |
} | |
if( all ) { | |
string newReason = reason + "~UnbanAll"; | |
foreach( PlayerInfo otherInfo in PlayerDB.FindPlayers( address ) ) { | |
PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( otherInfo, player, true, newReason ); | |
PlayerInfo.RaiseBanChangingEvent( e ); | |
if( e.Cancel ) return; | |
newReason = e.Reason; | |
if( otherInfo.ProcessUnban( player.Name, newReason ) ) { | |
PlayerInfo.RaiseBanChangedEvent( e ); | |
Server.Message( player, | |
"{0}&W was unbanned (UnbanAll) by {1}", | |
otherInfo.ClassyName, player.ClassyName ); | |
player.Message( "{0}&S matched IP and was also unbanned.", otherInfo.ClassyName ); | |
} | |
} | |
} | |
} else { | |
PlayerInfo[] infos = PlayerDB.FindPlayers( address ); | |
PlayerInfo cantBan = infos.FirstOrDefault( info => !player.Can( Permission.Ban, info.Rank ) ); | |
if( cantBan != null ) { | |
player.Message( "&W{0} is associated with player {1}&W, whom you are not allowed to ban.", | |
address, cantBan.ClassyName ); | |
return; | |
} | |
if( IPBanList.Add( new IPBanInfo( address, targetName, player.Name, reason ), true ) ) { | |
Logger.Log( "{0} banned {1}", LogType.UserActivity, player.Name, address ); | |
if( player.Can( Permission.ViewPlayerIPs ) ) { | |
player.Message( "{0} was added to the IP ban list.", address ); | |
} else { | |
player.Message( "This IP was added to the ban list." ); | |
} | |
var can = Server.Players.Can( Permission.ViewPlayerIPs ).Except( player ); | |
var cant = Server.Players.Cant( Permission.ViewPlayerIPs ).Except( player ); | |
if( !String.IsNullOrEmpty( targetName ) ) { | |
can.Message( "&W{0} (associated with {1}) was banned by {2}", | |
address, targetName, player.ClassyName ); | |
cant.Message( "&WIP associated with {0} was banned by {1}", | |
targetName, player.ClassyName ); | |
} else { | |
can.Message( "&W{0} was banned by {1}", | |
address, player.ClassyName ); | |
cant.Message( "&WAn IP was banned by {0}", | |
player.ClassyName ); | |
} | |
if( ConfigKey.AnnounceKickAndBanReasons.Enabled() && !String.IsNullOrEmpty( reason ) ) { | |
Server.Message( player, "&WBan reason: {0}", reason ); | |
} | |
foreach( Player other in Server.Players.FromIP( address ) ) { | |
if( other.Info.BanStatus == BanStatus.IPBanExempt ) { | |
player.Message( "&WPlayer {0}&W shares the IP, but is exempt from IP bans.", other.ClassyName ); | |
} else { | |
DoKick( player, other, reason, true, false, LeaveReason.BanIP ); | |
} | |
} | |
} else { | |
if( player.Can( Permission.ViewPlayerIPs ) ) { | |
player.Message( "{0} is already banned.", address ); | |
} else { | |
player.Message( "This IP is already banned." ); | |
} | |
} | |
if( all ) { | |
string newReason = reason + "~BanAll"; | |
foreach( PlayerInfo otherInfo in PlayerDB.FindPlayers( address ) ) { | |
PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs( otherInfo, player, false, newReason ); | |
PlayerInfo.RaiseBanChangingEvent( e ); | |
if( e.Cancel ) return; | |
newReason = e.Reason; | |
if( otherInfo.ProcessBan( player, player.Name, newReason ) ) { | |
PlayerInfo.RaiseBanChangedEvent( e ); | |
player.Message( "{0}&S matched IP and was also banned.", otherInfo.ClassyName ); | |
Server.Message( player, | |
"{0}&W was banned (BanAll) by {1}", | |
otherInfo.ClassyName, player.ClassyName ); | |
} | |
} | |
foreach( Player other in Server.Players.FromIP( address ) ) { | |
DoKick( player, other, reason, true, false, LeaveReason.BanAll ); | |
} | |
} | |
} | |
} | |
public static bool DoKick( [NotNull] Player player, [NotNull] Player target, | |
string reason, bool silent, bool recordToPlayerDB, LeaveReason leaveReason ) { | |
if( player == null ) throw new ArgumentNullException( "player" ); | |
if( target == null ) throw new ArgumentNullException( "target" ); | |
if( player == target ) { | |
player.Message( "You cannot kick yourself." ); | |
return false; | |
} | |
if( !player.Can( Permission.Kick, target.Info.Rank ) ) { | |
player.Message( "You can only kick players ranked {0}&S or lower.", | |
player.Info.Rank.GetLimit( Permission.Kick ).ClassyName ); | |
player.Message( "{0}&S is ranked {1}", target.ClassyName, target.Info.Rank.ClassyName ); | |
return false; | |
} else { | |
var e = new PlayerBeingKickedEventArgs( target, player, reason, silent, recordToPlayerDB, leaveReason ); | |
Player.RaisePlayerBeingKickedEvent( e ); | |
if( e.Cancel ) return false; | |
if( !e.IsSilent ) { | |
Server.Message( "{0}&W was kicked by {1}", | |
target.ClassyName, player.ClassyName ); | |
} | |
if( e.RecordToPlayerDB ) { | |
target.Info.ProcessKick( player, reason ); | |
} | |
Player[] otherPlayers = Server.Players.FromIP( target.Info.LastIP ).Except( target ).ToArray(); | |
if( otherPlayers.Length > 0 ) { | |
player.Message( "&WWarning: Other player(s) share IP with {0}&W: {1}", | |
target.Info.ClassyName, | |
otherPlayers.JoinToClassyString() ); | |
} | |
Player.RaisePlayerKickedEvent( e ); | |
if( !string.IsNullOrEmpty( reason ) ) { | |
if( !e.IsSilent && ConfigKey.AnnounceKickAndBanReasons.Enabled() ) { | |
Server.Message( "&WKick reason: {0}", reason ); | |
} | |
Logger.Log( "{0} was kicked by {1}. Reason: {2}", LogType.UserActivity, | |
target.Name, player.Name, reason ); | |
target.Kick( "Kicked by " + player.ClassyName + Color.White + ": " + reason, leaveReason ); | |
} else { | |
Logger.Log( "{0} was kicked by {1}", LogType.UserActivity, | |
target.Name, player.Name ); | |
target.Kick( "You were kicked by " + player.ClassyName, leaveReason ); | |
} | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment