commit 985f69561ab9b6eacef6a5c0348b777abaa24df6
Author: boredpasta <boredpasta@tutanota.com>
Date: Mon, 24 Feb 2025 23:21:08 +0200
initiate skynet
Diffstat:
A | mata_bot.pl | | | 108 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 108 insertions(+), 0 deletions(-)
diff --git a/mata_bot.pl b/mata_bot.pl
@@ -0,0 +1,108 @@
+use v5.38;
+use re 'strict';
+use POSIX qw(strftime);
+use IO::Socket qw(AF_INET SOCK_STREAM);
+use IO::Socket::SSL;
+
+my $LOGGING = 0;
+my $CHUNK_LENGTH = 1024;
+my $NETWORK = 'irc.libera.chat';
+my $PORT = '6697';
+my $NICK = 'mata_bot';
+my $USER = 'mata_bot_beta4';
+my $REAL = 'death to technomage!!';
+my $CHAN = '#unix_surrealism';
+my $SULTANA = 'anelli';
+
+sub logger {
+ my $logmessage = shift;
+ open(my $logfile, ">>", "bot.log") or die "Can't open bot.log: $!";
+ print $logfile strftime('%Y-%m-%dT%H:%M:%SZ ', gmtime()), $logmessage, "\n";
+}
+
+sub out {
+ my ($sock, $message) = @_;
+ logger($message) if ($LOGGING);
+ print $sock "$message\r\n";
+}
+
+sub msg {
+ my ($sock, $message) = @_;
+ out($sock, "PRIVMSG $CHAN :$message");
+}
+
+# respond to channel
+sub respond {
+ my ($sock, $sender_nick, $message) = @_;
+ # if no triggers found, check for mentions
+ if ($message =~ /^${NICK}(:|,)/) {
+ if ($sender_nick =~ /^${SULTANA}$/) {
+ msg($sock, "Done, Your Majesty, Sultana ${sender_nick}! <[^_^]>");
+ } else {
+ msg($sock, "${sender_nick}: BSOD!! <[x~x]>");
+ }
+ } elsif ($message =~ /${NICK}/) {
+ if ($sender_nick =~ /^${SULTANA}$/) {
+ msg($sock, "Yes, Your Majesty, Sultana ${sender_nick}? <[^_^]>");
+ } else {
+ msg($sock, "${sender_nick}: Bleep Bloop? <[._.]>");
+ }
+ }
+}
+
+# start the connection
+my $sock = IO::Socket::SSL->new(
+ PeerHost => $NETWORK,
+ PeerPort => $PORT,
+ Domain => AF_INET,
+ Type => SOCK_STREAM,
+ proto => 'tcp',
+) || die "Can't open socket: $IO::Socket::errstr";
+
+# set user, real, and nick, then join
+out($sock, "USER $USER * * :$REAL");
+out($sock, "NICK $NICK");
+out($sock, "JOIN $CHAN");
+
+# evasdrop
+my $buffer = '';
+my $chunk = '';
+my $message = '';
+while (1) {
+ # buffer up
+ #$sock->recv($chunk, $CHUNK_LENGTH);
+ $chunk = <$sock>;
+ $chunk =~ /^([^\r\n]+)(\r\n)?([^\r\n]+)?$/;
+ # keep reading if chunk is empty
+ next if (not $1);
+ # if chunks isn't empty, check for framing point
+ if ($2) {
+ # if we found a framing point, flush buffer and text till framing point
+ $message = $buffer . $1;
+ if ($3) {
+ # if we have text after framing, make it the new content of buffer
+ $buffer = $3;
+ } else {
+ # if we have no text after framing, clear buffer
+ $buffer = '';
+ }
+ } else {
+ # if there's no framing. append chunk to end of buffer and keep reading
+ $buffer .= $chunk;
+ next;
+ }
+
+ # log message
+ logger($message) if ($LOGGING);
+
+ # respond to message
+ if ($message =~ /^PING :([^\000\r\n\ ]+)$/) {
+ # if we got a ping, pong back
+ out($sock, "PONG :$1");
+ } elsif ($message =~ /^:([^\000\r\n\#\&\ ][^\000\r\n\ ]*)![^\000\r\n\ ]+@[^\000\r\n\ ]+ PRIVMSG ${CHAN} :([^\000\r\n]*)$/) {
+ # if we got a message to our chan. read and act accordingly
+ my $sender_nick = $1;
+ my $sender_message = $2;
+ respond($sock, $sender_nick, $sender_message);
+ }
+}