mirror of
https://github.com/pragma-/pbot.git
synced 2024-11-19 10:29:30 +01:00
Use event queue for unban/unmute timeouts
This commit is contained in:
parent
f5927c8761
commit
c815ccbc0d
@ -83,6 +83,7 @@ sub on_banlist_entry {
|
|||||||
reason => 'Temp ban on *!*@... or *!...@gateway/web'
|
reason => 'Temp ban on *!*@... or *!...@gateway/web'
|
||||||
};
|
};
|
||||||
$self->{pbot}->{chanops}->{unban_timeout}->add($channel, $target, $data);
|
$self->{pbot}->{chanops}->{unban_timeout}->add($channel, $target, $data);
|
||||||
|
$self->{pbot}->{chanops}->enqueue_unban_timeout($channel, $target, $timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,13 +205,22 @@ sub track_mode {
|
|||||||
delete $self->{banlist}->{$channel}->{$mode eq "-b" ? "+b" : "+q"}->{$target};
|
delete $self->{banlist}->{$channel}->{$mode eq "-b" ? "+b" : "+q"}->{$target};
|
||||||
|
|
||||||
if ($mode eq "-b") {
|
if ($mode eq "-b") {
|
||||||
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, $target)) { $self->{pbot}->{chanops}->{unban_timeout}->remove($channel, $target); }
|
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, $target)) {
|
||||||
|
$self->{pbot}->{chanops}->{unban_timeout}->remove($channel, $target);
|
||||||
|
$self->{pbot}->{timer}->dequeue_event("unban_timeout $channel $target");
|
||||||
|
}
|
||||||
elsif ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, "$target\$##stop_join_flood")) {
|
elsif ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, "$target\$##stop_join_flood")) {
|
||||||
# freenode strips channel forwards from unban result if no ban exists with a channel forward
|
# freenode strips channel forwards from unban result if no ban exists with a channel forward
|
||||||
$self->{pbot}->{chanops}->{unban_timeout}->remove($channel, "$target\$##stop_join_flood");
|
$self->{pbot}->{chanops}->{unban_timeout}->remove($channel, "$target\$##stop_join_flood");
|
||||||
|
$self->{pbot}->{timer}->dequeue_event(lc "unban_timeout $channel $target\$##stop_join_flood");
|
||||||
}
|
}
|
||||||
} elsif ($mode eq "-q") {
|
} elsif ($mode eq "-q") {
|
||||||
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($channel, $target)) { $self->{pbot}->{chanops}->{unmute_timeout}->remove($channel, $target); }
|
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($channel, $target)) {
|
||||||
|
$self->{pbot}->{chanops}->{unmute_timeout}->remove($channel, $target);
|
||||||
|
$self->{pbot}->{timer}->dequeue_event("unmute_timeout $channel $target");
|
||||||
|
} else {
|
||||||
|
$self->{pbot}->{logger}->log("No unmute timeout for $channel $target\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$self->{pbot}->{logger}->log("BanTracker: Unknown mode '$mode'\n");
|
$self->{pbot}->{logger}->log("BanTracker: Unknown mode '$mode'\n");
|
||||||
|
@ -37,6 +37,8 @@ sub initialize {
|
|||||||
|
|
||||||
$self->{unmute_timeout}->load;
|
$self->{unmute_timeout}->load;
|
||||||
|
|
||||||
|
$self->enqueue_timeouts;
|
||||||
|
|
||||||
$self->{ban_queue} = {};
|
$self->{ban_queue} = {};
|
||||||
$self->{unban_queue} = {};
|
$self->{unban_queue} = {};
|
||||||
|
|
||||||
@ -48,8 +50,6 @@ sub initialize {
|
|||||||
|
|
||||||
$self->{pbot}->{registry}->add_default('text', 'general', 'deop_timeout', 300);
|
$self->{pbot}->{registry}->add_default('text', 'general', 'deop_timeout', 300);
|
||||||
|
|
||||||
$self->{pbot}->{timer}->register(sub { $self->check_unban_timeouts }, 10);
|
|
||||||
$self->{pbot}->{timer}->register(sub { $self->check_unmute_timeouts }, 10);
|
|
||||||
$self->{pbot}->{timer}->register(sub { $self->check_opped_timeouts }, 10, 'Check Opped Timeouts');
|
$self->{pbot}->{timer}->register(sub { $self->check_opped_timeouts }, 10, 'Check Opped Timeouts');
|
||||||
$self->{pbot}->{timer}->register(sub { $self->check_unban_queue }, 30, 'Check Unban Queue');
|
$self->{pbot}->{timer}->register(sub { $self->check_unban_queue }, 30, 'Check Unban Queue');
|
||||||
}
|
}
|
||||||
@ -210,8 +210,7 @@ sub unban_user {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub ban_user_timed {
|
sub ban_user_timed {
|
||||||
my $self = shift;
|
my ($self, $owner, $reason, $mask, $channel, $length, $immediately) = @_;
|
||||||
my ($owner, $reason, $mask, $channel, $length, $immediately) = @_;
|
|
||||||
|
|
||||||
$channel = lc $channel;
|
$channel = lc $channel;
|
||||||
$mask = lc $mask;
|
$mask = lc $mask;
|
||||||
@ -224,8 +223,12 @@ sub ban_user_timed {
|
|||||||
$data->{owner} = $owner if defined $owner;
|
$data->{owner} = $owner if defined $owner;
|
||||||
$data->{reason} = $reason if defined $reason;
|
$data->{reason} = $reason if defined $reason;
|
||||||
$self->{unban_timeout}->add($channel, $mask, $data);
|
$self->{unban_timeout}->add($channel, $mask, $data);
|
||||||
|
$self->enqueue_unban_timeout($channel, $mask, $length);
|
||||||
} else {
|
} else {
|
||||||
if ($self->{unban_timeout}->exists($channel, $mask)) { $self->{unban_timeout}->remove($channel, $mask); }
|
if ($self->{unban_timeout}->exists($channel, $mask)) {
|
||||||
|
$self->{unban_timeout}->remove($channel, $mask);
|
||||||
|
$self->{pbot}->{timer}->dequeue_event("unban_timeout $channel $mask");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,12 +276,16 @@ sub mute_user_timed {
|
|||||||
$self->mute_user($mask, $channel, $immediately);
|
$self->mute_user($mask, $channel, $immediately);
|
||||||
|
|
||||||
if ($length > 0) {
|
if ($length > 0) {
|
||||||
my $data = {timeout => gettimeofday + $length};
|
my $data = { timeout => gettimeofday + $length };
|
||||||
$data->{owner} = $owner if defined $owner;
|
$data->{owner} = $owner if defined $owner;
|
||||||
$data->{reason} = $reason if defined $reason;
|
$data->{reason} = $reason if defined $reason;
|
||||||
$self->{unmute_timeout}->add($channel, $mask, $data);
|
$self->{unmute_timeout}->add($channel, $mask, $data);
|
||||||
|
$self->enqueue_unmute_timeout($channel, $mask, $length);
|
||||||
} else {
|
} else {
|
||||||
if ($self->{unmute_timeout}->exists($channel, $mask)) { $self->{unmute_timeout}->remove($channel, $mask); }
|
if ($self->{unmute_timeout}->exists($channel, $mask)) {
|
||||||
|
$self->{unmute_timeout}->remove($channel, $mask);
|
||||||
|
$self->{pbot}->{timer}->dequeue_event("unmute_timeout $channel $mask");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,8 +398,10 @@ sub check_ban_queue {
|
|||||||
|
|
||||||
sub add_to_unban_queue {
|
sub add_to_unban_queue {
|
||||||
my ($self, $channel, $mode, $target) = @_;
|
my ($self, $channel, $mode, $target) = @_;
|
||||||
push @{$self->{unban_queue}->{$channel}->{$mode}}, $target;
|
if (not grep { $_ eq $target } @{$self->{unban_queue}->{$channel}->{$mode}}) {
|
||||||
$self->{pbot}->{logger}->log("Added -$mode $target for $channel to unban queue.\n");
|
push @{$self->{unban_queue}->{$channel}->{$mode}}, $target;
|
||||||
|
$self->{pbot}->{logger}->log("Added -$mode $target for $channel to unban queue.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_unban_queue {
|
sub check_unban_queue {
|
||||||
@ -437,34 +446,62 @@ sub check_unban_queue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_unban_timeouts {
|
sub enqueue_unmute_timeout {
|
||||||
my $self = shift;
|
my ($self, $channel, $hostmask, $interval) = @_;
|
||||||
return if not $self->{pbot}->{joined_channels};
|
|
||||||
my $now = gettimeofday();
|
$self->{pbot}->{timer}->enqueue_event(
|
||||||
foreach my $channel ($self->{unban_timeout}->get_keys) {
|
sub {
|
||||||
foreach my $mask ($self->{unban_timeout}->get_keys($channel)) {
|
return if not $self->{pbot}->{joined_channels};
|
||||||
if ($self->{unban_timeout}->get_data($channel, $mask, 'timeout') < $now) {
|
$self->{pbot}->{timer}->update_interval("unmute_timeout $channel $hostmask", 60 * 15, 1); # try again in 15 minutes
|
||||||
$self->{unban_timeout}->set($channel, $mask, 'timeout', $now + 7200);
|
$self->unmute_user($hostmask, $channel);
|
||||||
$self->unban_user($mask, $channel);
|
}, $interval, "unmute_timeout $channel $hostmask", 1
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub enqueue_unban_timeout {
|
||||||
|
my ($self, $channel, $hostmask, $interval) = @_;
|
||||||
|
|
||||||
|
$self->{pbot}->{timer}->enqueue_event(
|
||||||
|
sub {
|
||||||
|
return if not $self->{pbot}->{joined_channels};
|
||||||
|
$self->{pbot}->{timer}->update_interval("unban_timeout $channel $hostmask", 60 * 15, 1); # try again in 15 minutes
|
||||||
|
$self->unban_user($hostmask, $channel);
|
||||||
|
}, $interval, "unban_timeout $channel $hostmask", 1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub enqueue_unmute_timeouts {
|
||||||
|
my ($self) = @_;
|
||||||
|
my $now = time;
|
||||||
|
|
||||||
|
foreach my $channel ($self->{unmute_timeout}->get_keys) {
|
||||||
|
foreach my $mask ($self->{unmute_timeout}->get_keys($channel)) {
|
||||||
|
my $interval = $self->{unmute_timeout}->get_data($channel, $mask, 'timeout') - $now;
|
||||||
|
$interval = 10 if $interval < 10;
|
||||||
|
$self->enqueue_unmute_timeout($channel, $mask, $interval);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub check_unmute_timeouts {
|
sub enqueue_unban_timeouts {
|
||||||
my $self = shift;
|
my ($self) = @_;
|
||||||
return if not $self->{pbot}->{joined_channels};
|
my $now = time;
|
||||||
my $now = gettimeofday();
|
|
||||||
foreach my $channel ($self->{unmute_timeout}->get_keys) {
|
foreach my $channel ($self->{unban_timeout}->get_keys) {
|
||||||
foreach my $mask ($self->{unmute_timeout}->get_keys($channel)) {
|
foreach my $mask ($self->{unban_timeout}->get_keys($channel)) {
|
||||||
if ($self->{unmute_timeout}->get_data($channel, $mask, 'timeout') < $now) {
|
my $interval = $self->{unban_timeout}->get_data($channel, $mask, 'timeout') - $now;
|
||||||
$self->{unmute_timeout}->set($channel, $mask, 'timeout', $now + 7200);
|
$interval = 10 if $interval < 10;
|
||||||
$self->unmute_user($mask, $channel);
|
$self->enqueue_unban_timeout($channel, $mask, $interval);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub enqueue_timeouts {
|
||||||
|
my ($self) = @_;
|
||||||
|
$self->enqueue_unmute_timeouts;
|
||||||
|
$self->enqueue_unban_timeouts;
|
||||||
|
}
|
||||||
|
|
||||||
sub check_opped_timeouts {
|
sub check_opped_timeouts {
|
||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $now = gettimeofday();
|
my $now = gettimeofday();
|
||||||
|
@ -82,10 +82,16 @@ sub remove {
|
|||||||
return "Usage: chanrem <channel>" if not defined $arguments or not length $arguments;
|
return "Usage: chanrem <channel>" if not defined $arguments or not length $arguments;
|
||||||
|
|
||||||
# clear unban timeouts
|
# clear unban timeouts
|
||||||
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($arguments)) { $self->{pbot}->{chanops}->{unban_timeout}->remove($arguments); }
|
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($arguments)) {
|
||||||
|
$self->{pbot}->{chanops}->{unban_timeout}->remove($arguments);
|
||||||
|
$self->{pbot}->{timer}->dequeue_event("unban_timeout $arguments .*");
|
||||||
|
}
|
||||||
|
|
||||||
# clear unmute timeouts
|
# clear unmute timeouts
|
||||||
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($arguments)) { $self->{pbot}->{chanops}->{unmute_timeout}->remove($arguments); }
|
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($arguments)) {
|
||||||
|
$self->{pbot}->{chanops}->{unmute_timeout}->remove($arguments);
|
||||||
|
$self->{pbot}->{timer}->dequeue_event("unmute_timeout $arguments .*");
|
||||||
|
}
|
||||||
|
|
||||||
# TODO: ignores, etc?
|
# TODO: ignores, etc?
|
||||||
return $self->{channels}->remove($arguments);
|
return $self->{channels}->remove($arguments);
|
||||||
|
@ -269,6 +269,7 @@ sub on_mode {
|
|||||||
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
||||||
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, $target)) {
|
if ($self->{pbot}->{chanops}->{unban_timeout}->exists($channel, $target)) {
|
||||||
$self->{pbot}->{chanops}->{unban_timeout}->set($channel, $target, 'timeout', gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
$self->{pbot}->{chanops}->{unban_timeout}->set($channel, $target, 'timeout', gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
||||||
|
$self->{pbot}->{timer}->update_interval("unban_timeout $channel $target", $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
||||||
} else {
|
} else {
|
||||||
my $data = {
|
my $data = {
|
||||||
reason => 'Temp ban for banned-by-ChanServ or mask is *!*@*##fix_your_connection',
|
reason => 'Temp ban for banned-by-ChanServ or mask is *!*@*##fix_your_connection',
|
||||||
@ -276,6 +277,7 @@ sub on_mode {
|
|||||||
timeout => gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'),
|
timeout => gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'),
|
||||||
};
|
};
|
||||||
$self->{pbot}->{chanops}->{unban_timeout}->add($channel, $target, $data);
|
$self->{pbot}->{chanops}->{unban_timeout}->add($channel, $target, $data);
|
||||||
|
$self->{pbot}->{chanops}->enqueue_unban_timeout($channel, $target, $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} elsif ($target =~ m/^\*!\*@/ or $target =~ m/^\*!.*\@gateway\/web/i) {
|
} elsif ($target =~ m/^\*!\*@/ or $target =~ m/^\*!.*\@gateway\/web/i) {
|
||||||
@ -294,6 +296,7 @@ sub on_mode {
|
|||||||
owner => $self->{pbot}->{registry}->get_value('irc', 'botnick'),
|
owner => $self->{pbot}->{registry}->get_value('irc', 'botnick'),
|
||||||
};
|
};
|
||||||
$self->{pbot}->{chanops}->{unban_timeout}->add($channel, $target, $data);
|
$self->{pbot}->{chanops}->{unban_timeout}->add($channel, $target, $data);
|
||||||
|
$self->{pbot}->{chanops}->enqueue_unban_timeout($channel, $target, $timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,6 +305,7 @@ sub on_mode {
|
|||||||
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
if ($self->{pbot}->{chanops}->can_gain_ops($channel)) {
|
||||||
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($channel, $target)) {
|
if ($self->{pbot}->{chanops}->{unmute_timeout}->exists($channel, $target)) {
|
||||||
$self->{pbot}->{chanops}->{unmute_timeout}->set($channel, $target, 'timeout', gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
$self->{pbot}->{chanops}->{unmute_timeout}->set($channel, $target, 'timeout', gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
||||||
|
$self->{pbot}->{timer}->update_interval("unmute_timeout $channel $target", $self->{pbot}->{registry}->get_value('bantracker', 'chanserv_ban_timeout'));
|
||||||
} else {
|
} else {
|
||||||
my $data = {
|
my $data = {
|
||||||
reason => 'Temp mute',
|
reason => 'Temp mute',
|
||||||
@ -309,6 +313,7 @@ sub on_mode {
|
|||||||
timeout => gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'mute_timeout'),
|
timeout => gettimeofday + $self->{pbot}->{registry}->get_value('bantracker', 'mute_timeout'),
|
||||||
};
|
};
|
||||||
$self->{pbot}->{chanops}->{unmute_timeout}->add($channel, $target, $data);
|
$self->{pbot}->{chanops}->{unmute_timeout}->add($channel, $target, $data);
|
||||||
|
$self->{pbot}->{chanops}->enqueue_unmute_timeout($channel, $target, $self->{pbot}->{registry}->get_value('bantracker', 'mute_timeout'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -587,7 +592,7 @@ my $who_pending = 0;
|
|||||||
sub on_whoreply {
|
sub on_whoreply {
|
||||||
my ($self, $event_type, $event) = @_;
|
my ($self, $event_type, $event) = @_;
|
||||||
|
|
||||||
my ($ignored, $id, $user, $host, $server, $nick, $usermodes, $gecos) = @{$event->{event}->{args}};
|
my (undef, $id, $user, $host, $server, $nick, $usermodes, $gecos) = @{$event->{event}->{args}};
|
||||||
($nick, $user, $host) = $self->{pbot}->{irchandlers}->normalize_hostmask($nick, $user, $host);
|
($nick, $user, $host) = $self->{pbot}->{irchandlers}->normalize_hostmask($nick, $user, $host);
|
||||||
my $hostmask = "$nick!$user\@$host";
|
my $hostmask = "$nick!$user\@$host";
|
||||||
my $channel;
|
my $channel;
|
||||||
@ -631,7 +636,7 @@ sub on_whoreply {
|
|||||||
sub on_whospcrpl {
|
sub on_whospcrpl {
|
||||||
my ($self, $event_type, $event) = @_;
|
my ($self, $event_type, $event) = @_;
|
||||||
|
|
||||||
my ($ignored, $id, $user, $host, $nick, $nickserv, $gecos) = @{$event->{event}->{args}};
|
my (undef, $id, $user, $host, $nick, $nickserv, $gecos) = @{$event->{event}->{args}};
|
||||||
($nick, $user, $host) = $self->{pbot}->{irchandlers}->normalize_hostmask($nick, $user, $host);
|
($nick, $user, $host) = $self->{pbot}->{irchandlers}->normalize_hostmask($nick, $user, $host);
|
||||||
$last_who_id = $id;
|
$last_who_id = $id;
|
||||||
my $hostmask = "$nick!$user\@$host";
|
my $hostmask = "$nick!$user\@$host";
|
||||||
|
10
PBot/PBot.pm
10
PBot/PBot.pm
@ -435,13 +435,11 @@ sub reload {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'blacklist' => sub {
|
'blacklist' => sub {
|
||||||
$self->{blacklist}->clear_blacklist;
|
|
||||||
$self->{blacklist}->load_blacklist;
|
$self->{blacklist}->load_blacklist;
|
||||||
return "Blacklist reloaded.";
|
return "Blacklist reloaded.";
|
||||||
},
|
},
|
||||||
|
|
||||||
'ban-exemptions' => sub {
|
'ban-exemptions' => sub {
|
||||||
$self->{antiflood}->{'ban-exemptions'}->clear;
|
|
||||||
$self->{antiflood}->{'ban-exemptions'}->load;
|
$self->{antiflood}->{'ban-exemptions'}->load;
|
||||||
return "Ban exemptions reloaded.";
|
return "Ban exemptions reloaded.";
|
||||||
},
|
},
|
||||||
@ -462,25 +460,25 @@ sub reload {
|
|||||||
},
|
},
|
||||||
|
|
||||||
'bantimeouts' => sub {
|
'bantimeouts' => sub {
|
||||||
$self->{chanops}->{unban_timeout}->clear;
|
$self->{timer}->dequeue_event('unban_timeout .*');
|
||||||
$self->{chanops}->{unban_timeout}->load;
|
$self->{chanops}->{unban_timeout}->load;
|
||||||
|
$self->{chanops}->enqueue_unban_timeouts;
|
||||||
return "Ban timeouts reloaded.";
|
return "Ban timeouts reloaded.";
|
||||||
},
|
},
|
||||||
|
|
||||||
'mutetimeouts' => sub {
|
'mutetimeouts' => sub {
|
||||||
$self->{chanops}->{unmute_timeout}->clear;
|
$self->{timer}->dequeue_event('unmute_timeout .*');
|
||||||
$self->{chanops}->{unmute_timeout}->load;
|
$self->{chanops}->{unmute_timeout}->load;
|
||||||
|
$self->{chanops}->enqueue_unmute_timeouts;
|
||||||
return "Mute timeouts reloaded.";
|
return "Mute timeouts reloaded.";
|
||||||
},
|
},
|
||||||
|
|
||||||
'registry' => sub {
|
'registry' => sub {
|
||||||
$self->{registry}->{registry}->clear;
|
|
||||||
$self->{registry}->load;
|
$self->{registry}->load;
|
||||||
return "Registry reloaded.";
|
return "Registry reloaded.";
|
||||||
},
|
},
|
||||||
|
|
||||||
'factoids' => sub {
|
'factoids' => sub {
|
||||||
$self->{factoids}->{factoids}->clear;
|
|
||||||
$self->{factoids}->load_factoids;
|
$self->{factoids}->load_factoids;
|
||||||
return "Factoids reloaded.";
|
return "Factoids reloaded.";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user