aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2016-04-18 19:30:15 +0200
committerKim Alvefur <zash@zash.se>2016-04-18 19:30:15 +0200
commitea4f52c8e2281ebcc6122c11ca07567743e928bf (patch)
tree1cc044388d40c87e720fed4f11dd7413a9f51693
parentbf656edb80380825c68fa93be86435583d12a853 (diff)
downloadprosody-ea4f52c8e2281ebcc6122c11ca07567743e928bf.tar.gz
prosody-ea4f52c8e2281ebcc6122c11ca07567743e928bf.zip
MUC: Add support for serializing live rooms, including occupants and their presence
-rw-r--r--plugins/muc/muc.lib.lua58
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