/// <summary> /// Performs a ban /// </summary> /// <param name="hostmask">The mask to ban</param> /// <param name="duration_or_null">The duration, or null</param> /// <param name="reason">The reason for the ban</param> /// <param name="by">The user who set the ban</param> public static void PerformBan(string hostmask, string duration_or_null, string reason, string by) { lock (State.GlobalSync) { if (state != BanSystemState.Synchronized) throw new Exception("Bad state"); if (State.UseQEnforce.Value && CanQBan()) { //if we use Q enforcement, queue a Q command if (duration_or_null == null) new PermBanCommand(hostmask, reason); else new TempBanCommand(hostmask, duration_or_null, reason); } else { //hostmask HostMask mask = new HostMask(hostmask); //add to list Ban ban = new Ban(); TimeSpan actual_duration = duration_or_null == null ? TimeSpan.FromSeconds(0) : ParseDuration(duration_or_null); ban.Expires = duration_or_null == null ? DateTime.MaxValue : DateTime.UtcNow + actual_duration; ban.Enforcer = BanEnforcement.ByMe; ban.Affected = GetAffectedNicks(mask); ban.Mask = mask; ban.Reason = reason; ban.SetBy = by; //check if a longer ban already in place Ban existing = State.BanList.Lookup(ban.Mask.Mask); if (existing != null && existing.Expires > ban.Expires) { throw new Exception("A ban with a longer duration is already in place"); } //add to banlist if (existing != null) State.BanList.Remove(existing); State.BanList.Add(ban); //ban from channel if (!CanChannelBan() && FreeBanSlot(1) == 0) { foreach (User user in State.UserList.GetItems()) { if (user.Left == DateTime.MaxValue && mask.Matches(user.HostMask)) { //kick from channel Irc.Kick(user.Nick, "Enforcing ban: " + reason); } } } else { Irc.Ban(hostmask); if (State.UseQuietBan.Value == false || duration_or_null == null) { foreach (User user in State.UserList.GetItems()) { if (user.Left == DateTime.MaxValue && mask.Matches(user.HostMask)) { //kick from channel Irc.Kick(user.Nick, "Enforcing ban: " + reason); } } } else { //put channel message Irc.SendChannelMessage(GetAffectedNicks(mask) + " has been timed out from chatting for " + ((int)(actual_duration.TotalMinutes + 0.5)).ToString() + " minutes: " + reason, false); } } } } }
/// <summary> /// Gets a user-friendly display of nicknames affected by a ban /// </summary> /// <param name="banmask">The banmask being searched</param> /// <returns>User-friendly string</returns> public static string GetAffectedNicks(HostMask banmask) { lock (State.GlobalSync) { string result = null; foreach (User user in State.UserList.GetItems()) { if (banmask.Matches(user.HostMask)) result = (result == null ? user.Nick : result + ", " + user.Nick); } return result == null ? "" : result; } }