3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-12-27 13:12:42 +01:00

Add join flood protection

This commit is contained in:
Pragmatic Software 2010-06-05 06:07:15 +00:00
parent 7df2346d01
commit 4b342be290
5 changed files with 58 additions and 39 deletions

View File

@ -48,13 +48,13 @@ sub initialize {
}
sub check_flood {
my ($self, $channel, $nick, $user, $host, $text, $max, $mode) = @_;
my ($self, $channel, $nick, $user, $host, $text, $max_messages, $max_time, $mode) = @_;
my $now = gettimeofday;
$channel = lc $channel;
$self->{pbot}->logger->log(sprintf("%-14s | %-65s | %s\n", $channel, "$nick!$user\@$host", $text));
return if $nick eq $self->{pbot}->botnick;
if(exists ${ $self->message_history }{$nick}) {
@ -63,16 +63,22 @@ sub check_flood {
if(not exists ${ $self->message_history }{$nick}{$channel}) {
#$self->{pbot}->logger->log("adding new channel for existing nick\n");
${ $self->message_history }{$nick}{$channel}{offenses} = 0;
${ $self->message_history }{$nick}{$channel}{join_watch} = $mode; # FLOOD_CHAT = 0; FLOOD_JOIN = 1
${ $self->message_history }{$nick}{$channel}{messages} = [];
}
print "$nick $channel joinwatch: ${ $self->message_history }{$nick}{$channel}{join_watch}\n";
#$self->{pbot}->logger->log("appending new message\n");
push(@{ ${ $self->message_history }{$nick}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode });
my $length = $#{ ${ $self->message_history }{$nick}{$channel}{messages} } + 1;
#$self->{pbot}->logger->log("length: $length, max nick messages: $MAX_NICK_MESSAGES\n");
if($max_messages > $self->{pbot}->{MAX_NICK_MESSAGES}) {
$self->{pbot}->logger->log("Warning: max_messages greater than MAX_NICK_MESSAGES; truncating.\n");
$max_messages = $self->{pbot}->{MAX_NICK_MESSAGES};
}
if($length >= $self->{pbot}->{MAX_NICK_MESSAGES}) {
my %msg = %{ shift(@{ ${ $self->message_history }{$nick}{$channel}{messages} }) };
@ -82,51 +88,65 @@ sub check_flood {
return if ($channel =~ /^#/) and (not exists ${ $self->{pbot}->channels->channels }{$channel} or ${ $self->{pbot}->channels->channels }{$channel}{is_op} == 0);
#$self->{pbot}->logger->log("length: $length, max: $max\n");
if($length >= $max) {
# $self->{pbot}->logger->log("More than $max messages spoken, comparing time differences\n");
my %msg = %{ @{ ${ $self->message_history }{$nick}{$channel}{messages} }[$length - $max] };
if($length >= $max_messages) {
$self->{pbot}->logger->log("More than $max_messages messages spoken, comparing time differences ($max_time)\n");
my %msg = %{ @{ ${ $self->message_history }{$nick}{$channel}{messages} }[$length - $max_messages] };
my %last = %{ @{ ${ $self->message_history }{$nick}{$channel}{messages} }[$length - 1] };
#$self->{pbot}->logger->log("Comparing $last{timestamp} against $msg{timestamp}: " . ($last{timestamp} - $msg{timestamp}) . " seconds\n");
$self->{pbot}->logger->log("Comparing $last{timestamp} against $msg{timestamp}: " . (int($last{timestamp} - $msg{timestamp})) . " seconds\n");
if($last{timestamp} - $msg{timestamp} <= 10 && not $self->{pbot}->admins->loggedin($channel, "$nick!$user\@$host")) {
${ $self->message_history }{$nick}{$channel}{offenses}++;
my $length = ${ $self->message_history }{$nick}{$channel}{offenses} ** ${ $self->message_history }{$nick}{$channel}{offenses} * ${ $self->message_history }{$nick}{$channel}{offenses} * 30;
if($channel =~ /^#/) { #channel flood (opposed to private message or otherwise)
return if exists $self->{pbot}->chanops->{quieted_masks}->{"*!*\@$host"};
if($mode == $self->{FLOOD_CHAT}) {
$self->{pbot}->chanops->quiet_user_timed("*!*\@$host", $channel, $length);
if($last{timestamp} - $msg{timestamp} <= $max_time && not $self->{pbot}->admins->loggedin($channel, "$nick!$user\@$host")) {
if($mode == $self->{FLOOD_JOIN}) {
if(${ $self->message_history }{$nick}{$channel}{join_watch} >= $max_messages) {
$self->{pbot}->chanops->quiet_user_timed("*!$user\@$host", $channel, 60 * 60);
$self->{pbot}->logger->log("$nick!$user\@$host banned for one hour due to join flooding.\n");
$self->{pbot}->conn->privmsg($nick, "You have been banned from $channel for one hour due to join flooding.");
}
} elsif($mode == $self->{FLOOD_CHAT}) {
${ $self->message_history }{$nick}{$channel}{offenses}++;
my $length = ${ $self->message_history }{$nick}{$channel}{offenses} ** ${ $self->message_history }{$nick}{$channel}{offenses} * ${ $self->message_history }{$nick}{$channel}{offenses} * 30;
if($channel =~ /^#/) { #channel flood (opposed to private message or otherwise)
return if exists $self->{pbot}->chanops->{quieted_masks}->{"*!*\@$host"};
if($mode == $self->{FLOOD_CHAT}) {
$self->{pbot}->chanops->quiet_user_timed("*!$user\@$host", $channel, $length);
$self->{pbot}->logger->log("$nick $channel flood offense ${ $self->message_history }{$nick}{$channel}{offenses} earned $length second quiet\n");
$self->{pbot}->logger->log("$nick $channel flood offense ${ $self->message_history }{$nick}{$channel}{offenses} earned $length second quiet\n");
if($length < 1000) {
$length = "$length seconds";
} else {
$length = "a little while";
}
$self->{pbot}->conn->privmsg($nick, "You have been quieted due to flooding. Please use a web paste service such as http://codepad.org for lengthy pastes. You will be allowed to speak again in $length.");
}
} else { # private message flood
return if exists $self->{pbot}->ignorelist->{ignore_list}->{"$nick!$user\@$host"}{$channel};
$self->{pbot}->logger->log("$nick msg flood offense ${ $self->message_history }{$nick}{$channel}{offenses} earned $length second ignore\n");
$self->{pbot}->{ignorelistcmds}->ignore_user("", "floodcontrol", "", "", "$nick!$user\@$host $channel $length");
if($length < 1000) {
$length = "$length seconds";
} else {
$length = "a little while";
}
$self->{pbot}->conn->privmsg($nick, "You have been quieted due to flooding. Please use a web paste service such as http://codepad.org for lengthy pastes. You will be allowed to speak again in $length.");
$self->{pbot}->conn->privmsg($nick, "You have used too many commands in too short a time period, you have been ignored for $length.");
}
} else { # private message flood
return if exists $self->{pbot}->ignorelist->{ignore_list}->{"$nick!$user\@$host"}{$channel};
$self->{pbot}->logger->log("$nick msg flood offense ${ $self->message_history }{$nick}{$channel}{offenses} earned $length second ignore\n");
$self->{pbot}->{ignorelistcmds}->ignore_user("", "floodcontrol", "", "", "$nick!$user\@$host $channel $length");
if($length < 1000) {
$length = "$length seconds";
} else {
$length = "a little while";
}
$self->{pbot}->conn->privmsg($nick, "You have used too many commands in too short a time period, you have been ignored for $length.");
}
}
}
if($mode == $self->{FLOOD_JOIN}) {
${ $self->message_history }{$nick}{$channel}{join_watch}++;
} elsif($mode == $self->{FLOOD_CHAT}) {
${ $self->message_history }{$nick}{$channel}{join_watch} = 0;
}
print "$nick $channel joinwatch adjusted: ${ $self->message_history }{$nick}{$channel}{join_watch}\n";
} else {
#$self->{pbot}->logger->log("brand new nick addition\n");
# new addition
${ $self->message_history }{$nick}{$channel}{offenses} = 0;
${ $self->message_history }{$nick}{$channel}{offenses} = 0;
${ $self->message_history }{$nick}{$channel}{join_watch} = $mode; # FLOOD_CHAT = 0; FLOOD_JOIN = 1
${ $self->message_history }{$nick}{$channel}{messages} = [];
push(@{ ${ $self->message_history }{$nick}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode });
}

View File

@ -152,18 +152,16 @@ sub on_mode {
sub on_join {
my ($self, $conn, $event) = @_;
my ($nick, $host, $channel) = ($event->nick, $event->host, $event->to);
my ($nick, $user, $host, $channel) = ($event->nick, $event->user, $event->host, $event->to);
#$self->{pbot}->logger->log("$nick!$user\@$host joined $channel\n");
#check_flood($nick, $host, $channel, 3, $FLOOD_JOIN);
$self->{pbot}->antiflood->check_flood($channel, $nick, $user, $host, "JOIN", 3, 90, $self->{pbot}->{FLOOD_JOIN});
}
sub on_departure {
my ($self, $conn, $event) = @_;
my ($nick, $host, $channel) = ($event->nick, $event->host, $event->to);
#check_flood($nick, $host, $channel, 3, $FLOOD_JOIN);
=cut
if(exists $admins{$nick} && exists $admins{$nick}{login}) {
$self->{pbot}->logger->log("Whoops, $nick left while still logged in.\n");

View File

@ -73,7 +73,7 @@ sub process_line {
my $pbot = $self->pbot;
$pbot->antiflood->check_flood($from, $nick, $user, $host, $text, $pbot->{MAX_FLOOD_MESSAGES}, $pbot->{FLOOD_CHAT}) if defined $from;
$pbot->antiflood->check_flood($from, $nick, $user, $host, $text, $pbot->{MAX_FLOOD_MESSAGES}, 10, $pbot->{FLOOD_CHAT}) if defined $from;
if($text =~ /^.?$mynick.?\s+(.*?)([\?!]*)$/i) {
$command = "$1";

View File

@ -89,7 +89,7 @@ sub initialize {
my $export_quotegrabs_site = delete $conf{export_quotegrabs_site};
$ircserver = "irc.freenode.net" unless defined $ircserver;
$botnick = "pbot2" unless defined $botnick;
$botnick = "pbot3" unless defined $botnick;
$identify_password = "" unless defined $identify_password;
$max_msg_len = 430 unless defined $max_msg_len;
@ -105,6 +105,7 @@ sub initialize {
$self->{MAX_FLOOD_MESSAGES} = $MAX_FLOOD_MESSAGES;
$self->{MAX_NICK_MESSAGES} = $MAX_NICK_MESSAGES;
$self->{FLOOD_CHAT} = 0;
$self->{FLOOD_JOIN} = 1;
my $logger = PBot::Logger->new(log_file => $log_file);
$self->{logger} = $logger;

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 142,
BUILD_REVISION => 143,
BUILD_DATE => "2010-06-04",
};