if ( ($pubcount % $i) == 0 and $pubcount) {
sleep 1;
+ $pubsleep++;
} elsif ($pubsize > $j) {
sleep 1;
$pubsize -= $j;
+ $pubsleep++;
}
} else {
my $j = &getChanConfDefault("sendPrivateLimitBytes", 1000);
if ( ($msgcount % $i) == 0 and $msgcount) {
sleep 1;
+ $msgsleep++;
} elsif ($msgsize > $j) {
sleep 1;
$msgsize -= $j;
+ $msgsleep++;
}
} else {
if ( ($notcount % $i) == 0 and $notcount) {
sleep 1;
+ $notsleep++;
} elsif ($notsize > $j) {
sleep 1;
$notsize -= $j;
+ $notsleep++;
}
} else {
sub nick {
my ($nick) = @_;
+ if (!defined $nick) {
+ &ERROR("nick: nick == NULL.");
+ return;
+ }
+
+ if (defined $ident and $nick eq $ident) {
+ &WARN("nick: nick == ident == '$ident'.");
+ }
+
+ my $bad = 0;
+ $bad++ if (exists $nuh{ $param{'ircNick'} });
+ $bad++ if (&IsNickInAnyChan($param{'ircNick'}));
+
+ if ($bad) {
+ &WARN("Nick: not going to try and get my nick back. [".
+ scalar(localtime). "]");
+ return;
+ }
+
if ($nick =~ /^$mask{nick}$/) {
- &DEBUG("nick: Changing nick to $nick (from $ident)");
rawout("NICK ".$nick);
- # unfortunately, on_nick doesn't catch ourself.
- $ident = $nick;
+
+ if (defined $ident) {
+ &status("nick: Changing nick to $nick (from $ident)");
+ } else {
+ &DEBUG("first time nick change.");
+ $ident = $nick;
+ }
+
return 1;
}
&DEBUG("nick: failed... why oh why (nick => $nick)");
# Usage: &joinNextChan();
sub joinNextChan {
- &DEBUG("joinNextChan called.");
-
if (scalar @joinchan) {
$chan = shift @joinchan;
&joinchan($chan);
&status("joinNextChan: $i chans to join.");
}
- } else {
- if (exists $cache{joinTime}) {
- my $delta = time() - $cache{joinTime};
- my $timestr = &Time2String($delta);
- my $rate = sprintf("%.1f", $delta / &getJoinChans() );
- delete $cache{joinTime};
+ return;
- &DEBUG("time taken to join all chans: $timestr; rate: $rate sec/join");
- }
- # chanserv check: global channels, in case we missed one.
+ }
- foreach ( &ChanConfList("chanServ_ops") ) {
- &chanServCheck($_);
- }
+ # !scalar @joinchan:
+
+ if (exists $cache{joinTime}) {
+ my $delta = time() - $cache{joinTime};
+ my $timestr = &Time2String($delta);
+ my $rate = sprintf("%.1f", $delta / &getJoinChans() );
+ delete $cache{joinTime};
+
+ &DEBUG("time taken to join all chans: $timestr; rate: $rate sec/join");
+ }
+ # chanserv check: global channels, in case we missed one.
+
+ foreach ( &ChanConfList("chanServ_ops") ) {
+ &chanServCheck($_);
}
}
my($chan) = @_;
my $l = $channels{$chan}{'l'};
- if (scalar keys %netsplitservers) {
+ &DEBUG("cLV: netsplitservers: ".scalar(keys %netsplitservers) );
+ &DEBUG("cLV: netsplit: ".scalar(keys %netsplit) );
+
+ if (scalar keys %netsplit) {
&WARN("clV: netsplit active (1); skipping.");
return;
}
### todo: unify code with chanlimitcheck()
if ($delta > 5) {
- &status("clc: big change in limit; changing.");
+ &status("clc: big change in limit; going for it.");
&rawout("MODE $chan +l ".($count+$plus) );
$cache{chanlimitChange}{$chan} = time();
}
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)");
sub on_endofmotd {
my ($self) = @_;
- # what's the following for?
- $ident = $param{'ircNick'};
# update IRCStats.
+ $ident ||= $param{'ircNick'}; # hack.
$ircstats{'ConnectTime'} = time();
$ircstats{'ConnectCount'}++;
$ircstats{'OffTime'} += time() - $ircstats{'DisconnectTime'}
}
# todo: do %flood* aswell.
- &DeleteUserInfo($nick,keys %channels);
+ &DeleteUserInfo($nick, keys %channels);
$nuh{lc $newnick} = $nuh{lc $nick};
delete $nuh{lc $nick};
- # successful self-nick change.
- &DEBUG("on_nick... nick => $nick, ident => $ident");
- if ($ident eq "$nick-" or "$ident-" eq $nick) {
- &DEBUG("on_nick: well... we need this bug fixed.");
- &DEBUG("ident => $ident");
- &DEBUG("nick => $nick");
- $ident = $newnick;
- }
-
if ($nick eq $ident) {
&status(">>> I materialized into $b_green$newnick$ob from $nick");
- $ident = $newnick;
+ $ident = $newnick;
} else {
&status(">>> $b_cyan$nick$ob materializes into $b_green$newnick$ob");
+
+ if ($nick =~ /^\Q$param{'ircNick'}\E$/i) {
+ &getNickInUse();
+ }
}
}
sub on_nick_taken {
- my ($self) = @_;
- my $nick = $self->nick;
- my $newnick = substr($nick,0,7)."-";
+ my ($self) = @_;
+ my $nick = $self->nick;
+ my $newnick = $nick."-";
- &status("nick taken; changing to temporary nick ($nick -> $newnick).");
- &nick($newnick);
- &getNickInUse(1);
+ &status("nick taken ($nick); preparing nick change.");
+
+ $self->whois($nick);
+ $conn->schedule(5, sub {
+ &status("nick taken; changing to temporary nick ($nick -> $newnick).");
+ &nick($newnick);
+ } );
}
sub on_notice {
# todo: move this out of hookMsg to here?
($user,$host) = split(/\@/, $uh);
+ # rare case should this happen - catch it just in case.
if ($bot_pid != $$) {
&ERROR("run-away fork; exiting.");
&delForked($forker);
}
- ### DEBUGGING.
- if ($statcount < 200) {
- foreach $chan (grep /[A-Z]/, keys %channels) {
- &DEBUG("leak: chan => '$chan'.");
- my ($i,$j);
- foreach $i (keys %{ $channels{$chan} }) {
- foreach (keys %{ $channels{$chan}{$i} }) {
- &DEBUG("leak: \$channels{$chan}{$i}{$_} ...");
- }
- }
- }
- }
-
- $msgtime = time();
- $lastWho{$chan} = $nick;
+ $msgtime = time();
+ $lastWho{$chan} = $nick;
### TODO: use $nick or lc $nick?
if (&IsChanConf("seenStats")) {
$userstats{lc $nick}{'Count'}++;
if ($reason =~ /^($mask{host})\s($mask{host})$/) { # netsplit.
$reason = "NETSPLIT: $1 <=> $2";
+ # chanlimit code.
if (&ChanConfList("chanlimitcheck") and !scalar keys %netsplit) {
&DEBUG("on_quit: netsplit detected; disabling chan limit.");
&rawout("MODE $chan -l");
my $delete = 0;
my $oldest = time();
foreach $chan (keys %::news) {
- &DEBUG("sched: chan => $chan");
+ my $i = 0;
+ my $total = scalar(keys %{ $::news{$chan} });
foreach $item (keys %{ $::news{$chan} }) {
my $t = $::news{$chan}{$item}{Expire};
- &DEBUG("sched; item => $item");
my $tadd = $::news{$chan}{$item}{Time};
$oldest = $tadd if ($oldest > $tadd);
- &DEBUG("sched: t => $t");
-
next if ($t == 0 or $t == -1);
if ($t < 1000) {
&status("newsFlush: Fixed Expire time for $chan/$item, should not happen anyway.");
}
my $delta = $t - time();
- &DEBUG("news: delta: $delta");
next unless (time() > $t);
# todo: show how old it was.
delete $::news{$chan}{$item};
- &VERB("NEWS: deleted '$item'", 2);
+ &status("NEWS: deleted '$item'");
$delete++;
+ $i++;
}
- }
- if ($delete) {
- &DEBUG("sched: Writing news....");
- &News::writeNews();
+ &status("NEWS {$chan}: deleted [$i/$total] news entries.");
}
# todo: flush users aswell.
}
}
-# &VERB("NEWS deleted $delete seen entries.",2);
- &status("NEWS deleted: $delete news entries; $duser user cache.");
+ if ($delete or $duser) {
+ &DEBUG("newsF: Writing news.");
+ &News::writeNews();
+ }
- &News::writeNews();
+ &status("NEWS deleted: $delete news entries; $duser user cache.");
}
sub chanlimitCheck {
delete $sched{"chanlimitCheck"}{RUNNING};
}
- if (scalar keys %netsplitservers) {
- &WARN("clC: netsplit active (2); skipping. (netsplit => $netsplit)");
- return;
- }
-
foreach $chan ( &ChanConfList("chanlimitcheck") ) {
next unless (&validChan($chan));
my $newlimit = scalar(keys %{ $channels{$chan}{''} }) + $limitplus;
my $limit = $channels{$chan}{'l'};
+ if (scalar keys %netsplitservers) {
+ if (defined $limit) {
+ &DEBUG("chanlimit: removing it for $chan.");
+ &rawout("MODE $chan -l");
+ $cache{chanlimitChange}{$chan} = time();
+ }
+
+ next;
+ }
+
if (defined $limit and scalar keys %{ $channels{$chan}{''} } > $limit) {
&FIXME("LIMIT: set too low!!! FIXME");
### run NAMES again and flush it.
delete $netsplit{$_};
}
+ &DEBUG("nsC: netsplitservers: ".scalar(keys %netsplitservers) );
+ &DEBUG("nsC: netsplit: ".scalar(keys %netsplit) );
+
if ($count and !scalar keys %netsplit) {
- &DEBUG("ok, netsplit is hopefully gone. reinstating chanlimit check.");
+ &DEBUG("nsC: netsplit is hopefully gone. reinstating chanlimit check.");
&chanlimitCheck();
}
}
### this is semi-scheduled
sub getNickInUse {
- &DEBUG("gNIU: ident => $ident, ircNick => $param{'ircNick'}");
if ($ident eq $param{'ircNick'}) {
&status("okay, got my nick back.");
return;
delete $sched{"getNickInUse"}{RUNNING};
}
- &status("Trying to get my nick back.");
&nick( $param{'ircNick'} );
}
print OUT "$_\n";
}
close OUT;
-
}
sub factoidCheck {
}
sub mkBackup {
- my($file, $time) = @_;
- my $backup = 0;
+ my($file, $time) = @_;
+ my $backup = 0;
if (! -f $file) {
- &WARN("mkB: file $file don't exist.");
+ &WARN("mkB: file '$file' does not exist.");
return;
}
}
return unless ($backup);
- my $age = &Time2String(time() - (stat $file)[9]);
+ my $delta = time() - (stat $file)[9];
+ &DEBUG("mkb: delta => $delta");
+
+ my $age = &Time2String($delta);
### TODO: do internal copying.
&status("Backup: $file ($age)");
&DEBUG("stale: $age2. (". &Time2String($age2) .")");
}
$age *= 60*60*24 if ($age >= 0 and $age < 30);
- &DEBUG("age = $age");
- &DEBUG("... = ".(stat $file)[9] );
return 1 if (time() - (stat($file))[9] > $age);
return 0;
}
close IN;
- &::DEBUG("vP: scanned $count items in index.");
+ &::VERB("vP: scanned $count items in index.",2);
return @files;
}
}
if (exists $dists{$dist}) {
- &::DEBUG("gD: returning dists{$dist} ($dists{$dist})");
+ &::VERB("gD: returning dists{$dist} ($dists{$dist})",2);
return $dists{$dist};
+
} else {
if (!grep /^\Q$dist\E$/i, %dists) {
&::msg($::who, "invalid dist '$dist'.");
return;
}
- &::DEBUG("gD: returning $dist (no change or conversion)");
+ &::VERB("gD: returning $dist (no change or conversion)",2);
return $dist;
}
}
}
sub writeNews {
- if (!scalar keys %::news) {
+ if (!scalar keys %::news and !scalar keys %::newsuser) {
&::DEBUG("wN: nothing to write.");
return;
}
&::DEBUG("item => '$item'.");
my $news = &getNewsItem($item);
- &::DEBUG("news => '$news'");
if (!defined $news) {
&::notice($::who, "Could not find item '$item' substring or # in news list.");
# don't list new items if they don't have Text.
if (!exists $::news{$chan}{$_}{Text}) {
- &::WARN("news: news{$chan}{$_}{Text} undef.");
+ if (time() - $::news{$chan}{$_}{Time} > 60*60*24*3) {
+ &::DEBUG("deleting news{$chan}{$_} because it was too old and had no text info.");
+ delete $::news{$chan}{$_};
+ } else {
+ &::WARN("news: news{$chan}{$_}{Text} undef.");
+ }
+
next;
}
return;
}
- &::DEBUG("gNI: part_string->full_string: $what->$items[0]");
if (@items) {
- &::DEBUG("gNI: Guessed '$items[0]'.");
+ &::DEBUG("gNI: part_string->full_string: $what->$items[0]");
return $items[0];
} else {
&::DEBUG("gNI: No match.");
my($count) = (sort { $b <=> $a } keys %new)[0];
if ($count) {
- $reply .= ". \002$new{$count}\002 has said the most with a total of \002$count\002 messages";
+ $reply .= ". \002$count\002 has said the most with a total of \002$new{$count}\002 messages";
}
&pSReply("$reply.");
}