ketracel/src/irce/modules/ngircd/init.moon

262 lines
7.5 KiB
Plaintext

irce = require "irce"
util = require "irce.util"
stringx = require "pl.stringx"
moon = require "moon"
ln = require "ln"
modeconv = require "irce.modules.ngircd.modes"
{
init: (state) =>
state.servers = {}
state.clients = {}
state.channels = {}
senders:
["REGISTER"]: (state, password, software, version, sname, real, nicklen) =>
assert @PASS password, software, version
assert @SERVER sname, real
assert @NICKLEN nicklen
assert @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: string.sub(modes, 2), :real, metadata: {}
string.format ":%s NICK %s 1 %s %s 1 %s :%s", state.sname, nick, user, host, modes, real
["CHANINFO"]: (state, channame) =>
if state.channels[channame] == nil
state.channels[channame] =
name: channame
mode: "tn"
topic: ""
members: {}
string.format ":%s CHANINFO %s +tn", state.sname, channame
["NJOIN"]: (state, channame, who, prefix) =>
if state.channels[channame] == nil
state.channels[channame] =
name: channame,
mode: ""
topic: ""
members: {}
pfxarr = {}
if prefix
for i = 1, #prefix
pfxarr[i] = string.sub prefix, i, i
state.channels[channame].members[string.lower who] = pfxarr
string.format ":%s NJOIN %s :%s%s", state.sname, channame, prefix or "", 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) =>
@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
["NOTICE"]: (state, nick, target, message) =>
string.format ":%s NOTICE %s :%s", nick, target, message
["PART"]: (state, nick, chan, why) =>
state.channels[chan].members[nick] = nil
if #state.channels[chan].members == 0
state.channels[chan] = nil
string.format ":%s PART %s :%s", nick, chan, why
handlers:
["461"]: (state, sender, params) =>
@handle "DIE", string.format("%s: %s", sender[1], params[1])
["ERROR"]: (state, sender, params) =>
error string.format "%s: %s", sender[1], params[1]
["PING"]: (state, sender, params) =>
@send "PONG", params[1]
sender, params[1]
["PONG"]: (state, sender, params) =>
sender, params[1]
["JOIN"]: (state, sender, params) =>
chan = params[1]
mode = {}
bell = string.find chan, "\x07"
if bell
sp = {string.sub(chan, 1, bell - 1), string.sub(chan, bell + 1)}
chan = sp[1]
mode = {modeconv.convert sp[2]}
nick = string.lower sender[1]
if not state.channels[chan]
state.channels[chan] = {name: chan, mode: "", members: {}, topic: ""}
state.channels[chan].members[nick] = mode
sender[1], state.channels[chan]
["PART"]: (state, sender, params) =>
chan = params[1]
nick = string.lower sender[1]
cinfo = state.channels[chan]
state.channels[chan].members[nick] = nil
if #state.channels[chan].members == 0
state.channels[chan] = nil
sender[1], cinfo
["QUIT"]: (state, sender, params) =>
nick = string.lower sender[1]
state.clients[nick] = nil
for k, v in pairs state.channels
v.members[nick] = nil
sender[1], params[1]
["NICK"]: (state, sender, params) =>
if #params == 1
oldnick = sender[1]
oldnicksmall = string.lower oldnick
newnick = params[1]
cli = state.clients[oldnicksmall]
cli.nick = newnick
state.clients[string.lower oldnicksmall] = nil
nick = string.lower newnick
state.clients[string.lower newnick] = cli
for k, v in pairs state.channels
for kk, vv in pairs v.members
if kk == oldnicksmall
v.members[nick] = v.members[oldnicksmall]
v.members[oldnicksmall] = nil
@handle "NICKCHG", sender, state.clients[nick]
return
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[string.lower 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]), ","
if state.channels[chan] == nil
state.channels[chan] =
name: chan
mode: ""
topic: ""
members: {}
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] = modeconv.convert 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: {}
state.channels[name]
["PRIVMSG"]: (state, sender, params) =>
if params[2] == "?state"
moon.p state
return 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, irc: @, :_VERSION
})
if err ~= nil
error err
result = fun!
if result ~= nil
@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
}