From b534916115d0115f22e79db30361c54403bd16f3 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Wed, 12 Sep 2018 13:24:39 +0200 Subject: add socket server --- bot.lua | 125 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 37 deletions(-) diff --git a/bot.lua b/bot.lua index f35f742..a422cb8 100644 --- a/bot.lua +++ b/bot.lua @@ -7,9 +7,8 @@ local loop = cqueues.new() local host, port, socketpath = ... -socketpath = socketpath or "./sock" - +-------------------------------------------------------------------------------- -- irc session local irc = { callbacks = {} } @@ -49,29 +48,6 @@ function irc:connect(host, port) self:send("NICK %s", self.nick) self:send("USER %s 0 * :%s", self.username, self.realname) - ---[[ --- self.conn:settimeout(-1) - - 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 @@ -275,18 +251,89 @@ end function irc:step() - local line, why = self.conn:read("*L") + local line, why = self.conn:recv("*L") if not line or #line == 0 then - if why == errno.ETIMEDOUT then - self:run_hooks("OnTimeout") - end return nil, why end self:handle(line) return line end +function irc:loop() + repeat + repeat + local ok, err = self:step() + print("DEBUG step:", ok, err) + until not ok + + cqueues.poll(self) + print("DEBUG: loop") + until self.conn:eof() +end + +-------------------------------------------------------------------------- +-- sockserver + +local sockserver = { callbacks = {}} +function sockserver.new(ircsession, socketpath, timeout) + local path = socketpath or "/tmp/albotty.sock" + local self = { + path = path, + ircsess = ircsession, + socket = socket.listen{path=path}, + timeout = timeout, + } + return setmetatable(self, { __index = sockserver }) +end + +sockserver.callbacks["/msg"] = function(self, data) + local dest,msg = string.match(data or "", "^([^ ]+) (.*)") + if dest then + self.ircsess:send_chat(dest, msg) + return "ok" + end + return "error: msg format" +end + +sockserver.callbacks["bye"] = function(serf, data) + return "bye!" +end + +function sockserver:run_callback(line) + local cmd = string.match(line, "^([^ ]+)") + local data = string.match(line, "^[^ ]+ (.*)") + print("DEBUG: cmd:", cmd) + print("DEBUG: data:", data) + if not cmd or type(self.callbacks[cmd]) ~= "function" then + return nil + end + return cmd, self.callbacks[cmd](self, data) +end + +function sockserver:loop(loop) + for conn in self.socket:clients(self.timeout) do + loop:wrap(function() + for line in conn:lines("*l") do + print("DEBUG: got line:", line) + local cmd, resp = self:run_callback(line) + if not cmd then + conn:write("error: unknown command\n") + end + if resp then + conn:write(resp.."\n") + end + if cmd == "bye" then + conn:shutdown("w") + break + end + end + end) + end +end + + --------------------------------------------------------------------------- + sess = irc.new() sess:hook("OnChat", function(self, user, channel, message) @@ -316,24 +363,28 @@ sess:hook("OnKick", function(self, channel, kicked, user, reason) end) sess:autojoin{"#alpine-test", "#alpine"} - sess:connect("172.16.3.54", "6667") - print("CONNECTED!") +local srv = sockserver.new(sess) + loop:wrap(function() - repeat - local ok, err = sess:step() - print("DEBUG step:", ok, err) - until not ok and err ~= errno.ETIMEDOUT - return true --nil, err + sess:loop() end) +loop:wrap(function() + srv:loop(loop) +end) + +------------------------------------------------------------------------------------------- +-- mainloop + while not loop:empty() do local ok, err = loop:step() + print("DEBUG: mainloop") if not ok then - os.remove(socketpath) + os.remove(srv.path) error("loop.step: "..err) end end -- cgit v1.2.3