if (&IsParam("useStrict")) { use strict; }
-my $nickserv = 0;
-
# GENERIC. TO COPY.
sub on_generic {
my ($self, $event) = @_;
my $sock = ($event->to)[0];
my $nick = $event->nick();
- if (!exists $nuh{lc $nick}) {
- &DEBUG("chat: nuh{$nick} doesn't exist; hrm should retry.");
+ 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';
- }
-
- if (!exists $dcc{'CHAT'}{$nick}) {
- my $userHandle = &verifyUser($who, $nuh);
- my $crypto = $userList{$userHandle}{'pass'};
+ }
+
+ ### 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++;
+### $success++;
+
} elsif (&ckpasswd($msg, $crypto)) {
- $self->privmsg($sock,"Authorized.");
- $self->privmsg($sock,"I'll respond as if through /msg and addressed in public. Addition to that, access to 'user' commands will be allowed, like 'die' and 'jump'.");
- # hrm... it's stupid to ask for factoids _within_ dcc chat.
- # perhaps it should be default to commands, especially
- # commands only authorized through DCC CHAT.
- &status("DCC CHAT: passwd is ok.");
+ # 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) unless (exists $sched{"dccStatus"}{RUNNING});
+
$success++;
+
} else {
&status("DCC CHAT: incorrect pass; closing connection.");
&DEBUG("chat: sock => '$sock'.");
### $sock->close();
+ delete $dcc{'CHAT'}{$nick};
&DEBUG("chat: after closing sock. FIXME");
### BUG: close seizes bot. why?
}
if ($success) {
&status("DCC CHAT: user $nick is here!");
- $dcc{'CHAT'}{$nick} = $sock;
- &DCCBroadcast("$nick ($uh) has joined the chat arena.");
+ &DCCBroadcast("*** $nick ($uh) joined the party line.");
+
+ $dcc{'CHATvrfy'}{$nick} = $userHandle;
+
+ return if ($userHandle eq "_default");
+
+ &dccsay($nick,"Flags: $users{$userHandle}{FLAGS}");
}
return;
}
-
- $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'});
- return '$noreply from userD' if (&userDCC() eq $noreply);
+ &loadMyModule( $myModules{'ircdcc'} );
+
+ &DCCBroadcast("#$who# $message","m");
+
+ my $retval = &userDCC();
+ return unless (defined $retval);
+ return if ($retval eq $noreply);
+
$conn->privmsg($dcc{'CHAT'}{$who}, "Invalid command.");
} else { # dcc chat arena.
+
foreach (keys %{$dcc{'CHAT'}}) {
$conn->privmsg($dcc{'CHAT'}{$_}, "<$who> $orig{message}");
}
sub on_endofmotd {
my ($self) = @_;
- if (&IsParam("wingate")) {
+ # what's the following for?
+ $ident = $param{'ircNick'};
+ # update IRCStats.
+ $ircstats{'ConnectTime'} = time();
+ $ircstats{'ConnectCount'}++;
+
+ if (&IsChanConf("wingate")) {
my $file = "$bot_base_dir/$param{'ircUser'}.wingate";
open(IN, $file);
while (<IN>) {
close IN;
}
- ### TODO: move this to end of &joinNextChan()?
if ($firsttime) {
- &DEBUG("on_EOM: calling sS in 60s.");
- $conn->schedule(60, \&setupSchedulers, "");
+ &ScheduleThis(1, \&setupSchedulers);
$firsttime = 0;
}
if (&IsParam("ircUMode")) {
- &status("Changing user modes to $param{'ircUMode'}.");
+ &status("Attempting change of user modes to $param{'ircUMode'}.");
&rawout("MODE $ident $param{'ircUMode'}");
}
&status("End of motd. Now lets join some channels...");
if (!scalar @joinchan) {
&WARN("joinchan array is empty!!!");
- @joinchan = split /[\t\s]+/, $param{'join_channels'};
+ @joinchan = &getJoinChans();
}
&joinNextChan();
my $nick = $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{lc $nick} = "GETTING-NOW"; # trying.
+ }
+ $type ||= "???";
- if ($type eq 'SEND') {
+ if ($type eq 'SEND') { # GET for us.
# incoming DCC SEND. we're receiving a file.
- $self->new_get($event, \*FH);
+ my $get = ($event->args)[2];
+ open(DCCGET,">$get");
+
+ $self->new_get($nick,
+ ($event->args)[2],
+ ($event->args)[3],
+ ($event->args)[4],
+ ($event->args)[5],
+ \*DCCGET
+ );
+ } elsif ($type eq 'GET') { # SEND for us?
+ &status("DCC: Initializing SEND for $nick.");
+ $self->new_send($event->args);
} elsif ($type eq 'CHAT') {
+ &status("DCC: Initializing CHAT for $nick.");
$self->new_chat($event);
} else {
- &status("${b_green}DCC $type$ob unknown ...");
+ &WARN("${b_green}DCC $type$ob (1)");
}
}
my $nick = $event->nick();
my $sock = ($event->to)[0];
- &DEBUG("dcc_close: nick => '$nick'.");
+ # DCC CHAT close on fork exit workaround.
+ if ($bot_pid != $$) {
+ &WARN("run-away fork; exiting.");
+ &delForked($forker);
+ }
- if (exists $dcc{'SEND'}{$nick} and -f "temp/$nick.txt") {
+ if (exists $dcc{'SEND'}{$nick} and -f "$param{tempDir}/$nick.txt") {
&status("${b_green}DCC SEND$ob close from $b_cyan$nick$ob");
&status("dcc_close: purging $nick.txt from Debian.pl");
- unlink "temp/$nick.txt";
+ unlink "$param{tempDir}/$nick.txt";
delete $dcc{'SEND'}{$nick};
} 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");
+ &status("${b_green}DCC$ob UNKNOWN close from $b_cyan$nick$ob (2)");
}
}
my $type = uc( ($event->args)[0] );
my $nick = $event->nick();
my $sock = ($event->to)[0];
+
$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 ($nuh{$nick})");
- my $userHandle = &verifyUser($nick, $nuh{lc $nick});
- my $crypto = $userList{$userHandle}{'pass'};
- if (defined $crypto) {
- $self->privmsg($sock,"Enter Password, $userHandle.");
+ # 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 {
- $self->privmsg($sock,"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 {
- &status("${b_green}DCC $type$ob unknown ...");
+ &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.");
}
}
my $what = ($event->args)[0];
&status("disconnect from $from ($what).");
- $ircstats{'DisconnectReason'} = $what;
+ $ircstats{'DisconnectTime'} = time();
+ $ircstats{'DisconnectReason'} = $what;
+ $ircstats{'DisconnectCount'}++;
# clear any variables on reconnection.
$nickserv = 0;
&clearIRCVars();
-
if (!$self->connect()) {
- &WARN("not connected? help me. ircCheck() should reconnect me");
+ &WARN("not connected? help me. gonna call ircCheck() in 1800s");
+ &ScheduleThis(30, "ircCheck");
}
}
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.");
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 (&IsParam("chanServ_ops"));
- return unless ($nickserv);
-
- my @chans = split(/[\s\t]+/, $param{'chanServ_ops'});
+ }
- foreach $chan (keys %channels) {
- next unless (grep /^$chan$/i, @chans);
+ 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");
- }
- }
+ if (!exists $channels{$chan}{'o'}{$ident}) {
+ &status("ChanServ ==> Requesting ops for $chan.");
+ &rawout("PRIVMSG ChanServ :OP $chan $ident");
}
-
}
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;
$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);
# netjoin detection.
my $netsplit = 0;
$netsplit = 1;
}
+ if ($netsplit and !$netsplittime) {
+ &DEBUG("on_join: ok.... re-running chanlimitCheck in 60.");
+ $conn->schedule(60, sub {
+ &chanlimitCheck();
+ $netsplittime = undef;
+ } );
+
+ $netsplittime = time();
+ }
+
# how to tell if there's a netjoin???
my $netsplitstr = "";
&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 = keys %{ $bans{$chan} };
+ push(@bans, keys %{ $bans{"*"} });
+ foreach (@bans) {
+ s/\*/\\S*/g;
+ next unless /^\Q$nuh\E$/i;
+
+ ### TODO: check $channels{$chan}{'b'} if ban already exists.
+ foreach (keys %{ $channels{$chan}{'b'} }) {
+ &DEBUG(" bans_on_chan($chan) => $_");
+ }
+
+ ### TODO: kick
+ &ban( "*!*@".&makeHostMask($host), $chan);
+ last;
+ }
### ROOTWARN:
&rootWarn($who,$user,$host,$chan)
- if (&IsParam("rootWarn") &&
+ if (&IsChanConf("rootWarn") &&
$user =~ /^r(oo|ew|00)t$/i &&
$channels{$chan}{'o'}{$ident});
+ ### 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 :)
&status(">>> kick/$b_blue$chan$ob [$b$kickee!$uh$ob] by $b_cyan$kicker$ob $b_yellow($ob$reason$b_yellow)$ob");
+ $chan = lc $chan; # forgot about this, found by xsdg, 20001229.
$chanstats{$chan}{'Kick'}++;
if ($kickee eq $ident) {
sub on_msg {
my ($self, $event) = @_;
my $nick = $event->nick;
- my $chan = lc ( ($event->to)[0] ); # CASING.
- my $msg = ($event->args)[0];
+ my $msg = ($event->args)[0];
($user,$host) = split(/\@/, $event->userhost);
$uh = $event->userhost();
$nuh = $nick."!".$uh;
- &hookMsg('private', $chan, $nick, $msg);
+ &hookMsg('private', undef, $nick, $msg);
}
sub on_names {
my $newnick = ($event->args)[0];
if (exists $netsplit{lc $newnick}) {
- &DEBUG("on_nick: $newnick/$nick came back from netsplit and changed to original nick! removing from hash.");
+ &status("Netsplit: $newnick/$nick came back from netsplit and changed to original nick! removing from hash.");
delete $netsplit{lc $newnick};
}
my $nick = $event->nick;
my $userhost = $event->userhost;
+ 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};
}
$nuh = $nick."!".$uh;
($user,$host) = split(/\@/, $uh);
+ if ($bot_pid != $$) {
+ &ERROR("run-away fork; exiting.");
+ &delForked($forker);
+ }
+
### DEBUGGING.
if ($statcount < 200) {
foreach $chan (grep /[A-Z]/, keys %channels) {
$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")) {
# #...
# }
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.");
&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'});
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($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();
# 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);
}
&status(">>> set by $b_cyan$setby$ob $timestr");
}
+sub on_crversion {
+ my ($self, $event) = @_;
+ my $nick = $event->nick();
+ my $ver;
+
+ if (scalar $event->args() != 1) { # old.
+ $ver = join ' ', $event->args();
+ $ver =~ s/^VERSION //;
+ } else { # new.
+ $ver = ($event->args())[0];
+ }
+
+ if (grep /^\Q$nick\E$/i, @vernick) {
+ &WARN("nick $nick found in vernick; skipping.");
+ return;
+ }
+ push(@vernick, $nick);
+
+ if ($ver =~ /bitchx/i) {
+ $ver{bitchx}{$nick} = $ver;
+ } elsif ($ver =~ /xc\!|xchat/i) {
+ $ver{xchat}{$nick} = $ver;
+ } elsif ($ver =~ /irssi/i) {
+ $ver{irssi}{$nick} = $ver;
+ } elsif ($ver =~ /epic/i) {
+ $ver{epic}{$nick} = $ver;
+ } elsif ($ver =~ /mirc/i) {
+ $ver{mirc}{$nick} = $ver;
+ } elsif ($ver =~ /ircle/i) {
+ $ver{ircle}{$nick} = $ver;
+ } elsif ($ver =~ /ircII/i) {
+ $ver{ircII}{$nick} = $ver;
+ } elsif ($ver =~ /sirc /i) {
+ $ver{sirc}{$nick} = $ver;
+ } elsif ($ver =~ /kvirc/i) {
+ $ver{kvirc}{$nick} = $ver;
+ } elsif ($ver =~ /eggdrop/i) {
+ $ver{eggdrop}{$nick} = $ver;
+ } elsif ($ver =~ /xircon/i) {
+ $ver{xircon}{$nick} = $ver;
+ } else {
+ $ver{other}{$nick} = $ver;
+ }
+}
+
sub on_version {
my ($self, $event) = @_;
my $nick = $event->nick;
my ($self, $event) = @_;
my @args = $event->args;
+ &DEBUG("on_whoisuser: @args");
+
$nuh{lc $args[1]} = $args[1]."!".$args[2]."\@".$args[3];
}
}
# modes w/ target affecting nick => cache it.
- if ($mode =~ /[ov]/) {
+ if ($mode =~ /[bov]/) {
$channels{$chan}{$mode}{$target}++ if $parity;
delete $channels{$chan}{$mode}{$target} if !$parity;
}
}
# 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) {
### public != personal who so the below is kind of pointless.
my @who;
foreach (keys %flood) {
- next if (/^\Q$floodwho\E$/ or /^\Q$chan\E$/);
+ next if (/^\Q$floodwho\E$/);
+ next if (defined $chan and /^\Q$chan\E$/);
+
push(@who, grep /^\Q$message\E$/i, keys %{$flood{$_}});
}
+
if (scalar @who) {
- &msg($who, "you already said what ".join(@who)." have said.");
+ &msg($who, "you already said what ".
+ join(' ', @who)." have said.");
} else {
&msg($who,"Someone already said that ". (time - $time) ." seconds ago" );
}
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();
}
- ($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}}) {
&status("FLOOD overflow detected from $floodwho; ignoring");
my $expire = $param{'ignoreAutoExpire'} || 5;
- $ignoreList{"*!$uh"} = time() + ($expire * 60);
+ &ignoreAdd("*!$uh", $chan, $expire, "flood overflow auto-detected.");
return;
}
$flood{$floodwho}{$message} = time();
}
- # public.
- if ($msgType =~ /public/i) {
- $talkchannel = $chan;
+ my @ignore;
+ if ($msgType =~ /public/i) { # public.
+ $talkchannel = $chan;
&status("<$orig{who}/$chan> $orig{message}");
- }
-
- # private.
- if ($msgType =~ /private/i) {
+ @ignore = keys %{ $ignore{$chan} };
+ } elsif ($msgType =~ /private/i) { # private.
&status("[$orig{who}] $orig{message}");
+ $talkchannel = undef;
+ $chan = "_default";
+ } else {
+ &DEBUG("unknown msgType => $msgType.");
+ }
+ push(@ignore, keys %{ $ignore{"*"} });
+
+ if ((!$skipmessage or &IsChanConf("seenStoreAll")) and
+ &IsChanConf("seen") and
+ $msgType =~ /public/
+ ) {
+ $seencache{$who}{'time'} = time();
+ $seencache{$who}{'nick'} = $orig{who};
+ $seencache{$who}{'host'} = $uh;
+ $seencache{$who}{'chan'} = $talkchannel;
+ $seencache{$who}{'msg'} = $orig{message};
+ $seencache{$who}{'msgcount'}++;
}
return if ($skipmessage);
return unless (&IsParam("minVolunteerLength") or $addressed);
- local $ignore = 0;
- foreach (keys %ignoreList) {
- my $ignoreRE = $_;
- my @parts = split /\*/, "a${ignoreRE}a";
- my $recast = join '\S*', map quotemeta($_), @parts;
- $recast =~ s/^a(.*)a$/$1/;
- if ($nuh =~ /^$recast$/) {
- $ignore++;
- last;
- }
+ foreach (@ignore) {
+ s/\*/\\S*/g;
+
+ next unless (eval { $nuh =~ /^$_$/i });
+
+ &status("IGNORE <$who> $message");
+ return;
}
if (defined $nuh) {
- $userHandle = &verifyUser($who, $nuh);
+ if (!defined $userHandle) {
+ &DEBUG("line 1074: need verifyUser?");
+ &verifyUser($who, $nuh);
+ }
} else {
&DEBUG("hookMsg: 'nuh' not defined?");
}
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 > 3) {
+ &WARN("clc: nowl($nowl) > l($l) - 3");
+ &rawout("MODE $chan +l ".($nowl+$plus) );
+ }
+ }
+}
+
1;