# Rtype -- an IRC bot written in R, the Language of the Future. # Written by Chris Pressey of Cat's Eye Technologies. # This work is hereby placed in the public domain. # This bot's personality is modeled after that of a cat I knew once. # Please forgive its inhospitable nature; it had a hard life. args <- commandArgs(trailing=TRUE) if (length(args) != 3) { cat("Usage: R ... --args botname irc.server.net '#channel'\n", file=stderr()) quit(status=1) } bot <- args[1] server <- args[2] channel <- args[3] hunt <- function(haystack, needle) { return(length(grep(needle, haystack, fixed=TRUE)) > 0) } irc <- socketConnection(host=server, port=6667, blocking=TRUE, open="a+b") shove <- function(s) { cat(s,file=irc) cat(s,file=stderr()) } action <- function(channel, s) { shove(paste("PRIVMSG", channel, ":\x01ACTION", s, "\x01\n")) } grab <- function() { line <- readLines(con=irc, n=1) cat(paste(">", line, "\n"), file=stderr()) return(line) } state <- 0 done <- FALSE while (!done) { line <- grab() if (length(line) == 0) { next } if (state == 0) { # I suppose this might only apply to certain servers. # (And to the case where you are not running ident.) loc <- hunt(line, "No Ident response") if (loc) { shove(paste("USER", bot, bot, bot, bot, "\n")) shove(paste("NICK", bot, "\n")) shove(paste("JOIN", channel, "\n")) state <- 1 } } if (state == 1) { xform <- gsub('^:(.*?)\\!(.*?)\\s+PRIVMSG\\s+(.*?)\\s+\\:(.*?)$', '\\1\u2603\\2\u2603\\3\u2603\\4', line, perl=TRUE) if (length(xform) == 0) { next } if (xform != line) { parts <- strsplit(xform, '\u2603', fixed=TRUE) nick <- parts[[1]][1] in_channel <- parts[[1]][3] message <- parts[[1]][4] if (in_channel == channel & length(grep(bot, message, fixed=TRUE)) > 0) { choice = sample(1:4, 1) if (choice == 1) { action(channel, paste("scowls at", nick)) } else if (choice == 2) { action(channel, paste("groans")) } else if (choice == 3) { action(channel, paste("hisses")) } else if (choice == 4) { shove(paste("PRIVMSG", channel, ":groan\n")) } } } } loc <- hunt(line, "PING") if (loc) { shove("PONG :irc.irc.irc\n") } if (!isOpen(irc)) { done <- TRUE } }