-
- -- Send presence stanza about original occupant
- if orig_occupant ~= nil and orig_occupant ~= dest_occupant then
- local orig_x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
- local dest_nick;
- if dest_occupant == nil then -- Session is leaving
- log("debug", "session %s is leaving occupant %s", real_jid, orig_occupant.nick);
- if is_last_orig_session then
- orig_occupant.role = nil;
- end
- orig_occupant:set_session(real_jid, stanza);
- else
- log("debug", "session %s is changing from occupant %s to %s", real_jid, orig_occupant.nick, dest_occupant.nick);
- local generated_unavail = st.presence {from = orig_occupant.nick, to = real_jid, type = "unavailable"};
- orig_occupant:set_session(real_jid, generated_unavail);
- dest_nick = select(3, jid_split(dest_occupant.nick));
- 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();
- add_item(x, self:get_affiliation(bare_jid), "none");
- local pr = st.presence{from = dest_occupant.nick, to = real_jid, type = "unavailable"}
- :add_child(x);
- self:route_stanza(pr);
- end
- if is_first_dest_session and is_last_orig_session then -- Normal nick change
- log("debug", "no sessions in %s left; publically marking as nick change", orig_occupant.nick);
- orig_x:tag("status", {code = "303";}):up();
- else -- The session itself always needs to see a nick change
- -- don't want to get our old nick's available presence,
- -- so remove our session from there, and manually generate an unavailable
- orig_occupant:remove_session(real_jid);
- log("debug", "generating nick change for %s", real_jid);
- local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
- -- self:build_item_list(orig_occupant, x, false, dest_nick); -- COMPAT: clients get confused if they see other items besides their own
- add_item(x, self:get_affiliation(bare_jid), orig_occupant.role, real_jid, dest_nick);
- x:tag("status", {code = "303";}):up();
- x:tag("status", {code = "110";}):up();
- self:route_stanza(generated_unavail:add_child(x));
- dest_nick = nil; -- set dest_nick to nil; so general populance doesn't see it for whole orig_occupant
- end
- end
- self:save_occupant(orig_occupant);
- self:publicise_occupant_status(orig_occupant, orig_x, dest_nick);
-
- if is_last_orig_session then
- module:fire_event("muc-occupant-left", {
- room = self;
- nick = orig_occupant.nick;
- occupant = orig_occupant;
- origin = origin;
- stanza = stanza;
- });
- end
+ self:publicise_occupant_status(dest_occupant, dest_x);
+
+ if orig_occupant ~= nil and orig_occupant ~= dest_occupant and not is_last_orig_session then -- If user is swapping and wasn't last original session
+ log("debug", "session %s split nicks; showing %s rejoining", real_jid, orig_occupant.nick);
+ -- Show the original nick joining again
+ local pr = st.clone(orig_occupant:get_presence());
+ pr.attr.to = real_jid;
+ local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
+ self:build_item_list(orig_occupant, x, false);
+ -- TODO: new status code to inform client this was the multi-session it left?
+ pr:add_child(x);
+ self:route_stanza(pr);