mirror of https://github.com/pragma-/pbot.git
109 lines
3.8 KiB
Perl
109 lines
3.8 KiB
Perl
|
# File: NewModule.pm
|
||
|
# Authoer: pragma_
|
||
|
#
|
||
|
# Purpose: New module skeleton
|
||
|
|
||
|
package PBot::AntiFlood;
|
||
|
|
||
|
use warnings;
|
||
|
use strict;
|
||
|
|
||
|
BEGIN {
|
||
|
use Exporter ();
|
||
|
use vars qw($VERSION @ISA @EXPORT_OK);
|
||
|
|
||
|
$VERSION = $PBot::PBot::VERSION;
|
||
|
@ISA = qw(Exporter);
|
||
|
@EXPORT_OK = qw($logger $botnick %flood_watch $MAX_NICK_MESSAGES $FLOOD_CHAT $conn $last_timestamp $flood_msg
|
||
|
%channels);
|
||
|
}
|
||
|
|
||
|
use vars @EXPORT_OK;
|
||
|
|
||
|
use Time::HiRes qw(gettimeofday);
|
||
|
|
||
|
*logger = \$PBot::PBot::logger;
|
||
|
*botnick = \$PBot::PBot::botnick;
|
||
|
*conn = \$PBot::PBot::conn;
|
||
|
*MAX_NICK_MESSAGES = \$PBot::PBot::MAX_NICK_MESSAGES;
|
||
|
*channels = \%PBot::ChannelStuff::channels;
|
||
|
|
||
|
# do not modify
|
||
|
$FLOOD_CHAT = 0;
|
||
|
#$FLOOD_JOIN = 1; # currently unused -- todo?
|
||
|
|
||
|
$last_timestamp = gettimeofday;
|
||
|
$flood_msg = 0;
|
||
|
|
||
|
%flood_watch = ();
|
||
|
|
||
|
sub check_flood {
|
||
|
my ($channel, $nick, $user, $host, $text, $max, $mode) = @_;
|
||
|
my $now = gettimeofday;
|
||
|
|
||
|
$channel = lc $channel;
|
||
|
|
||
|
$logger->log(sprintf("check flood %-48s %-16s %s\n", "$nick!$user\@$host", "[$channel]", $text));
|
||
|
|
||
|
return if $nick eq $botnick;
|
||
|
|
||
|
if(exists $flood_watch{$nick}) {
|
||
|
#$logger->log("nick exists\n");
|
||
|
|
||
|
if(not exists $flood_watch{$nick}{$channel}) {
|
||
|
#$logger->log("adding new channel for existing nick\n");
|
||
|
$flood_watch{$nick}{$channel}{offenses} = 0;
|
||
|
$flood_watch{$nick}{$channel}{messages} = [];
|
||
|
}
|
||
|
|
||
|
#$logger->log("appending new message\n");
|
||
|
|
||
|
push(@{ $flood_watch{$nick}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode });
|
||
|
|
||
|
my $length = $#{ $flood_watch{$nick}{$channel}{messages} } + 1;
|
||
|
|
||
|
#$logger->log("length: $length, max nick messages: $MAX_NICK_MESSAGES\n");
|
||
|
|
||
|
if($length >= $MAX_NICK_MESSAGES) {
|
||
|
my %msg = %{ shift(@{ $flood_watch{$nick}{$channel}{messages} }) };
|
||
|
#$logger->log("shifting message off top: $msg{msg}, $msg{timestamp}\n");
|
||
|
$length--;
|
||
|
}
|
||
|
|
||
|
return if not exists $channels{$channel} or $channels{$channel}{is_op} == 0;
|
||
|
|
||
|
#$logger->log("length: $length, max: $max\n");
|
||
|
|
||
|
if($length >= $max) {
|
||
|
# $logger->log("More than $max messages spoken, comparing time differences\n");
|
||
|
my %msg = %{ @{ $flood_watch{$nick}{$channel}{messages} }[$length - $max] };
|
||
|
my %last = %{ @{ $flood_watch{$nick}{$channel}{messages} }[$length - 1] };
|
||
|
|
||
|
#$logger->log("Comparing $last{timestamp} against $msg{timestamp}: " . ($last{timestamp} - $msg{timestamp}) . " seconds\n");
|
||
|
|
||
|
if($last{timestamp} - $msg{timestamp} <= 10 && not PBot::BotAdminStuff::loggedin($nick, $host)) {
|
||
|
$flood_watch{$nick}{$channel}{offenses}++;
|
||
|
my $length = $flood_watch{$nick}{$channel}{offenses} * $flood_watch{$nick}{$channel}{offenses} * 30;
|
||
|
if($channel =~ /^#/) { #channel flood (opposed to private message or otherwise)
|
||
|
if($mode == $FLOOD_CHAT) {
|
||
|
PBot::OperatorStuff::quiet_nick_timed($nick, $channel, $length);
|
||
|
$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 seconds.");
|
||
|
$logger->log("$nick $channel flood offense $flood_watch{$nick}{$channel}{offenses} earned $length second quiet\n");
|
||
|
}
|
||
|
} else { # private message flood
|
||
|
$logger->log("$nick msg flood offense $flood_watch{$nick}{$channel}{offenses} earned $length second ignore\n");
|
||
|
PBot::IgnoreList::ignore_user("", "floodcontrol", "", "$nick" . '@' . "$host $channel $length");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
#$logger->log("brand new nick addition\n");
|
||
|
# new addition
|
||
|
$flood_watch{$nick}{$channel}{offenses} = 0;
|
||
|
$flood_watch{$nick}{$channel}{messages} = [];
|
||
|
push(@{ $flood_watch{$nick}{$channel}{messages} }, { timestamp => $now, msg => $text, mode => $mode });
|
||
|
}
|
||
|
}
|
||
|
|
||
|
1;
|