3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-23 04:19:27 +01:00

Add more values to registry for antiflood and lagchecker

This commit is contained in:
Pragmatic Software 2014-05-19 02:42:18 +00:00
parent 020d512ee4
commit 937282a114
6 changed files with 73 additions and 41 deletions

View File

@ -51,13 +51,22 @@ sub initialize {
$self->{pbot}->{timer}->register(sub { $self->adjust_offenses }, 60 * 60 * 1);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'max_join_flood', $conf{max_join_flood} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'max_chat_flood', $conf{max_chat_flood} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'max_enter_flood', $conf{max_enter_flood} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'max_nick_flood', $conf{max_nick_flood} // 3);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_lines', $conf{enter_abuse_max_lines} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_seconds', $conf{enter_abuse_max_seconds} // 20);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_offenses', $conf{enter_abuse_max_offenses} // 3);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'join_flood_threshold', $conf{join_flood_threshold} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'join_flood_time_threshold', $conf{join_flood_time_threshold} // 60 * 30);
$self->{pbot}->{registry}->add_default('array', 'antiflood', 'join_flood_punishment', $conf{join_flood_punishment} // '28800,86400,604800,2419200,14515200');
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'chat_flood_threshold', $conf{chat_flood_threshold} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'chat_flood_time_threshold', $conf{chat_flood_time_threshold} // 10);
$self->{pbot}->{registry}->add_default('array', 'antiflood', 'chat_flood_punishment', $conf{chat_flood_punishment} // '60,300,3600,86400,604800,2419200');
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'nick_flood_threshold', $conf{nick_flood_threshold} // 3);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'nick_flood_time_threshold', $conf{nick_flood_time_threshold} // 60 * 30);
$self->{pbot}->{registry}->add_default('array', 'antiflood', 'nick_flood_punishment', $conf{nick_flood_punishment} // '60,300,3600,86400,604800,2419200');
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'enter_abuse_threshold', $conf{enter_abuse_threshold} // 4);
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'enter_abuse_time_threshold', $conf{enter_abuse_time_threshold} // 20);
$self->{pbot}->{registry}->add_default('array', 'antiflood', 'enter_abuse_punishment', $conf{enter_abuse_punishment} // '28800,86400,604800,2419200,14515200');
$self->{pbot}->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_offenses', $conf{enter_abuse_max_offenses} // 3);
$self->{pbot}->{commands}->register(sub { return $self->unbanme(@_) }, "unbanme", 0);
$self->{pbot}->{commands}->register(sub { return $self->whitelist(@_) }, "whitelist", 10);
@ -258,16 +267,17 @@ sub check_flood {
if(defined $self->{channels}->{$channel}->{last_spoken_nick} and $nick eq $self->{channels}->{$channel}->{last_spoken_nick}) {
my $messages = $self->{pbot}->{messagehistory}->{database}->get_recent_messages($account, $channel, 2, $self->{pbot}->{messagehistory}->{MSG_CHAT});
my $enter_abuse_max_lines = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_lines');
my $enter_abuse_max_seconds = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_seconds');
my $enter_abuse_max_offenses = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_offenses');
my $enter_abuse_threshold = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_threshold');
my $enter_abuse_time_threshold = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_time_threshold');
my $enter_abuse_max_offenses = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_offenses');
if($messages->[1]->{timestamp} - $messages->[0]->{timestamp} <= $enter_abuse_max_seconds) {
if(++$channel_data->{enter_abuse} >= $enter_abuse_max_lines - 1) {
$channel_data->{enter_abuse} = $enter_abuse_max_lines / 2 - 1;
if($messages->[1]->{timestamp} - $messages->[0]->{timestamp} <= $enter_abuse_time_threshold) {
if(++$channel_data->{enter_abuse} >= $enter_abuse_threshold - 1) {
$channel_data->{enter_abuse} = $enter_abuse_threshold / 2 - 1;
if(++$channel_data->{enter_abuses} >= $enter_abuse_max_offenses) {
my $offenses = $channel_data->{enter_abuses} - $enter_abuse_max_offenses + 1;
my $ban_length = $offenses ** $offenses * $offenses * 30;
my @punishment = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_punishment');
my $ban_length = $punishment[$offenses - 1 > $#punishment ? $#punishment : $offenses - 1];
$self->{pbot}->{chanops}->ban_user_timed("*!$user\@$host", $channel, $ban_length);
$ban_length = duration($ban_length);
$self->{pbot}->{logger}->log("$nick $channel enter abuse offense " . $channel_data->{enter_abuses} . " earned $ban_length ban\n");
@ -281,7 +291,7 @@ sub check_flood {
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
} else {
if($channel_data->{enter_abuse} > 0) {
#$self->{pbot}->{logger}->log("$nick $channel more than $enter_abuse_max_seconds seconds since last message, enter abuse counter reset\n");
#$self->{pbot}->{logger}->log("$nick $channel more than $enter_abuse_time_threshold seconds since last message, enter abuse counter reset\n");
$channel_data->{enter_abuse} = 0;
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
}
@ -333,12 +343,14 @@ sub check_flood {
$channel_data->{offenses}++;
$channel_data->{last_offense} = gettimeofday;
my $timeout = (2 ** (($channel_data->{offenses} + 2) < 10 ? $channel_data->{offenses} + 2 : 10));
my @punishment = $self->{pbot}->{registry}->get_value('antiflood', 'join_flood_punishment');
my $timeout = $punishment[$channel_data->{offenses} - 1 > $#punishment ? $#punishment : $channel_data->{offenses} - 1];
my $duration = duration($timeout);
my $banmask = address_to_mask($host);
$self->{pbot}->{chanops}->ban_user_timed("*!$user\@$banmask\$##stop_join_flood", $channel, $timeout * 60 * 60);
$self->{pbot}->{logger}->log("$nick!$user\@$banmask banned for $timeout hours due to join flooding (offense #" . $channel_data->{offenses} . ").\n");
$self->{pbot}->{conn}->privmsg($nick, "You have been banned from $channel due to join flooding. If your connection issues have been fixed, or this was an accident, you may request an unban at any time by responding to this message with: unbanme $channel, otherwise you will be automatically unbanned in $timeout hours.");
$self->{pbot}->{chanops}->ban_user_timed("*!$user\@$banmask\$##stop_join_flood", $channel, $timeout);
$self->{pbot}->{logger}->log("$nick!$user\@$banmask banned for $duration due to join flooding (offense #" . $channel_data->{offenses} . ").\n");
$self->{pbot}->{conn}->privmsg($nick, "You have been banned from $channel due to join flooding. If your connection issues have been fixed, or this was an accident, you may request an unban at any time by responding to this message with: unbanme $channel, otherwise you will be automatically unbanned in $duration.");
$channel_data->{join_watch} = $max_messages - 2; # give them a chance to rejoin
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
}
@ -352,7 +364,8 @@ sub check_flood {
$channel_data->{last_offense} = gettimeofday;
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
my $length = $channel_data->{offenses} ** $channel_data->{offenses} * $channel_data->{offenses} * 30;
my @punishment = $self->{pbot}->{registry}->get_value('antiflood', 'chat_flood_punishment');
my $length = $punishment[$channel_data->{offenses} - 1 > $#punishment ? $#punishment : $channel_data->{offenses} - 1];
$self->{pbot}->{chanops}->ban_user_timed("*!$user\@$host", $channel, $length);
$length = duration($length);
@ -368,7 +381,8 @@ sub check_flood {
$channel_data->{last_offense} = gettimeofday;
$self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data);
my $length = $channel_data->{offenses} ** $channel_data->{offenses} * $channel_data->{offenses} * 30;
my @punishment = $self->{pbot}->{registry}->get_value('antiflood', 'chat_flood_punishment');
my $length = $punishment[$channel_data->{offenses} - 1 > $#punishment ? $#punishment : $channel_data->{offenses} - 1];
$self->{pbot}->{ignorelist}->{commands}->ignore_user("", "floodcontrol", "", "", "$nick!$user\@$host $channel $length");
$length = duration($length);
@ -382,7 +396,8 @@ sub check_flood {
$self->{nickflood}->{$account}->{changes} = $max_messages - 2; # allow 1 more change (to go back to original nick)
$self->{nickflood}->{$account}->{timestamp} = gettimeofday;
my $length = $self->{nickflood}->{$account}->{offenses} ** $self->{nickflood}->{$account}->{offenses} * $self->{nickflood}->{$account}->{offenses} * 60 * 4;
my @punishment = $self->{pbot}->{registry}->get_value('antiflood', 'nick_flood_punishment');
my $length = $punishment[$self->{nickflood}->{$account}->{offenses} - 1 > $#punishment ? $#punishment : $self->{nickflood}->{$account}->{offenses} - 1];
my @channels = $self->{pbot}->{messagehistory}->{database}->get_channels($account);
foreach my $chan (@channels) {

View File

@ -183,7 +183,10 @@ sub on_join {
my $message_account = $self->{pbot}->{messagehistory}->get_message_account($nick, $user, $host);
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, "JOIN", $self->{pbot}->{messagehistory}->{MSG_JOIN});
$self->{pbot}->{antiflood}->check_flood($channel, $nick, $user, $host, "JOIN", $self->{pbot}->{registry}->get_value('antiflood', 'max_join_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_JOIN});
$self->{pbot}->{antiflood}->check_flood($channel, $nick, $user, $host, "JOIN",
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_threshold'),
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_time_threshold'),
$self->{pbot}->{messagehistory}->{MSG_JOIN});
}
sub on_kick {
@ -201,7 +204,10 @@ sub on_kick {
my $text = "KICKED by $nick!$user\@$host ($reason)";
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, $text, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE});
$self->{pbot}->{antiflood}->check_flood($channel, $target_nick, $target_user, $target_host, $text, $self->{pbot}->{registry}->get_value('antiflood', 'max_join_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE});
$self->{pbot}->{antiflood}->check_flood($channel, $target_nick, $target_user, $target_host, $text,
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_threshold'),
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_time_threshold'),
$self->{pbot}->{messagehistory}->{MSG_DEPARTURE});
}
}
@ -225,7 +231,10 @@ sub on_departure {
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, $text, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE});
}
$self->{pbot}->{antiflood}->check_flood($channel, $nick, $user, $host, $text, $self->{pbot}->{registry}->get_value('antiflood', 'max_join_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE});
$self->{pbot}->{antiflood}->check_flood($channel, $nick, $user, $host, $text,
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_threshold'),
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_time_threshold'),
$self->{pbot}->{messagehistory}->{MSG_DEPARTURE});
my $admin = $self->{pbot}->{admins}->find_admin($channel, "$nick!$user\@$host");
if(defined $admin and $admin->{loggedin}) {
@ -253,7 +262,10 @@ sub on_nickchange {
$self->{pbot}->{messagehistory}->{database}->devalidate_all_channels($newnick_account);
$self->{pbot}->{messagehistory}->{database}->update_hostmask_data($newnick_account, { last_seen => scalar gettimeofday });
$self->{pbot}->{antiflood}->check_flood("$nick!$user\@$host", $nick, $user, $host, "NICKCHANGE $newnick", $self->{pbot}->{registry}->get_value('antiflood', 'max_nick_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE});
$self->{pbot}->{antiflood}->check_flood("$nick!$user\@$host", $nick, $user, $host, "NICKCHANGE $newnick",
$self->{pbot}->{registry}->get_value('antiflood', 'nick_flood_threshold'),
$self->{pbot}->{registry}->get_value('antiflood', 'nick_flood_time_threshold'),
$self->{pbot}->{messagehistory}->{MSG_NICKCHANGE});
}
1;

View File

@ -97,7 +97,10 @@ sub process_line {
my $message_account = $pbot->{messagehistory}->get_message_account($nick, $user, $host);
$pbot->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $from, $text, $pbot->{messagehistory}->{MSG_CHAT});
$pbot->{antiflood}->check_flood($from, $nick, $user, $host, $text, $pbot->{registry}->get_value('antiflood', 'max_chat_flood'), 10, $pbot->{messagehistory}->{MSG_CHAT}) if defined $from;
$pbot->{antiflood}->check_flood($from, $nick, $user, $host, $text,
$pbot->{registry}->get_value('antiflood', 'chat_flood_threshold'),
$pbot->{registry}->get_value('antiflood', 'chat_flood_time_threshold'),
$pbot->{messagehistory}->{MSG_CHAT}) if defined $from;
$text =~ s/^\s+//;
$text =~ s/\s+$//;

View File

@ -30,23 +30,23 @@ sub new {
sub initialize {
my ($self, %conf) = @_;
my $pbot = delete $conf{pbot};
if(not defined $pbot) {
Carp::croak("Missing pbot reference to LagChecker");
}
my $pbot = delete $conf{pbot} // Carp::croak("Missing pbot reference to LagChecker");
$self->{pbot} = $pbot;
$self->{LAG_HISTORY_MAX} = 3; # maximum number of lag history entries to retain
$self->{LAG_THRESHOLD} = 2; # lagging is true if lag_average reaches or exceeds this threshold, in seconds
$self->{LAG_HISTORY_INTERVAL} = 10; # how often to send PING, in seconds
# maximum number of lag history entries to retain
$pbot->{registry}->add_default('text', 'lagchecker', 'lag_history_max', $conf{lag_history_max} // 3);
# lagging is true if lag_average reaches or exceeds this threshold, in seconds
$pbot->{registry}->add_default('text', 'lagchecker', 'lag_threshold', $conf{lag_threadhold} // 2);
# how often to send PING, in seconds
$pbot->{registry}->add_default('text', 'lagchecker', 'lag_history_interval', $conf{lag_history_max} // 10);
$self->{lag_average} = undef; # average of entries in lag history, in seconds
$self->{lag_string} = undef; # string representation of lag history and lag average
$self->{lag_history} = []; # history of previous PING/PONG timings
$self->{pong_received} = undef; # tracks pong replies; undef if no ping sent; 0 if ping sent but no pong reply yet; 1 if ping/pong completed
$self->{ping_send_time} = undef; # when last ping was sent
$pbot->{timer}->register(sub { $self->send_ping }, $self->{LAG_HISTORY_INTERVAL});
$pbot->{timer}->register(sub { $self->send_ping }, $pbot->{registry}->get_value('lagchecker', 'lag_history_interval'));
$pbot->{commands}->register(sub { return $self->lagcheck(@_) }, "lagcheck", 0);
}
@ -71,7 +71,9 @@ sub on_pong {
my $len = @{ $self->{lag_history} };
if($len > $self->{LAG_HISTORY_MAX}) {
my $lag_history_max = $self->{pbot}->{registry}->get_value('lagchecker', 'lag_history_max');
while($len > $lag_history_max) {
shift @{ $self->{lag_history} };
$len--;
}
@ -99,11 +101,11 @@ sub lagging {
if(defined $self->{pong_received} and $self->{pong_received} == 0) {
# a ping has been sent (pong_received is not undef) and no pong has been received yet
my $elapsed = tv_interval($self->{ping_send_time});
return $elapsed >= $self->{LAG_THRESHOLD};
return $elapsed >= $self->{pbot}->{registry}->get_value('lagchecker', 'lag_threshold');
}
return 0 if not defined $self->{lag_average};
return $self->{lag_average} >= $self->{LAG_THRESHOLD};
return $self->{lag_average} >= $self->{pbot}->{registry}->get_value('lagchecker', 'lag_threshold');
}
sub lagstring {

View File

@ -98,7 +98,7 @@ sub initialize {
$self->{stdin_reader} = PBot::StdinReader->new(pbot => $self);
$self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => delete $conf{admins_file});
$self->{bantracker} = PBot::BanTracker->new(pbot => $self);
$self->{lagchecker} = PBot::LagChecker->new(pbot => $self);
$self->{lagchecker} = PBot::LagChecker->new(pbot => $self, %conf);
$self->{messagehistory} = PBot::MessageHistory->new(pbot => $self, filename => delete $conf{messagehistory_file}, %conf);
$self->{antiflood} = PBot::AntiFlood->new(pbot => $self, %conf);
$self->{ignorelist} = PBot::IgnoreList->new(pbot => $self, filename => delete $conf{ignorelist_file});

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 587,
BUILD_REVISION => 588,
BUILD_DATE => "2014-05-18",
};