Limitsbot
# compile using "nim c -d:release --threads:on ChessBot.nim"
import std/net, std/strutils, std/osproc, std/streams, std/os, std/threadpool
const SERVER = "irc.ircnow.org"
const POR = 6667
const CHANNEL = "#chess_arena"
const NICK = "ChessBot"
const ADMINS = ["Limits", "jrmu"]
const AUTHOR = "Limits"
const GNUCHESS_PATH = "/usr/local/bin/gnuchess"
var ch: Channel[string]
open(ch)
proc readLineTimeout(readStream: Stream): int =
while true:
let k = readStream.readLine
while not ch.trySend(k):
sleep(10)
proc printLines(socket: Socket, channel: string, text: string) =
for line in text.split("\n"):
socket.send("PRIVMSG " & channel & " :" & line & "\n")
let gnuchess = startProcess(GNUCHESS_PATH, args = ["-m"])
discard spawn readLineTimeout(gnuchess.outputStream)
sleep(1000)
let s = ch.peek
for _ in 1..<s:
discard ch.recv
let socket = newSocket()
socket.connect(SERVER, Port(POR))
socket.send("NICK " & NICK & "\n")
socket.send("USER " & NICK & " * 0 :IRC Chess Bot\n")
while true:
var data = socket.recvLine().split()
echo("IRC: ", data)
if data[0] == "PING":
socket.send("PONG " & data[1] & "\n")
elif data[0] == "":
discard
elif data[1] == "001":
socket.send("JOIN " & CHANNEL & "\n")
elif data[1] == "PRIVMSG" and data[3] == ":!chess":
if data.len > 4:
case data[4]
of "hello": socket.send("PRIVMSG " & data[2] & " :HELLO " & data[0].split("!")[0][1 .. ^1] & "\n")
of "author": socket.send("PRIVMSG " & data[2] & " :Author = " & AUTHOR & "\n")
of "version": socket.send("PRIVMSG " & data[2] & " :Version = 0.1.0\n")
of "gnuchess":
gnuchess.inputstream.writeLine(data[5..^1].join(" "))
gnuchess.inputstream.flush
sleep(100)
let s = ch.peek
for _ in 1..<s:
let k = ch.recv
socket.send("PRIVMSG " & data[2] & " :" & k & "\n")
discard ch.recv
of "quit":
if ADMINS.contains(data[0].split("!")[0][1 .. ^1]):
socket.send("PRIVMSG " & data[2] & " :BYE\n")
gnuchess.close
socket.close
break
of "admins":
socket.send("PRIVMSG " & data[2] & " :" & ADMINS.join(" ") & "\n")
of "help":
socket.printLines(data[2], """ChessBot
!chess author prints author
!chess version prints version
!chess gnuchess <cmd> executes cmd in gnuchess and prints the output
!chess admins prints bot admins
!chess quit quits the ChessBot (only executable by bot admins)
!chess help prints this message""")
else:
socket.send("PRIVMSG " & data[2] & " :Needs an argument\n")