2021-06-05 22:36:51 +02:00
|
|
|
# File: MiscCommands.pm
|
2021-06-05 22:20:03 +02:00
|
|
|
#
|
2021-06-19 06:23:34 +02:00
|
|
|
# Purpose: Registers misc PBot commands that don't really belong in any
|
|
|
|
# other file.
|
2021-06-05 22:20:03 +02:00
|
|
|
|
2021-07-11 00:00:22 +02:00
|
|
|
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
|
|
|
|
# SPDX-License-Identifier: MIT
|
2021-06-05 22:20:03 +02:00
|
|
|
|
|
|
|
package PBot::MiscCommands;
|
|
|
|
use parent 'PBot::Class';
|
|
|
|
|
2021-06-19 06:23:34 +02:00
|
|
|
use PBot::Imports;
|
2021-06-05 22:20:03 +02:00
|
|
|
|
|
|
|
use Time::Duration qw/duration/;
|
|
|
|
|
|
|
|
sub initialize {
|
|
|
|
my ($self, %conf) = @_;
|
|
|
|
|
|
|
|
# misc commands
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_nop(@_) }, 'nop', 0);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_uptime(@_) }, 'uptime', 0);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_in_channel(@_) }, 'in', 0);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_list(@_) }, 'list', 0);
|
|
|
|
|
|
|
|
# misc administrative commands
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_sl(@_) }, 'sl', 1);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_die(@_) }, 'die', 1);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_export(@_) }, 'export', 1);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_eval(@_) }, 'eval', 1);
|
|
|
|
$self->{pbot}->{commands}->register(sub { $self->cmd_reload(@_) }, 'reload', 1);
|
|
|
|
|
|
|
|
# misc capabilities
|
|
|
|
$self->{pbot}->{capabilities}->add('admin', 'can-in', 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_nop {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
$self->{pbot}->{logger}->log("Disregarding NOP command.\n");
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_uptime {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
return localtime($self->{pbot}->{startup_timestamp}) . ' [' . duration(time - $self->{pbot}->{startup_timestamp}) . ']';
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_in_channel {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
|
|
|
|
my $usage = 'Usage: in <channel> <command>';
|
2021-06-11 23:58:16 +02:00
|
|
|
|
|
|
|
if (not length $context->{arguments}) {
|
|
|
|
return $usage;
|
|
|
|
}
|
2021-06-05 22:20:03 +02:00
|
|
|
|
|
|
|
my ($channel, $command) = $self->{pbot}->{interpreter}->split_args($context->{arglist}, 2, 0, 1);
|
|
|
|
|
2021-06-11 23:58:16 +02:00
|
|
|
if (not defined $channel or not defined $command) {
|
|
|
|
return $usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
# invoker must be present in that channel
|
2021-06-05 22:20:03 +02:00
|
|
|
if (not $self->{pbot}->{nicklist}->is_present($channel, $context->{nick})) {
|
|
|
|
return "You must be present in $channel to do this.";
|
|
|
|
}
|
|
|
|
|
2021-06-11 23:58:16 +02:00
|
|
|
# update context with new channel and command
|
2021-06-05 22:20:03 +02:00
|
|
|
$context->{from} = $channel;
|
|
|
|
$context->{command} = $command;
|
2021-06-11 23:58:16 +02:00
|
|
|
|
|
|
|
# perform the command and return the result
|
2021-06-05 22:20:03 +02:00
|
|
|
return $self->{pbot}->{interpreter}->interpret($context);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_list {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
my $text;
|
|
|
|
|
|
|
|
my $usage = 'Usage: list <modules|commands>';
|
|
|
|
|
|
|
|
return $usage if not length $context->{arguments};
|
|
|
|
|
|
|
|
if ($context->{arguments} =~ /^modules$/i) {
|
|
|
|
$text = 'Loaded modules: ';
|
2021-07-09 23:39:35 +02:00
|
|
|
foreach my $channel (sort $self->{pbot}->{factoids}->{storage}->get_keys) {
|
|
|
|
foreach my $command (sort $self->{pbot}->{factoids}->{storage}->get_keys($channel)) {
|
2021-06-05 22:20:03 +02:00
|
|
|
next if $command eq '_name';
|
2021-07-09 23:39:35 +02:00
|
|
|
if ($self->{pbot}->{factoids}->{storage}->get_data($channel, $command, 'type') eq 'module') {
|
|
|
|
$text .= $self->{pbot}->{factoids}->{storage}->get_data($channel, $command, '_name') . ' ';
|
2021-06-05 22:20:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($context->{arguments} =~ /^commands$/i) {
|
|
|
|
$text = 'Registered commands: ';
|
|
|
|
foreach my $command (sort { $a->{name} cmp $b->{name} } @{$self->{pbot}->{commands}->{handlers}}) {
|
|
|
|
if ($command->{requires_cap}) {
|
|
|
|
$text .= "+$command->{name} ";
|
|
|
|
} else {
|
|
|
|
$text .= "$command->{name} ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_sl {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
return "Usage: sl <ircd command>" if not length $context->{arguments};
|
|
|
|
$self->{pbot}->{conn}->sl($context->{arguments});
|
|
|
|
return "/msg $context->{nick} sl: command sent. See log for result.";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_die {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
$self->{pbot}->{logger}->log("$context->{hostmask} made me exit.\n");
|
|
|
|
$self->{pbot}->{conn}->privmsg($context->{from}, "Good-bye.") if $context->{from} ne 'stdin@pbot';
|
|
|
|
$self->{pbot}->{conn}->quit("Departure requested.") if defined $self->{pbot}->{conn};
|
2021-06-12 01:49:56 +02:00
|
|
|
$self->{pbot}->atexit();
|
2021-06-05 22:20:03 +02:00
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_export {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
return "Usage: export <factoids>" if not length $context->{arguments};
|
|
|
|
if ($context->{arguments} =~ /^factoids$/i) { return $self->{pbot}->{factoids}->export_factoids; }
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_eval {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
|
|
|
|
$self->{pbot}->{logger}->log("eval: $context->{from} $context->{hostmask} evaluating `$context->{arguments}`\n");
|
|
|
|
|
|
|
|
my $ret = '';
|
|
|
|
my $result = eval $context->{arguments};
|
|
|
|
if ($@) {
|
|
|
|
if (length $result) { $ret .= "[Error: $@] "; }
|
|
|
|
else { $ret .= "Error: $@"; }
|
|
|
|
$ret =~ s/ at \(eval \d+\) line 1.//;
|
|
|
|
}
|
|
|
|
$result = 'Undefined.' if not defined $result;
|
|
|
|
$result = 'No output.' if not length $result;
|
|
|
|
return "/say $ret $result";
|
|
|
|
}
|
|
|
|
|
|
|
|
sub cmd_reload {
|
|
|
|
my ($self, $context) = @_;
|
|
|
|
|
|
|
|
my %reloadables = (
|
|
|
|
'capabilities' => sub {
|
|
|
|
$self->{pbot}->{capabilities}->{caps}->load;
|
|
|
|
return "Capabilities reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'commands' => sub {
|
|
|
|
$self->{pbot}->{commands}->{metadata}->load;
|
|
|
|
return "Commands metadata reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'blacklist' => sub {
|
|
|
|
$self->{pbot}->{blacklist}->clear_blacklist;
|
|
|
|
$self->{pbot}->{blacklist}->load_blacklist;
|
|
|
|
return "Blacklist reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'ban-exemptions' => sub {
|
|
|
|
$self->{pbot}->{antiflood}->{'ban-exemptions'}->load;
|
|
|
|
return "Ban exemptions reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'ignores' => sub {
|
2021-07-09 23:39:35 +02:00
|
|
|
$self->{pbot}->{ignorelist}->{storage}->load;
|
2021-06-05 22:20:03 +02:00
|
|
|
return "Ignore list reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'users' => sub {
|
|
|
|
$self->{pbot}->{users}->load;
|
|
|
|
return "Users reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'channels' => sub {
|
2021-07-09 23:39:35 +02:00
|
|
|
$self->{pbot}->{channels}->{storage}->load;
|
2021-06-05 22:20:03 +02:00
|
|
|
return "Channels reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'banlist' => sub {
|
2021-06-22 02:26:24 +02:00
|
|
|
$self->{pbot}->{event_queue}->dequeue_event('unban #.*');
|
|
|
|
$self->{pbot}->{event_queue}->dequeue_event('unmute #.*');
|
2021-06-05 22:20:03 +02:00
|
|
|
$self->{pbot}->{banlist}->{banlist}->load;
|
|
|
|
$self->{pbot}->{banlist}->{quietlist}->load;
|
|
|
|
$self->{pbot}->{banlist}->enqueue_timeouts($self->{pbot}->{banlist}->{banlist}, 'b');
|
|
|
|
$self->{pbot}->{banlist}->enqueue_timeouts($self->{pbot}->{banlist}->{quietlist}, 'q');
|
|
|
|
return "Ban list reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'registry' => sub {
|
|
|
|
$self->{pbot}->{registry}->load;
|
|
|
|
return "Registry reloaded.";
|
|
|
|
},
|
|
|
|
|
|
|
|
'factoids' => sub {
|
|
|
|
$self->{pbot}->{factoids}->load_factoids;
|
|
|
|
return "Factoids reloaded.";
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
if (not length $context->{arguments} or not exists $reloadables{$context->{arguments}}) {
|
|
|
|
my $usage = 'Usage: reload <';
|
|
|
|
$usage .= join '|', sort keys %reloadables;
|
|
|
|
$usage .= '>';
|
|
|
|
return $usage;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $reloadables{$context->{arguments}}();
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|