commit 029d7e66cc971a4f5a97ac4fd76713e8de6e5b80 from: Izzy Blacklock date: Thu Aug 03 21:41:38 2023 UTC Moved main IRC processing loop into IRCNOW::IO::IRC commit - 2f6757c2add6396d61f52b7ab93e4c180c7838b6 commit + 029d7e66cc971a4f5a97ac4fd76713e8de6e5b80 blob - 18e3eb2885a388c39e9efbe3023d4aa0e45d59d5 blob + 50d54cb85c9f33c6dc606e54381dd5410901d0cf --- botnow +++ botnow @@ -113,23 +113,6 @@ my $backupspath = $IRCNOW::IO::backupspath; my $staff = $conf{staff}; my $localnet = $conf{localnet}; -my $irc = new IRCNOW::IO::IRC( - networks => [split(/\s+/, $conf{networks})], - localnet => $conf{localnet}, - stafflist => [split(/ /, $staff)], - nick => $conf{nick}, - host => $conf{host}, - port => $conf{port}, - pass => $conf{pass}, -); -my $bots=$irc->{bots}; -my $call=$irc->{call}; -my @chans = split /[,\s]+/m, $conf{chans}; -my @teamchans; -if (defined($conf{teamchans})) { @teamchans = split /[,\s]+/m, $conf{teamchans}; } -my $nick = $conf{nick}; -my $pass = $conf{pass}; -my $expires = $conf{expires}; unveil("./", "r") or die "Unable to unveil $!"; unveil("$confpath", "r") or die "Unable to unveil $!"; @@ -142,296 +125,20 @@ unveil() or die "Unable to lock unveil $!"; #rpath for reading file, wpath for writing file, cpath for creating path #flock, fattr for sqlite pledge( qw(stdio rpath wpath cpath inet dns proc exec flock fattr) ) or die "Unable to pledge: $!"; -my $sel = $irc->{sockets}; -while(my @ready = $sel->can_read) { - my ($bot, $response); - my ($sender, $val); - foreach my $socket (@ready) { - foreach my $b (@$bots) { - if($socket == $b->{sock}) { - $bot = $b; - last; - } - } - if (!defined($response = <$socket>)) { - debug(ERRORS, "ERROR ".$bot->{name}." has no response:"); - next; - } - if ($response =~ /^PING :(.*)\r\n$/i) { - $irc->putserv($bot, "PONG :$1"); - } elsif ($response =~ /^:irc.znc.in (.*) (.*) :(.*)\r\n$/) { - my ($type, $target, $text) = ($1, $2, $3); - if ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Password required") { - $irc->putserv($bot, "PASS $nick/$bot->{name}:$pass"); - if ($bot->{name} =~ /^$localnet$/i) { - $irc->putserv($bot, "OPER $nick $pass"); - $irc->putserv($bot, "PRIVMSG *status :LoadMod --type=user controlpanel"); - $irc->putserv($bot, "PRIVMSG *controlpanel :get Admin $nick"); - $irc->putserv($bot, "PRIVMSG *controlpanel :get Nick cloneuser"); - foreach my $chan (@teamchans) { - $irc->putserv($bot, "JOIN $chan"); - } - } - if ($bot->{name} !~ /^$localnet$/i) { - foreach my $chan (@chans) { - $irc->putserv($bot, "JOIN $chan"); - } - } - } elsif ($type eq "464" && $target =~ /^$nick.?$/ && $text eq "Invalid Password") { - die "ERROR: Wrong Username/Password: $bot->{name}"; - } else { - debug(ALL, "Debug type: $type, target: $target, text: $text"); - } - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PRIVMSG ([^ ]+) :(.*)\r\n$/i) { - chomp($response); - debug(ALL, "-->COMMAND--> $response"); - my ($hostmask, $sendnick, $host, $target, $text) = ($1, $2, $3, $4, $5); - if ($hostmask eq '*status!znc@znc.in' && $target =~ /^$nick.?$/) { - if ($text =~ /Network ([[:ascii:]]+) doesn't exist./) { - debug(ERRORS, "ERROR: nonexistent: $1"); - } elsif ($text eq "You are currently disconnected from IRC. Use 'connect' to reconnect.") { - debug(ERRORS, "ERROR: disconnected: $bot->{name}"); - } elsif ($text =~ /Unable to load module (.*): Module (.*) already loaded./) { - debug(ALL, "Module $1 already loaded\n"); - } elsif ($text =~ /^Disconnected from IRC.*$/) { - debug(ERRORS, "ERROR: $bot->{name}: $text"); - } elsif ($text =~ /^|/) { - debug(ERRORS, "ERROR: $bot->{name}: $text"); - } else { - debug(ERRORS, "ERROR: Unexpected: $response"); - } - } elsif ($text =~ /^!([[:graph:]]+)\s*(.*)/) { - my ($cmd, $text) = ($1, $2); - debug(ALL, qq{<>}); - my $hand = $staff; # TODO fix later - if ($target =~ /^#/) { - foreach my $c (@{$call->{pub}}) { - if ($cmd eq $c->{cmd}) { - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $target, $text); - } - } - } else { - foreach my $c (@{$call->{msg}}) { - if ($cmd eq $c->{cmd}) { - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $text); - } - } - } - } else { - my $hand = $staff; # TODO fix later - if ($target =~ /^#/) { - foreach my $c (@{$call->{pubm}}) { - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $target, $text); - } - } else { - foreach my $c (@{$call->{msgm}}) { - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $text); - } - } - } - debug(ALL, "$hostmask $target $text"); - } elsif($response =~ /^:([^ ]+) NOTICE ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $target, $text) = ($1, $2, $3); - if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) { - my ($sendnick, $host) = ($1, $2); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{notc}}) { - # if ($text eq $c->{mask}) { # TODO fix later - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $text, $target); - # } - } - - # CTCP replies - if ($hostmask ne '*status!znc@znc.in') { - if ($text =~ /^(PING|VERSION|TIME|USERINFO) (.*)$/i) { - my ($key, $val) = ($1, $2); - my $id = BotNow::SQLite::id("irc", "nick", $sendnick, $expires); - BotNow::SQLite::set("irc", "id", $id, "ctcp".lc($key), $val); - BotNow::SQLite::set("irc", "id", $id, "localtime", time()); - } - } - } - debug(ALL, "$hostmask NOTICE $target $text"); -#:portlane.se.quakenet.org NOTICE guava :Highest connection count: 1541 (1540 clients) -#:portlane.se.quakenet.org NOTICE guava :on 2 ca 2(4) ft 20(20) tr - } elsif($response =~ /^:([^ ]+) MODE ([^ ]+) ([^ ]+)\s*(.*)\r\n$/i) { - my ($hostmask, $chan, $change, $targets) = ($1, $2, $3, $4); - if ($hostmask =~ /([^!]+)!([^@]+@[^@ ]+)/) { - my ($sendnick, $host) = ($1, $2); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{mode}}) { - # TODO filter by mask - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $chan, $change, $targets); - } - } - debug(ALL, "$hostmask MODE $chan $change $targets"); -#:guava!guava@guava.guava.ircnow.org MODE guava :+Ci -#:ChanServ!services@services.irc.ircnow.org MODE #testing +q jrmu -#:jrmu!jrmu@jrmu.staff.ircnow.org MODE #testing +o jrmu -#Unexpected bncnow.pl 460: :irc.guava.ircnow.org MODE guava :+o - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) JOIN :?(.*)\r\n$/i) { - my ($hostmask, $sendnick, $host, $chan) = ($1, $2, $3, $4); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{join}}) { - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $chan); - } - debug(ALL, "$hostmask JOIN $chan"); -#:jrmu!jrmu@jrmu.staff.ircnow.org JOIN :#testing - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) PART ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $sendnick, $host, $chan, $text) = ($1, $2, $3, $4, $5); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{part}}) { - # if ($text eq $c->{mask}) { # TODO fix later - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $chan, $text); - # } - } - debug(ALL, "$hostmask PART $chan :$text"); -#:jrmu!jrmu@jrmu.staff.ircnow.org PART #testing : - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) KICK (#[^ ]+) ([^ ]+) :(.*)\r\n$/i) { - my ($hostmask, $sendnick, $host, $chan, $kicked, $text) = ($1, $2, $3, $4, $5, $6); - my $hand = $staff; # TODO fix later - foreach my $c (@{$call->{kick}}) { - # if ($text eq $c->{mask}) { # TODO fix later - my $proc = $c->{proc}; - $proc->($bot, $sendnick, $host, $hand, $chan, $text); - # } - } - debug(ALL, "$hostmask KICK $chan $kicked :$text"); -#jrmu!jrmu@jrmu.users.undernet.org KICK #ircnow guava :this is a test - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) NICK :?(.*)\r\n$/i) { - my ($hostmask, $sendnick, $host, $text) = ($1, $2, $3, $4); - debug(ALL, "$hostmask NICK $text"); -#:Fly0nDaWaLL|dal!psybnc@do.not.h4ck.me NICK :nec|dal - } elsif($response =~ /^:(([^!]+)!([^@]+@[^@ ]+)) QUIT :(.*)\r\n$/i) { - my ($hostmask, $sendnick, $host, $text) = ($1, $2, $3, $4); - debug(ALL, "$hostmask QUIT :$text"); -#:Testah!~sid268081@aa38a510 QUIT :Client closed connection - } elsif($response =~ /^NOTICE AUTH :(.*)\r\n$/i) { - my ($text) = ($1); - debug(ALL, "NOTICE AUTH: $text"); -#NOTICE AUTH :*** Looking up your hostname -#NOTICE AUTH: *** Looking up your hostname -#NOTICE AUTH: *** Checking Ident -#NOTICE AUTH: *** Got ident response -#NOTICE AUTH: *** Found your hostname - } elsif ($response =~ /^:([[:graph:]]+) (\d\d\d) $nick.? :?(.*)\r?\n?\r$/i) { - my ($server, $code, $text) = ($1, $2, $3); - if ($code =~ /^001$/) { # Server Info - debug(ERRORS, "connected: $bot->{name}"); - } elsif ($code =~ /^0\d\d$/) { # Server Info - debug(ALL, "$server $code $text"); - } elsif ($code =~ /^2\d\d$/) { # Server Stats - debug(ALL, "$server $code $text"); - } elsif ($code == 301 && $text =~ /^([-_\|`a-zA-Z0-9]+) :([[:graph:]]+)/) { - debug(ALL, "$text"); - } elsif ($code == 307 && $text =~ /^([-_\|`a-zA-Z0-9]+) (.*)/) { - my ($sender, $key) = ($1, "registered"); - $val = $2 eq ":is a registered nick" ? "True" : "$2"; - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, "identified", $val); - debug(ALL, "$key: $val"); - } elsif ($code == 311 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+)\s+([^:]+) \* :([^:]*)/) { - my ($sender, $key, $val) = ($1, "hostmask", "$1\!$2\@$3"); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 312 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([^:]+) :([^:]+)/) { - my ($sender, $key, $val) = ($1, "server", $2); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 313 && $text =~ /^([-_\|`a-zA-Z0-9]+) :?(.*)/) { - my ($sender, $key, $val) = ($1, "oper", ($2 eq "is an IRC operator" ? "True" : "$2")); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 315 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHO(IS)? list/) { - debug(ALL, "End of WHOIS"); - } elsif ($code == 317 && $text =~ /^([-_\|`a-zA-Z0-9]+) (\d+) (\d+) :?(.*)/) { - ($sender, my $idle, my $epochtime) = ($1, $2, $3); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, "idle", $idle); -# BotNow::SQLite::set("irc", "id", $id, "epochtime", time()); - debug(ALL, "idle: $idle, epochtime: $epochtime"); - } elsif ($code == 318 && $text =~ /^([-_\|`a-zA-Z0-9]+) :End of \/?WHOIS list/) { - debug(ALL, "End of WHOIS"); - } elsif ($code == 319 && $text =~ /^([-_\|`a-zA-Z0-9]+) :(.*)/) { - my ($sender, $key, $val) = ($1, "chans", $2); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 330 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([-_\|`a-zA-Z0-9]+) :?(.*)/) { - my ($sender, $key, $val) = ($1, "identified", ($3 eq "is logged in as" ? "True" : $2)); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 338 && $text =~ /^([-_\|`a-zA-Z0-9]+) ([0-9a-fA-F:.]+) :actually using host/) { - my ($sender, $key, $val) = ($1, "ip", $2); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - #Unexpected: efnet.port80.se 338 jrmu 206.253.167.44 :actually using host - } elsif ($code == 378 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is connecting from ([^ ]+)\s*([0-9a-fA-F:.]+)?/) { - my ($sender, $key, $val) = ($1, "ip", $3); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code == 671 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is using a secure connection/) { - my ($sender, $key, $val) = ($1, "ssl", "True"); - my $id = BotNow::SQLite::id("irc", "nick", $sender, $expires); - BotNow::SQLite::set("irc", "id", $id, $key, $val); - debug(ALL, "$key: $val"); - } elsif ($code =~ /^332$/) { # Topic - # print "$text\r\n"; - } elsif ($code =~ /^333$/) { # - # print "$server $text\r\n"; - #karatkievich.freenode.net 333 #ircnow jrmu!znc@206.253.167.44 1579277253 - } elsif ($code =~ /^352$/) { # Hostmask -#:datapacket.hk.quakenet.org 352 * znc guava.guava.ircnow.org *.quakenet.org guava H :0 guava - # print "$server $code $text\r\n"; - } elsif ($code =~ /^353$/) { # Names - # print "$server $code $text\r\n"; - } elsif ($code =~ /^366$/) { # End of names - # print "$server $code $text\r\n"; - } elsif ($code =~ /^37\d$/) { # MOTD - # print "$server $code $text\r\n"; - } elsif ($code =~ /^381$/) { # IRC Operator Verified - # print "IRC Oper Verified\r\n"; - } elsif ($code =~ /^401$/) { # IRC Operator Verified - # print "IRC Oper Verified\r\n"; - } elsif ($code =~ /^403$/) { # No such channel - # debug(ERRORS, "$text"); - } elsif ($code =~ /^422$/) { # MOTD missing - # print "$server $code $text\r\n"; - } elsif ($code =~ /^396$/) { # Display hostname - # print "$server $code $text\r\n"; -#Unexpected bncnow.pl 454: irc.guava.ircnow.org 396 guava.guava.ircnow.org :is your displayed hostname now - } elsif ($code =~ /^464$/) { # Invalid password for oper - foreach my $chan (@teamchans) { - $irc->putserv($bot, "PRIVMSG $chan :$nick oper password failed; the bot will be unable to view uncloaked IP addresses"); - } - } elsif ($code =~ /^477$/) { # Can't join channel - foreach my $chan (@teamchans) { - $irc->putserv($bot, "PRIVMSG $chan :ERROR: $nick on $server: $text"); - } - } elsif ($code == 716 && $text =~ /^([-_\|`a-zA-Z0-9]+) :is in \+g mode \(server-side ignore.\)/) { - debug(ALL, "$text"); - } else { - debug(ERRORS, "Unexpected bncnow.pl 454: $server $code $text"); - } - } else { - chomp($response); - debug(ERRORS, "--> $response"); - } - } -} +my $irc = new IRCNOW::IO::IRC( + networks => [split(/\s+/, $conf{networks})], + localnet => $conf{localnet}, + stafflist => [split(/ /, $staff)], + nick => $conf{nick}, + host => $conf{host}, + port => $conf{port}, + pass => $conf{pass}, + expires => $conf{expires}, + chans => [split /[,\s]+/m, $conf{chans}], + teamchans => [split /[,\s]+/m, $conf{teamchans}], +); +$irc->run(); + +