X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2FIRC%2FIrcHelpers.pl;h=ad5ec8ba52ae3c42e82fb9d6108dba80113ff4ec;hb=3e80b587d8a517bbefd5d4d53d528a2c93aacb84;hp=fc96d2830552281bd702fb6fee1c34f49068e271;hpb=f157fbbfa81c71c2e68ed701bf18638e247d938c;p=infobot.git diff --git a/src/IRC/IrcHelpers.pl b/src/IRC/IrcHelpers.pl index fc96d28..ad5ec8b 100644 --- a/src/IRC/IrcHelpers.pl +++ b/src/IRC/IrcHelpers.pl @@ -6,8 +6,6 @@ # 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 ######## ####################################################################### @@ -45,13 +43,18 @@ sub hookMode { # modes w/ target affecting nick => cache it. if ($mode =~ /[bov]/) { - if ($mode eq "o" and $nick eq "ChanServ" and $target =~ /^\Q$ident$\E/i) { - &DEBUG("hookmode: chanserv deopped us! asking"); - &chanServCheck($chan); - } - $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]/) { @@ -80,6 +83,7 @@ sub hookMsg { $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(); @@ -87,20 +91,34 @@ sub hookMsg { 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/^\Q$param{'addressCharacter'}\E//) { + if (&IsChanConf('addressCharacter') > 0) { + $addressCharacter = getChanConf('addressCharacter'); + if ($message =~ s/^\Q$addressCharacter\E//) { $addrchar = 1; $addressed = 1; } + elsif ($message =~ s/^\Q~\E//){ + @chans = &getNickInChans('apt'); + if (not grep $chan, @chans){ + $addrchar = 1; + $addressed = 1; + } + } } - if ($message =~ /^($mask{nick})([\;\:\>\, ]+) */) { + if (!$addressed and $message =~ /^($mask{nick})([\;\:\>\, ]+) */) { my $newmessage = $'; - if ($1 =~ /^\Q$ident\E$/i) { + if ($1 =~ /^\Q$mynick\E$/i) { $message = $newmessage; $addressed = 1; } else { @@ -112,22 +130,25 @@ sub hookMsg { # 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 (!&IsFlag('o') and $msgType eq "public" and (time() - $time < $interval)) { ### public != personal who so the below is kind of pointless. my @who; foreach (keys %flood) { @@ -139,12 +160,10 @@ sub hookMsg { 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; @@ -163,15 +182,15 @@ sub hookMsg { } 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. @@ -191,10 +210,12 @@ sub hookMsg { 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; } @@ -210,16 +231,25 @@ sub hookMsg { } elsif ($msgType =~ /private/i) { # private. &status("[$orig{who}] $orig{message}"); $talkchannel = undef; - $chan = "_default"; + $chan = '_default'; } else { &DEBUG("unknown msgType => $msgType."); } - push(@ignore, keys %{ $ignore{"*"} }) if (exists $ignore{"*"}); - - if ((!$skipmessage or &IsChanConf("seenStoreAll")) and - &IsChanConf("seen") and - $msgType =~ /public/ - ) { + push(@ignore, keys %{ $ignore{'*'} }) if (exists $ignore{'*'}); + + if ((!$skipmessage or &IsChanConf('seenStoreAll') > 0) and + &IsChanConf('sed') > 0 and &IsChanConf('seen') > 0 and + $msgType =~ /public/ and + $orig{message} =~ /^s\/([^;\/]*)\/([^;\/]*)\/([g]*)$/) { + my $sedmsg = $seencache{$who}{'msg'}; + eval "\$sedmsg =~ s/\Q$1\E/\Q$2\E/$3;"; + if ($sedmsg ne $seencache{$who}{'msg'}) { + &DEBUG("sed \"" . $orig{message} . "\" \"" . + $seencache{$who}{'msg'} . "\" \"" . $sedmsg. "\""); + &msg($talkchannel, "$orig{who} meant: $sedmsg"); + } + } elsif ((!$skipmessage or &IsChanConf('seenStoreAll') > 0) and + &IsChanConf('seen') > 0 and $msgType =~ /public/) { $seencache{$who}{'time'} = time(); $seencache{$who}{'nick'} = $orig{who}; $seencache{$who}{'host'} = $uh; @@ -227,14 +257,24 @@ sub hookMsg { $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; @@ -254,52 +294,69 @@ sub hookMsg { # &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'}; - if (scalar keys %netsplitservers) { - &WARN("clV: netsplit active (1); skipping. (netsplit => $netsplit)"); + 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 $int = &getChanConfDefault("chanlimitcheckInterval", 10, $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} < $int*60) { - return; - } + if (exists $cache{chanlimitChange}{$chan}) { + if (time() - $cache{chanlimitChange}{$chan} < $int*60) { + return; } + } - &chanServCheck($chan); + &chanServCheck($chan); - ### todo: unify code with chanlimitcheck() - if ($delta > 5) { - &status("clc: big change in limit; changing."); - &rawout("MODE $chan +l ".($count+$plus) ); - $cache{chanlimitChange}{$chan} = time(); - } - } + ### 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 =~ /^$/) { + if (!defined $chan or $chan =~ /^\s*$/) { &WARN("chanServCheck: chan == NULL."); return 0; } @@ -308,17 +365,22 @@ sub chanServCheck { &DEBUG("chanServCheck: lowercased chan ($chan)"); } - if (! &IsChanConf("chanServ_ops") ) { + if (! &IsChanConf("chanServ_ops") > 0) { return 0; } - &DEBUG("chanServCheck($chan) called."); + &VERB("chanServCheck($chan) called.",2); if ( &IsParam("nickServ_pass") and !$nickserv) { - &DEBUG("chanServ_ops($chan): nickserv enabled but not alive? (ircCheck)"); + $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; } - return 0 if (exists $channels{$chan}{'o'}{$ident}); &status("ChanServ ==> Requesting ops for $chan. (chanServCheck)"); &rawout("PRIVMSG ChanServ :OP $chan $ident");