From 552e8b29dc0f35f1d18539d76ea59ba1a23abbc5 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Fri, 3 Aug 2018 16:39:31 +0200 Subject: initial commit --- bot.lua | 191 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 bot.lua diff --git a/bot.lua b/bot.lua new file mode 100644 index 0000000..d218771 --- /dev/null +++ b/bot.lua @@ -0,0 +1,191 @@ + +local cqueues = require("cqueues") +local socket = require("cqueues.socket") + +local loop = cqueues.new() + +local host, port, socketpath = ... + +socketpath = socketpath or "./sock" + + +-- irc session +local irc = { callbacks = {} } + +function irc.new(nick, username, password, realname) + local self = { + nick = nick or "albotty", + username = username or "albotty", + password = password, + realname = realname or "albotty" + } + return setmetatable(self, { __index = irc }) +end + +function irc:connect(host, port) + local hostname, password, tls, timeout + if type(host) == "table" then + hostname = host.host + port = host.port + password = host.password + tls = host.tls + timeout = host.timeout + else + hostname = host + end + self.conn = socket.connect(hostname, port) + self.conn:settimeout(timeout or 30) + + self:send("NICK %s", self.nick) + self:send("USER %s 0 * :%s", self.username, self.realname) + + local loop = cqueues.new() + loop:wrap(function() + for line in sess.conn:lines("*L") do + if line and #line > 0 then + sess:handle(line) + end + if self.authed then + return + end + end + end) + while not loop:empty() and not self.authed do + local ok, err = loop:step() + if not ok then + error("loop.step: "..err) + end + end + + return self +end + +function irc:pollfd() + return self.conn:pollfd() +end + +function irc:events() + return self.conn:events() +end + +function irc:send(msg, ...) + if select("#", ...) > 0 then + msg = msg:format(...) + end + -- call send hook + self.conn:write(msg.."\r\n") + self.conn:flush() +end + +local function irc_parse(line) + local prefix + local lineStart = 1 + if line:sub(1,1) == ":" then + local space = line:find(" ") + prefix = line:sub(2, space-1) + lineStart = space + end + + local _, trailToken = line:find("%s+:", lineStart) + local lineStop = line:len() + local trailing + if trailToken then + trailing = line:sub(trailToken + 1) + lineStop = trailToken - 2 + end + + local params = {} + + local _, cmdEnd, cmd = line:find("(%S+)", lineStart) + local pos = cmdEnd + 1 + while true do + local _, stop, param = line:find("(%S+)", pos) + if not param or stop > lineStop then + break + end + + pos = stop + 1 + params[#params + 1] = param + end + + if trailing then + params[#params + 1] = trailing + end + + return prefix, cmd, params +end + +local function parse_prefix(prefix) + local user = {} + if prefix then + user.access, user.nick, user.username, user.host = prefix:match("^([%+@]*)(.+)!(.+)@(.+)$") + end + return user +end + +irc.callbacks["001"] = function(self, prefix, me) + self.authed = true + self.nick = me +end + +irc.callbacks["NOTICE"] = function(self, prefix, channel, msg) +end + +irc.callbacks["NICK"] = function(self, prefix, newnick) + local user = parse_prefix(prefix) + if self.nick == user.nick then + self.nick = newnick + end +end + +irc.callbacks["NICK"] = function(self, prefix, newnick) + local user = parse_prefix(prefix) + if self.nick == user.nick then + self.nick = newnick + end +end + +irc.callbacks["PING"] = function(self, prefix, query) + self:send("PONG :%", query) +end + +function irc:handle(line) + local prefix, cmd, params = irc_parse(line) + callback = self.callbacks[cmd] + if type(callback) == "function" then + print("DEBUG: calling handler for:", cmd, prefix, table.unpack(params)) + return callback(self, prefix, table.unpack(params)) + else + print("DEBUG no handler for:", cmd, "prefix:",prefix) + end +end + + +function irc:step() + local line, why, errmsg = self.conn:read("*L") + if not line or #line == 0 then + return nil + end + self:handle(line) + return line +end + +sess = irc.new() +sess:connect("chat.freenode.net", "6667") + +print("CONNECTED!!!!!!!!!!!!!!!!!!!!!!!!!!!!11") + +loop:wrap(function() + while sess:step() do + print("witing for next") + end +end) + +while not loop:empty() do + local ok, err = loop:step() + if not ok then + os.remove(socketpath) + error("loop.step: "..err) + end +end +os.remove(socketpath) -- cgit v1.2.3