From fc4fbc6af39bae3782dc1cc185dea2e6bd1b2c91 Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Tue, 5 Jun 2018 22:59:33 -0700 Subject: [PATCH] Group comma-separated bans/mutes together in one MODE --- PBot/ChanOpCommands.pm | 27 ++++++++++++--- PBot/ChanOps.pm | 78 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 91 insertions(+), 14 deletions(-) diff --git a/PBot/ChanOpCommands.pm b/PBot/ChanOpCommands.pm index 139927aa..ce6c9d8a 100644 --- a/PBot/ChanOpCommands.pm +++ b/PBot/ChanOpCommands.pm @@ -87,8 +87,13 @@ sub ban_user { } my @targets = split /,/, $target; + my $immediately = @targets > 1 ? 0 : 1; foreach my $t (@targets) { - $self->{pbot}->{chanops}->ban_user_timed($t, $channel, $length); + $self->{pbot}->{chanops}->ban_user_timed($t, $channel, $length, $immediately); + } + + if (not $immediately) { + $self->{pbot}->{chanops}->check_ban_queue; } if ($length > 0) { @@ -131,12 +136,16 @@ sub unban_user { } my @targets = split /,/, $target; - $immediately = 0 if @targets > 2; + $immediately = 0 if @targets > 1; foreach my $t (@targets) { $self->{pbot}->{chanops}->unban_user($t, $channel, $immediately); } + if (@targets > 1) { + $self->{pbot}->{chanops}->check_unban_queue; + } + return "/msg $nick $target has been unbanned from $channel."; } @@ -186,8 +195,13 @@ sub mute_user { } my @targets = split /,/, $target; + my $immediately = @targets > 1 ? 0 : 1; foreach my $t (@targets) { - $self->{pbot}->{chanops}->mute_user_timed($t, $channel, $length); + $self->{pbot}->{chanops}->mute_user_timed($t, $channel, $length, $immediately); + } + + if (not $immediately) { + $self->{pbot}->{chanops}->check_ban_queue; } if ($length > 0) { @@ -230,11 +244,16 @@ sub unmute_user { } my @targets = split /,/, $target; - $immediately = 0 if @targets > 2; + $immediately = 0 if @targets > 1; foreach my $t (@targets) { $self->{pbot}->{chanops}->unmute_user($t, $channel, $immediately); } + + if (@targets > 1) { + $self->{pbot}->{chanops}->check_unban_queue; + } + return "/msg $nick $target has been unmuted in $channel."; } diff --git a/PBot/ChanOps.pm b/PBot/ChanOps.pm index b5b404d7..e7650445 100644 --- a/PBot/ChanOps.pm +++ b/PBot/ChanOps.pm @@ -47,6 +47,7 @@ sub initialize { $self->{unmute_timeout}->load; + $self->{ban_queue} = {}; $self->{unban_queue} = {}; $self->{op_commands} = {}; @@ -120,10 +121,13 @@ sub perform_op_commands { sub ban_user { my $self = shift; - my ($mask, $channel) = @_; + my ($mask, $channel, $immediately) = @_; - $self->add_op_command($channel, "mode $channel +b $mask"); - $self->gain_ops($channel); + $self->add_to_ban_queue($channel, 'b', $mask); + + if (not defined $immediately or $immediately != 0) { + $self->check_ban_queue; + } } sub get_bans { @@ -192,7 +196,7 @@ sub unban_user { sub ban_user_timed { my $self = shift; - my ($mask, $channel, $length) = @_; + my ($mask, $channel, $length, $immediately) = @_; $channel = lc $channel; $mask = lc $mask; @@ -212,7 +216,8 @@ sub ban_user_timed { } } - $self->ban_user($mask, $channel); + $self->ban_user($mask, $channel, $immediately); + if ($length > 0) { $self->{unban_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + $length; $self->{unban_timeout}->save; @@ -225,10 +230,13 @@ sub ban_user_timed { sub mute_user { my $self = shift; - my ($mask, $channel) = @_; + my ($mask, $channel, $immediately) = @_; - $self->add_op_command($channel, "mode $channel +q $mask"); - $self->gain_ops($channel); + $self->add_to_ban_queue($channel, 'q', $mask); + + if (not defined $immediately or $immediately != 0) { + $self->check_ban_queue; + } } sub unmute_user { @@ -241,13 +249,13 @@ sub unmute_user { sub mute_user_timed { my $self = shift; - my ($mask, $channel, $length) = @_; + my ($mask, $channel, $length, $immediately) = @_; $channel = lc $channel; $mask = lc $mask; $mask .= '!*@*' if $mask !~ m/[\$!@]/; - $self->mute_user($mask, $channel); + $self->mute_user($mask, $channel, $immediately); if ($length > 0) { $self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + $length; $self->{unmute_timeout}->save; @@ -300,6 +308,56 @@ sub has_mute_timeout { return exists $self->{unmute_timeout}->hash->{lc $channel}->{lc $mask}; } +sub add_to_ban_queue { + my ($self, $channel, $mode, $target) = @_; + push @{$self->{ban_queue}->{$channel}->{$mode}}, $target; + $self->{pbot}->{logger}->log("Added +$mode $target for $channel to ban queue.\n"); +} + +sub check_ban_queue { + my $self = shift; + + my $MAX_COMMANDS = 4; + my $commands = 0; + + foreach my $channel (keys %{$self->{ban_queue}}) { + my $done = 0; + while (not $done) { + my ($list, $count, $modes); + $list = ''; + $modes = '+'; + $count = 0; + + foreach my $mode (keys %{$self->{ban_queue}->{$channel}}) { + while (@{$self->{ban_queue}->{$channel}->{$mode}}) { + my $target = pop @{$self->{ban_queue}->{$channel}->{$mode}}; + $list .= " $target"; + $modes .= $mode; + last if ++$count >= $self->{pbot}->{ircd}->{MODES}; + } + + if (not @{$self->{ban_queue}->{$channel}->{$mode}}) { + delete $self->{ban_queue}->{$channel}->{$mode}; + } + + last if $count >= $self->{pbot}->{ircd}->{MODES}; + } + + if (not keys %{ $self->{ban_queue}->{$channel} }) { + delete $self->{ban_queue}->{$channel}; + $done = 1; + } + + if ($count) { + $self->add_op_command($channel, "mode $channel $modes $list"); + $self->gain_ops($channel); + + return if ++$commands >= $MAX_COMMANDS; + } + } + } +} + sub add_to_unban_queue { my ($self, $channel, $mode, $target) = @_; push @{$self->{unban_queue}->{$channel}->{$mode}}, $target;