mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-25 05:19:29 +01:00
Refactor ban/unmute commands
This commit is contained in:
parent
c9112ac809
commit
b04c06f396
16
doc/Admin.md
16
doc/Admin.md
@ -498,18 +498,20 @@ Bans or mutes a user. If the argument is a nick instead of a hostmask, it will d
|
||||
The argument can be a comma-separated list of multiple nicks or masks.
|
||||
|
||||
Usages:
|
||||
- `ban <nick or hostmask> [channel [timeout]]`
|
||||
- `mute <nick or hostmask> [channel [timeout]]`
|
||||
- `ban <mask> [timeout (default: 24h) [reason]] [-c <channel>] [-t <timeout>] [-r <reason>]`
|
||||
- `mute <mask> [timeout (default: 24h) [reason]] [-c <channel>] [-t <timeout>] [-r <reason>]`
|
||||
|
||||
If `timeout` is omitted, PBot will ban the user for 24 hours. Timeout can be specified as an relative time in English; for instance, `5 minutes`, `1 month and 2 weeks`, `next thursday`, `friday after next`, `forever` and such.
|
||||
|
||||
If a ban already exists, you may update the timeout or reason at any time.
|
||||
|
||||
### unban/unmute
|
||||
Unbans or unmutes a user. If the argument is a nick instead of a hostmask, it will find all bans that match any of that nick's hostmasks or NickServ accounts and unban them.
|
||||
The argument can be a comma-separated list of multiple nicks or masks. If the argument is `*` then all bans/mutes for the channel will be removed.
|
||||
|
||||
Usages:
|
||||
- `unban <nick or hostmask> [channel]`
|
||||
- `unmute <nick or hostmask> [channel]`
|
||||
- `unban <nick/hostmask,...> [channel]`
|
||||
- `unmute <nick/hostmask,...> [channel]`
|
||||
|
||||
### checkban
|
||||
The `checkban` command displays information about an entry in PBot's internal banlist. PBot's internal banlist
|
||||
@ -523,7 +525,7 @@ If the `[channel]` option is omitted, the channel in which the command is invoke
|
||||
Example:
|
||||
|
||||
<pragma-> checkban loser!*@*
|
||||
<PBot> loser!*@* banned in #c on Tue Aug 31 06:41:24 2021 PDT (14d15h ago) by candide!~pbot3@about/c/bot/candide for chat-flooding (2h remaining)
|
||||
<PBot> loser!*@* banned in #c on Tue Aug 31 06:41:24 2021 PDT (14d15h ago) by candide!~pbot3@about/c/bot/candide because chat-flooding (2h remaining)
|
||||
|
||||
### checkmute
|
||||
The `checkmute` command is identical to the [`checkban`](#checkban) command, except for mutes instead of bans.
|
||||
@ -538,8 +540,8 @@ Usage: `invite [channel] <nick>`
|
||||
### kick
|
||||
Removes a user from the channel. `<nick>` can be a comma-separated list of multiple users, optionally containing wildcards. If `[reason]` is omitted, a random insult will be used.
|
||||
|
||||
Usage from channel: `kick <nick> [reason]`
|
||||
From private message: `kick <channel> <nick> [reason]`
|
||||
Usage from channel: `kick <nick,...> [reason]`
|
||||
From private message: `kick <channel> <nick,...> [reason]`
|
||||
|
||||
## Applet-management
|
||||
Note that applets are "reloaded" each time they are executed. There is no need to `refresh` after editing an applet.
|
||||
|
@ -83,7 +83,7 @@ sub checkban($self, $channel, $mode, $mask) {
|
||||
}
|
||||
|
||||
$result .= "by $data->{owner} " if defined $data->{owner};
|
||||
$result .= "for $data->{reason} " if defined $data->{reason};
|
||||
$result .= "because $data->{reason} " if defined $data->{reason};
|
||||
|
||||
if (exists $data->{timeout} and $data->{timeout} > 0) {
|
||||
my $duration = concise duration($data->{timeout} - gettimeofday);
|
||||
|
@ -25,7 +25,6 @@ sub initialize($self, %conf) {
|
||||
|
||||
# add capability to admin group
|
||||
$self->{pbot}->{capabilities}->add('admin', 'can-ban-exempt', 1);
|
||||
|
||||
}
|
||||
|
||||
sub cmd_banlist($self, $context) {
|
||||
@ -49,7 +48,7 @@ sub cmd_banlist($self, $context) {
|
||||
}
|
||||
|
||||
$result .= "by $data->{owner} " if defined $data->{owner};
|
||||
$result .= "for $data->{reason} " if defined $data->{reason};
|
||||
$result .= "because $data->{reason} " if defined $data->{reason};
|
||||
if (defined $data->{timeout} and $data->{timeout} > 0) {
|
||||
my $duration = concise duration($data->{timeout} - gettimeofday);
|
||||
$result .= "($duration remaining)";
|
||||
@ -74,7 +73,7 @@ sub cmd_banlist($self, $context) {
|
||||
}
|
||||
|
||||
$result .= "by $data->{owner} " if defined $data->{owner};
|
||||
$result .= "for $data->{reason} " if defined $data->{reason};
|
||||
$result .= "because $data->{reason} " if defined $data->{reason};
|
||||
if (defined $data->{timeout} and $data->{timeout} > 0) {
|
||||
my $duration = concise duration($data->{timeout} - gettimeofday);
|
||||
$result .= "($duration remaining)";
|
||||
|
@ -337,81 +337,7 @@ sub cmd_mode($self, $context) {
|
||||
}
|
||||
|
||||
sub cmd_ban($self, $context) {
|
||||
my ($target, $channel, $length) = $self->{pbot}->{interpreter}->split_args($context->{arglist}, 3);
|
||||
|
||||
$channel = '' if not defined $channel;
|
||||
$length = '' if not defined $length;
|
||||
|
||||
if (not defined $context->{from}) {
|
||||
$self->{pbot}->{logger}->log("Command missing ~from parameter!\n");
|
||||
return "";
|
||||
}
|
||||
|
||||
if ($channel !~ m/^#/) {
|
||||
$length = "$channel $length";
|
||||
$length = undef if $length eq ' ';
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from};
|
||||
}
|
||||
|
||||
if (not defined $channel or not length $channel) {
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from};
|
||||
}
|
||||
|
||||
if (not defined $target) { return "Usage: ban <mask> [channel [timeout (default: 24 hours)]]"; }
|
||||
|
||||
my $no_length = 0;
|
||||
if (not defined $length) {
|
||||
# TODO: user account length override
|
||||
$length = $self->{pbot}->{registry}->get_value($channel, 'default_ban_timeout', 0, $context)
|
||||
// $self->{pbot}->{registry}->get_value('general', 'default_ban_timeout', 0, $context) // 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;
|
||||
|
||||
my $result = '';
|
||||
my $sep = '';
|
||||
my @targets = split /,/, $target;
|
||||
my $immediately = @targets > 1 ? 0 : 1;
|
||||
my $duration;
|
||||
|
||||
foreach my $t (@targets) {
|
||||
my $mask = lc $self->{pbot}->{banlist}->nick_to_banmask($t);
|
||||
|
||||
my $timeout = $self->{pbot}->{banlist}->{banlist}->get_data($channel, $mask, 'timeout') // 0;
|
||||
|
||||
if ($no_length && $timeout > 0) {
|
||||
my $d = duration($timeout - gettimeofday);
|
||||
$result .= "$sep$mask has $d remaining on their $channel ban";
|
||||
$sep = '; ';
|
||||
} else {
|
||||
$self->{pbot}->{banlist}->ban_user_timed($channel, 'b', $mask, $length, $context->{hostmask}, undef, $immediately);
|
||||
$duration = $length > 0 ? duration $length : 'all eternity';
|
||||
if ($immediately) {
|
||||
$result .= "$sep$mask banned in $channel for $duration";
|
||||
$sep = '; ';
|
||||
} else {
|
||||
$result .= "$sep$mask";
|
||||
$sep = ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (not $immediately) {
|
||||
$result .= " banned in $channel for $duration";
|
||||
$self->{pbot}->{banlist}->flush_ban_queue;
|
||||
}
|
||||
|
||||
$result = "/msg $context->{nick} $result" if $result !~ m/remaining on their/;
|
||||
return $result;
|
||||
return do_ban_or_mute($self, $context, 'ban');
|
||||
}
|
||||
|
||||
sub cmd_unban($self, $context) {
|
||||
@ -428,7 +354,7 @@ sub cmd_unban($self, $context) {
|
||||
$channel = $temp;
|
||||
}
|
||||
|
||||
if (not defined $target) { return "Usage: unban <nick/mask> [channel [false value to use unban queue]]"; }
|
||||
if (not defined $target) { return "Usage: unban <nick/mask,...> [channel [false value to use unban queue]]"; }
|
||||
|
||||
if (not defined $channel) {
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from};
|
||||
@ -436,7 +362,7 @@ sub cmd_unban($self, $context) {
|
||||
|
||||
$immediately = 1 if not defined $immediately;
|
||||
|
||||
return "Usage for /msg: unban <nick/mask> <channel> [false value to use unban queue]" if $channel !~ /^#/;
|
||||
return "Usage: unban <nick/mask,...> <channel> [false value to use unban queue]" if $channel !~ /^#/;
|
||||
|
||||
my @targets = split /,/, $target;
|
||||
$immediately = 0 if @targets > 1;
|
||||
@ -465,83 +391,7 @@ sub cmd_unban($self, $context) {
|
||||
}
|
||||
|
||||
sub cmd_mute($self, $context) {
|
||||
my ($target, $channel, $length) = $self->{pbot}->{interpreter}->split_args($context->{arglist}, 3);
|
||||
|
||||
$channel = '' if not defined $channel;
|
||||
|
||||
if (not defined $context->{from}) {
|
||||
$self->{pbot}->{logger}->log("Command missing ~from parameter!\n");
|
||||
return "";
|
||||
}
|
||||
|
||||
if (not length $channel and $context->{from} !~ m/^#/) {
|
||||
return "Usage from private message: mute <mask> <channel> [timeout (default: 24 hours)]";
|
||||
}
|
||||
|
||||
if ($channel !~ m/^#/) {
|
||||
$length = $channel . ' ' . (defined $length ? $length : '');
|
||||
$length = undef if $length eq ' ';
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from};
|
||||
}
|
||||
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from} if not defined $channel;
|
||||
|
||||
if ($channel !~ m/^#/) { return "Please specify a channel."; }
|
||||
|
||||
if (not defined $target) { return "Usage: mute <mask> [channel [timeout (default: 24 hours)]]"; }
|
||||
|
||||
my $no_length = 0;
|
||||
if (not defined $length) {
|
||||
$length = $self->{pbot}->{registry}->get_value($channel, 'default_mute_timeout', 0, $context)
|
||||
// $self->{pbot}->{registry}->get_value('general', 'default_mute_timeout', 0, $context) // 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;
|
||||
|
||||
my $result = '';
|
||||
my $sep = '';
|
||||
my @targets = split /,/, $target;
|
||||
my $immediately = @targets > 1 ? 0 : 1;
|
||||
my $duration;
|
||||
|
||||
foreach my $t (@targets) {
|
||||
my $mask = lc $self->{pbot}->{banlist}->nick_to_banmask($t);
|
||||
|
||||
my $timeout = $self->{pbot}->{banlist}->{quietlist}->get_data($channel, $mask, 'timeout') // 0;
|
||||
|
||||
if ($no_length && $timeout > 0) {
|
||||
my $d = duration($timeout - gettimeofday);
|
||||
$result .= "$sep$mask has $d remaining on their $channel mute";
|
||||
$sep = '; ';
|
||||
} else {
|
||||
$self->{pbot}->{banlist}->ban_user_timed($channel, 'q', $t, $length, $context->{hostmask}, undef, $immediately);
|
||||
$duration = $length > 0 ? duration $length : 'all eternity';
|
||||
if ($immediately) {
|
||||
$result .= "$sep$mask muted in $channel for $duration";
|
||||
$sep = '; ';
|
||||
} else {
|
||||
$result .= "$sep$mask";
|
||||
$sep = ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (not $immediately) {
|
||||
$result .= " muted in $channel for $duration";
|
||||
$self->{pbot}->{banlist}->flush_ban_queue;
|
||||
}
|
||||
|
||||
$result = "/msg $context->{nick} $result" if $result !~ m/remaining on their/;
|
||||
return $result;
|
||||
return do_ban_or_mute($self, $context, 'mute');
|
||||
}
|
||||
|
||||
sub cmd_unmute($self, $context) {
|
||||
@ -558,12 +408,12 @@ sub cmd_unmute($self, $context) {
|
||||
$channel = $temp;
|
||||
}
|
||||
|
||||
if (not defined $target) { return "Usage: unmute <nick/mask> [channel [false value to use unban queue]]"; }
|
||||
if (not defined $target) { return "Usage: unmute <nick/mask,...> [channel [false value to use unban queue]]"; }
|
||||
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from} if not defined $channel;
|
||||
$immediately = 1 if not defined $immediately;
|
||||
|
||||
return "Usage for /msg: unmute <nick/mask> <channel> [false value to use unban queue]" if $channel !~ /^#/;
|
||||
return "Usage for /msg: unmute <nick/mask,...> <channel> [false value to use unban queue]" if $channel !~ /^#/;
|
||||
|
||||
my @targets = split /,/, $target;
|
||||
$immediately = 0 if @targets > 1;
|
||||
@ -597,13 +447,13 @@ sub cmd_kick($self, $context) {
|
||||
|
||||
if (not $context->{from} =~ /^#/) {
|
||||
# used in private message
|
||||
if (not $arguments =~ s/^(^#\S+) (\S+)\s*//) { return "Usage from private message: kick <channel> <nick[,nicks...]> [reason]; <nick> may include wildcards"; }
|
||||
if (not $arguments =~ s/^(^#\S+) (\S+)\s*//) { return "Usage from private message: kick <channel> <nick,...> [reason]; <nick> may include wildcards"; }
|
||||
($channel, $victim) = ($1, $2);
|
||||
} else {
|
||||
# used in channel
|
||||
if ($arguments =~ s/^(#\S+)\s+(\S+)\s*//) { ($channel, $victim) = ($1, $2); }
|
||||
elsif ($arguments =~ s/^(\S+)\s*//) { ($victim, $channel) = ($1, exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from}); }
|
||||
else { return "Usage: kick [channel] <nick[,nicks...]> [reason]; <nick> may include wildcards"; }
|
||||
else { return "Usage: kick [channel] <nick,...> [reason]; <nick> may include wildcards"; }
|
||||
}
|
||||
|
||||
$reason = $arguments;
|
||||
@ -672,4 +522,131 @@ sub cmd_kick($self, $context) {
|
||||
return "";
|
||||
}
|
||||
|
||||
sub do_ban_or_mute($self, $context, $mode) {
|
||||
my ($target, $channel, $length, $reason);
|
||||
|
||||
my $usage = "usage: $mode <mask,...> [timeout (default: 24h) [reason]] [-c <channel>] [-t <timeout>] [-r <reason>]";
|
||||
|
||||
my %opts = (
|
||||
channel => \$channel,
|
||||
timeout => \$length,
|
||||
reason => \$reason,
|
||||
);
|
||||
|
||||
my ($opt_args, $opt_error) = $self->{pbot}->{interpreter}->getopt(
|
||||
$context->{arguments},
|
||||
\%opts,
|
||||
['bundling'],
|
||||
'channel|c=s',
|
||||
'timeout|t=s',
|
||||
'reason|r=s',
|
||||
);
|
||||
|
||||
return "$opt_error -- $usage" if defined $opt_error;
|
||||
|
||||
$target = shift @$opt_args;
|
||||
$length = shift @$opt_args if not defined $length;
|
||||
$reason = "@$opt_args" if not defined $reason;
|
||||
|
||||
$channel = '' if not defined $channel;
|
||||
$length = '' if not defined $length;
|
||||
|
||||
$reason = undef if not length $reason;
|
||||
|
||||
if (not defined $target) {
|
||||
return $usage;
|
||||
}
|
||||
|
||||
if (not length $channel) {
|
||||
$channel = exists $context->{admin_channel_override} ? $context->{admin_channel_override} : $context->{from};
|
||||
}
|
||||
|
||||
if ($channel eq $context->{nick}) {
|
||||
return "Channel argument is required in private-message; $usage";
|
||||
}
|
||||
|
||||
if ($channel !~ m/^#/) {
|
||||
return "Bad channel '$channel'; $usage";
|
||||
}
|
||||
|
||||
my $error;
|
||||
($length, $error) = $self->{pbot}->{parsedate}->parsedate($length);
|
||||
return $error if defined $error;
|
||||
|
||||
$channel = lc $channel;
|
||||
$target = lc $target;
|
||||
|
||||
my $result = '';
|
||||
my $sep = '';
|
||||
my @targets = split /,/, $target;
|
||||
my $immediately = @targets > 1 ? 0 : 1;
|
||||
my $duration;
|
||||
|
||||
foreach my $t (@targets) {
|
||||
my $mask = lc $self->{pbot}->{banlist}->nick_to_banmask($t);
|
||||
|
||||
my $ban = $self->{pbot}->{banlist}->{banlist}->get_data($channel, $mask);
|
||||
|
||||
if (defined $ban) {
|
||||
my $save = 0;
|
||||
|
||||
if (defined $reason) {
|
||||
$ban->{reason} = $reason;
|
||||
$save = 1;
|
||||
}
|
||||
|
||||
if ($length) {
|
||||
$ban->{timeout} = gettimeofday + $length;
|
||||
$save = 1;
|
||||
}
|
||||
|
||||
$self->{pbot}->{banlist}->{banlist}->save if $save;
|
||||
|
||||
$result .= "$sep$mask ";
|
||||
|
||||
if (not $save) {
|
||||
$result .= 'is already ';
|
||||
}
|
||||
|
||||
$result .= ($mode eq 'ban' ? 'banned' : 'muted') . " in $channel";
|
||||
|
||||
if (defined $ban->{reason}) {
|
||||
$result .= " because $ban->{reason}";
|
||||
}
|
||||
|
||||
if ($ban->{timeout} > 0) {
|
||||
my $d = duration($ban->{timeout} - gettimeofday);
|
||||
$result .= " ($d remaining)";
|
||||
}
|
||||
|
||||
$sep = '; ';
|
||||
} else {
|
||||
if (not $length) {
|
||||
# TODO: user account length override
|
||||
$length = $self->{pbot}->{registry}->get_value($channel, "default_${mode}_timeout", 0, $context)
|
||||
// $self->{pbot}->{registry}->get_value('general', "default_${mode}_timeout", 0, $context) // 60 * 60 * 24; # 24 hours
|
||||
}
|
||||
|
||||
$self->{pbot}->{banlist}->ban_user_timed($channel, $mode eq 'ban' ? 'b' : 'q', $mask, $length, $context->{hostmask}, $reason, $immediately);
|
||||
$duration = $length > 0 ? duration $length : 'all eternity';
|
||||
if ($immediately) {
|
||||
$result .= "$sep$mask " . ($mode eq 'ban' ? 'banned' : 'muted') . " in $channel ($duration)";
|
||||
$result .= " because $reason" if defined $reason;
|
||||
$sep = '; ';
|
||||
} else {
|
||||
$result .= "$sep$mask";
|
||||
$sep = ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (not $immediately) {
|
||||
$result .= ($mode eq 'ban' ? ' banned' : ' muted') . " in $channel for $duration";
|
||||
$self->{pbot}->{banlist}->flush_ban_queue;
|
||||
}
|
||||
|
||||
$result = "/msg $context->{nick} $result" if $result !~ m/remaining/;
|
||||
return $result;
|
||||
}
|
||||
|
||||
1;
|
||||
|
@ -25,7 +25,7 @@ use PBot::Imports;
|
||||
# These are set by the /misc/update_version script
|
||||
use constant {
|
||||
BUILD_NAME => "PBot",
|
||||
BUILD_REVISION => 4655,
|
||||
BUILD_REVISION => 4656,
|
||||
BUILD_DATE => "2023-05-04",
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user