MUC: Log cases of possible room resynchronisation
[prosody.git] / plugins / muc / muc.lib.lua
index 470d199e4e366c24d872266bdd61608c89dd8d5f..dde1e13f6e1d7c91d4dd21f9172127613010f82d 100644 (file)
@@ -196,7 +196,7 @@ function room_mt:publicise_occupant_status(occupant, base_x, nick, actor, reason
        local base_presence do
                -- Try to use main jid's presence
                local pr = occupant:get_presence();
-               if pr and (pr.attr.type ~= "unavailable" or occupant.role == nil) then
+               if pr and (pr.attr.type ~= "unavailable" and occupant.role ~= nil) then
                        base_presence = st.clone(pr);
                else -- user is leaving but didn't send a leave presence. make one for them
                        base_presence = st.presence {from = occupant.nick; type = "unavailable";};
@@ -429,6 +429,14 @@ function room_mt:handle_presence_to_occupant(origin, stanza)
                        is_last_orig_session = iter(ob, iter(ob, last)) == nil;
                end
 
+               -- TODO Handle these cases sensibly
+               local muc_x = stanza:get_child("x", "http://jabber.org/protocol/muc");
+               if orig_occupant == nil and not muc_x then
+                       module:log("debug", "Join without <x>, possibly desynced");
+               elseif orig_occupant ~= nil and muc_x then
+                       module:log("debug", "Presence update with <x>, possibly desynced");
+               end
+
                local event, event_name = {
                        room = self;
                        origin = origin;
@@ -709,7 +717,7 @@ function room_mt:process_form(origin, stanza)
                end
                event.field, event.value = nil, nil;
 
-               self:save(true);
+               self:save();
                origin.send(st.reply(stanza));
 
                if next(event.status_codes) then
@@ -737,7 +745,6 @@ function room_mt:clear(x)
                occupants_updated[occupant] = true;
        end
        for occupant in pairs(occupants_updated) do
-               occupant:set_session(occupant.jid, st.presence({type="unavailable"}), true);
                self:publicise_occupant_status(occupant, x);
                module:fire_event("muc-occupant-left", { room = self; nick = occupant.nick; occupant = occupant;});
        end
@@ -1160,7 +1167,7 @@ function room_mt:set_affiliation(actor, jid, affiliation, reason)
                end
        end
 
-       self:save(true);
+       self:save();
 
        module:fire_event("muc-set-affiliation", {
                room = self;
@@ -1184,7 +1191,7 @@ function room_mt:set_role(actor, occupant_jid, role, reason)
        if not actor then return nil, "modify", "not-acceptable"; end
 
        local occupant = self:get_occupant_by_nick(occupant_jid);
-       if not occupant then return nil, "modify", "not-acceptable"; end
+       if not occupant then return nil, "modify", "item-not-found"; end
 
        if valid_roles[role or "none"] == nil then
                return nil, "modify", "not-acceptable";
@@ -1284,10 +1291,10 @@ function _M.restore_room(frozen)
        for jid, data in pairs(frozen) do
                local node, host, resource = jid_split(jid);
                if node or host:sub(1,1) ~= "_" then
-                       if not resource then
+                       if not resource and type(data) == "string" then
                                -- bare jid: affiliation
                                room._affiliations[jid] = data;
-                       elseif host == room_host and node == room_name then
+                       elseif host == room_host and node == room_name and resource then
                                -- full room jid: bare real jid and role
                                local bare_jid = data.bare_jid;
                                local   occupant = occupant_lib.new(bare_jid, jid);