2001-08-14 20:53:30 +04:00
|
|
|
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
2003-10-03 19:47:35 +04:00
|
|
|
# $Id: Flood.bm,v 1.2 2003-10-03 15:46:54 ian%hixie.ch Exp $
|
2001-08-14 20:53:30 +04:00
|
|
|
###########################
|
|
|
|
# Flood Protection module #
|
|
|
|
###########################
|
|
|
|
|
|
|
|
package BotModules::Flood;
|
|
|
|
use vars qw(@ISA);
|
|
|
|
@ISA = qw(BotModules);
|
|
|
|
1;
|
|
|
|
|
|
|
|
sub RegisterConfig {
|
|
|
|
my $self = shift;
|
|
|
|
$self->SUPER::RegisterConfig(@_);
|
|
|
|
|
|
|
|
foreach my $chan (@{$self->{'channels'}}) {
|
|
|
|
$self->registerVariables( ["join_$chan", 0, 0, []] );
|
|
|
|
}
|
|
|
|
$self->registerVariables(
|
|
|
|
['numberOfJoins', 1, 1, '7'],
|
|
|
|
['secondsToTrigger', 1, 1, '2'],
|
|
|
|
['minutesToProtect', 1, 1, '5'],
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub Help {
|
|
|
|
my $self = shift;
|
|
|
|
my ($event) = @_;
|
|
|
|
return {
|
|
|
|
'' => 'This module will help control "join flood" attacks on IRC',
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
# Set - called to set a variable to a particular value.
|
|
|
|
sub Set {
|
|
|
|
my $self = shift;
|
|
|
|
my ($event, $variable, $value) = @_;
|
|
|
|
# If changing the setting for numberOfJoins make sure
|
|
|
|
# that the arrays are empty. Otherwise, reducing the
|
|
|
|
# numberOfJoins value would not work properly.
|
|
|
|
if ($variable eq 'numberOfJoins') {
|
|
|
|
foreach my $chan (@{$self->{'channels'}}) {
|
|
|
|
@{$self->{"join_$chan"}} = ();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# now actually do the setting of the variable
|
|
|
|
return $self->SUPER::Set($event, $variable, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
sub JoinedChannel {
|
|
|
|
my $self = shift;
|
|
|
|
my ($event, $channel) = @_;
|
|
|
|
$self->registerVariables( ["join_$channel", 0, 0, []] );
|
|
|
|
return $self->SUPER::JoinedChannel($event, $channel); # call inherited method
|
|
|
|
}
|
|
|
|
|
|
|
|
sub SpottedJoin {
|
|
|
|
my $self = shift;
|
|
|
|
my ($event, $channel, $who) = @_;
|
|
|
|
# If numberOfJoins or secondsToTrigger is not a positive Integer, don't do anything
|
|
|
|
if ($self->{'numberOfJoins'} !~ m/^[1-9][0-9]*$/o || $self->{'secondsToTrigger'} !~ m/^[1-9][0-9]*$/o) {
|
|
|
|
# We didn't do anything, so don't pretend like we did :)
|
|
|
|
return $self->SUPER::SpottedJoin($event, $channel, $who);
|
|
|
|
}
|
|
|
|
# Here we have the 'join_times' array to push and shift to/from
|
2003-10-03 19:47:35 +04:00
|
|
|
push(@{$self->{"join_$channel"}}, $event->{'time'});
|
2001-08-14 20:53:30 +04:00
|
|
|
if (scalar(@{$self->{"join_$channel"}}) >= $self->{'numberOfJoins'}) {
|
|
|
|
my $oldest = shift(@{$self->{"join_$channel"}});
|
2003-10-03 19:47:35 +04:00
|
|
|
my $timechange = $event->{'time'} - $oldest;
|
2001-08-14 20:53:30 +04:00
|
|
|
if ($self->{'secondsToTrigger'} >= $timechange) {
|
|
|
|
# We have just seen many joins happen very quickly. This channel should
|
|
|
|
# have its mode set to +i until an op can figure out what went wrong.
|
|
|
|
$self->mode($event, $event->{'channel'}, '+i');
|
|
|
|
my $extra_text = "";
|
|
|
|
# If minutesToProtect is a positive integer we should set mode -i after
|
|
|
|
# that number of minutes has passed.
|
|
|
|
if ($self->{'minutesToProtect'} =~ m/^[1-9][0-9]*$/o) {
|
|
|
|
my $seconds = $self->{'minutesToProtect'} * 60;
|
|
|
|
my @mode = ('mode', $event->{'channel'}, '-i');
|
|
|
|
$self->schedule($event, $seconds, 1, @mode);
|
|
|
|
$extra_text = "I'll set it -i in $self->{'minutesToProtect'} minutes";
|
|
|
|
}
|
|
|
|
$self->say($event, "I just saw a lot of joins happen very quickly. Because of " .
|
|
|
|
"that I set this channel's mode to be Invite Only... $extra_text");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
# By returning 0 we ensure that a join won't be processed more than once.
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub Scheduled {
|
|
|
|
my $self = shift;
|
|
|
|
my ($event, @data) = @_;
|
|
|
|
|
|
|
|
my $what = shift(@data);
|
|
|
|
if ($what eq 'mode') {
|
|
|
|
$self->mode($event, @data);
|
|
|
|
} else {
|
|
|
|
# Call the inherited event
|
|
|
|
return $self->SUPER::Schedule(@_);
|
|
|
|
}
|
|
|
|
}
|