diff --git a/src/bots/Tupfile b/src/bots/Tupfile new file mode 100644 index 0000000..591db9c --- /dev/null +++ b/src/bots/Tupfile @@ -0,0 +1,3 @@ +include_rules +.gitignore + diff --git a/src/bots/ketracel.moon b/src/bots/ketracel.moon new file mode 100644 index 0000000..6a13ed1 --- /dev/null +++ b/src/bots/ketracel.moon @@ -0,0 +1,40 @@ +irce = require "irce" +moon = require "moon" +stringx = require "pl.stringx" + +{ + hooks: + ["376"]: (state) => + self\NICK "Ketracel", "white", "the.dominion", "+io", "Ketracel White" + self\NJOIN "#ketracel", "@Ketracel" + + --["NJOIN"]: (state, chan) => + -- self\NJOIN chan, "Ketracel" + + ["PRIVMSG"]: (state, sender, params) => + cmdchar = params[2]\sub 1, 1 + destsigil = params[1]\sub 1, 1 + + if params[1]\lower! == "ketracel" + sp = stringx.split params[2] + cmd = sp[1] + table.remove sp, 1 + self\handle("Ketracel command", sender[1], params[1], cmd, sp) + + if cmdchar == "?" and destsigil == "#" + sp = stringx.split params[2] + cmd = string.sub sp[1], 2 + table.remove sp, 1 + self\handle("Ketracel command", sender[1], params[1], cmd, sp) + + ["Ketracel command"]: (state, sender, target, cmd, args) => + switch string.upper cmd + when "VHOST" + if #args > 0 + self\VHOST sender, args[1] + self\PRIVMSG "Ketracel", sender, "your vhost is now " ..args[1] + else + self\PRIVMSG "Ketracel", sender, "usage: VHOST " + else + self\PRIVMSG "Ketracel", sender, "i don't know " .. cmd +} diff --git a/src/irce/modules/ngircd/Tupfile b/src/irce/modules/ngircd/Tupfile new file mode 100644 index 0000000..591db9c --- /dev/null +++ b/src/irce/modules/ngircd/Tupfile @@ -0,0 +1,3 @@ +include_rules +.gitignore + diff --git a/src/irce/modules/ngircd/init.moon b/src/irce/modules/ngircd/init.moon new file mode 100644 index 0000000..841aa48 --- /dev/null +++ b/src/irce/modules/ngircd/init.moon @@ -0,0 +1,158 @@ +irce = require "irce" +util = require "irce.util" +stringx = require "pl.stringx" +moon = require "moon" + +{ + init: (state) => + state.servers = {} + state.clients = {} + state.channels = {} + + senders: + ["REGISTER"]: (state, password, software, version, sname, real, nicklen) => + assert self\PASS password, software, version + assert self\SERVER sname, real + assert self\NICKLEN nicklen + assert self\EMOTD! + string.format ":%s PING :%s", sname, sname + + ["PASS"]: (state, password, software, version) => + state.pass = password + string.format "PASS %s 0210-IRC+ %s|%s:CHLMSXo", password, software, version + + ["SERVER"]: (state, sname, real) => + state.sname = sname + state.servers[sname] = real + string.format "SERVER %s 1 :%s", sname, real + + ["NICKLEN"]: (state, len) => + string.format ":%s 005 * NICKLEN=%s :are supported on this server", state.sname, len + + ["EMOTD"]: (state) => + string.format ":%s 376 * :End of MOTD command", state.sname + + ["KILL"]: (state, who, reason) => + string.format ":%s KILL %s :%s: %s", state.sname, who, state.sname, reason + + ["PING"]: (state, param) => + ":" .. state.sname .. " PING :" .. param + + ["PONG"]: (state, param) => + ":" .. state.sname .. " PONG :" .. param + + ["NICK"]: (state, nick, user, host, modes, real) => + state.clients[string.lower nick] = + :nick, :user, :host, :modes, :real, metadata: {} + string.format ":%s NICK %s 1 %s %s 1 %s :%s", state.sname, nick, user, host, modes, real + + ["NJOIN"]: (state, channame, who) => + string.format ":%s NJOIN %s :%s", state.sname, channame, who + + ["METADATA"]: (state, nick, key, val) => + state.clients[string.lower nick].metadata[key] = val + string.format ":%s METADATA %s %s :%s", state.sname, nick, key, val + + ["VHOST"]: (state, nick, vhost) => + self\METADATA nick, "cloakhost", vhost + string.format ":%s MODE %s +x", state.sname, nick + + ["PRIVMSG"]: (state, nick, target, message) => + string.format ":%s PRIVMSG %s :%s", nick, target, message + + handlers: + ["ERROR"]: (state, sender, params) => + error string.format "%s: %s", sender[1], params[1] + + ["PING"]: (state, sender, params) => + self\send "PONG", params[1] + sender, params[1] + + ["PONG"]: (state, sender, params) => + sender, params[1] + + ["NICK"]: (state, sender, params) => + nick = params[1] + user = params[3] + host = params[4] + modes = string.sub params[6], 2 + real = params[7] + metadata = {} + + state.clients[string.lower nick] = + :nick, :user, :host, :modes, :real, :metadata + + sender, state.clients[nick] + + ["METADATA"]: (state, sender, params) => + nick = params[1] + key = params[2] + value = params[3] + + state.clients[string.lower nick].metadata[key] = value + sender, nick, key: value + + ["NJOIN"]: (state, sender, params) => + chan = params[1] + whose = stringx.split tostring(params[2]), "," + + for k, v in pairs whose + pfxlen = string.find v, "%a+" + nick = string.lower string.sub v, pfxlen + prefix = string.sub v, 1, pfxlen - 1 + pfxarr = {} + + for i = 1, #prefix + pfxarr[i] = string.sub prefix, i, i + + state.channels[chan].members[nick] = pfxarr + + chan, whose + + ["CHANINFO"]: (state, sender, params) => + name = params[1] + mode = string.sub params[2], 2 + topic = params[#params] + key = nil + limit = nil + + if #params == 5 + key = params[3] + if key == "*" + key = nil + + limit = params[4] + if limit == "0" + limit = nil + + state.channels[name] = + :name, :mode, :topic, :key, :limit, members: {} + + ["PRIVMSG"]: (state, sender, params) => + if sender[1] == "Cadey" and stringx.startswith params[2], "?eval" + code = string.sub(params[2], 7) + print string.format "%s %s %s - evaling", params[1], sender[1], code + fun, err = load(code, sender[1].."-"..params[1], "t", { + state: state, :string, + }) + if err ~= nil + error err + result = fun! + if result ~= nil + self\PRIVMSG state.sname, params[1], tostring result + + sender, params + + ["SERVER"]: (state, sender, params) => + sname = params[1] + real = params[#params] + + state.servers[sname] = real + sender, sname, real + + ["PASS"]: (state, sender, params) => + if params[1] ~= state.pass + error "got wrong password from " .. sender[1] + + state.pass = nil +} diff --git a/src/ketracel.moon b/src/ketracel.moon index 3bb6e29..2515ae2 100644 --- a/src/ketracel.moon +++ b/src/ketracel.moon @@ -3,27 +3,22 @@ socket = require "socket" config = server: os.getenv("IRC_HOST") or "127.0.0.1" - nick: os.getenv("IRC_NICK") or "Ketracel-dev" - user: os.getenv("IRC_USER") or "white" - real: os.getenv("IRC_REAL") or "The favorite of the Jem'Hadar" - oper: os.getenv("IRC_OPER") - channels: { "#ketracel", "#opers" } + sname: os.getenv("KETRACEL_SNAME") or "ketracel.akua" + spass: os.getenv("KETRACEL_SPASS") or error("need KETRACEL_SPASS") + sreal: os.getenv("KETRACEL_SREAL") or "The favorite of the Jem'Hadar" debug: os.getenv("KETRACEL_DEBUG") + nicklen: os.getenv("KETRACEL_NICKLEN") or "31" irc = irce.new! running = true -- load IRC modules -assert irc\load_module require "irce.modules.base" -assert irc\load_module require "irce.modules.channel" -assert irc\load_module require "irce.modules.message" -assert irc\load_module require "irce.modules.motd" -assert irc\load_module require "irce.modules.oper" +assert irc\load_module require "irce.modules.ngircd" +assert irc\load_module require "bots.ketracel" client = socket.tcp! client\settimeout 1 --- irc engine callbacks irc\set_send_func (message) => client\send message @@ -31,26 +26,12 @@ if config.debug irc\set_callback irce.RAW, (send, message) => print string.format "%s %s", (send and ">" or "<"), message -irc\set_callback "CTCP", (sender, origin, command, params, pm) => - if command == "VERSION" - self\CTCP_REPLY origin, "VERSION", string.format("Ketracel white - dev (%s, %s)", irce._VERSION, _VERSION) - -irc\set_callback "001", (...) => - for k, chan in ipairs config.channels - assert irc\JOIN chan - -irc\set_callback "PRIVMSG", (sender, origin, message, pm) => - if message == "?quit" - assert self\QUIT "Ran out of white" - running = false +print "Ketracel loaded using " .. irce._VERSION .. " running on " .. _VERSION -- connect to irc server assert client\connect config.server, 6667 -assert irc\NICK config.nick -assert irc\USER config.user, config.real - -print "Ketracel loaded using " .. irce._VERSION .. " running on " .. _VERSION +assert irc\REGISTER config.spass, "ketracel", "0.0.1", config.sname, config.sreal, config.nicklen if config.oper irc\OPER config.nick, config.oper