2010-03-22 07:33:44 +00:00
|
|
|
# File: IgnoreList.pm
|
2010-03-24 06:47:40 +00:00
|
|
|
# Author: pragma_
|
2010-03-17 06:36:54 +00:00
|
|
|
#
|
2010-03-22 07:33:44 +00:00
|
|
|
# Purpose: Manages ignore list.
|
2010-03-17 06:36:54 +00:00
|
|
|
|
|
|
|
package PBot::IgnoreList;
|
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
|
2014-05-18 00:27:57 +00:00
|
|
|
use PBot::IgnoreListCommands;
|
2010-03-17 06:36:54 +00:00
|
|
|
use Time::HiRes qw(gettimeofday);
|
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
sub new {
|
|
|
|
if(ref($_[1]) eq 'HASH') {
|
|
|
|
Carp::croak("Options to Commands should be key/value pairs, not hash reference");
|
|
|
|
}
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
my ($class, %conf) = @_;
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
my $self = bless {}, $class;
|
|
|
|
$self->initialize(%conf);
|
|
|
|
return $self;
|
|
|
|
}
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
sub initialize {
|
|
|
|
my ($self, %conf) = @_;
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2014-05-17 20:08:19 +00:00
|
|
|
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to Channels");
|
|
|
|
$self->{filename} = delete $conf{filename};
|
2010-04-06 18:38:27 +00:00
|
|
|
|
2014-05-18 00:27:57 +00:00
|
|
|
$self->{ignore_list} = {};
|
2010-04-06 19:15:42 +00:00
|
|
|
$self->{ignore_flood_counter} = {};
|
2014-05-18 00:27:57 +00:00
|
|
|
$self->{last_timestamp} = {};
|
|
|
|
|
|
|
|
$self->{commands} = PBot::IgnoreListCommands->new(pbot => $self->{pbot});
|
2010-03-23 18:24:02 +00:00
|
|
|
|
2014-05-17 20:08:19 +00:00
|
|
|
$self->load_ignores;
|
|
|
|
|
2014-05-18 20:09:05 +00:00
|
|
|
$self->{pbot}->{timer}->register(sub { $self->check_ignore_timeouts }, 10);
|
2010-03-22 07:33:44 +00:00
|
|
|
}
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
sub add {
|
|
|
|
my $self = shift;
|
|
|
|
my ($hostmask, $channel, $length) = @_;
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2010-04-06 18:38:27 +00:00
|
|
|
if($length == -1) {
|
|
|
|
${ $self->{ignore_list} }{$hostmask}{$channel} = -1;
|
|
|
|
} else {
|
|
|
|
${ $self->{ignore_list} }{$hostmask}{$channel} = gettimeofday + $length;
|
|
|
|
}
|
|
|
|
|
|
|
|
$self->save_ignores();
|
2010-03-17 06:36:54 +00:00
|
|
|
}
|
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
sub remove {
|
|
|
|
my $self = shift;
|
|
|
|
my ($hostmask, $channel) = @_;
|
2010-03-17 06:36:54 +00:00
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
delete ${ $self->{ignore_list} }{$hostmask}{$channel};
|
2010-04-06 18:38:27 +00:00
|
|
|
$self->save_ignores();
|
|
|
|
}
|
|
|
|
|
|
|
|
sub load_ignores {
|
|
|
|
my $self = shift;
|
|
|
|
my $filename;
|
|
|
|
|
|
|
|
if(@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
|
|
|
|
|
|
|
if(not defined $filename) {
|
|
|
|
Carp::carp "No ignorelist path specified -- skipping loading of ignorelist";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-05-18 20:09:05 +00:00
|
|
|
$self->{pbot}->{logger}->log("Loading ignorelist from $filename ...\n");
|
2010-04-06 18:38:27 +00:00
|
|
|
|
|
|
|
open(FILE, "< $filename") or Carp::croak "Couldn't open $filename: $!\n";
|
|
|
|
my @contents = <FILE>;
|
|
|
|
close(FILE);
|
|
|
|
|
|
|
|
my $i = 0;
|
|
|
|
|
|
|
|
foreach my $line (@contents) {
|
|
|
|
chomp $line;
|
|
|
|
$i++;
|
|
|
|
|
|
|
|
my ($hostmask, $channel, $length) = split(/\s+/, $line);
|
|
|
|
|
|
|
|
if(not defined $hostmask || not defined $channel || not defined $length) {
|
|
|
|
Carp::croak "Syntax error around line $i of $filename\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if(exists ${ $self->{ignore_list} }{$hostmask}{$channel}) {
|
|
|
|
Carp::croak "Duplicate ignore [$hostmask][$channel] found in $filename around line $i\n";
|
|
|
|
}
|
|
|
|
|
2012-09-06 10:09:44 +00:00
|
|
|
${ $self->{ignore_list} }{$hostmask}{$channel} = $length;
|
2010-04-06 18:38:27 +00:00
|
|
|
}
|
|
|
|
|
2014-05-18 20:09:05 +00:00
|
|
|
$self->{pbot}->{logger}->log(" $i entries in ignorelist\n");
|
|
|
|
$self->{pbot}->{logger}->log("Done.\n");
|
2010-04-06 18:38:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub save_ignores {
|
|
|
|
my $self = shift;
|
|
|
|
my $filename;
|
|
|
|
|
|
|
|
if(@_) { $filename = shift; } else { $filename = $self->{filename}; }
|
|
|
|
|
|
|
|
if(not defined $filename) {
|
|
|
|
Carp::carp "No ignorelist path specified -- skipping saving of ignorelist\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
open(FILE, "> $filename") or die "Couldn't open $filename: $!\n";
|
|
|
|
|
|
|
|
foreach my $ignored (keys %{ $self->{ignore_list} }) {
|
|
|
|
foreach my $ignored_channel (keys %{ ${ $self->{ignore_list} }{$ignored} }) {
|
|
|
|
my $length = $self->{ignore_list}->{$ignored}{$ignored_channel};
|
|
|
|
print FILE "$ignored $ignored_channel $length\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close(FILE);
|
2010-03-17 06:36:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sub check_ignore {
|
2010-03-22 07:33:44 +00:00
|
|
|
my $self = shift;
|
2010-03-17 06:36:54 +00:00
|
|
|
my ($nick, $user, $host, $channel) = @_;
|
2010-03-23 03:09:03 +00:00
|
|
|
my $pbot = $self->{pbot};
|
2010-03-17 06:36:54 +00:00
|
|
|
$channel = lc $channel;
|
|
|
|
|
|
|
|
my $hostmask = "$nick!$user\@$host";
|
|
|
|
|
2010-03-23 03:09:03 +00:00
|
|
|
my $now = gettimeofday;
|
|
|
|
|
|
|
|
if(defined $channel) { # do not execute following if text is coming from STDIN ($channel undef)
|
|
|
|
if($channel =~ /^#/) {
|
2014-04-19 10:34:21 +00:00
|
|
|
$self->{ignore_flood_counter}->{$channel}++;
|
2010-03-23 03:09:03 +00:00
|
|
|
}
|
|
|
|
|
2010-04-06 19:15:42 +00:00
|
|
|
if(not exists $self->{last_timestamp}->{$channel}) {
|
|
|
|
$self->{last_timestamp}->{$channel} = $now;
|
2010-04-14 00:01:42 +00:00
|
|
|
} elsif($now - $self->{last_timestamp}->{$channel} >= 30) {
|
2010-04-06 19:15:42 +00:00
|
|
|
$self->{last_timestamp}->{$channel} = $now;
|
2010-06-04 04:44:08 +00:00
|
|
|
if(exists $self->{ignore_flood_counter}->{$channel} and $self->{ignore_flood_counter}->{$channel} > 0) {
|
2010-04-14 00:01:42 +00:00
|
|
|
$self->{ignore_flood_counter}->{$channel} = 0;
|
2010-04-06 18:38:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-01 00:15:21 +00:00
|
|
|
=cut
|
2010-05-30 02:22:38 +00:00
|
|
|
if(exists $self->{ignore_flood_counter}->{$channel} and $self->{ignore_flood_counter}->{$channel} > 5) {
|
2014-05-18 00:27:57 +00:00
|
|
|
$self->{commands}->ignore_user("", "floodcontrol", "", "", ".* $channel 300");
|
2010-04-06 19:15:42 +00:00
|
|
|
$self->{ignore_flood_counter}->{$channel} = 0;
|
2010-03-23 03:09:03 +00:00
|
|
|
if($channel =~ /^#/) {
|
2014-05-18 20:09:05 +00:00
|
|
|
$pbot->{conn}->me($channel, "has been overwhelmed.");
|
|
|
|
$pbot->{conn}->me($channel, "lies down and falls asleep.");
|
2010-04-06 19:15:42 +00:00
|
|
|
return 1;
|
2010-03-23 03:09:03 +00:00
|
|
|
}
|
|
|
|
}
|
2014-11-01 00:15:21 +00:00
|
|
|
=cut
|
2010-03-23 03:09:03 +00:00
|
|
|
}
|
|
|
|
|
2010-03-22 07:33:44 +00:00
|
|
|
foreach my $ignored (keys %{ $self->{ignore_list} }) {
|
|
|
|
foreach my $ignored_channel (keys %{ ${ $self->{ignore_list} }{$ignored} }) {
|
2014-05-18 20:09:05 +00:00
|
|
|
#$self->{pbot}->{logger}->log("check_ignore: comparing '$hostmask' against '$ignored' for channel '$channel'\n");
|
2012-09-06 10:09:44 +00:00
|
|
|
my $ignored_channel_escaped = quotemeta $ignored_channel;
|
|
|
|
my $ignored_escaped = quotemeta $ignored;
|
|
|
|
|
|
|
|
$ignored_channel_escaped =~ s/\\(\.|\*)/$1/g;
|
|
|
|
$ignored_escaped =~ s/\\(\.|\*)/$1/g;
|
|
|
|
|
|
|
|
if(($channel =~ /$ignored_channel_escaped/i) && ($hostmask =~ /$ignored_escaped/i)) {
|
2014-05-18 20:09:05 +00:00
|
|
|
$self->{pbot}->{logger}->log("$nick!$user\@$host message ignored in channel $channel (matches [$ignored] host and [$ignored_channel] channel)\n");
|
2010-03-17 06:36:54 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-03-22 07:33:44 +00:00
|
|
|
return 0;
|
2010-03-17 06:36:54 +00:00
|
|
|
}
|
|
|
|
|
2010-03-23 18:24:02 +00:00
|
|
|
sub check_ignore_timeouts {
|
|
|
|
my $self = shift;
|
|
|
|
my $now = gettimeofday();
|
|
|
|
|
|
|
|
foreach my $hostmask (keys %{ $self->{ignore_list} }) {
|
|
|
|
foreach my $channel (keys %{ $self->{ignore_list}->{$hostmask} }) {
|
|
|
|
next if($self->{ignore_list}->{$hostmask}{$channel} == -1); #permanent ignore
|
|
|
|
|
|
|
|
if($self->{ignore_list}->{$hostmask}{$channel} < $now) {
|
2014-05-18 00:27:57 +00:00
|
|
|
$self->{commands}->unignore_user("", "floodcontrol", "", "", "$hostmask $channel");
|
2010-03-23 18:24:02 +00:00
|
|
|
if($hostmask eq ".*") {
|
2014-05-18 20:09:05 +00:00
|
|
|
$self->{pbot}->{conn}->me($channel, "awakens.");
|
2010-03-23 18:24:02 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
#my $timediff = $ignore_list{$host}{$channel} - $now;
|
2014-05-18 20:09:05 +00:00
|
|
|
#${logger}->log "ignore: $host has $timediff seconds remaining\n"
|
2010-03-23 18:24:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-03-17 06:36:54 +00:00
|
|
|
1;
|