Compare commits
No commits in common. "master" and "ngircd-link" have entirely different histories.
master
...
ngircd-lin
|
@ -2,10 +2,4 @@ FROM xena/lua:5.3
|
||||||
WORKDIR /ketracel
|
WORKDIR /ketracel
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV PATH $PATH:/root/.luarocks/bin
|
ENV PATH $PATH:/root/.luarocks/bin
|
||||||
RUN apk --no-cache add ngircd \
|
RUN ./scripts/build_docker.sh
|
||||||
&& luarocks-5.3 install --local moonscript \
|
|
||||||
&& luarocks-5.3 install --local busted \
|
|
||||||
&& luarocks-5.3 install --local --only-deps ./ketracel*.rockspec \
|
|
||||||
&& ./scripts/test.sh \
|
|
||||||
&& ./scripts/build_docker.sh \
|
|
||||||
&& apk del ngircd
|
|
||||||
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
export LUA_PATH='/root/.luarocks/share/lua/5.3/?.lua;/root/.luarocks/share/lua/5.3/?/init.lua'
|
export LUA_PATH='/root/.luarocks/share/lua/5.3/?.lua;/root/.luarocks/share/lua/5.3/?/init.lua'
|
||||||
export LUA_CPATH='/root/.luarocks/lib/lua/5.3/?.so'
|
export LUA_CPATH='/root/.luarocks/lib/lua/5.3/?.so'
|
||||||
lua5.3 -l ketracel.main
|
lua5.3 -l ketracel
|
||||||
|
|
|
@ -16,19 +16,11 @@ dependencies = {
|
||||||
"lua ~> 5.3",
|
"lua ~> 5.3",
|
||||||
"irc-engine",
|
"irc-engine",
|
||||||
"luasocket",
|
"luasocket",
|
||||||
"ln",
|
|
||||||
"uuid",
|
|
||||||
}
|
}
|
||||||
build = {
|
build = {
|
||||||
type = "builtin",
|
type = "builtin",
|
||||||
modules = {
|
modules = {
|
||||||
["ketracel.bots.commands"] = "src/ketracel/bots/commands.lua",
|
["ketracel"] = "src/ketracel.lua",
|
||||||
["ketracel.bots.ketracel"] = "src/ketracel/bots/ketracel.lua",
|
|
||||||
["ketracel.main"] = "src/ketracel/main.lua",
|
|
||||||
["ketracel.server"] = "src/ketracel/server.lua",
|
|
||||||
["irce.modules.ngircd"] = "src/irce/modules/ngircd/init.lua",
|
|
||||||
["irce.modules.ngircd.channel"] = "src/irce/modules/ngircd/channel.lua",
|
|
||||||
["irce.modules.ngircd.modes"] = "src/irce/modules/ngircd/modes.lua",
|
|
||||||
["irce.modules.oper"] = "src/irce/modules/oper.lua",
|
["irce.modules.oper"] = "src/irce/modules/oper.lua",
|
||||||
},
|
},
|
||||||
install = {
|
install = {
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
moonc-5.3 `find -type f | grep -v spec | grep 'moon$'`
|
|
||||||
ngircd -f `pwd`/spec/ngircd.conf
|
|
||||||
|
|
||||||
function trap_ctrlc () {
|
|
||||||
killall ngircd
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
trap "trap_ctrlc" 2
|
|
||||||
|
|
||||||
cd src
|
|
||||||
export KETRACEL_DEBUG=yes
|
|
||||||
export KETRACEL_SPASS=hunter2
|
|
||||||
lua5.3 -l set_paths ketracel/main.lua
|
|
||||||
trap_ctrlc
|
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
tup
|
tup
|
||||||
cd src
|
cd src
|
||||||
godotenv -f ../.env lua5.3 -l set_paths ./ketracel/main.lua
|
godotenv -f ../.env lua5.3 -l set_paths ketracel.lua
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
moonc `find -type f | grep -v spec | grep 'moon$'`
|
|
||||||
busted -o TAP
|
|
|
@ -1,46 +0,0 @@
|
||||||
[Global]
|
|
||||||
Name = test.localhost
|
|
||||||
Info = oh god
|
|
||||||
Listen = 0.0.0.0
|
|
||||||
MotdPhrase = testing
|
|
||||||
Network = ShadowNET
|
|
||||||
Ports = 6667
|
|
||||||
ServerGID = 65534
|
|
||||||
ServerUID = 65534
|
|
||||||
|
|
||||||
[Limits]
|
|
||||||
MaxJoins = 50
|
|
||||||
MaxNickLength = 31
|
|
||||||
MaxListSize = 100
|
|
||||||
PingTimeout = 120
|
|
||||||
PongTimeout = 20
|
|
||||||
|
|
||||||
[Options]
|
|
||||||
AllowedChannelTypes = #&+
|
|
||||||
AllowRemoteOper = yes
|
|
||||||
CloakUserToNick = yes
|
|
||||||
DNS = no
|
|
||||||
Ident = no
|
|
||||||
MorePrivacy = no
|
|
||||||
NoticeBeforeRegistration = yes
|
|
||||||
OperCanUseMode = yes
|
|
||||||
OperChanPAutoOp = yes
|
|
||||||
PAM = no
|
|
||||||
PAMIsOptional = yes
|
|
||||||
RequireAuthPing = yes
|
|
||||||
|
|
||||||
[Channel]
|
|
||||||
Name = #lobby
|
|
||||||
Topic = Welcome to the new ShadowNET!
|
|
||||||
Modes = tn
|
|
||||||
|
|
||||||
[Operator]
|
|
||||||
Name = Cadey
|
|
||||||
Password = hunter2
|
|
||||||
|
|
||||||
[Server]
|
|
||||||
Name = ketracel.akua
|
|
||||||
Passive = yes
|
|
||||||
MyPassword = hunter2
|
|
||||||
PeerPassword = hunter2
|
|
||||||
ServiceMask = Ketracel,*Serv
|
|
|
@ -1,27 +0,0 @@
|
||||||
Channel = require "irce.modules.ngircd.channel"
|
|
||||||
|
|
||||||
describe "Channel", ->
|
|
||||||
it "requires a channel name", ->
|
|
||||||
assert.has.errors -> Channel {}
|
|
||||||
|
|
||||||
it "lets you create a channel", ->
|
|
||||||
assert.truthy Channel name: "#butts"
|
|
||||||
|
|
||||||
it "lets you set modes", ->
|
|
||||||
with Channel name: "#butts"
|
|
||||||
\add_mode "p"
|
|
||||||
assert .modes[1] == "p"
|
|
||||||
\del_mode "p"
|
|
||||||
assert #.modes == 0
|
|
||||||
|
|
||||||
it "requires channel membership to give hats", ->
|
|
||||||
with Channel name: "#butts"
|
|
||||||
assert.has.errors -> \add_hat "cadey", "@"
|
|
||||||
assert.has.errors -> \del_hat "cadey", "@"
|
|
||||||
|
|
||||||
it "lets you give people hats", ->
|
|
||||||
with Channel name: "#butts", members: {cadey: {}}
|
|
||||||
\add_hat "cadey", "@"
|
|
||||||
assert .members.cadey[1] == "o"
|
|
||||||
\del_hat "cadey", "@"
|
|
||||||
assert #.members.cadey == 0
|
|
|
@ -1,87 +0,0 @@
|
||||||
irce = require "irce"
|
|
||||||
socket = require "socket"
|
|
||||||
test = require "ketracel.test"
|
|
||||||
Server = require("ketracel.server").Server
|
|
||||||
uuid = require "uuid"
|
|
||||||
ln = require "ln"
|
|
||||||
|
|
||||||
describe "ngircd protocol support", ->
|
|
||||||
local server
|
|
||||||
local client
|
|
||||||
|
|
||||||
setup ->
|
|
||||||
file = io.popen "ngircd -n -f ./spec/ngircd.conf", "r"
|
|
||||||
server = Server
|
|
||||||
server: "127.0.0.1"
|
|
||||||
sname: "ketracel.akua"
|
|
||||||
spass: "hunter2"
|
|
||||||
sreal: "Ketracel"
|
|
||||||
nicklen: "31"
|
|
||||||
debug: os.getenv "DEBUG"
|
|
||||||
client = test.Client "test_user"
|
|
||||||
|
|
||||||
teardown ->
|
|
||||||
with io.popen "killall ngircd", "r"
|
|
||||||
\close!
|
|
||||||
|
|
||||||
it "actually is running ngircd", ->
|
|
||||||
with io.popen "pstree"
|
|
||||||
data = \read "*all"
|
|
||||||
assert.truthy string.find data, "ngircd"
|
|
||||||
|
|
||||||
it "sees end of burst", ->
|
|
||||||
server\wait_for "376"
|
|
||||||
|
|
||||||
it "can use the Client class", ->
|
|
||||||
client\wait_for "005"
|
|
||||||
|
|
||||||
it "sees the client", ->
|
|
||||||
server\wait_for "NICK", (source, user) ->
|
|
||||||
user.nick == "test_user"
|
|
||||||
|
|
||||||
local channame
|
|
||||||
|
|
||||||
it "sees the client join a new channel", ->
|
|
||||||
channame = uuid()
|
|
||||||
client.irc\JOIN "#" .. channame
|
|
||||||
server\wait_for "JOIN", (who, chan) ->
|
|
||||||
chan.name == "#" .. channame
|
|
||||||
client\wait_for "JOIN", (sender, channel) ->
|
|
||||||
channel\sub(2) == channame
|
|
||||||
|
|
||||||
it "sees the client part the channel", ->
|
|
||||||
client.irc\PART "#" .. channame
|
|
||||||
server\wait_for "PART", (who, chan) ->
|
|
||||||
chan.name == "#" .. channame
|
|
||||||
|
|
||||||
it "sees nickchanges", ->
|
|
||||||
client.irc\send_raw "NICK newnick"
|
|
||||||
server\wait_for "NICKCHG", (sender, clinfo) ->
|
|
||||||
clinfo.nick == "newnick"
|
|
||||||
|
|
||||||
it "sees quits", ->
|
|
||||||
cli = test.Client "quitter"
|
|
||||||
cli\wait_for "005"
|
|
||||||
cli.irc\QUIT "bye"
|
|
||||||
server\wait_for "QUIT", (sender, msg) ->
|
|
||||||
sender == "quitter"
|
|
||||||
|
|
||||||
it "sees a privmsg", ->
|
|
||||||
client.irc\JOIN "#ketracel"
|
|
||||||
client.irc\PRIVMSG "#ketracel", "hi"
|
|
||||||
server\wait_for "PRIVMSG", (sender, params) ->
|
|
||||||
params[1] == "#ketracel" and params[2] == "hi"
|
|
||||||
|
|
||||||
describe "ketracel bot", ->
|
|
||||||
it "has a working VHOST command", ->
|
|
||||||
client.irc\PRIVMSG "Ketracel", "VHOST my.cool.vhost"
|
|
||||||
server\wait_for "PRIVMSG", (sender, params) ->
|
|
||||||
params[1] == "Ketracel" and params[2] == "VHOST my.cool.vhost"
|
|
||||||
client\wait_for "396"
|
|
||||||
client\wait_for "NOTICE", (sender, origin, message, pm) ->
|
|
||||||
message\find "my.cool.vhost"
|
|
||||||
|
|
||||||
it "replies to unknown commands", ->
|
|
||||||
client.irc\PRIVMSG "KETRACEL", uuid()
|
|
||||||
server\wait_for "PRIVMSG"
|
|
||||||
client\wait_for "NOTICE"
|
|
|
@ -1,20 +0,0 @@
|
||||||
modes = require "irce.modules.ngircd.modes"
|
|
||||||
|
|
||||||
describe "mode conversion", ->
|
|
||||||
it "has modes2prefix", ->
|
|
||||||
assert.truthy modes.mode2prefix
|
|
||||||
|
|
||||||
it "has prefix2modes", ->
|
|
||||||
assert.truthy modes.prefix2mode
|
|
||||||
|
|
||||||
it "has convert", ->
|
|
||||||
assert.truthy modes.convert
|
|
||||||
|
|
||||||
describe "convert", ->
|
|
||||||
for k, v in pairs modes.mode2prefix
|
|
||||||
msg = string.format "%s: %s", k, v
|
|
||||||
it msg, ->
|
|
||||||
assert.equal(modes.convert(k), v)
|
|
||||||
msg = string.format "%s: %s", v, k
|
|
||||||
it msg, ->
|
|
||||||
assert.equal(modes.convert(v), k)
|
|
|
@ -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 <your.vhost>"
|
||||||
|
else
|
||||||
|
self\PRIVMSG "Ketracel", sender, "i don't know " .. cmd
|
||||||
|
}
|
|
@ -1,43 +0,0 @@
|
||||||
modeconv = require "irce.modules.ngircd.modes"
|
|
||||||
|
|
||||||
class Channel
|
|
||||||
new: (data) =>
|
|
||||||
assert data.name
|
|
||||||
data.members = {} unless data.members
|
|
||||||
data.modes = {} unless data.modes
|
|
||||||
data.topic = "" unless data.topic
|
|
||||||
for k, v in pairs data
|
|
||||||
self[k] = v
|
|
||||||
|
|
||||||
add_hat: (who, mode) =>
|
|
||||||
hat = modeconv.convert mode
|
|
||||||
usermodes = assert @members[who\lower!]
|
|
||||||
for _, chhat in pairs usermodes
|
|
||||||
return if chhat == hat
|
|
||||||
|
|
||||||
usermodes[#usermodes+1] = hat
|
|
||||||
|
|
||||||
del_hat: (who, mode) =>
|
|
||||||
hat = modeconv.convert mode
|
|
||||||
usermodes = assert @members[who\lower!]
|
|
||||||
|
|
||||||
for i, v in pairs usermodes
|
|
||||||
if v == hat
|
|
||||||
table.remove usermodes, i
|
|
||||||
return
|
|
||||||
|
|
||||||
add_mode: (mode) =>
|
|
||||||
for _, chmd in pairs @modes
|
|
||||||
return if chmd == mode
|
|
||||||
|
|
||||||
@modes[#@modes+1] = mode
|
|
||||||
|
|
||||||
del_mode: (mode) =>
|
|
||||||
for i, v in pairs @modes
|
|
||||||
if v == mode
|
|
||||||
table.remove @modes, i
|
|
||||||
return
|
|
||||||
|
|
||||||
string.format "desync detected: mode %s isn't set on %s", mode, @name
|
|
||||||
|
|
||||||
Channel
|
|
|
@ -2,8 +2,6 @@ irce = require "irce"
|
||||||
util = require "irce.util"
|
util = require "irce.util"
|
||||||
stringx = require "pl.stringx"
|
stringx = require "pl.stringx"
|
||||||
moon = require "moon"
|
moon = require "moon"
|
||||||
ln = require "ln"
|
|
||||||
modeconv = require "irce.modules.ngircd.modes"
|
|
||||||
|
|
||||||
{
|
{
|
||||||
init: (state) =>
|
init: (state) =>
|
||||||
|
@ -13,10 +11,10 @@ modeconv = require "irce.modules.ngircd.modes"
|
||||||
|
|
||||||
senders:
|
senders:
|
||||||
["REGISTER"]: (state, password, software, version, sname, real, nicklen) =>
|
["REGISTER"]: (state, password, software, version, sname, real, nicklen) =>
|
||||||
assert @PASS password, software, version
|
assert self\PASS password, software, version
|
||||||
assert @SERVER sname, real
|
assert self\SERVER sname, real
|
||||||
assert @NICKLEN nicklen
|
assert self\NICKLEN nicklen
|
||||||
assert @EMOTD!
|
assert self\EMOTD!
|
||||||
string.format ":%s PING :%s", sname, sname
|
string.format ":%s PING :%s", sname, sname
|
||||||
|
|
||||||
["PASS"]: (state, password, software, version) =>
|
["PASS"]: (state, password, software, version) =>
|
||||||
|
@ -45,124 +43,35 @@ modeconv = require "irce.modules.ngircd.modes"
|
||||||
|
|
||||||
["NICK"]: (state, nick, user, host, modes, real) =>
|
["NICK"]: (state, nick, user, host, modes, real) =>
|
||||||
state.clients[string.lower nick] =
|
state.clients[string.lower nick] =
|
||||||
:nick, :user, :host, modes: string.sub(modes, 2), :real, metadata: {}
|
:nick, :user, :host, :modes, :real, metadata: {}
|
||||||
string.format ":%s NICK %s 1 %s %s 1 %s :%s", state.sname, nick, user, host, modes, real
|
string.format ":%s NICK %s 1 %s %s 1 %s :%s", state.sname, nick, user, host, modes, real
|
||||||
|
|
||||||
["CHANINFO"]: (state, channame) =>
|
["NJOIN"]: (state, channame, who) =>
|
||||||
if state.channels[channame] == nil
|
string.format ":%s NJOIN %s :%s", state.sname, channame, who
|
||||||
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) =>
|
["METADATA"]: (state, nick, key, val) =>
|
||||||
state.clients[string.lower nick].metadata[key] = val
|
state.clients[string.lower nick].metadata[key] = val
|
||||||
string.format ":%s METADATA %s %s :%s", state.sname, nick, key, val
|
string.format ":%s METADATA %s %s :%s", state.sname, nick, key, val
|
||||||
|
|
||||||
["VHOST"]: (state, nick, vhost) =>
|
["VHOST"]: (state, nick, vhost) =>
|
||||||
@METADATA nick, "cloakhost", vhost
|
self\METADATA nick, "cloakhost", vhost
|
||||||
string.format ":%s MODE %s +x", state.sname, nick
|
string.format ":%s MODE %s +x", state.sname, nick
|
||||||
|
|
||||||
["PRIVMSG"]: (state, nick, target, message) =>
|
["PRIVMSG"]: (state, nick, target, message) =>
|
||||||
string.format ":%s PRIVMSG %s :%s", 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:
|
handlers:
|
||||||
["461"]: (state, sender, params) =>
|
|
||||||
@handle "DIE", string.format("%s: %s", sender[1], params[1])
|
|
||||||
|
|
||||||
["ERROR"]: (state, sender, params) =>
|
["ERROR"]: (state, sender, params) =>
|
||||||
error string.format "%s: %s", sender[1], params[1]
|
error string.format "%s: %s", sender[1], params[1]
|
||||||
|
|
||||||
["PING"]: (state, sender, params) =>
|
["PING"]: (state, sender, params) =>
|
||||||
@send "PONG", params[1]
|
self\send "PONG", params[1]
|
||||||
sender, params[1]
|
sender, params[1]
|
||||||
|
|
||||||
["PONG"]: (state, sender, params) =>
|
["PONG"]: (state, sender, params) =>
|
||||||
sender, params[1]
|
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) =>
|
["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]
|
nick = params[1]
|
||||||
user = params[3]
|
user = params[3]
|
||||||
host = params[4]
|
host = params[4]
|
||||||
|
@ -173,7 +82,7 @@ modeconv = require "irce.modules.ngircd.modes"
|
||||||
state.clients[string.lower nick] =
|
state.clients[string.lower nick] =
|
||||||
:nick, :user, :host, :modes, :real, :metadata
|
:nick, :user, :host, :modes, :real, :metadata
|
||||||
|
|
||||||
sender, state.clients[string.lower nick]
|
sender, state.clients[nick]
|
||||||
|
|
||||||
["METADATA"]: (state, sender, params) =>
|
["METADATA"]: (state, sender, params) =>
|
||||||
nick = params[1]
|
nick = params[1]
|
||||||
|
@ -187,13 +96,6 @@ modeconv = require "irce.modules.ngircd.modes"
|
||||||
chan = params[1]
|
chan = params[1]
|
||||||
whose = stringx.split tostring(params[2]), ","
|
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
|
for k, v in pairs whose
|
||||||
pfxlen = string.find v, "%a+"
|
pfxlen = string.find v, "%a+"
|
||||||
nick = string.lower string.sub v, pfxlen
|
nick = string.lower string.sub v, pfxlen
|
||||||
|
@ -201,7 +103,7 @@ modeconv = require "irce.modules.ngircd.modes"
|
||||||
pfxarr = {}
|
pfxarr = {}
|
||||||
|
|
||||||
for i = 1, #prefix
|
for i = 1, #prefix
|
||||||
pfxarr[i] = modeconv.convert string.sub prefix, i, i
|
pfxarr[i] = string.sub prefix, i, i
|
||||||
|
|
||||||
state.channels[chan].members[nick] = pfxarr
|
state.channels[chan].members[nick] = pfxarr
|
||||||
|
|
||||||
|
@ -225,24 +127,19 @@ modeconv = require "irce.modules.ngircd.modes"
|
||||||
|
|
||||||
state.channels[name] =
|
state.channels[name] =
|
||||||
:name, :mode, :topic, :key, :limit, members: {}
|
:name, :mode, :topic, :key, :limit, members: {}
|
||||||
state.channels[name]
|
|
||||||
|
|
||||||
["PRIVMSG"]: (state, sender, params) =>
|
["PRIVMSG"]: (state, sender, params) =>
|
||||||
if params[2] == "?state"
|
|
||||||
moon.p state
|
|
||||||
return sender, params
|
|
||||||
|
|
||||||
if sender[1] == "Cadey" and stringx.startswith params[2], "?eval"
|
if sender[1] == "Cadey" and stringx.startswith params[2], "?eval"
|
||||||
code = string.sub(params[2], 7)
|
code = string.sub(params[2], 7)
|
||||||
print string.format "%s %s %s - evaling", params[1], sender[1], code
|
print string.format "%s %s %s - evaling", params[1], sender[1], code
|
||||||
fun, err = load(code, sender[1].."-"..params[1], "t", {
|
fun, err = load(code, sender[1].."-"..params[1], "t", {
|
||||||
state: state, :string, irc: @, :_VERSION
|
state: state, :string,
|
||||||
})
|
})
|
||||||
if err ~= nil
|
if err ~= nil
|
||||||
error err
|
error err
|
||||||
result = fun!
|
result = fun!
|
||||||
if result ~= nil
|
if result ~= nil
|
||||||
@PRIVMSG state.sname, params[1], tostring result
|
self\PRIVMSG state.sname, params[1], tostring result
|
||||||
|
|
||||||
sender, params
|
sender, params
|
||||||
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
mode2prefix =
|
|
||||||
q: "~"
|
|
||||||
a: "&"
|
|
||||||
o: "@"
|
|
||||||
h: "%"
|
|
||||||
v: "+"
|
|
||||||
|
|
||||||
prefix2mode =
|
|
||||||
["~"]: "q"
|
|
||||||
["&"]: "a"
|
|
||||||
["@"]: "o"
|
|
||||||
["%"]: "h"
|
|
||||||
["+"]: "v"
|
|
||||||
|
|
||||||
convert = (mode_or_prefix) ->
|
|
||||||
mode2prefix[mode_or_prefix] or prefix2mode[mode_or_prefix]
|
|
||||||
|
|
||||||
{
|
|
||||||
:mode2prefix
|
|
||||||
:prefix2mode
|
|
||||||
:convert
|
|
||||||
}
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
irce = require "irce"
|
||||||
|
socket = require "socket"
|
||||||
|
|
||||||
|
config =
|
||||||
|
server: os.getenv("IRC_HOST") or "127.0.0.1"
|
||||||
|
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.ngircd"
|
||||||
|
assert irc\load_module require "bots.ketracel"
|
||||||
|
|
||||||
|
client = socket.tcp!
|
||||||
|
client\settimeout 1
|
||||||
|
|
||||||
|
irc\set_send_func (message) =>
|
||||||
|
client\send message
|
||||||
|
|
||||||
|
if config.debug
|
||||||
|
irc\set_callback irce.RAW, (send, message) =>
|
||||||
|
print string.format "%s %s", (send and ">" or "<"), message
|
||||||
|
|
||||||
|
print "Ketracel loaded using " .. irce._VERSION .. " running on " .. _VERSION
|
||||||
|
|
||||||
|
-- connect to irc server
|
||||||
|
assert client\connect config.server, 6667
|
||||||
|
|
||||||
|
assert irc\REGISTER config.spass, "ketracel", "0.0.1", config.sname, config.sreal, config.nicklen
|
||||||
|
|
||||||
|
if config.oper
|
||||||
|
irc\OPER config.nick, config.oper
|
||||||
|
print "IRC operator status requested for " .. config.nick
|
||||||
|
|
||||||
|
while running
|
||||||
|
irc\process client\receive!
|
||||||
|
|
||||||
|
client\close!
|
|
@ -1,3 +0,0 @@
|
||||||
include_rules
|
|
||||||
.gitignore
|
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
ln = require "ln"
|
|
||||||
stringx = require "pl.stringx"
|
|
||||||
|
|
||||||
class CommandRouter
|
|
||||||
new: (bot, cmdchar = "?") =>
|
|
||||||
@bot = bot
|
|
||||||
@cmdchar = cmdchar
|
|
||||||
@commands = {}
|
|
||||||
|
|
||||||
register: (verb, action) =>
|
|
||||||
self.commands[verb] = action
|
|
||||||
|
|
||||||
run: (sender, target, verb, args) =>
|
|
||||||
verb = string.upper verb
|
|
||||||
cmd = self.commands[verb]
|
|
||||||
if cmd == nil
|
|
||||||
@bot.irc\NOTICE @bot.name, sender, "unknown command verb " .. verb
|
|
||||||
return
|
|
||||||
|
|
||||||
cmd sender, target, verb, args
|
|
||||||
|
|
||||||
privmsg: (sender, params) =>
|
|
||||||
cmdchar = params[2]\sub 1, 1
|
|
||||||
destsigil = params[1]\sub 1, 1
|
|
||||||
|
|
||||||
if params[1]\lower! == @bot.name\lower!
|
|
||||||
sp = stringx.split params[2]
|
|
||||||
cmd = sp[1]
|
|
||||||
table.remove sp, 1
|
|
||||||
@run sender[1], params[1], cmd, sp
|
|
||||||
|
|
||||||
if cmdchar == @cmdchar and destsigil == "#"
|
|
||||||
sp = stringx.split params[2]
|
|
||||||
cmd = string.sub sp[1], (#@cmdchar + 1)
|
|
||||||
table.remove sp, 1
|
|
||||||
@run sender[1], params[1], cmd, sp
|
|
||||||
|
|
||||||
CommandRouter
|
|
|
@ -1,48 +0,0 @@
|
||||||
irce = require "irce"
|
|
||||||
ln = require "ln"
|
|
||||||
moon = require "moon"
|
|
||||||
stringx = require "pl.stringx"
|
|
||||||
CommandRouter = require "ketracel.bots.commands"
|
|
||||||
|
|
||||||
class Ketracel
|
|
||||||
new: (irc) =>
|
|
||||||
@name = "Ketracel"
|
|
||||||
@irc = irc
|
|
||||||
router = CommandRouter self
|
|
||||||
router\register "DIE", (sender, target, verb, args) -> @die sender, target, verb, args
|
|
||||||
router\register "VHOST", (...) -> @set_vhost ...
|
|
||||||
router\register "STATE", ->
|
|
||||||
router\register "EVAL", ->
|
|
||||||
@router = router
|
|
||||||
|
|
||||||
burst: =>
|
|
||||||
@irc\NICK @name, "white", "the.dominion", "+io", "Ketracel White"
|
|
||||||
|
|
||||||
njoin: (chan) =>
|
|
||||||
@irc\NJOIN chan, "Ketracel"
|
|
||||||
|
|
||||||
die: (sender, target, verb, args) =>
|
|
||||||
@irc\handle "DIE", string.format("%s asked me to die in %s", sender, target)
|
|
||||||
|
|
||||||
set_vhost: (sender, target, verb, args) =>
|
|
||||||
if #args > 0
|
|
||||||
ln.log :sender, vhost: args[1], action: "setting vhost"
|
|
||||||
@irc\VHOST sender, args[1]
|
|
||||||
@irc\NOTICE "Ketracel", sender, "your vhost is now " ..args[1]
|
|
||||||
else
|
|
||||||
@irc\NOTICE "Ketracel", sender, "usage: VHOST <your.vhost>"
|
|
||||||
|
|
||||||
{
|
|
||||||
init: (state) =>
|
|
||||||
state.bot = Ketracel self
|
|
||||||
|
|
||||||
hooks:
|
|
||||||
["376"]: (state) =>
|
|
||||||
state.bot\burst!
|
|
||||||
|
|
||||||
["NJOIN"]: (state, chan) =>
|
|
||||||
state.bot\njoin chan
|
|
||||||
|
|
||||||
["PRIVMSG"]: (state, sender, params) =>
|
|
||||||
state.bot.router\privmsg sender, params
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
irce = require "irce"
|
|
||||||
ln = require "ln"
|
|
||||||
socket = require "socket"
|
|
||||||
server = require "ketracel.server"
|
|
||||||
|
|
||||||
config =
|
|
||||||
server: os.getenv("IRC_HOST") or "127.0.0.1"
|
|
||||||
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"
|
|
||||||
|
|
||||||
with server.Server config
|
|
||||||
\run!
|
|
|
@ -1,59 +0,0 @@
|
||||||
irce = require "irce"
|
|
||||||
ln = require "ln"
|
|
||||||
socket = require "socket"
|
|
||||||
|
|
||||||
class Server
|
|
||||||
new: (config) =>
|
|
||||||
@config = config
|
|
||||||
sock = socket.tcp!
|
|
||||||
irc = irce.new!
|
|
||||||
|
|
||||||
irc\load_module require "irce.modules.ngircd"
|
|
||||||
irc\load_module require "ketracel.bots.ketracel"
|
|
||||||
|
|
||||||
irc\set_send_func (message) =>
|
|
||||||
sock\send message
|
|
||||||
|
|
||||||
if config.debug
|
|
||||||
ln.log {"msg": "debug enabled"}, config
|
|
||||||
irc\set_callback irce.RAW, (send, message) =>
|
|
||||||
sigil = send and ">" or "<"
|
|
||||||
print string.format "%s %s", (send and ">" or "<"), message
|
|
||||||
|
|
||||||
ln.log msg: "Ketracel loaded", irce: irce._VERSION, lua: _VERSION
|
|
||||||
|
|
||||||
assert sock\connect config.server, 6667
|
|
||||||
assert irc\REGISTER config.spass, "ketracel", "0.0.1", config.sname, config.sreal, config.nicklen
|
|
||||||
|
|
||||||
@irc = irc
|
|
||||||
@socket = sock
|
|
||||||
|
|
||||||
wait_for: (event, checker) =>
|
|
||||||
running = true
|
|
||||||
|
|
||||||
@irc\set_callback event, (...) =>
|
|
||||||
if checker and not checker(...)
|
|
||||||
return
|
|
||||||
print "! got event " .. event if os.getenv "DEBUG"
|
|
||||||
running = false
|
|
||||||
|
|
||||||
while running
|
|
||||||
@irc\process @socket\receive!
|
|
||||||
|
|
||||||
@irc\clear_callback event
|
|
||||||
|
|
||||||
run: =>
|
|
||||||
running = true
|
|
||||||
|
|
||||||
@irc\set_callback "DIE", (why) =>
|
|
||||||
ln.err why, {msg: "told to die"}
|
|
||||||
running = false
|
|
||||||
|
|
||||||
while running
|
|
||||||
@irc\process @socket\receive!
|
|
||||||
|
|
||||||
@socket\close!
|
|
||||||
|
|
||||||
{
|
|
||||||
:Server
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
irce = require "irce"
|
|
||||||
socket = require "socket"
|
|
||||||
|
|
||||||
get_client_modules = (irc) ->
|
|
||||||
irc\load_module require "irce.modules.base"
|
|
||||||
irc\load_module require "irce.modules.message"
|
|
||||||
irc\load_module require "irce.modules.channel"
|
|
||||||
|
|
||||||
class Client
|
|
||||||
new: (nick) =>
|
|
||||||
@nick = nick
|
|
||||||
sock = socket.tcp!
|
|
||||||
irc = irce.new!
|
|
||||||
get_client_modules irc
|
|
||||||
irc\set_send_func (message) =>
|
|
||||||
print string.format "[client %s] > %s", nick, message if os.getenv "DEBUG"
|
|
||||||
sock\send message
|
|
||||||
|
|
||||||
sock\connect "127.0.0.1", 6667
|
|
||||||
irc\NICK nick
|
|
||||||
irc\USER nick, nick
|
|
||||||
|
|
||||||
@socket = sock
|
|
||||||
@irc = irc
|
|
||||||
|
|
||||||
wait_for: (event, checker) =>
|
|
||||||
running = true
|
|
||||||
nick = @nick
|
|
||||||
@irc\set_callback event, (...) =>
|
|
||||||
if checker and not checker ...
|
|
||||||
return
|
|
||||||
print string.format "[client %s] ! got event %s", nick, event if os.getenv "DEBUG"
|
|
||||||
running = false
|
|
||||||
while running
|
|
||||||
msg = assert @socket\receive!
|
|
||||||
print string.format "[client %s] < %s", nick, msg if os.getenv "DEBUG"
|
|
||||||
@irc\process msg
|
|
||||||
|
|
||||||
@irc\clear_callback event
|
|
||||||
|
|
||||||
quit: =>
|
|
||||||
@irc\QUIT "bye"
|
|
||||||
@socket\close!
|
|
||||||
|
|
||||||
{
|
|
||||||
:Client
|
|
||||||
}
|
|
Loading…
Reference in New Issue