next;
}
- &DEBUG("pCH(hooks_$hashname): $cmd matched $ident");
+ &status("hooks($hashname): $cmd matched '$ident'");
my %hash = %{ ${"hooks_$hashname"}{$ident} };
if (!scalar keys %hash) {
return 1;
}
+ if ($hash{NoArgs} and $flatarg) {
+ &DEBUG("cmd $ident does not take args; skipping.");
+ next;
+ }
+
if (!exists $hash{CODEREF}) {
&ERROR("CODEREF undefined for $cmd or $ident.");
return 1;
### DEBUG.
foreach (keys %hash) {
- &DEBUG(" $cmd->$_ => '$hash{$_}'.");
+ &VERB(" $cmd->$_ => '$hash{$_}'.",2);
}
### HELP.
$cmdstats{ $hash{'Cmdstats'} }++;
}
- &DEBUG("pCH: ended.");
+ &VERB("hooks: End of command.",2);
$done = 1;
}
'Forker' => 1, 'Identifier' => 'insult', 'Help' => "insult" ) );
&addCmdHook("extra", 'kernel', ('CODEREF' => 'Kernel::Kernel',
'Forker' => 1, 'Identifier' => 'kernel',
- 'Cmdstats' => 'Kernel') );
+ 'Cmdstats' => 'Kernel', 'NoArgs' => 1) );
&addCmdHook("extra", 'listauth', ('CODEREF' => 'CmdListAuth',
'Identifier' => 'search', Module => 'factoids',
'Help' => 'listauth') );
}
}
- &DEBUG("chans => ".scalar(keys %chanconf)." - 1");
foreach (keys %opts) {
+ next unless ($opts{$_} > 1);
&DEBUG(" opts{$_} => $opts{$_}");
}
}
}
- if (&update($lhs, $mhs, $rhs)) {
- return; # success.
- }
+ # success.
+ return if (&update($lhs, $mhs, $rhs));
}
return "CONTINUE";
}
# also checking.
- my $also = ($rhs =~ s/^(-?)also //i);
- &DEBUG("1=>$1");
+ my $also = ($rhs =~ s/^(\-)?also //i);
+ &DEBUG("1=>$1"); # this does not work!
my $also_or = ($also and $rhs =~ s/\s+(or|\|\|)\s+//);
# freshmeat
return unless (&IsChanConf("joinfloodCheck"));
if (exists $netsplit{lc $who}) { # netsplit join.
- &DEBUG("jfC: $who was in netsnipe; not checking.");
+ &DEBUG("jfC: $who was in netsplit; not checking.");
}
if (exists $floodjoin{$chan}{$who}{Time}) {
### 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')");
$user =~ /^r(oo|ew|00)t$/i &&
$channels{$chan}{'o'}{$ident});
+ ### NEWS:
+ if (&IsChanConf("news") && &IsChanConf("newsKeepRead")) {
+ my @new;
+ foreach (keys %{ $::news{$chan} }) {
+ my $t = $::newsuser{$chan}{$who};
+ next if (!defined $t);
+ next if ($t > $::news{$chan}{$_}{Time});
+
+ push(@new, $_);
+ }
+
+ if (scalar @new) {
+ &msg($who, "+==== New news for $chan (".scalar(@new)."):");
+ # todo: show how many sec/min/etc ago?
+ my $timestr = &Time2String( $::newsuser{$chan}{$who} );
+ &msg($who, "|= Last time read $timestr ago");
+
+ foreach (@new) {
+ my $i = &News::getNewsItem($_);
+ my $age = time() - $::news{$chan}{$_}{Time};
+ &msg($who, sprintf("\002[\002%2d\002]\002 %s (%s)",
+ $i, $_, &Time2String($age) ) );
+ }
+
+ # lame hack to prevent dupes if we just ignore it.
+ $::newsuser{$chan}{$who} = time();
+ }
+ }
+
### chanlimit check.
&chanLimitVerify($chan);
$nuh = $nick."!".$uh;
$msgtime = time();
+ if ($nick eq $ident) { # hopefully ourselves.
+ if ($msg eq "TEST") {
+ &status("Local: Yes, we're alive.");
+ delete $cache{connect};
+ return;
+ }
+ }
+
&hookMsg('private', undef, $nick, $msg);
}
# ONCE OFF.
# REPETITIVE.
+ # 1 for run straight away, 2 for on next-run.
&uptimeLoop(1);
&randomQuote(2);
&randomFactoid(2);
&ignoreCheck(1); # mandatory
&seenFlushOld(2);
&ircCheck(1); # mandatory
- &miscCheck(2); # mandatory
+ &miscCheck(1); # mandatory
&shmFlush(1); # mandatory
&slashdotLoop(2);
&freshmeatLoop(2);
&kernelLoop(2);
&wingateWriteFile(2);
&factoidCheck(2);
+ &newsFlush(1);
# my $count = map { exists $sched{$_}{TIME} } keys %sched;
my $count = 0;
}
+sub newsFlush {
+ if (@_) {
+ &ScheduleThis(1440, "newsFlush");
+ return if ($_[0] eq "2"); # defer.
+ } else {
+ delete $sched{"newsFlush"}{RUNNING};
+ }
+
+ return unless (&IsChanConf("news") > 0);
+
+ my $delete = 0;
+ my $oldest = time();
+ foreach $chan (keys %::news) {
+ foreach $item (keys %{ $::news{$chan} }) {
+ my $t = $::news{$chan}{$item}{Expire};
+
+ next if ($t == 0 or $t == -1);
+ if ($t < 1000) {
+ &status("newsFlush: Fixed Expire time for $chan/$item, should not happen anyway.");
+ $::news{$chan}{$item}{Expire} = time() + $t*60*60*24;
+ next;
+ }
+
+ $oldest = $t if ($t < $oldest);
+
+ next unless (time() > $t);
+ # todo: show how old it was.
+ &DEBUG("delete $chan/'$item'.");
+ delete $::news{$chan}{$item};
+ $delete++;
+ }
+ }
+
+ # todo: flush users aswell.
+ my $duser = 0;
+ foreach $chan (keys %::newsuser) {
+ foreach (keys %{ $::newsuser{$chan} }) {
+ my $t = $::newsuser{$chan}{$_};
+ if (!defined $t or $t < 1000) {
+ &DEBUG("something wrong with newsuser{$chan}{$_} => $t");
+ next;
+ }
+
+ next unless ($oldest > $t);
+
+ delete $::newsuser{$chan}{$_};
+ $duser++;
+ }
+ }
+
+ &News::writeNews();
+
+# &VERB("NEWS deleted $delete seen entries.",2);
+ &status("NEWS deleted $delete news entries; $duser user cache.");
+}
+
sub chanlimitCheck {
my $interval = &getChanConfDefault("chanlimitcheckInterval", 10);
}
if (!$conn->connected or time - $msgtime > 3600) {
+ # todo: shouldn't we use cache{connect} somewhere?
if (exists $cache{connect}) {
&WARN("ircCheck: no msg for 3600 and disco'd! reconnecting!");
$msgtime = time(); # just in case.
} else {
&DEBUG("shm: $shmid is not ours or old blootbot => ($z)");
- next;
+# next;
}
&status("SHM: nuking shmid $shmid");
}
if (!defined $user) {
- &pSReply("user $user does not exist.");
+ &pSReply("user does not exist.");
return;
}
}
}
-
# factoid forget.
if ($message =~ s/^forget\s+//i) {
return 'forget: no addr' unless ($addressed);
return;
}
-
# Fix up $message for question.
- for ($message) {
+ my $question = $message;
+ for ($question) {
# fix the string.
s/^hey([, ]+)where/where/i;
s/whois/who is/ig;
$correction_plausible = 0;
}
- my $result = &doQuestion($message);
+ my $result = &doQuestion($question);
if (!defined $result or $result eq $noreply) {
return 'result from doQ undef.';
}
Forker => "NULL", ) );
&addCmdHook("main", 'tell|explain', ('CODEREF' => 'tell',
Help => 'tell', Identifier => 'allowTelling', ) );
-
+&addCmdHook("main", 'news', ('CODEREF' => 'News::Parse', ) );
&status("CMD: loaded ".scalar(keys %hooks_main)." MAIN command hooks.");
push(@nicks, $_);
}
}
+ &DEBUG("nicks => '".scalar(@nicks)."'...");
+ if (scalar @nicks != $uucount) {
+ &DEBUG("nicks != uucount...");
+ }
my $chans = scalar(keys %channels);
&pSReply(
}
# ircstats.
- if ($message =~ /^ircstats$/i) {
+ if ($message =~ /^ircstats?$/i) {
+ $ircstats{'TotalTime'} ||= 0;
+ $ircstats{'OffTime'} ||= 0;
+
my $count = $ircstats{'ConnectCount'};
my $format_time = &Time2String(time() - $ircstats{'ConnectTime'});
- my $total_time = time() - $ircstats{'ConnectTime'} + $ircstats{'TotalTime'};
+ my $total_time = time() - $ircstats{'ConnectTime'} +
+ $ircstats{'TotalTime'};
my $reply;
- &DEBUG("ircstats: total_time => $total_time.");
- &DEBUG("ircstats: offtime => $ircstats{'OffTime'}");
+ my $connectivity = 100 * ($total_time - $ircstats{'OffTime'}) /
+ $total_time;
+ my $p = sprintf("%.02f", $connectivity);
+ $p =~ s/(\.\d*)0+$/$1/;
+ if ($p =~ s/\.0$//) {
+ &DEBUG("p sar not working properly :(");
+ } else {
+ $p =~ s/\.$//
+ }
+
+ &DEBUG("connectivity => $p %");
- foreach (keys %ircstats) {
- &DEBUG("ircstats: $_ => '$ircstats{$_}'.");
+ if ($total_time != (time() - $ircstats{'ConnectTime'}) ) {
+ my $tt_format = &Time2String($total_time);
+ &DEBUG("tt_format => $tt_format");
}
### RECONNECT COUNT.
&writeUserFile();
&writeChanFile();
&uptimeWriteFile() if (&ChanConfList("uptime"));
+ &News::writeNews() if (&ChanConfList("news"));
&closeDB();
&closeSHM($shm);
&dumpallvars() if (&IsParam("dumpvarsAtExit"));
&openDB($param{'DBName'}, $param{'SQLUser'}, $param{'SQLPass'});
&status("Setup: ". &countKeys("factoids") ." factoids.");
+ &News::readNews() if (&ChanConfList("news"));
$param{tempDir} =~ s#\~/#$ENV{HOME}/#;
"kernel" => "Kernel.pl",
"ircdcc" => "UserDCC.pl",
"perlMath" => "Math.pl",
+ "news" => "News.pl",
"quote" => "Quote.pl",
"rootwarn" => "RootWarn.pl",
"search" => "Search.pl",
"nickometer" => "nickometer.pl",
"babelfish" => "babel.pl",
);
+### THIS IS NOT LOADED ON RELOAD :(
BEGIN {
- @myModulesLoadNow = ('topic', 'uptime',);
+ @myModulesLoadNow = ('topic', 'uptime', 'news');
@myModulesReloadNot = ('IRC/Irc.pl','IRC/Schedulers.pl');
}
next;
}
- if (!&IsParam($_) and !&IsChanConf($_)) {
+ if (!&IsParam($_) and !&IsChanConf($_) and !&getChanConfList($_)) {
+ &DEBUG("_ => $_");
if (exists $myModules{$_}) {
&status("myModule: $myModules{$_} (1) not loaded.");
} else {
$loaded++;
}
- &status("Module: Loaded/Total [$loaded/$total]");
+ &status("Module: Runtime: Loaded/Total [$loaded/$total]");
}
### rename to moduleReloadAll?