# NOTE: Based on code by Kevin Lenzo & Patrick Cole (c) 1997
#
-if (&IsParam("useStrict")) { use strict; }
-
#######################################################################
####### IRC HOOK HELPERS IRC HOOK HELPERS IRC HOOK HELPERS ########
#######################################################################
#####
-# Usage: &hookMode($chan, $modes, @targets);
+# Usage: &hookMode($nick, $modes, @targets);
sub hookMode {
- my ($chan, $modes, @targets) = @_;
+ my ($nick, $modes, @targets) = @_;
my $parity = 0;
- $chan = lc $chan; # !!!.
+ if ($chan =~ tr/A-Z/a-z/) {
+ &VERB("hookMode: cased $chan.",2);
+ }
my $mode;
foreach $mode (split(//, $modes)) {
if ($mode =~ /[bov]/) {
$channels{$chan}{$mode}{$target}++ if $parity;
delete $channels{$chan}{$mode}{$target} if !$parity;
+
+ # lets do some custom stuff.
+ if ($mode eq "o" and $parity) {
+ if ($nick eq "ChanServ" and $target =~ /^\Q$ident\E$/i) {
+ &VERB("hookmode: chanserv deopped us! asking",2);
+ &chanServCheck($chan);
+ }
+
+ &chanLimitVerify($chan);
+ }
}
if ($mode =~ /[l]/) {
$message =~ s/[\cA-\c_]//ig; # strip control characters
$message =~ s/^\s+//; # initial whitespaces.
$who =~ tr/A-Z/a-z/; # lowercase.
+ my $mynick = $conn->nick();
&showProc();
if ($msgType =~ /private/) {
# private messages.
$addressed = 1;
+ if (&IsChanConf('addressCharacter') > 0) {
+ $addressCharacter = getChanConf('addressCharacter');
+ if ($message =~ s/^\Q$addressCharacter\E//) {
+ &msg($who, "The addressCharacter \"$addressCharacter\" is to get my attention in a normal channel. Please leave it off when messaging me directly.");
+ }
+ }
} else {
# public messages.
# addressing revamped by the xk.
### below needs to be fixed...
- if (&IsParam("addressCharacter")) {
- if ($message =~ s/^$param{'addressCharacter'}//) {
+ if (&IsChanConf('addressCharacter') > 0) {
+ $addressCharacter = getChanConf('addressCharacter');
+ if ($message =~ s/^\Q$addressCharacter\E//) {
$addrchar = 1;
$addressed = 1;
}
if ($message =~ /^($mask{nick})([\;\:\>\, ]+) */) {
my $newmessage = $';
- if ($1 =~ /^\Q$ident\E$/i) {
+ if ($1 =~ /^\Q$mynick\E$/i) {
$message = $newmessage;
$addressed = 1;
} else {
# Determine floodwho.
my $c = "_default";
- if ($msgType =~ /public/i) { # public.
+ if ($msgType =~ /public/i) {
+ # public.
$floodwho = $c = lc $chan;
- } elsif ($msgType =~ /private/i) { # private.
+ } elsif ($msgType =~ /private/i) {
+ # private.
$floodwho = lc $who;
- } else { # dcc?
- &DEBUG("FIXME: floodwho = ???");
+ } else {
+ # dcc?
+ &FIXME("floodwho = ???");
}
- my $val = &getChanConfDefault("floodRepeat", "2:10", $c);
+ my $val = &getChanConfDefault("floodRepeat", "2:5", $c);
my ($count, $interval) = split /:/, $val;
# flood repeat protection.
if ($addressed) {
my $time = $flood{$floodwho}{$message} || 0;
- if ($msgType eq "public" and (time() - $time < $interval)) {
+ if (!&hasFlag("o") and $msgType eq "public" and (time() - $time < $interval)) {
### public != personal who so the below is kind of pointless.
my @who;
foreach (keys %flood) {
return if ($lobotomized);
- if (scalar @who) {
- &msg($who, "you already said what ".
- join(' ', @who)." have said.");
- } else {
- &msg($who,"Someone already said that ". (time - $time) ." seconds ago" );
+ if (!scalar @who) {
+ push(@who,"Someone");
}
+ &msg($who,join(' ', @who)." already said that ". (time - $time) ." seconds ago" );
### TODO: delete old floodwarn{} keys.
my $floodwarn = 0;
}
if ($addrchar) {
- &status("$b_cyan$who$ob is short-addressing me");
+ &status("$b_cyan$who$ob is short-addressing $mynick");
} elsif ($msgType eq "private") { # private.
- &status("$b_cyan$who$ob is /msg'ing me");
+ &status("$b_cyan$who$ob is /msg'ing $mynick");
} else { # public?
- &status("$b_cyan$who$ob is addressing me");
+ &status("$b_cyan$who$ob is addressing $mynick");
}
$flood{$floodwho}{$message} = time();
- } elsif ($msgType eq "public" and &IsChanConf("kickOnRepeat")) {
+ } elsif ($msgType eq "public" and &IsChanConf("kickOnRepeat") > 0) {
# unaddressed, public only.
### TODO: use a separate "short-time" hash.
# flood overflow protection.
if ($addressed) {
- foreach (keys %{$flood{$floodwho}}) {
+ foreach (keys %{ $flood{$floodwho} }) {
next unless (time() - $flood{$floodwho}{$_} > $interval);
delete $flood{$floodwho}{$_};
}
- my $i = scalar keys %{$flood{$floodwho}};
+ my $i = scalar keys %{ $flood{$floodwho} };
if ($i > $count) {
- &msg($who,"overflow of messages ($i > $count)");
+ my $expire = $param{'ignoreAutoExpire'} || 5;
+
+# &msg($who,"overflow of messages ($i > $count)");
+ &msg($who,"Too many queries from you, ignoring for $expire minutes.");
&status("FLOOD overflow detected from $floodwho; ignoring");
- my $expire = $param{'ignoreAutoExpire'} || 5;
&ignoreAdd("*!$uh", $chan, $expire, "flood overflow auto-detected.");
return;
}
}
push(@ignore, keys %{ $ignore{"*"} }) if (exists $ignore{"*"});
- if ((!$skipmessage or &IsChanConf("seenStoreAll")) and
- &IsChanConf("seen") and
+ if ((!$skipmessage or &IsChanConf("seenStoreAll") > 0) and
+ &IsChanConf("seen") > 0 and
$msgType =~ /public/
) {
$seencache{$who}{'time'} = time();
$seencache{$who}{'msg'} = $orig{message};
$seencache{$who}{'msgcount'}++;
}
-
+ if (&IsChanConf("minVolunteerLength") > 0) {
+ # FIXME hack to treat unaddressed as if using addrchar
+ $addrchar = 1;
+ }
return if ($skipmessage);
- return unless (&IsParam("minVolunteerLength") or $addressed);
+ return unless ($addrchar or $addressed);
foreach (@ignore) {
s/\*/\\S*/g;
- next unless (eval { $nuh =~ /^$_$/i });
+ next unless (eval { $nuh =~ /^$_$/i } );
+
+ # better to ignore an extra message than to allow one to get
+ # through, although it would be better to go through ignore
+ # checking again.
+ if (time() - ($cache{ignoreCheckTime} || 0) > 60) {
+ &ignoreCheck();
+ }
&status("IGNORE <$who> $message");
return;
# &DEBUG("IrcHooks: process returned '$_'.");
}
+ # hack to remove +o from ppl with +O flag.
+ if (exists $users{$userHandle} && exists $users{$userHandle}{FLAGS} &&
+ $users{$userHandle}{FLAGS} =~ /O/
+ ) {
+ $users{$userHandle}{FLAGS} =~ s/o//g;
+ }
+
return;
}
+# this is basically run on on_join or on_quit
sub chanLimitVerify {
- my($chan) = @_;
+ my($c) = @_;
+ $chan = $c;
my $l = $channels{$chan}{'l'};
+ return unless (&IsChanConf("chanlimitcheck") > 0);
+
+ if (scalar keys %netsplit) {
+ &WARN("clV: netsplit active (1, chan = $chan); skipping.");
+ return;
+ }
+
+ if (!defined $l) {
+ &DEBUG("$chan: running chanlimitCheck from chanLimitVerify.");
+ &chanlimitCheck();
+ return;
+ }
+
# only change it if it's not set.
- if (defined $l and &IsChanConf("chanlimitcheck")) {
- my $plus = &getChanConfDefault("chanlimitcheckPlus", 5, $chan);
- my $count = scalar(keys %{ $channels{$chan}{''} });
+ my $plus = &getChanConfDefault("chanlimitcheckPlus", 5, $chan);
+ my $count = scalar(keys %{ $channels{$chan}{''} });
+ my $int = &getChanConfDefault("chanlimitcheckInterval", 10, $chan);
- my $delta = $count + $plus - $l;
- $delta =~ s/^\-//;
+ my $delta = $count + $plus - $l;
+# $delta =~ s/^\-//;
- if ($plus <= 3) {
- &WARN("clc: stupid to have plus at $plus, fix it!");
- }
+ if ($plus <= 3) {
+ &WARN("clc: stupid to have plus at $plus, fix it!");
+ }
- if (exists $cache{chanlimitChange_$chan}) {
- if (time() - $cache{chanlimitChange_$chan} < 60) {
- &DEBUG("not going to change chanlimit!");
- return;
- }
- delete $cache{chanlimitChange_$chan};
+ if (exists $cache{chanlimitChange}{$chan}) {
+ if (time() - $cache{chanlimitChange}{$chan} < $int*60) {
+ return;
}
+ }
- ### todo: check if we have ops.
- ### todo: if not, check if nickserv/chanserv is avail.
- ### todo: unify code with chanlimitcheck()
- if ($delta > 5) {
- &status("clc: big change in limit; changing.");
- &rawout("MODE $chan +l ".($count+$plus) );
- }
+ &chanServCheck($chan);
+
+ ### TODO: unify code with chanlimitcheck()
+ return if ($delta > 5);
+
+ &status("clc: big change in limit for $chan ($delta);".
+ "going for it. (was: $l; now: ".($count+$plus).")");
+
+ $conn->mode($chan, "+l", $count+$plus);
+ $cache{chanlimitChange}{$chan} = time();
+}
+
+sub chanServCheck {
+ ($chan) = @_;
+
+ if (!defined $chan or $chan =~ /^\s*$/) {
+ &WARN("chanServCheck: chan == NULL.");
+ return 0;
+ }
+
+ if ($chan =~ tr/A-Z/a-z/) {
+ &DEBUG("chanServCheck: lowercased chan ($chan)");
}
+
+ if (! &IsChanConf("chanServ_ops") > 0) {
+ return 0;
+ }
+
+ &VERB("chanServCheck($chan) called.",2);
+
+ if ( &IsParam("nickServ_pass") and !$nickserv) {
+ $conn->who("NickServ");
+ return 0;
+ }
+
+ # check for first hash then for next hash.
+ # TODO: a function for &ischanop()? &isvoice()?
+ if (exists $channels{$chan} and exists $channels{$chan}{'o'}{$ident}) {
+ return 0;
+ }
+
+ &status("ChanServ ==> Requesting ops for $chan. (chanServCheck)");
+ &rawout("PRIVMSG ChanServ :OP $chan $ident");
+ return 1;
}
1;