]> git.donarmstrong.com Git - infobot.git/blobdiff - src/IRC/IrcHooks.pl
A round of fixes:
[infobot.git] / src / IRC / IrcHooks.pl
index 9eec53b043cfa0fa0276b020e810951d36e62ac2..461d9de730b69a5ba45c33c878bc8d6fc60d4b4e 100644 (file)
@@ -39,7 +39,7 @@ 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{$nick}) {
        &DEBUG("chat: nuh{$nick} doesn't exist; trying WHOIS .");
@@ -65,10 +65,12 @@ sub on_chat {
 
        ### 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')");
@@ -133,6 +135,20 @@ 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 <pass> to get master access through DCC CHAT.");
+    }
+    # end of first time run.
 
     if (&IsChanConf("wingate")) {
        my $file = "$bot_base_dir/$param{'ircUser'}.wingate";
@@ -167,12 +183,12 @@ 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 :)
     if (!exists $nuh{lc $nick}) {
        $self->whois($nick);
-       $nuh{lc $nick}  = "GETTING-NOW";        # trying.
+       $nuh{$nick}     = "GETTING-NOW";        # trying.
     }
     $type ||= "???";
 
@@ -229,7 +245,7 @@ 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';
@@ -265,13 +281,9 @@ sub on_dcc_open {
 # really custom sub to get NUH since Net::IRC doesn't appear to support
 # it.
 sub on_dcc_open_chat {
-    my(undef, $nick,$sock) = @_;
+    my(undef, $nick, $sock) = @_;
 
-    &DEBUG("nuh{$nick} => $nuh{$nick}.");
-    if ($nuh{$nick} =~ /^(\S+)(\d+)$/) {
-       my $i = $2;
-       $i++;
-       $nuh{$nick} = $1.$i;
+    if ($nuh{$nick} eq "GETTING-NOW") {
        &DEBUG("getting nuh for $nick failed. FIXME.");
        return;
     }
@@ -305,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;
@@ -332,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 "");
@@ -346,6 +359,9 @@ sub on_endofnames {
 
     if (scalar @joinchan) {    # remaining channels to join.
        &joinNextChan();
+    } else {
+       &DEBUG("running ircCheck to get chanserv ops.");
+       &ircCheck();
     }
 
     return unless (&IsChanConf("chanServ_ops") > 0);
@@ -422,23 +438,40 @@ 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:
@@ -447,6 +480,12 @@ sub on_join {
                    $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);
 
@@ -522,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);
 }
@@ -588,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.");
@@ -687,7 +739,6 @@ sub on_public {
        }
     }
 
-
     $msgtime = time();
     $lastWho{$chan} = $nick;
     ### TODO: use $nick or lc $nick?
@@ -709,15 +760,20 @@ sub on_quit {
     my $nick = $event->nick();
     my $reason = ($event->args)[0];
 
+    my $count  = 0;
     foreach (keys %channels) {
        # fixes inconsistent chanstats bug #1.
        if (!&IsNickInChan($nick,$_)) {
-           &DEBUG("on_quit: nick $nick was not in chan $_.");
+           $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}) {
@@ -759,8 +815,9 @@ sub on_targettoofast {
     my $nick = $event->nick();
     my($me,$chan,$why) = $event->args();
 
+    ### TODO: incomplete.
 ###    .* wait (\d+) second/) {
-       &status("X1 $msg");
+       &status("on_ttf: X1 $msg") if (defined $msg);
        my $sleep = 5;
        &status("going to sleep for $sleep...");
        sleep $sleep;
@@ -994,18 +1051,20 @@ sub hookMsg {
 
     # 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$/);
                next if (defined $chan and /^\Q$chan\E$/);
 
-               push(@who, grep /^\Q$message\E$/i, keys %{$flood{$_}});
+               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.");
@@ -1038,6 +1097,12 @@ sub hookMsg {
        }
 
        $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});
     }
 
     $val = &getChanConfDefault("floodMessages", "5:30", $c);
@@ -1063,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;
@@ -1073,6 +1140,7 @@ sub hookMsg {
     } else {
        &DEBUG("unknown msgType => $msgType.");
     }
+    push(@ignore, keys %{ $ignore{"*"} }) if (exists $ignore{"*"});
 
     if ((!$skipmessage or &IsChanConf("seenStoreAll")) and
        &IsChanConf("seen") and
@@ -1089,15 +1157,13 @@ 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) {
@@ -1135,8 +1201,8 @@ sub chanLimitVerify {
        ### todo: check if we have ops.
        ### todo: if not, check if nickserv/chanserv is avail.
        ### todo: unify code with chanlimitcheck()
-       if ($delta > 3) {
-           &WARN("clc: nowl($nowl) > l($l) - 3");
+       if ($delta > 5) {
+           &status("clc: big change in limit; changing.");
            &rawout("MODE $chan +l ".($nowl+$plus) );
        }
     }