comparison plugins/muc/occupant.lib.lua @ 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 74b9e05af71e
children
comparison
equal deleted inserted replaced
13902:7e6deed12e03 13903:4af7d00a2966
21 end 21 end
22 22
23 -- Deep copy an occupant 23 -- Deep copy an occupant
24 local function copy_occupant(occupant) 24 local function copy_occupant(occupant)
25 local sessions = {}; 25 local sessions = {};
26 for full_jid, presence_stanza in pairs(occupant.sessions) do 26 for full_jid, session in pairs(occupant.sessions) do
27 local presence_stanza = session.presence;
27 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session 28 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session
28 if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then 29 if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then
29 sessions[full_jid] = presence_stanza; 30 sessions[full_jid] = session;
30 end 31 end
31 end 32 end
32 return setmetatable({ 33 return setmetatable({
33 bare_jid = occupant.bare_jid; 34 bare_jid = occupant.bare_jid;
34 nick = occupant.nick; 35 nick = occupant.nick;
46 end 47 end
47 end 48 end
48 return nil; 49 return nil;
49 end 50 end
50 51
52 function occupant_mt:get_session(real_jid)
53 return self.sessions[real_jid];
54 end
55
51 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) 56 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary)
52 local pr = get_filtered_presence(presence_stanza); 57 local pr = get_filtered_presence(presence_stanza);
53 pr.attr.from = self.nick; 58 pr.attr.from = self.nick;
54 pr.attr.to = real_jid; 59 pr.attr.to = real_jid;
55 60
56 self.sessions[real_jid] = pr; 61 self.sessions[real_jid] = { presence = pr };
57 if replace_primary then 62 if replace_primary then
58 self.jid = real_jid; 63 self.jid = real_jid;
59 elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then 64 elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then
60 -- Only leave an unavailable presence as primary when there are no other options 65 -- Only leave an unavailable presence as primary when there are no other options
61 self.jid = self:choose_new_primary() or real_jid; 66 self.jid = self:choose_new_primary() or real_jid;
68 if self.jid == real_jid then 73 if self.jid == real_jid then
69 self.jid = self:choose_new_primary(); 74 self.jid = self:choose_new_primary();
70 end 75 end
71 end 76 end
72 77
78 -- An iterator over self.sessions that returns (jid, presence, session)
79 local function _session_iter(s, var)
80 local k = next(s, var);
81 if k then
82 local v = s[k];
83 return k, v.presence, v;
84 end
85 end
86
73 function occupant_mt:each_session() 87 function occupant_mt:each_session()
74 return pairs(self.sessions) 88 return _session_iter, self.sessions;
75 end 89 end
76 90
77 function occupant_mt:get_presence(real_jid) 91 function occupant_mt:get_presence(real_jid)
78 return self.sessions[real_jid or self.jid] 92 local session = self.sessions[real_jid or self.jid];
93 if not session then return; end
94 return session.presence;
79 end 95 end
80 96
81 return { 97 return {
82 new = new_occupant; 98 new = new_occupant;
83 copy = copy_occupant; 99 copy = copy_occupant;