diff --git a/PBot/AntiFlood.pm b/PBot/AntiFlood.pm index 537638d9..4f90cc0f 100644 --- a/PBot/AntiFlood.pm +++ b/PBot/AntiFlood.pm @@ -75,117 +75,117 @@ sub check_flood { my $account = $self->get_flood_account($nick, $user, $host); - if(defined $account) { - #$self->{pbot}->logger->log("nick exists\n"); + if(not defined $account) { + # new addition + #$self->{pbot}->logger->log("brand new nick addition\n"); + ${ $self->message_history }{$nick}{$channel}{offenses} = 0; + ${ $self->message_history }{$nick}{$channel}{join_watch} = 0; + ${ $self->message_history }{$nick}{$channel}{messages} = []; + ${ $self->message_history }{$nick}{hostmask} = "$nick!$user\@$host"; + push(@{ ${ $self->message_history }{$nick}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode }); - if(not exists ${ $self->message_history }{$account}{$channel}) { - #$self->{pbot}->logger->log("adding new channel for existing nick\n"); - ${ $self->message_history }{$account}{$channel}{offenses} = 0; - ${ $self->message_history }{$account}{$channel}{join_watch} = 0; - ${ $self->message_history }{$account}{$channel}{messages} = []; - } + $account = $nick; + } - #$self->{pbot}->logger->log("appending new message\n"); + if(not exists ${ $self->message_history }{$account}{$channel}) { + #$self->{pbot}->logger->log("adding new channel for existing nick\n"); + ${ $self->message_history }{$account}{$channel}{offenses} = 0; + ${ $self->message_history }{$account}{$channel}{join_watch} = 0; + ${ $self->message_history }{$account}{$channel}{messages} = []; + } - push(@{ ${ $self->message_history }{$account}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode }); + #$self->{pbot}->logger->log("appending new message\n"); - my $length = $#{ ${ $self->message_history }{$account}{$channel}{messages} } + 1; + push(@{ ${ $self->message_history }{$account}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode }); - 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}; - } + my $length = $#{ ${ $self->message_history }{$account}{$channel}{messages} } + 1; - if($length >= $self->{pbot}->{MAX_NICK_MESSAGES}) { - my %msg = %{ shift(@{ ${ $self->message_history }{$account}{$channel}{messages} }) }; - #$self->{pbot}->logger->log("shifting message off top: $msg{msg}, $msg{timestamp}\n"); - $length--; - } + 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}; + } - return if ($channel =~ /^#/) and (not exists ${ $self->{pbot}->channels->channels }{$channel} or ${ $self->{pbot}->channels->channels }{$channel}{is_op} == 0); + if($length >= $self->{pbot}->{MAX_NICK_MESSAGES}) { + my %msg = %{ shift(@{ ${ $self->message_history }{$account}{$channel}{messages} }) }; + #$self->{pbot}->logger->log("shifting message off top: $msg{msg}, $msg{timestamp}\n"); + $length--; + } - if($mode == $self->{FLOOD_JOIN}) { - if($text =~ /^JOIN/) { + return if ($channel =~ /^#/) and (not exists ${ $self->{pbot}->channels->channels }{$channel} or ${ $self->{pbot}->channels->channels }{$channel}{is_op} == 0); + + if($mode == $self->{FLOOD_JOIN}) { + if($text =~ /^JOIN/) { + ${ $self->message_history }{$account}{$channel}{join_watch}++; + $self->{pbot}->logger->log("$nick $channel joinwatch adjusted: ${ $self->message_history }{$account}{$channel}{join_watch}\n"); + } else { + # PART or QUIT -- check QUIT message for netsplits, and decrement joinwatch if found + if($text =~ /^QUIT .*\.net .*\.split/) { + foreach my $ch (keys %{ $self->message_history->{$account} }) { + next if $ch eq 'hostmask'; # TODO: move channels into {channel} subkey + ${ $self->message_history }{$account}{$ch}{join_watch}--; + ${ $self->message_history }{$account}{$ch}{join_watch} = 0 if ${ $self->message_history }{$account}{$ch}{join_watch} < 0; + $self->{pbot}->logger->log("$nick $ch joinwatch adjusted: ${ $self->message_history }{$account}{$ch}{join_watch}\n"); + } + } elsif($text =~ /^QUIT Ping timeout/) { + # deal with ping timeouts agressively ${ $self->message_history }{$account}{$channel}{join_watch}++; $self->{pbot}->logger->log("$nick $channel joinwatch adjusted: ${ $self->message_history }{$account}{$channel}{join_watch}\n"); - } else { - # PART or QUIT -- check QUIT message for netsplits, and decrement joinwatch if found - if($text =~ /^QUIT .*\.net .*\.split/) { - foreach my $ch (keys %{ $self->message_history->{$account} }) { - next if $ch eq 'hostmask'; # TODO: move channels into {channel} subkey - ${ $self->message_history }{$account}{$ch}{join_watch}--; - ${ $self->message_history }{$account}{$ch}{join_watch} = 0 if ${ $self->message_history }{$account}{$ch}{join_watch} < 0; - $self->{pbot}->logger->log("$nick $ch joinwatch adjusted: ${ $self->message_history }{$account}{$ch}{join_watch}\n"); - } - } elsif($text =~ /^QUIT Ping timeout/) { - # deal with ping timeouts agressively - ${ $self->message_history }{$account}{$channel}{join_watch}++; - $self->{pbot}->logger->log("$nick $channel joinwatchannel adjusted: ${ $self->message_history }{$account}{$channel}{join_watchannel}\n"); - } } - } elsif($mode == $self->{FLOOD_CHAT}) { - ${ $self->message_history }{$account}{$channel}{join_watch} = 0; } + } elsif($mode == $self->{FLOOD_CHAT}) { + ${ $self->message_history }{$account}{$channel}{join_watch} = 0; + } - if($max_messages > 0 and $length >= $max_messages) { - $self->{pbot}->logger->log("More than $max_messages messages, comparing time differences ($max_time)\n") if $mode == $self->{FLOOD_JOIN}; - my %msg = %{ @{ ${ $self->message_history }{$account}{$channel}{messages} }[$length - $max_messages] }; - my %last = %{ @{ ${ $self->message_history }{$account}{$channel}{messages} }[$length - 1] }; + if($max_messages > 0 and $length >= $max_messages) { + $self->{pbot}->logger->log("More than $max_messages messages, comparing time differences ($max_time)\n") if $mode == $self->{FLOOD_JOIN}; + my %msg = %{ @{ ${ $self->message_history }{$account}{$channel}{messages} }[$length - $max_messages] }; + my %last = %{ @{ ${ $self->message_history }{$account}{$channel}{messages} }[$length - 1] }; - $self->{pbot}->logger->log("Comparing " . int($last{timestamp}) . " against " . int($msg{timestamp}) . ": " . (int($last{timestamp} - $msg{timestamp})) . " seconds\n") if $mode == $self->{FLOOD_JOIN}; + $self->{pbot}->logger->log("Comparing " . int($last{timestamp}) . " against " . int($msg{timestamp}) . ": " . (int($last{timestamp} - $msg{timestamp})) . " seconds\n") if $mode == $self->{FLOOD_JOIN}; - 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 }{$account}{$channel}{join_watch} >= $max_messages) { - ${ $self->message_history }{$account}{$channel}{offenses}++; - my $timeout = (2 ** (${ $self->message_history }{$account}{$channel}{offenses} < 6 ? ${ $self->message_history }{$account}{$channel}{offenses} : 6)); - $self->{pbot}->chanops->quiet_user_timed("*!$user\@$host", $channel, $timeout * 60 * 60); - $self->{pbot}->logger->log("$nick!$user\@$host banned for $timeout hours due to join flooding (offense #${ $self->message_history }{$account}{$channel}{offenses}).\n"); - $timeout = "several" if($timeout > 8); - $self->{pbot}->conn->privmsg($nick, "You have been banned from $channel for $timeout hours due to join flooding."); - ${ $self->message_history }{$account}{$channel}{join_watch} = $max_messages - 2; # give them a chance to rejoin - } - } elsif($mode == $self->{FLOOD_CHAT}) { + 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 }{$account}{$channel}{join_watch} >= $max_messages) { ${ $self->message_history }{$account}{$channel}{offenses}++; - my $length = ${ $self->message_history }{$account}{$channel}{offenses} ** ${ $self->message_history }{$account}{$channel}{offenses} * ${ $self->message_history }{$account}{$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); + my $timeout = (2 ** (${ $self->message_history }{$account}{$channel}{offenses} < 6 ? ${ $self->message_history }{$account}{$channel}{offenses} : 6)); + $self->{pbot}->chanops->quiet_user_timed("*!$user\@$host", $channel, $timeout * 60 * 60); + $self->{pbot}->logger->log("$nick!$user\@$host banned for $timeout hours due to join flooding (offense #${ $self->message_history }{$account}{$channel}{offenses}).\n"); + $timeout = "several" if($timeout > 8); + $self->{pbot}->conn->privmsg($nick, "You have been banned from $channel for $timeout hours due to join flooding."); + ${ $self->message_history }{$account}{$channel}{join_watch} = $max_messages - 2; # give them a chance to rejoin + } + } elsif($mode == $self->{FLOOD_CHAT}) { + ${ $self->message_history }{$account}{$channel}{offenses}++; + my $length = ${ $self->message_history }{$account}{$channel}{offenses} ** ${ $self->message_history }{$account}{$channel}{offenses} * ${ $self->message_history }{$account}{$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 }{$account}{$channel}{offenses} earned $length second quiet\n"); + $self->{pbot}->logger->log("$nick $channel flood offense ${ $self->message_history }{$account}{$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 }{$account}{$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."); + $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 }{$account}{$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."); } } } - } else { - #$self->{pbot}->logger->log("brand new nick addition\n"); - # new addition - ${ $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} = []; - ${ $self->message_history }{$nick}{hostmask} = "$nick!$user\@$host"; - push(@{ ${ $self->message_history }{$nick}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode }); } } diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index 9db356f0..14f94af2 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -13,7 +13,7 @@ use warnings; # These are set automatically by the build/commit script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 159, + BUILD_REVISION => 160, BUILD_DATE => "2010-06-11", };