diff options
Diffstat (limited to 'bot.lua')
-rw-r--r-- | bot.lua | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/bot.lua b/bot.lua index db01ba8..0704b63 100644 --- a/bot.lua +++ b/bot.lua @@ -7,7 +7,9 @@ local fifo = require("fifo") local mom = require("mom") local function parse_message(data) - if string.match(data, "[\0\r\n]") then return nil, "illegal character" end + if string.match(data, "[\0\r\n]") then + return nil, "illegal character" + end local pos = 1 local prefix @@ -108,16 +110,23 @@ function irc_handlers.JOIN(state, line) if not state.channels[line.params[1]] then -- TODO validate the params at all local ch_name = line.params[1] + local ch_config = config.channels[ch_name] local ch = {} state.channels[ch_name] = ch - ch.command = config.channels[ch_name].command or config.command - ch.invoke = config.channels[ch_name].invoke or config.invoke + ch.command = ch_config.command or config.command + ch.invoke = ch_config.invoke or config.invoke + ch.directory = ch_config.directory or config.directory ch.mom_id, ch.tx_queue = state.mom:create( ch.command, ch_name, - state.rx_queue + state.rx_queue, + ch.directory + ) + else + state.mom:start_process( + state.channels[line.params[1]].mom_id ) end end @@ -134,6 +143,7 @@ function irc_handlers.PRIVMSG(state, line) local full_line = line.params[2] local line for _, prefix in ipairs(state.channels[ch].invoke) do + -- TODO: escape the nick itself prefix = string.gsub(prefix, "%%n", state.nick) prefix = string.gsub(prefix, "%%%", "%") -- TODO parens and stuff maybe @@ -199,8 +209,10 @@ local function irc_connect(loop, config) -- a channel has the fields: -- - invoke, a list of patterns (as in config, but being -- properly populated with defaults) + -- - command, the command to run as a list + -- - directory, the dir to run it in -- - mom_id, the id in the state's process mom - -- - tx_queue: to send messages to the ed queue + -- - tx_queue, to send messages to the ed queue -- (note we don't have rx_queue: that is shared) channels = {}, } @@ -220,6 +232,10 @@ local function irc_connect(loop, config) line = { command = "BADLINE", params = { line } } end + if line.command == "ERROR" or state.config.debug then + print(raw_line) + end + local command = (tonumber(line.command) and "_" or "") .. line.command if irc_handlers[command] then irc_handlers[command](state, line) @@ -239,14 +255,53 @@ local function irc_connect(loop, config) state.mom = mom.new(loop) loop:wrap(function () handle_ed_rx(state) end) + + if config.pass then + fifo.put(state.queue, { + command = "PASS", params = { config.pass } + }) + end + fifo.put(state.queue, { command = "NICK", params = { config.nick } }) -- TODO: config fifo.put(state.queue, { command = "USER", - params = { "ed1bot", "0", "*", ":)" }, + params = { config.user, "0", "*", ":)" }, }) end +local function validate_config(c) + local function valid(name, thing, kind) + assert(type(thing) == kind, + kind .. " " .. name .. " must be specified" + ) + end + + local function optional(name, thing, kind) + if thing then valid(name, thing, kind) end + end + + valid("host", c.host, "table") + valid("host.host", c.host.host, "string") + valid("host.port", c.host.port, "number") + valid("nick", c.nick, "string") + valid("user", c.user, "string") + optional("pass", c.pass, "string") + valid("directory", c.directory, "string") + -- TODO better + valid("command", c.command, "table") + valid("invoke", c.invoke, "table") + valid("channels", c.channels, "table") + + for k, v in pairs(c.channels) do + local name = string.format("channels[%q]", k) + valid(name, v, "table") + optional(name .. ".invoke", v.invoke, "table") + optional(name .. ".command", v.command, "table") + optional(name .. ".directory", v.directory, "string") + end +end + do local main = cqueues.new() if not arg[1] then @@ -255,6 +310,7 @@ do end local config = assert(dofile(arg[1])) + validate_config(config) main:wrap(function () irc_connect(main, config) |