MUC: Treat explicit join presence as join
[prosody.git] / plugins / muc / muc.lib.lua
index fea0ba93c97063f73317af439b49c9aaab65439f..71f199dd48206d1d4dce2ab350b54f88478faec3 100644 (file)
@@ -446,6 +446,7 @@ end
 
 function room_mt:handle_normal_presence(origin, stanza)
        local type = stanza.attr.type;
+       local muc_x = stanza:get_child("x", "http://jabber.org/protocol/muc");
        local real_jid = stanza.attr.from;
        local bare_jid = jid_bare(real_jid);
        local orig_occupant = self:get_occupant_by_real_jid(real_jid);
@@ -455,13 +456,18 @@ function room_mt:handle_normal_presence(origin, stanza)
        if type == "unavailable" then -- luacheck: ignore 542
                -- FIXME Why the empty if branch?
                -- dest_occupant = nil
-       elseif orig_occupant and orig_occupant.nick == stanza.attr.to then -- Just a presence update
+       elseif orig_occupant and not muc_x and orig_occupant.nick == stanza.attr.to then -- Just a presence update
                log("debug", "presence update for %s from session %s", orig_occupant.nick, real_jid);
                dest_occupant = orig_occupant;
        else
                local dest_jid = stanza.attr.to;
                dest_occupant = self:get_occupant_by_nick(dest_jid);
-               if dest_occupant == nil then
+               if muc_x then
+                       dest_occupant = self:new_occupant(bare_jid, dest_jid);
+                       if dest_occupant == nil then
+                               is_first_dest_session = true;
+                       end
+               elseif dest_occupant == nil then
                        log("debug", "no occupant found for %s; creating new occupant object for %s", dest_jid, real_jid);
                        is_first_dest_session = true;
                        dest_occupant = self:new_occupant(bare_jid, dest_jid);
@@ -477,7 +483,6 @@ function room_mt:handle_normal_presence(origin, stanza)
        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
@@ -531,10 +536,10 @@ function room_mt:handle_normal_presence(origin, stanza)
                        if not is_first_dest_session then -- User is swapping into another pre-existing session
                                log("debug", "session %s is swapping into multisession %s, showing it leave.", real_jid, dest_occupant.nick);
                                -- Show the other session leaving
-                               local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";})
-                                       :tag("status"):text("you are joining pre-existing session " .. dest_nick):up();
+                               local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
                                add_item(x, self:get_affiliation(bare_jid), "none");
                                local pr = st.presence{from = dest_occupant.nick, to = real_jid, type = "unavailable"}
+                                       :tag("status"):text("you are joining pre-existing session " .. dest_nick):up()
                                        :add_child(x);
                                self:route_stanza(pr);
                        end
@@ -1343,10 +1348,10 @@ function _M.restore_room(frozen, state)
        local room_jid = frozen._jid;
        local room = _M.new_room(room_jid, frozen._data);
 
-       if frozen._last_message and frozen._last_message_at then
+       if state and state._last_message and state._last_message_at then
                room._history = {
-                       { stanza = st.deserialize(frozen._last_message),
-                         timestamp = frozen._last_message_at, },
+                       { stanza = st.deserialize(state._last_message),
+                         timestamp = state._last_message_at, },
                };
        end