diff options
author | Kim Alvefur <zash@zash.se> | 2016-04-18 19:30:15 +0200 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2016-04-18 19:30:15 +0200 |
commit | 8e6b8de0389b04b5b7e24bd49b702aa95c39e566 (patch) | |
tree | 1cc044388d40c87e720fed4f11dd7413a9f51693 | |
parent | b3b9ebb0c460d0cd270adc67ba68564431d4db27 (diff) | |
download | prosody-8e6b8de0389b04b5b7e24bd49b702aa95c39e566.tar.gz prosody-8e6b8de0389b04b5b7e24bd49b702aa95c39e566.zip |
MUC: Add support for serializing live rooms, including occupants and their presence
-rw-r--r-- | plugins/muc/muc.lib.lua | 58 |
1 files changed, 55 insertions, 3 deletions
diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 75bc825e..470d199e 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -1244,7 +1244,7 @@ function _M.new_room(jid, config) }, room_mt); end -function room_mt:freeze() +function room_mt:freeze(live) local frozen = { _jid = self.jid; _data = self._data; @@ -1252,6 +1252,18 @@ function room_mt:freeze() for user, affiliation in pairs(self._affiliations) do frozen[user] = affiliation; end + if live then + for nick, occupant in self:each_occupant() do + frozen[nick] = { + bare_jid = occupant.bare_jid; + role = occupant.role; + jid = occupant.jid; + } + for jid, presence in occupant:each_session() do + frozen[jid] = st.preserialize(presence); + end + end + end return frozen; end @@ -1266,12 +1278,52 @@ function _M.restore_room(frozen) local room_jid = frozen._jid; local room = _M.new_room(room_jid, frozen._data); + local occupants = {}; + local occupant_sessions = {}; + local room_name, room_host = jid_split(room_jid); for jid, data in pairs(frozen) do - local node, host = jid_split(jid); + local node, host, resource = jid_split(jid); if node or host:sub(1,1) ~= "_" then - room._affiliations[jid] = data; + if not resource then + -- bare jid: affiliation + room._affiliations[jid] = data; + elseif host == room_host and node == room_name then + -- full room jid: bare real jid and role + local bare_jid = data.bare_jid; + local occupant = occupant_lib.new(bare_jid, jid); + occupant.jid = data.jid; + occupant.role = data.role; + occupants[bare_jid] = occupant; + local sessions = occupant_sessions[bare_jid]; + if sessions then + for full_jid, presence in pairs(sessions) do + occupant:set_session(full_jid, presence); + end + end + occupant_sessions[bare_jid] = nil; + else + -- full user jid: presence + local presence = st.deserialize(data); + local bare_jid = jid_bare(jid); + local occupant = occupants[bare_jid]; + local sessions = occupant_sessions[bare_jid]; + if occupant then + occupant:set_session(jid, presence); + elseif sessions then + sessions[jid] = presence; + else + occupant_sessions[bare_jid] = { + [jid] = presence; + }; + end + end end end + + for _, occupant in pairs(occupants) do + room:save_occupant(occupant); + end + return room; end |