Mercurial > prosody-hg
changeset 13903:4af7d00a2966
MUC: occupant: refactor to allow storing more than just presence for a session
Previously a "session" (i.e. a full JID joined to a MUC) was stored as simply
a mapping of full JIDs->presence, contained within occupant objects (an
occupant object groups all sessions behind a certain nick in the MUC).
To enable developing GC3 and other features, it would be helpful if we can
store additional metadata when a client joins a room, for example, whether it
has opted out of receiving presence stanzas (a GC3 feature).
This changes the internal data structure, which shouldn't be used outside this
module, it adds a new :get_session() method, and modifies the :each_session()
iterator to return the session as an additional result (which should be
backwards compatible with code that just consumes the existing two results).
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 11 Nov 2024 12:47:01 +0000 |
| parents | 7e6deed12e03 |
| children | f8779be95156 |
| files | plugins/muc/occupant.lib.lua |
| diffstat | 1 files changed, 21 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/plugins/muc/occupant.lib.lua Thu Jun 26 13:04:40 2025 +0100 +++ b/plugins/muc/occupant.lib.lua Mon Nov 11 12:47:01 2024 +0000 @@ -23,10 +23,11 @@ -- Deep copy an occupant local function copy_occupant(occupant) local sessions = {}; - for full_jid, presence_stanza in pairs(occupant.sessions) do + for full_jid, session in pairs(occupant.sessions) do + local presence_stanza = session.presence; -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then - sessions[full_jid] = presence_stanza; + sessions[full_jid] = session; end end return setmetatable({ @@ -48,12 +49,16 @@ return nil; end +function occupant_mt:get_session(real_jid) + return self.sessions[real_jid]; +end + function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) local pr = get_filtered_presence(presence_stanza); pr.attr.from = self.nick; pr.attr.to = real_jid; - self.sessions[real_jid] = pr; + self.sessions[real_jid] = { presence = pr }; if replace_primary then self.jid = real_jid; elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then @@ -70,12 +75,23 @@ end end +-- An iterator over self.sessions that returns (jid, presence, session) +local function _session_iter(s, var) + local k = next(s, var); + if k then + local v = s[k]; + return k, v.presence, v; + end +end + function occupant_mt:each_session() - return pairs(self.sessions) + return _session_iter, self.sessions; end function occupant_mt:get_presence(real_jid) - return self.sessions[real_jid or self.jid] + local session = self.sessions[real_jid or self.jid]; + if not session then return; end + return session.presence; end return {
