/// <summary> Unbans given IP address and all accounts on that IP. </summary>
/// <param name="targetAddress"> IP address that is being unbanned. </param>
/// <param name="player"> Player who is unbanning. </param>
/// <param name="reason"> Reason for unban. May be null or empty, if permitted by server configuration. </param>
/// <param name="announce"> Whether unban should be publicly announced on the server. </param>
/// <param name="raiseEvents"> Whether RemovingIPBan, RemovedIPBan, BanChanging, and BanChanged events should be raised. </param>
/// <exception cref="ArgumentNullException"> targetAddress or player is null. </exception>
/// <exception cref="PlayerOpException"> Permission or configuration issues arise, or if everyone has already been unbanned. </exception>
public static void UnbanAll([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;
}
if (!player.Can(Permission.Ban, Permission.BanIP, Permission.BanAll))
{
PlayerOpException.ThrowPermissionMissing(player, null, "unban-all",
Permission.Ban, Permission.BanIP, Permission.BanAll);
}
// Check if player is trying to unban self
if (targetAddress.Equals(player.IP) && !player.IsSuper)
{
PlayerOpException.ThrowCannotTargetSelf(player, null, "unban-all");
}
// 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);
}
PlayerOpException.CheckBanReason(reason, player, null, true);
bool somethingGotUnbanned = false;
lock ( BanListLock ) {
CheckIfLoaded();
// Unban the IP
if (Contains(targetAddress))
{
if (Remove(targetAddress, raiseEvents))
{
Logger.Log(LogType.UserActivity,
"{0} unbanned {1} (UnbanAll {1}). Reason: {2}",
player.Name, targetAddress, reason ?? "");
// Announce unban on the server
if (announce)
{
var can = Server.Players.Can(Permission.ViewPlayerIPs);
can.Message("&W{0} was unbanned by {1}", targetAddress, player.ClassyName);
var cant = Server.Players.Cant(Permission.ViewPlayerIPs);
cant.Message("&WAn IP was unbanned by {0}", player.ClassyName);
}
somethingGotUnbanned = true;
}
}
// Unban individual players
PlayerInfo[] allPlayersOnIP = PlayerDB.FindPlayers(targetAddress);
foreach (PlayerInfo targetAlt in allPlayersOnIP)
{
if (targetAlt.BanStatus != BanStatus.Banned)
{
continue;
}
// Raise PlayerInfo.BanChanging event
PlayerInfoBanChangingEventArgs e = new PlayerInfoBanChangingEventArgs(targetAlt, player, true,
reason, announce);
if (raiseEvents)
{
PlayerInfo.RaiseBanChangingEvent(e);
if (e.Cancel)
{
continue;
}
reason = e.Reason;
}
// Do the ban
if (targetAlt.ProcessUnban(player.Name, reason))
{
if (raiseEvents)
{
PlayerInfo.RaiseBanChangedEvent(e);
}
// Log and announce ban
Logger.Log(LogType.UserActivity,
"{0} unbanned {1} (UnbanAll {2}). Reason: {3}",
player.Name, targetAlt.Name, targetAddress, reason ?? "");
if (announce)
{
Server.Message("&WPlayer {0}&W was unbanned by {1}&W (UnbanAll)",
targetAlt.ClassyName, player.ClassyName);
}
somethingGotUnbanned = true;
}
}
}
// If no one ended up getting unbanned, quit here
if (!somethingGotUnbanned)
{
PlayerOpException.ThrowNoOneToUnban(player, null, targetAddress);
}
// Announce UnbanAll reason towards the end of all unbans
if (announce && ConfigKey.AnnounceKickAndBanReasons.Enabled() && reason != null)
{
Server.Message("&WUnbanAll reason: {0}", reason);
}
}