summaryrefslogtreecommitdiff
path: root/xmpp
diff options
context:
space:
mode:
authorolive <olive@olive.ooo>2026-09-13 17:05:53 +0100
committerolive <olive@olive.ooo>2026-09-13 17:09:32 +0100
commit359b94d98084b1e005d5add74f3739f6ef36aa8b (patch)
tree273c39c61c472ad59b1e3829ead357011e38d546 /xmpp
parentc95ff81b4fced35a329493ca593a0c9a0610e4a1 (diff)
xmpp: multi-muc, sep out user resolution
Diffstat (limited to 'xmpp')
-rw-r--r--xmpp/pylon.lua100
1 files changed, 62 insertions, 38 deletions
diff --git a/xmpp/pylon.lua b/xmpp/pylon.lua
index 9568999..5056f18 100644
--- a/xmpp/pylon.lua
+++ b/xmpp/pylon.lua
@@ -12,11 +12,12 @@ local Xmpp = class.extend(BasePylon)
function Xmpp.init(self)
self:_check_fields"server component component_secret"
- self.nicks_inuse = {}
+
+ self.mucs = {}
end
-- only use on local connections!
-function Xmpp._connect_component(self)
+function Xmpp._connect(self)
local sock = assert(socket.connect(self.server, 5347))
self.sock = sock
sock:setmode('bn','bn')
@@ -37,9 +38,51 @@ function Xmpp._connect_component(self)
sock:write(xmlify(X.handshake{sha1.sha1(streamid..self.component_secret)}))
check_and_send('<handshake/>',nil)
+ for busname, bus in pairs(self.wilson.busses) do
+ for _, channel in ipairs(bus) do
+ if channel.pylon == self then
+ self:add_channel(channel)
+ end
+ end
+ end
+
return sock
end
-Xmpp._connect = Xmpp._connect_component
+
+function Xmpp.add_channel(self, channel)
+ local muc = { nick_to_user={}, user_to_nick={} }
+ self.mucs[channel.descriptor] = muc
+ self.nick_bot = self:ensure_and_get_user(channel.descriptor, "wilson")
+end
+
+function Xmpp.ensure_and_get_user(self, muc_jid, nick)
+ local muc = assert(self.mucs[muc_jid])
+ local user = muc.nick_to_user[nick]
+ if user then
+ local user_jid = user..'@'..self.component
+ local nick_jid = muc_jid..'/'..nick
+ return user, nick, user_jid, nick_jid
+ end
+
+ -- join up new user
+
+ user = nick:gsub("[^a-zA-Z0-9%.]","."):match("^%.*(.-)%.*$")
+ while muc.user_to_nick[user] do user = user..'-' end
+ muc.nick_to_user[nick] = user
+ muc.user_to_nick[user] = nick
+
+ local user_jid = user..'@'..self.component
+ local nick_jid = muc_jid..'/'..nick
+
+ self.log("Joining up new user "..user_jid.." to "..nick_jid)
+
+ self.sock:write(xmlify(
+ X.presence{from=user_jid, to=nick_jid,
+ X.x{xmlns='http://jabber.org/protocol/muc',
+ X.history{maxstanzas='0'}}}))
+
+ return user, nick, user_jid, nick_jid
+end
function Xmpp.recving(self)
local function getmore()
@@ -53,50 +96,31 @@ function Xmpp.recving(self)
self.log:debug(xmlify(x))
local body = x'body' and x'body'[1]
if x.label == 'message' then
- local from = x.xarg.from
- local to = x.xarg.to
- local from_addr, from_nick = from and from:match"(.*)/(.*)"
- if
- from_nick
- and not self.nicks_inuse[from_nick]
- and body
- and to == 'wilson@'..self.component
- then
- self.log:proto('<',from_addr,from_nick,body)
- self.wilson:deliver(Channel(self, from_addr), {
- body = body,
- sender = '[x]'..from_nick
- })
+ local from_bare_jid, from_nick
+ if x.xarg.from then from_bare_jid, from_nick = x.xarg.from:match"(.*)/(.*)" end
+ local muc = self.mucs[from_bare_jid] ; if muc then
+ if
+ x.xarg.to == 'wilson@'..self.component
+ and body
+ and from_nick and not muc.nick_to_user[from_nick]
+ then
+ self.log:proto('<',from_bare_jid,from_nick,body)
+ self.wilson:deliver(Channel(self, from_bare_jid), {
+ body = body,
+ sender = '[x]'..from_nick
+ })
+ end
end
end
end
end
function Xmpp.sending(self)
- local users_inuse = {}
- local function ensure_joined(muc,user,nick)
- if self.nicks_inuse[nick] then return end
- user = user:gsub("[^a-zA-Z0-9%.]","."):match("^%.*(.-)%.*$")
- while users_inuse[user] do user = user..'-' end
- local jid = user..'@'..self.component
- local mucjid = muc..'/'..nick
- self.nicks_inuse[nick] = true
- users_inuse[user] = true
-
- self.sock:write(xmlify(
- X.presence{from=jid, to=mucjid,
- X.x{xmlns='http://jabber.org/protocol/muc',
- X.history{maxstanzas='0'}}}))
- end
- ensure_joined('d@conference.ubq323.website', 'wilson', 'wilson')
for dest_channel, message in self.inbox:iter() do
self.log:proto('>',dest_channel,message.sender,message.body)
- local muc = dest_channel.descriptor
- ensure_joined(muc, message.sender, message.sender)
- local user = message.sender:gsub("[^a-zA-Z0-9%.]","."):match("^%.*(.-)%.*$")
- local jid = user..'@'..self.component
+ local user, nick, user_jid, nick_jid = self:ensure_and_get_user(dest_channel.descriptor, message.sender)
self.sock:write(xmlify(
- X.message{to=muc, type='groupchat', from=jid,
+ X.message{to=dest_channel.descriptor, type='groupchat', from=user_jid,
X.body{message.body}}))
end
end