From aa87cadb65e1489348706738b2850500098d167f Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Tue, 23 Jul 2019 08:55:24 -0700 Subject: [PATCH] Add checkban/checkmute commands so users can see remaining timeout duration. `mute` now translates nick to banmask. `ban`/`mute` commands will now show remaining timeout duration if no length argument is provided. --- PBot/ChanOpCommands.pm | 145 ++++++++++++++++++++++++++++++++++++----- PBot/ChanOps.pm | 37 ++++++----- 2 files changed, 151 insertions(+), 31 deletions(-) diff --git a/PBot/ChanOpCommands.pm b/PBot/ChanOpCommands.pm index 63b6c948..cf179def 100644 --- a/PBot/ChanOpCommands.pm +++ b/PBot/ChanOpCommands.pm @@ -16,6 +16,7 @@ use feature 'unicode_strings'; use Carp (); use Time::Duration; +use Time::HiRes qw/gettimeofday/; sub new { if (ref($_[1]) eq 'HASH') { @@ -44,6 +45,72 @@ sub initialize { $pbot->{commands}->register(sub { return $self->mute_user(@_) }, "mute", 10); $pbot->{commands}->register(sub { return $self->unmute_user(@_) }, "unmute", 10); $pbot->{commands}->register(sub { return $self->kick_user(@_) }, "kick", 10); + $pbot->{commands}->register(sub { return $self->checkban(@_) }, "checkban", 0); + $pbot->{commands}->register(sub { return $self->checkmute(@_) }, "checkmute", 0); +} + +sub checkban { + my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_; + my ($target, $channel) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2); + + if (not defined $target) { + return "Usage: checkban [channel]"; + } + + if (not defined $channel) { + $channel = $from; + } + + if ($channel !~ /^#/) { + return "Please specify a channel."; + } + + $channel = lc $channel; + $target = lc $target; + + my $mask = $self->{pbot}->{chanops}->nick_to_banmask($target); + + if (exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel} + && exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}) { + my $timeout = $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}{timeout}; + my $duration = duration($timeout - gettimeofday); + + return "$mask has $duration remaining on their $channel ban"; + } else { + return "$mask has no ban timeout"; + } +} + +sub checkmute { + my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_; + my ($target, $channel) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2); + + if (not defined $target) { + return "Usage: checkmute [channel]"; + } + + if (not defined $channel) { + $channel = $from; + } + + if ($channel !~ /^#/) { + return "Please specify a channel."; + } + + $channel = lc $channel; + $target = lc $target; + + my $mask = $self->{pbot}->{chanops}->nick_to_banmask($target); + + if (exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel} + && exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}) { + my $timeout = $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}{timeout}; + my $duration = duration($timeout - gettimeofday); + + return "$mask has $duration remaining on their $channel mute"; + } else { + return "$mask has no mute timeout"; + } } sub ban_user { @@ -71,14 +138,19 @@ sub ban_user { return "/msg $nick Usage: ban [channel [timeout (default: 24 hours)]]"; } + my $no_length = 0; if (not defined $length) { $length = 60 * 60 * 24; # 24 hours + $no_length = 1; } else { my $error; ($length, $error) = $self->{pbot}->{parsedate}->parsedate($length); return $error if defined $error; } + $channel = lc $channel; + $target = lc $target; + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); return "I don't think so." if $target =~ /^\Q$botnick\E!/i; @@ -86,23 +158,41 @@ sub ban_user { return "/msg $nick You are not an admin for $channel."; } + my $result = ''; + my $sep = ''; my @targets = split /,/, $target; my $immediately = @targets > 1 ? 0 : 1; foreach my $t (@targets) { - $self->{pbot}->{chanops}->ban_user_timed($t, $channel, $length, $immediately); + my $mask = $self->{pbot}->{chanops}->nick_to_banmask($t); + + if ($no_length && exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel} + && exists $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}) { + my $timeout = $self->{pbot}->{chanops}->{unban_timeout}->hash->{$channel}->{$mask}{timeout}; + my $duration = duration($timeout - gettimeofday); + + $result .= "$sep$mask has $duration remaining on their $channel ban"; + $sep = '; '; + } else { + $self->{pbot}->{chanops}->ban_user_timed($mask, $channel, $length, $immediately); + + my $duration; + if ($length > 0) { + $duration = duration($length); + } else { + $duration = 'all eternity'; + } + + $result .= "$sep$mask banned in $channel for $duration"; + $sep = '; '; + } } if (not $immediately) { $self->{pbot}->{chanops}->check_ban_queue; } - if ($length > 0) { - $length = duration($length); - } else { - $length = 'all eternity'; - } - - return "/msg $nick $target banned in $channel for $length"; + $result = "/msg $nick $result" if $result !~ m/remaining on their/; + return $result; } sub unban_user { @@ -179,14 +269,19 @@ sub mute_user { return "/msg $nick Usage: mute [channel [timeout (default: 24 hours)]]"; } + my $no_length = 0; if (not defined $length) { $length = 60 * 60 * 24; # 24 hours + $no_length = 1; } else { my $error; ($length, $error) = $self->{pbot}->{parsedate}->parsedate($length); return $error if defined $error; } + $channel = lc $channel; + $target = lc $target; + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); return "I don't think so." if $target =~ /^\Q$botnick\E!/i; @@ -194,23 +289,41 @@ sub mute_user { return "/msg $nick You are not an admin for $channel."; } + my $result = ''; + my $sep = ''; my @targets = split /,/, $target; my $immediately = @targets > 1 ? 0 : 1; foreach my $t (@targets) { - $self->{pbot}->{chanops}->mute_user_timed($t, $channel, $length, $immediately); + my $mask = $self->{pbot}->{chanops}->nick_to_banmask($t); + + if ($no_length && exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel} + && exists $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}) { + my $timeout = $self->{pbot}->{chanops}->{unmute_timeout}->hash->{$channel}->{$mask}{timeout}; + my $duration = duration($timeout - gettimeofday); + + $result .= "$sep$mask has $duration remaining on their $channel mute"; + $sep = '; '; + } else { + $self->{pbot}->{chanops}->mute_user_timed($t, $channel, $length, $immediately); + + my $duration; + if ($length > 0) { + $duration = duration($length); + } else { + $duration = 'all eternity'; + } + + $result .= "$sep$mask muted in $channel for $duration"; + $sep = '; '; + } } if (not $immediately) { $self->{pbot}->{chanops}->check_ban_queue; } - if ($length > 0) { - $length = duration($length); - } else { - $length = 'all eternity'; - } - - return "/msg $nick $target muted in $channel for $length"; + $result = "/msg $nick $result" if $result !~ m/remaining on their/; + return $result; } sub unmute_user { diff --git a/PBot/ChanOps.pm b/PBot/ChanOps.pm index f1c68580..f9bc4016 100644 --- a/PBot/ChanOps.pm +++ b/PBot/ChanOps.pm @@ -190,20 +190,8 @@ sub unmode_user { $self->check_unban_queue if $immediately; } -sub unban_user { - my ($self, $mask, $channel, $immediately) = @_; - $mask = lc $mask; - $channel = lc $channel; - $self->{pbot}->{logger}->log("Unbanning $channel $mask\n"); - $self->unmode_user($mask, $channel, $immediately, 'b'); -} - -sub ban_user_timed { - my $self = shift; - my ($mask, $channel, $length, $immediately) = @_; - - $channel = lc $channel; - $mask = lc $mask; +sub nick_to_banmask { + my ($self, $mask) = @_; if ($mask !~ m/[!@\$]/) { my ($message_account, $hostmask) = $self->{pbot}->{messagehistory}->{database}->find_message_account_by_nick($mask); @@ -219,7 +207,25 @@ sub ban_user_timed { $mask .= '!*@*'; } } + return $mask; +} +sub unban_user { + my ($self, $mask, $channel, $immediately) = @_; + $mask = lc $mask; + $channel = lc $channel; + $self->{pbot}->{logger}->log("Unbanning $channel $mask\n"); + $self->unmode_user($mask, $channel, $immediately, 'b'); +} + +sub ban_user_timed { + my $self = shift; + my ($mask, $channel, $length, $immediately) = @_; + + $channel = lc $channel; + $mask = lc $mask; + + $mask = $self->nick_to_banmask($mask); $self->ban_user($mask, $channel, $immediately); if ($length > 0) { @@ -258,8 +264,9 @@ sub mute_user_timed { $channel = lc $channel; $mask = lc $mask; - $mask .= '!*@*' if $mask !~ m/[\$!@]/; + $mask = $self->nick_to_banmask($mask); $self->mute_user($mask, $channel, $immediately); + if ($length > 0) { $self->{unmute_timeout}->hash->{$channel}->{$mask}{timeout} = gettimeofday + $length; $self->{unmute_timeout}->save;