gecko-dev/webtools/mozbot/BotModules/Flood.bm

103 lines
3.6 KiB
Plaintext

# -*- Mode: perl; indent-tabs-mode: nil -*-
# $Id: Flood.bm,v 1.2 2003/10/03 15:46:54 ian%hixie.ch Exp $
###########################
# 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
push(@{$self->{"join_$channel"}}, $event->{'time'});
if (scalar(@{$self->{"join_$channel"}}) >= $self->{'numberOfJoins'}) {
my $oldest = shift(@{$self->{"join_$channel"}});
my $timechange = $event->{'time'} - $oldest;
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(@_);
}
}