summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Multi/IRC.pm52
1 files changed, 40 insertions, 12 deletions
diff --git a/lib/Multi/IRC.pm b/lib/Multi/IRC.pm
index 92f887ea..43007e2f 100644
--- a/lib/Multi/IRC.pm
+++ b/lib/Multi/IRC.pm
@@ -48,7 +48,7 @@ sub spawn {
POE::Session->create(
package_states => [
$p => [qw|
- _start shutdown irc_001 irc_public irc_ctcp_action irc_msg command reply
+ _start shutdown throttle_gc irc_001 irc_public irc_ctcp_action irc_msg command reply
cmd_info cmd_list cmd_uptime cmd_vn cmd_vn_results cmd_quote cmd_quote_result cmd_say cmd_me
cmd_eval cmd_die cmd_post vndbid formatid
|],
@@ -60,8 +60,7 @@ sub spawn {
channels => [ '#vndb' ],
masters => [ 'yorhel!*@*' ],
@_,
- log => {},
- privpers => {},
+ throttle => {},
notify => [],
commands => {
info => 0, # argument = authentication level/flags,
@@ -80,6 +79,31 @@ sub spawn {
}
+# non-POE helper function
+# Arguments: $_[HEAP], key, timeout, (optional) num
+# no key = remove all keys with no activity in the last hour
+# returns false if throttling isn't necessary for that key
+sub throttle {
+ my($heap, $key, $tm, $num) = @_;
+
+ # garbage collect
+ return ($heap->{throttle} = {
+ map $_->[$#$_] > time-3600 ? ($_, $heap->{throttle}{$_}) : (), keys %{$heap->{throttle}}
+ }) if !$key;
+
+ $num ||= 1;
+ my $dat = $heap->{throttle};
+ if(!$dat->{$key}) {
+ $dat->{$key} = [ time ];
+ return 0;
+ }
+ $dat->{$key} = [ grep $_ > time-$tm, @{$dat->{$key}} ];
+ return 1 if @{$dat->{$key}} >= $num;
+ push @{$dat->{$key}}, time;
+ return 0;
+}
+
+
sub _start {
$_[KERNEL]->alias_set('irc');
@@ -122,15 +146,23 @@ sub _start {
});
$_[KERNEL]->sig(shutdown => 'shutdown');
+ $_[KERNEL]->delay(throttle_gc => 1800);
}
sub shutdown {
$irc->yield(shutdown => $_[ARG1]);
+ $_[KERNEL]->delay('throttle_gc');
$_[KERNEL]->alias_remove('irc');
}
+sub throttle_gc {
+ throttle $_[HEAP];
+ $_[KERNEL]->delay(throttle_gc => 1800);
+}
+
+
sub irc_001 {
$irc->yield(join => $_) for (@{$_[HEAP]{channels}});
$_[KERNEL]->call(core => log => 'Connected to IRC');
@@ -152,9 +184,8 @@ sub irc_msg { # mask, dest, msg
return if $_[KERNEL]->call($_[SESSION] => command => $_[ARG0], [scalar parse_user($_[ARG0])], $_[ARG2]);
my $usr = parse_user($_[ARG0]);
- return if ($_[HEAP]{privpers}{$usr}||0) > time-300;
- $irc->yield(notice => $usr, 'I am not human, join #vndb or PM Yorhel if you need something.');
- $_[HEAP]{privpers}{$usr} = time;
+ $irc->yield(notice => $usr, 'I am not human, join #vndb or PM Yorhel if you need something.')
+ unless throttle $_[HEAP], "pm-$usr", 30;
}
@@ -230,6 +261,8 @@ sub cmd_uptime {
sub cmd_vn {
(my $q = $_[ARG]||'') =~ s/%//g;
return $_[KERNEL]->yield(reply => $_[DEST], 'You forgot the search query, dummy~~!', $_[USER]) if !$q;
+ return $_[KERNEL]->yield(reply => $_[DEST], 'Stop abusing me, it\'s not like I enjoy spamming this channel!', $_[USER])
+ if throttle $_[HEAP], "query-$_[USER]-$_[DEST][0]", 60, 5;
$_[KERNEL]->post(pg => query => q|
SELECT 'v'::text AS type, v.id, vr.title
@@ -310,9 +343,6 @@ sub cmd_post {
sub vndbid { # dest, msg
my($dest, $msg) = @_[ARG0, ARG1];
- $_[HEAP]{log}{$_} < time-60 and delete $_[HEAP]{log}{$_}
- for (keys %{$_[HEAP]{log}});
-
my @id; # [ type, id, ref ]
for (split /[, ]/, $msg) {
next if length > 15 or m{[a-z]{3,6}://}i; # weed out URLs and too long things
@@ -322,9 +352,7 @@ sub vndbid { # dest, msg
for (@id) {
my($t, $id, $rev) = @$_;
-
- next if $_[HEAP]{log}{$t.$id.'.'.$rev};
- $_[HEAP]{log}{$t.$id.'.'.$rev} = time;
+ next if throttle $_[HEAP], "$dest->[0].$t$id.$rev", 60;
# plain vn/user/producer/thread/tag/release
$_[KERNEL]->post(pg => query => 'SELECT ?::text AS type, ?::integer AS id, '.(