pbot/PBot/IgnoreList.pm

128 lines
3.6 KiB
Perl
Raw Normal View History

# File: IgnoreList.pm
# Authoer: pragma_
#
# Purpose: Manages ignore list.
package PBot::IgnoreList;
use warnings;
use strict;
use vars qw($VERSION);
$VERSION = $PBot::PBot::VERSION;
use Time::HiRes qw(gettimeofday);
sub new {
if(ref($_[1]) eq 'HASH') {
Carp::croak("Options to Commands should be key/value pairs, not hash reference");
}
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
my $pbot = delete $conf{pbot};
if(not defined $pbot) {
Carp::croak("Missing pbot reference to Channels");
}
$self->{pbot} = $pbot;
$self->{ignore_list} = {};
$self->{ignore_flood_counter} = 0;
$self->{last_timestamp} = gettimeofday;
$pbot->timer->register(sub { $self->check_ignore_timeouts }, 10);
}
sub add {
my $self = shift;
my ($hostmask, $channel, $length) = @_;
${ $self->{ignore_list} }{$hostmask}{$channel} = gettimeofday + $length;
}
sub remove {
my $self = shift;
my ($hostmask, $channel) = @_;
delete ${ $self->{ignore_list} }{$hostmask}{$channel};
}
sub check_ignore {
my $self = shift;
my ($nick, $user, $host, $channel) = @_;
my $pbot = $self->{pbot};
$channel = lc $channel;
my $hostmask = "$nick!$user\@$host";
my $now = gettimeofday;
if(defined $channel) { # do not execute following if text is coming from STDIN ($channel undef)
if($channel =~ /^#/) {
$self->{ignore_flood_counter}++; # TODO: make this per channel, e.g., ${ $self->{ignore_flood_counter} }{$channel}++
$pbot->logger->log("flood_msg: $self->{ignore_flood_counter}\n");
}
if($self->{ignore_flood_counter} > 4) {
$pbot->logger->log("flood_msg exceeded! [$self->{ignore_flood_counter}]\n");
$self->{pbot}->{ignorelistcmds}->ignore_user("", "floodcontrol", "", "", ".* $channel 300");
$self->{ignore_flood_counter} = 0;
if($channel =~ /^#/) {
$pbot->conn->me($channel, "has been overwhelmed.");
$pbot->conn->me($channel, "lies down and falls asleep.");
return;
}
}
if($now - $self->{last_timestamp} >= 15) {
$self->{last_timestamp} = $now;
if($self->{ignore_flood_counter} > 0) {
$pbot->logger->log("flood_msg reset: (was $self->{ignore_flood_counter})\n");
$self->{ignore_flood_counter} = 0;
}
}
}
foreach my $ignored (keys %{ $self->{ignore_list} }) {
foreach my $ignored_channel (keys %{ ${ $self->{ignore_list} }{$ignored} }) {
$self->{pbot}->logger->log("check_ignore: comparing '$hostmask' against '$ignored' for channel '$channel'\n");
if(($channel =~ /$ignored_channel/i) && ($hostmask =~ /$ignored/i)) {
$self->{pbot}->logger->log("$nick!$user\@$host message ignored in channel $channel (matches [$ignored] host and [$ignored_channel] channel)\n");
return 1;
}
}
}
return 0;
}
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) {
$self->{pbot}->{ignorelistcmds}->unignore_user("", "floodcontrol", "", "", "$hostmask $channel");
if($hostmask eq ".*") {
$self->{pbot}->conn->me($channel, "awakens.");
}
} else {
#my $timediff = $ignore_list{$host}{$channel} - $now;
#$logger->log "ignore: $host has $timediff seconds remaining\n"
}
}
}
}
1;