summaryrefslogtreecommitdiffstats
path: root/bot.lua
diff options
context:
space:
mode:
Diffstat (limited to 'bot.lua')
-rw-r--r--bot.lua191
1 files changed, 191 insertions, 0 deletions
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)