X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=src%2FIRC%2FIrcHooks.pl;h=461d9de730b69a5ba45c33c878bc8d6fc60d4b4e;hb=79ddec2f34e07300f6fdb0803b56746b8399c0f4;hp=f716b6f9ff7e71bdc73310837bf3297a35016b7c;hpb=e00f8cdfd78b4098a0c0d2aedf6ac2d57a0ba1b7;p=infobot.git diff --git a/src/IRC/IrcHooks.pl b/src/IRC/IrcHooks.pl index f716b6f..461d9de 100644 --- a/src/IRC/IrcHooks.pl +++ b/src/IRC/IrcHooks.pl @@ -7,8 +7,6 @@ if (&IsParam("useStrict")) { use strict; } -my $nickserv = 0; - # GENERIC. TO COPY. sub on_generic { my ($self, $event) = @_; @@ -41,39 +39,44 @@ sub on_chat { my ($self, $event) = @_; my $msg = ($event->args)[0]; my $sock = ($event->to)[0]; - my $nick = $event->nick(); + my $nick = lc $event->nick(); - if (!exists $nuh{lc $nick}) { - &DEBUG("chat: nuh{$nick} doesn't exist; hrm should retry."); - &msg($nick, "could not get whois info?"); + if (!exists $nuh{$nick}) { + &DEBUG("chat: nuh{$nick} doesn't exist; trying WHOIS ."); + $self->whois($nick); return; - } else { - $message = $msg; - $who = lc $nick; - $orig{who} = $nick; - $orig{message} = $msg; - $nuh = $nuh{$who}; - $uh = (split /\!/, $nuh)[1]; - $addressed = 1; - $msgType = 'chat'; } + ### set vars that would have been set in hookMsg. + $userHandle = ""; # reset. + $who = lc $nick; + $message = $msg; + $orig{who} = $nick; + $orig{message} = $msg; + $nuh = $nuh{$who}; + $uh = (split /\!/, $nuh)[1]; + $addressed = 1; + $msgType = 'chat'; + if (!exists $dcc{'CHATvrfy'}{$nick}) { $userHandle = &verifyUser($who, $nuh); my $crypto = $users{$userHandle}{PASS}; my $success = 0; + ### TODO: prevent users without CRYPT chatting. if (!defined $crypto) { - &DEBUG("chat: no pass required."); - $success++; + &DEBUG("todo: dcc close chat"); + &msg($who, "nope, no guest logins allowed..."); + return; + } - } elsif (&ckpasswd($msg, $crypto)) { + if (&ckpasswd($msg, $crypto)) { # stolen from eggdrop. $self->privmsg($sock, "Connected to $ident"); $self->privmsg($sock, "Commands start with '.' (like '.quit' or '.help')"); $self->privmsg($sock, "Everything else goes out to the party line."); - &dccStatus(2) if (scalar keys %{ $dcc{'CHAT'} } == 1); + &dccStatus(2) unless (exists $sched{"dccStatus"}{RUNNING}); $success++; @@ -88,28 +91,23 @@ sub on_chat { if ($success) { &status("DCC CHAT: user $nick is here!"); -# &DCCBroadcast("$nick ($uh) has joined the chat arena."); &DCCBroadcast("*** $nick ($uh) joined the party line."); - $dcc{'CHATvrfy'}{$nick} = 1; - if ($userHandle ne "_default") { - &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}"); - } + $dcc{'CHATvrfy'}{$nick} = $userHandle; + + return if ($userHandle eq "_default"); + + &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}"); } return; } - if (defined $userHandle) { - &DEBUG("IrcHooks.pl: line 104: remove vUser"); - } - - $userHandle = &verifyUser($who, $nuh); &status("$b_red=$b_cyan$who$b_red=$ob $message"); if ($message =~ s/^\.//) { # dcc chat commands. ### TODO: make use of &Forker(); here? - &loadMyModule($myModules{'ircdcc'}); + &loadMyModule( $myModules{'ircdcc'} ); &DCCBroadcast("#$who# $message","m"); @@ -137,8 +135,22 @@ sub on_endofmotd { # update IRCStats. $ircstats{'ConnectTime'} = time(); $ircstats{'ConnectCount'}++; + $ircstats{'OffTime'} += time() - $ircstats{'DisconnectTime'} + if (defined $ircstats{'DisconnectTime'}); + + # first time run. + if (!exists $users{_default}) { + &status("First time run... adding _default user."); + $users{_default}{FLAGS} = "mrt"; + $users{_default}{HOSTS} = "*!*@*"; + } + + if (scalar keys %users < 2) { + &status("Ok... now /msg $ident PASS to get master access through DCC CHAT."); + } + # end of first time run. - if (&IsParam("wingate")) { + if (&IsChanConf("wingate")) { my $file = "$bot_base_dir/$param{'ircUser'}.wingate"; open(IN, $file); while () { @@ -150,7 +162,7 @@ sub on_endofmotd { } if ($firsttime) { - $conn->schedule(60, \&setupSchedulers, ""); + &ScheduleThis(1, \&setupSchedulers); $firsttime = 0; } @@ -171,10 +183,13 @@ sub on_endofmotd { sub on_dcc { my ($self, $event) = @_; my $type = uc( ($event->args)[1] ); - my $nick = $event->nick(); + my $nick = lc $event->nick(); # pity Net::IRC doesn't store nuh. Here's a hack :) - $self->whois($nick); + if (!exists $nuh{lc $nick}) { + $self->whois($nick); + $nuh{$nick} = "GETTING-NOW"; # trying. + } $type ||= "???"; if ($type eq 'SEND') { # GET for us. @@ -190,10 +205,10 @@ sub on_dcc { \*DCCGET ); } elsif ($type eq 'GET') { # SEND for us? - &DEBUG("starting get."); + &status("DCC: Initializing SEND for $nick."); $self->new_send($event->args); } elsif ($type eq 'CHAT') { - &DEBUG("starting chat."); + &status("DCC: Initializing CHAT for $nick."); $self->new_chat($event); } else { &WARN("${b_green}DCC $type$ob (1)"); @@ -211,8 +226,6 @@ sub on_dcc_close { &delForked($forker); } - &DEBUG("dcc_close: nick => '$nick'."); - if (exists $dcc{'SEND'}{$nick} and -f "$param{tempDir}/$nick.txt") { &status("${b_green}DCC SEND$ob close from $b_cyan$nick$ob"); @@ -223,6 +236,7 @@ sub on_dcc_close { } elsif (exists $dcc{'CHAT'}{$nick} and $dcc{'CHAT'}{$nick} eq $sock) { &status("${b_green}DCC CHAT$ob close from $b_cyan$nick$ob"); delete $dcc{'CHAT'}{$nick}; + delete $dcc{'CHATvrfy'}{$nick}; } else { &status("${b_green}DCC$ob UNKNOWN close from $b_cyan$nick$ob (2)"); } @@ -231,37 +245,66 @@ sub on_dcc_close { sub on_dcc_open { my ($self, $event) = @_; my $type = uc( ($event->args)[0] ); - my $nick = $event->nick(); + my $nick = lc $event->nick(); my $sock = ($event->to)[0]; - $msgType = 'chat'; + $msgType = 'chat'; $type ||= "???"; + ### BUG: who is set to bot's nick? + # lets do it. if ($type eq 'SEND') { &status("${b_green}DCC lGET$ob established with $b_cyan$nick$ob"); - } elsif ($type eq 'CHAT') { - &status("${b_green}DCC CHAT$ob established with $b_cyan$nick$ob $b_yellow($ob$nuh{$nick}$b_yellow)$ob"); - $userHandle = &verifyUser($nick, $nuh{lc $nick}); - my $crypto = $users{$userHandle}{PASS}; - $dcc{'CHAT'}{$nick} = $sock; - foreach (keys %{ $users{$userHandle} }) { - &VERB(" $_ => $users{$userHandle}{$_}",2); - } - - if (defined $crypto) { -### &dccsay($nick,"Enter your password, $userHandle."); - &dccsay($nick,"Enter your password."); + } elsif ($type eq 'CHAT') { + # very cheap hack. + ### TODO: run ScheduleThis inside on_dcc_open_chat recursively + ### 1,3,5,10 seconds then fail. + if ($nuh{$nick} eq "GETTING-NOW") { + &ScheduleThis(3/60, "on_dcc_open_chat", $nick, $sock); } else { - &dccsay($nick,"Welcome to blootbot DCC CHAT interface, $userHandle."); + on_dcc_open_chat(undef, $nick, $sock); } + } elsif ($type eq 'SEND') { &DEBUG("Starting DCC receive."); foreach ($event->args) { &DEBUG(" => '$_'."); } + } else { &WARN("${b_green}DCC $type$ob (3)"); + + } +} + +# really custom sub to get NUH since Net::IRC doesn't appear to support +# it. +sub on_dcc_open_chat { + my(undef, $nick, $sock) = @_; + + if ($nuh{$nick} eq "GETTING-NOW") { + &DEBUG("getting nuh for $nick failed. FIXME."); + return; + } + + &status("${b_green}DCC CHAT$ob established with $b_cyan$nick$ob $b_yellow($ob$nuh{$nick}$b_yellow)$ob"); + + &verifyUser($nick, $nuh{lc $nick}); + + if (!exists $users{$userHandle}{HOSTS}) { + &pSReply("you have no hosts defined in my user file; rejecting."); + ### TODO: $sock->close(); + return; + } + + my $crypto = $users{$userHandle}{PASS}; + $dcc{'CHAT'}{$nick} = $sock; + + if (defined $crypto) { + &dccsay($nick,"Enter your password."); + } else { + &dccsay($nick,"Welcome to blootbot DCC CHAT interface, $userHandle."); } } @@ -274,6 +317,7 @@ sub on_disconnect { $ircstats{'DisconnectTime'} = time(); $ircstats{'DisconnectReason'} = $what; $ircstats{'DisconnectCount'}++; + $ircstats{'TotalTime'} += time() - $ircstats{'ConnectTime'}; # clear any variables on reconnection. $nickserv = 0; @@ -281,7 +325,7 @@ sub on_disconnect { &clearIRCVars(); if (!$self->connect()) { &WARN("not connected? help me. gonna call ircCheck() in 1800s"); - $conn->schedule(1800, \&ircCheck(), ""); + &ScheduleThis(30, "ircCheck"); } } @@ -289,8 +333,8 @@ sub on_endofnames { my ($self, $event) = @_; my $chan = ($event->args)[1]; - if (exists $jointime{$chan}) { - my $delta_time = sprintf("%.03f", &gettimeofday() - $jointime{$chan}); + if (exists $cache{jointime}{$chan}) { + my $delta_time = sprintf("%.03f", &gettimeofday() - $cache{jointime}{$chan}); $delta_time = 0 if ($delta_time < 0); &status("$b_blue$chan$ob: sync in ${delta_time}s."); @@ -301,7 +345,7 @@ sub on_endofnames { my $txt; my @array; foreach ("o","v","") { - my $count = scalar(keys %{$channels{$chan}{$_}}); + my $count = scalar(keys %{ $channels{$chan}{$_} }); next unless ($count); $txt = "total" if ($_ eq ""); @@ -316,16 +360,16 @@ sub on_endofnames { if (scalar @joinchan) { # remaining channels to join. &joinNextChan(); } else { - ### chanserv support. - ### TODO: what if we rejoin a channel.. need to set a var that - ### we've done the request-for-ops-on-join. - return unless (&IsChanConf("chanServ_ops") > 0); - return unless ($nickserv); - - if (!exists $channels{$chan}{'o'}{$ident}) { - &status("ChanServ ==> Requesting ops for $chan."); - &rawout("PRIVMSG ChanServ :OP $chan $ident"); - } + &DEBUG("running ircCheck to get chanserv ops."); + &ircCheck(); + } + + return unless (&IsChanConf("chanServ_ops") > 0); + return unless ($nickserv); + + if (!exists $channels{$chan}{'o'}{$ident}) { + &status("ChanServ ==> Requesting ops for $chan."); + &rawout("PRIVMSG ChanServ :OP $chan $ident"); } } @@ -339,19 +383,16 @@ sub on_init { sub on_invite { my ($self, $event) = @_; - my $chan = ($event->args)[0]; + my $chan = lc( ($event->args)[0] ); my $nick = $event->nick; - &DEBUG("on_invite: chan => '$chan', nick => '$nick'."); - - # chan + possible_key. - ### do we need to know the key if we're invited??? - ### grep the channel list? - foreach (split /[\s\t]+/, $param{'join_channels'}) { - next unless /^\Q$chan\E(,\S+)?$/i; - s/,/ /; + if ($nick =~ /^\Q$ident\E$/) { + &DEBUG("on_invite: self invite."); + return; + } - next if ($nick =~ /^\Q$ident\E$/); + ### TODO: join key. + if (exists $chanconf{$chan}) { if (&validChan($chan)) { &msg($who, "i'm already in \002$chan\002."); next; @@ -369,7 +410,7 @@ sub on_join { $who = $event->nick(); $chanstats{$chan}{'Join'}++; - $userstats{lc $who}{'Join'} = time() if (&IsParam("seenStats")); + $userstats{lc $who}{'Join'} = time() if (&IsChanConf("seenStats")); &joinfloodCheck($who, $chan, $event->userhost); @@ -381,7 +422,7 @@ sub on_join { } if ($netsplit and !$netsplittime) { - &status("ok.... re-running chanlimitCheck in 60."); + &DEBUG("on_join: ok.... re-running chanlimitCheck in 60."); $conn->schedule(60, sub { &chanlimitCheck(); $netsplittime = undef; @@ -397,40 +438,66 @@ sub on_join { &status(">>> join/$b_blue$chan$ob $b_cyan$who$ob $b_yellow($ob$user\@$host$b_yellow)$ob$netsplitstr"); $channels{$chan}{''}{$who}++; - $nuh{lc $who} = $who."!".$user."\@".$host unless (exists $nuh{lc $who}); + $nuh = $who."!".$user."\@".$host; + $nuh{lc $who} = $nuh unless (exists $nuh{lc $who}); + + ### on-join bans. + my @bans; + push(@bans, keys %{ $bans{$chan} }) if (exists $bans{$chan}); + push(@bans, keys %{ $bans{"*"} }) if (exists $bans{"*"}); + foreach (@bans) { + my $ban = $_; + s/\?/./g; + s/\*/\\S*/g; + my $mask = $_; + next unless ($nuh =~ /^$mask$/i); + + ### TODO: check $channels{$chan}{'b'} if ban already exists. + foreach (keys %{ $channels{$chan}{'b'} }) { + &DEBUG(" bans_on_chan($chan) => $_"); + } - ### on-join ban. (TODO: kick) - if (exists $bans{$chan}) { - ### TODO: need to do $chan and _default - foreach (keys %{ $bans{$chan} }) { - s/\*/\\S*/g; - next unless /^\Q$nuh\E$/i; + my $reason = "no reason"; + foreach ($chan, "*") { + next unless (exists $bans{$_}); + next unless (exists $bans{$_}{$ban}); - foreach (keys %{ $channels{$chan}{'b'} }) { - &DEBUG(" bans_on_chan($chan) => $_"); - } + my @array = @{ $bans{$_}{$ban} }; - ### TODO: check $channels{$chan}{'b'} if ban already exists. - &ban( "*!*@".&makeHostMask($host), $chan); + $reason = $array[4] if ($array[4]); last; } + + &ban($ban, $chan); + &kick($who, $chan, $reason); + + last; } ### ROOTWARN: &rootWarn($who,$user,$host,$chan) - if (&IsParam("rootWarn") && + if (&IsChanConf("rootWarn") && $user =~ /^r(oo|ew|00)t$/i && $channels{$chan}{'o'}{$ident}); + ### NEWS: + if (&IsChanConf("news") && &IsChanConf("newsKeepRead")) { + # todo: what if it hasn't been loaded? + &News::latest($chan); + } + + ### chanlimit check. + &chanLimitVerify($chan); + # used to determine sync time. if ($who =~ /^$ident$/i) { - if (defined( my $whojoin = $joinverb{$chan} )) { + if (defined( my $whojoin = $cache{join}{$chan} )) { &msg($chan, "Okay, I'm here. (courtesy of $whojoin)"); - delete $joinverb{$chan}; + delete $cache{join}{$chan}; } ### TODO: move this to &joinchan()? - $jointime{$chan} = &gettimeofday(); + $cache{jointime}{$chan} = &gettimeofday(); rawout("WHO $chan"); } else { ### TODO: this may go wild on a netjoin :) @@ -494,6 +561,15 @@ sub on_msg { ($user,$host) = split(/\@/, $event->userhost); $uh = $event->userhost(); $nuh = $nick."!".$uh; + $msgtime = time(); + + if ($nick eq $ident) { # hopefully ourselves. + if ($msg eq "TEST") { + &status("IRCTEST: Yes, we're alive."); + delete $cache{connect}; + return; + } + } &hookMsg('private', undef, $nick, $msg); } @@ -560,7 +636,11 @@ sub on_notice { if ($nick =~ /^NickServ$/i) { # nickserv. &status("NickServ: <== '$args'"); - if ($args =~ /^This nickname is registered/i) { + my $check = 0; + $check++ if ($args =~ /^This nickname is registered/i); + $check++ if ($args =~ /nickname.*owned/i); + + if ($check) { &status("nickserv told us to register; doing it."); if (&IsParam("nickServ_pass")) { &status("NickServ: ==> Identifying."); @@ -602,16 +682,14 @@ sub on_part { my $nick = $event->nick; my $userhost = $event->userhost; - if (!exists $floodjoin{$chan}{$nick}{Time}) { - &WARN("on_part: $nick/$chan not in floodjoin hash?"); - } else { + if (exists $floodjoin{$chan}{$nick}{Time}) { delete $floodjoin{$chan}{$nick}; } $chanstats{$chan}{'Part'}++; &DeleteUserInfo($nick,$chan); &clearChanVars($chan) if ($nick eq $ident); - if (!&IsNickInAnyChan($nick) and &IsParam("seenStats")) { + if (!&IsNickInAnyChan($nick) and &IsChanConf("seenStats")) { delete $userstats{lc $nick}; } @@ -661,16 +739,15 @@ sub on_public { } } - $msgtime = time(); $lastWho{$chan} = $nick; ### TODO: use $nick or lc $nick? - if (&IsParam("seenStats")) { + if (&IsChanConf("seenStats")) { $userstats{lc $nick}{'Count'}++; $userstats{lc $nick}{'Time'} = time(); } -# if (&IsParam("hehCounter")) { +# if (&IsChanConf("hehCounter")) { # #... # } @@ -683,23 +760,38 @@ sub on_quit { my $nick = $event->nick(); my $reason = ($event->args)[0]; + my $count = 0; foreach (keys %channels) { # fixes inconsistent chanstats bug #1. - next unless (&IsNickInChan($nick,$_)); + if (!&IsNickInChan($nick,$_)) { + $count++; + next; + } $chanstats{$_}{'SignOff'}++; } + + if ($count == scalar keys %channels) { + &DEBUG("on_quit: nick $nick was not found in any chan."); + } + &DeleteUserInfo($nick, keys %channels); + if (exists $nuh{lc $nick}) { delete $nuh{lc $nick}; } else { &DEBUG("on_quit: nuh{lc $nick} does not exist! FIXME"); } - delete $userstats{lc $nick} if (&IsParam("seenStats")); + delete $userstats{lc $nick} if (&IsChanConf("seenStats")); # should fix chanstats inconsistencies bug #2. if ($reason=~/^($mask{host})\s($mask{host})$/) { # netsplit. $reason = "NETSPLIT: $1 <=> $2"; + if (&ChanConfList("chanlimitcheck") and !scalar keys %netsplit) { + &DEBUG("on_quit: netsplit detected; disabling chan limit."); + &rawout("MODE $chan -l"); + } + $netsplit{lc $nick} = time(); if (!exists $netsplitservers{$1}{$2}) { &status("netsplit detected between $1 and $2."); @@ -709,8 +801,9 @@ sub on_quit { &status(">>> $b_cyan$nick$ob has signed off IRC $b_red($ob$reason$b_red)$ob"); if ($nick =~ /^\Q$ident\E$/) { - &DEBUG("!!! THIS SHOULD NEVER HAPPEN. FIXME HOPEFULLY"); + &DEBUG("^^^ THIS SHOULD NEVER HAPPEN."); } + if ($nick !~ /^\Q$ident\E$/ and $nick =~ /^\Q$param{'ircNick'}\E$/i) { &status("own nickname became free; changing."); &nick($param{'ircNick'}); @@ -720,19 +813,12 @@ sub on_quit { sub on_targettoofast { my ($self, $event) = @_; my $nick = $event->nick(); - my $chan = ($event->to)[0]; - - &DEBUG("on_targettoofast: nick => '$nick'."); - &DEBUG("on_targettoofast: chan => '$chan'."); - - foreach ($event->args) { - &DEBUG("on_targettoofast: args => '$_'."); - } + my($me,$chan,$why) = $event->args(); + ### TODO: incomplete. ### .* wait (\d+) second/) { - &status("X1 $msg"); - my $sleep = $3 + 10; - + &status("on_ttf: X1 $msg") if (defined $msg); + my $sleep = 5; &status("going to sleep for $sleep..."); sleep $sleep; &joinNextChan(); @@ -756,13 +842,13 @@ sub on_topic { # this may be fixed at a later date with topic queueing. ### - $topic{$chan}{'Current'} = $topic if (1 and &IsParam("topic") == 1); + $topic{$chan}{'Current'} = $topic if (1); $chanstats{$chan}{'Topic'}++; &status(">>> topic/$b_blue$chan$ob by $b_cyan$nick$ob -> $topic"); } else { # join. my ($nick, $chan, $topic) = $event->args; - if (&IsParam("topic")) { + if (&IsChanConf("topic")) { $topic{$chan}{'Current'} = $topic; &topicAddHistory($chan,$topic); } @@ -850,6 +936,8 @@ sub on_whoisuser { my ($self, $event) = @_; my @args = $event->args; + &DEBUG("on_whoisuser: @args"); + $nuh{lc $args[1]} = $args[1]."!".$args[2]."\@".$args[3]; } @@ -949,27 +1037,34 @@ sub hookMsg { } # Determine floodwho. + my $c = "_default"; if ($msgType =~ /public/i) { # public. - $floodwho = lc $chan; + $floodwho = $c = lc $chan; } elsif ($msgType =~ /private/i) { # private. $floodwho = lc $who; } else { # dcc? &DEBUG("FIXME: floodwho = ???"); } - my ($count, $interval) = split(/:/, $param{'floodRepeat'} || "2:10"); + my $val = &getChanConfDefault("floodRepeat", "2:10", $c); + my ($count, $interval) = split /:/, $val; # flood repeat protection. if ($addressed) { - my $time = $flood{$floodwho}{$message}; + my $time = $flood{$floodwho}{$message} || 0; - if (defined $time and (time - $time < $interval)) { + if ($msgType eq "public" and (time() - $time < $interval)) { ### public != personal who so the below is kind of pointless. my @who; foreach (keys %flood) { - next if (/^\Q$floodwho\E$/ or /^\Q$chan\E$/); - push(@who, grep /^\Q$message\E$/i, keys %{$flood{$_}}); + next if (/^\Q$floodwho\E$/); + next if (defined $chan and /^\Q$chan\E$/); + + push(@who, grep /^\Q$message\E$/i, keys %{ $flood{$_} }); } + + return if ($lobotomized); + if (scalar @who) { &msg($who, "you already said what ". join(' ', @who)." have said."); @@ -995,14 +1090,24 @@ sub hookMsg { if ($addrchar) { &status("$b_cyan$who$ob is short-addressing me"); - } else { + } elsif ($msgType eq "private") { # private. + &status("$b_cyan$who$ob is /msg'ing me"); + } else { # public? &status("$b_cyan$who$ob is addressing me"); } $flood{$floodwho}{$message} = time(); + } elsif ($msgType eq "public" and &IsChanConf("kickOnRepeat")) { + # unaddressed, public only. + + ### TODO: use a separate "short-time" hash. + my @data; + @data = keys %{ $flood{$floodwho} } if (exists $flood{$floodwho}); } - ($count, $interval) = split(/:/, $param{'floodMessages'} || "5:30"); + $val = &getChanConfDefault("floodMessages", "5:30", $c); + ($count, $interval) = split /:/, $val; + # flood overflow protection. if ($addressed) { foreach (keys %{$flood{$floodwho}}) { @@ -1023,9 +1128,11 @@ sub hookMsg { $flood{$floodwho}{$message} = time(); } + my @ignore; if ($msgType =~ /public/i) { # public. $talkchannel = $chan; &status("<$orig{who}/$chan> $orig{message}"); + push(@ignore, keys %{ $ignore{$chan} }) if (exists $ignore{$chan}); } elsif ($msgType =~ /private/i) { # private. &status("[$orig{who}] $orig{message}"); $talkchannel = undef; @@ -1033,9 +1140,10 @@ sub hookMsg { } else { &DEBUG("unknown msgType => $msgType."); } + push(@ignore, keys %{ $ignore{"*"} }) if (exists $ignore{"*"}); - if ((!$skipmessage or &IsParam("seenStoreAll")) and - &IsParam("seen") and + if ((!$skipmessage or &IsChanConf("seenStoreAll")) and + &IsChanConf("seen") and $msgType =~ /public/ ) { $seencache{$who}{'time'} = time(); @@ -1049,22 +1157,20 @@ sub hookMsg { return if ($skipmessage); return unless (&IsParam("minVolunteerLength") or $addressed); - local $ignore = 0; - if (exists $ignore{lc $chan}) { - foreach (keys %{ $ignore{lc $chan} }) { - s/\*/\\S*/g; + foreach (@ignore) { + s/\*/\\S*/g; - next unless ($nuh =~ /^\Q$_\E$/i); - $ignore++; - last; - } + next unless (eval { $nuh =~ /^$_$/i }); + + &status("IGNORE <$who> $message"); + return; } if (defined $nuh) { - if (defined $userHandle) { - &DEBUG("line 1074: remove verifyUser"); + if (!defined $userHandle) { + &DEBUG("line 1074: need verifyUser?"); + &verifyUser($who, $nuh); } - $userHandle = &verifyUser($who, $nuh); } else { &DEBUG("hookMsg: 'nuh' not defined?"); } @@ -1077,4 +1183,29 @@ sub hookMsg { return; } +sub chanLimitVerify { + my($chan) = @_; + my $l = $channels{$chan}{'l'}; + + # only change it if it's not set. + if (defined $l and &IsChanConf("chanlimitcheck")) { + my $plus = &getChanConfDefault("chanlimitcheckPlus", 5, $chan); + my $nowl = scalar(keys %{ $channels{$chan}{''} }); + my $delta = $nowl - $l; + $delta =~ s/^\-//; + + if ($plus <= 3) { + &WARN("clc: stupid to have plus at $plus, fix it!"); + } + + ### 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 ".($nowl+$plus) ); + } + } +} + 1;