plugins/muc/muc.lib.lua
changeset 6212 b82523f92b06
parent 6211 a4d26656df04
child 6213 95bddf0142f4
equal deleted inserted replaced
6211:a4d26656df04 6212:b82523f92b06
   236 	return st.presence {from = occupant.nick; type = "unavailable";};
   236 	return st.presence {from = occupant.nick; type = "unavailable";};
   237 end
   237 end
   238 
   238 
   239 -- Broadcasts an occupant's presence to the whole room
   239 -- Broadcasts an occupant's presence to the whole room
   240 -- Takes the x element that goes into the stanzas
   240 -- Takes the x element that goes into the stanzas
   241 function room_mt:publicise_occupant_status(occupant, base_x, actor, reason)
   241 function room_mt:publicise_occupant_status(occupant, base_x, nick, actor, reason)
   242 	-- Build real jid and (optionally) occupant jid template presences
   242 	-- Build real jid and (optionally) occupant jid template presences
   243 	local function get_presence(is_anonymous)
   243 	local function get_presence(is_anonymous)
   244 		local x = st.clone(base_x);
   244 		local x = st.clone(base_x);
   245 		self:build_item_list(occupant, x, is_anonymous, actor, reason);
   245 		self:build_item_list(occupant, x, is_anonymous, nick, actor, reason);
   246 		return get_base_presence(occupant):add_child(x), x;
   246 		return get_base_presence(occupant):add_child(x), x;
   247 	end
   247 	end
   248 	local full_p, full_x = get_presence(false);
   248 	local full_p, full_x = get_presence(false);
   249 	local anon_p, anon_x;
   249 	local anon_p, anon_x;
   250 	local function get_anon_p()
   250 	local function get_anon_p()
   275 		-- They get an unavailable
   275 		-- They get an unavailable
   276 		self:route_to_occupant(occupant, full_p);
   276 		self:route_to_occupant(occupant, full_p);
   277 	else
   277 	else
   278 		-- use their own presences as templates
   278 		-- use their own presences as templates
   279 		for full_jid, pr in occupant:each_session() do
   279 		for full_jid, pr in occupant:each_session() do
   280 			if pr.attr.type ~= "unavailable" then
   280 			pr = st.clone(pr);
   281 				pr = st.clone(pr);
   281 			pr.attr.to = full_jid;
   282 				pr.attr.to = full_jid;
   282 			-- You can always see your own full jids
   283 				-- You can always see your own full jids
   283 			pr:add_child(full_x);
   284 				pr:add_child(full_x);
   284 			self:route_stanza(pr);
   285 				self:route_stanza(pr);
       
   286 			end
       
   287 		end
   285 		end
   288 	end
   286 	end
   289 end
   287 end
   290 
   288 
   291 function room_mt:send_occupant_list(to, filter)
   289 function room_mt:send_occupant_list(to, filter)
   669 		end
   667 		end
   670 
   668 
   671 		-- Send presence stanza about original occupant
   669 		-- Send presence stanza about original occupant
   672 		if orig_occupant ~= nil and orig_occupant ~= dest_occupant then
   670 		if orig_occupant ~= nil and orig_occupant ~= dest_occupant then
   673 			local orig_x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
   671 			local orig_x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
   674 
   672 			local dest_nick;
   675 			if dest_occupant == nil then -- Session is leaving
   673 			if dest_occupant == nil then -- Session is leaving
   676 				log("debug", "session %s is leaving occupant %s", real_jid, orig_occupant.nick);
   674 				log("debug", "session %s is leaving occupant %s", real_jid, orig_occupant.nick);
   677 				orig_occupant:set_session(real_jid, stanza);
   675 				orig_occupant:set_session(real_jid, stanza);
   678 			else
   676 			else
   679 				log("debug", "session %s is changing from occupant %s to %s", real_jid, orig_occupant.nick, dest_occupant.nick);
   677 				log("debug", "session %s is changing from occupant %s to %s", real_jid, orig_occupant.nick, dest_occupant.nick);
   680 				orig_occupant:remove_session(real_jid); -- If we are moving to a new nick; we don't want to get our own presence
   678 				local generated_unavail = st.presence {from = orig_occupant.nick, to = real_jid, type = "unavailable"};
   681 
   679 				orig_occupant:set_session(real_jid, generated_unavail);
   682 				local dest_nick = select(3, jid_split(dest_occupant.nick));
   680 				dest_nick = select(3, jid_split(dest_occupant.nick));
   683 				local affiliation = self:get_affiliation(bare_jid);
       
   684 
       
   685 				-- This session
       
   686 				if not is_first_dest_session then -- User is swapping into another pre-existing session
   681 				if not is_first_dest_session then -- User is swapping into another pre-existing session
   687 					log("debug", "session %s is swapping into multisession %s, showing it leave.", real_jid, dest_occupant.nick);
   682 					log("debug", "session %s is swapping into multisession %s, showing it leave.", real_jid, dest_occupant.nick);
   688 					-- Show the other session leaving
   683 					-- Show the other session leaving
   689 					local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";})
   684 					local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";})
   690 						:tag("status"):text("you are joining pre-existing session " .. dest_nick):up();
   685 						:tag("status"):text("you are joining pre-existing session " .. dest_nick):up();
   691 					add_item(x, affiliation, "none");
   686 					add_item(x, self:get_affiliation(bare_jid), "none");
   692 					local pr = st.presence{from = dest_occupant.nick, to = real_jid, type = "unavailable"}
   687 					local pr = st.presence{from = dest_occupant.nick, to = real_jid, type = "unavailable"}
   693 						:add_child(x);
   688 						:add_child(x);
   694 					self:route_stanza(pr);
   689 					self:route_stanza(pr);
   695 				else
       
   696 					if is_last_orig_session then -- User is moving to a new session
       
   697 						log("debug", "no sessions in %s left; marking as nick change", orig_occupant.nick);
       
   698 						-- Everyone gets to see this as a nick change
       
   699 						local jid = self:get_whois() ~= "anyone" and real_jid or nil; -- FIXME: mods should see real jids
       
   700 						add_item(orig_x, affiliation, orig_occupant.role, jid, dest_nick);
       
   701 						orig_x:tag("status", {code = "303";}):up();
       
   702 					end
       
   703 				end
   690 				end
   704 				-- The session itself always sees a nick change
   691 				if is_first_dest_session and is_last_orig_session then -- Normal nick change
   705 				local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
   692 					log("debug", "no sessions in %s left; publically marking as nick change", orig_occupant.nick);
   706 				add_item(x, affiliation, orig_occupant.role, real_jid, dest_nick);
   693 					orig_x:tag("status", {code = "303";}):up();
   707 				-- self:build_item_list(orig_occupant, x, false); -- COMPAT
   694 				else -- The session itself always needs to see a nick change
   708 				x:tag("status", {code = "303";}):up();
   695 					-- don't want to get our old nick's available presence,
   709 				x:tag("status", {code = "110";}):up();
   696 					-- so remove our session from there, and manually generate an unavailable
   710 				self:route_stanza(st.presence{from = orig_occupant.nick, to = real_jid, type = "unavailable"}:add_child(x));
   697 					orig_occupant:remove_session(real_jid);
       
   698 					log("debug", "generating nick change for %s", real_jid);
       
   699 					local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user";});
       
   700 					-- self:build_item_list(orig_occupant, x, false, dest_nick); -- COMPAT: clients get confused if they see other items besides their own
       
   701 					add_item(x, self:get_affiliation(bare_jid), orig_occupant.role, real_jid, dest_nick);
       
   702 					x:tag("status", {code = "303";}):up();
       
   703 					x:tag("status", {code = "110";}):up();
       
   704 					self:route_stanza(generated_unavail:add_child(x));
       
   705 					dest_nick = nil; -- set dest_nick to nil; so general populance doesn't see it for whole orig_occupant
       
   706 				end
   711 			end
   707 			end
   712 			self:save_occupant(orig_occupant);
   708 			self:save_occupant(orig_occupant);
   713 			self:publicise_occupant_status(orig_occupant, orig_x);
   709 			self:publicise_occupant_status(orig_occupant, orig_x, dest_nick);
   714 
   710 
   715 			if is_last_orig_session then
   711 			if is_last_orig_session then
   716 				module:fire_event("muc-occupant-left", {room = self; nick = orig_occupant.nick;});
   712 				module:fire_event("muc-occupant-left", {room = self; nick = orig_occupant.nick;});
   717 			end
   713 			end
   718 		end
   714 		end
  1379 			x:tag("status", {code="321"}):up(); -- affiliation change
  1375 			x:tag("status", {code="321"}):up(); -- affiliation change
  1380 		end
  1376 		end
  1381 	end
  1377 	end
  1382 	local is_semi_anonymous = self:get_whois() == "moderators";
  1378 	local is_semi_anonymous = self:get_whois() == "moderators";
  1383 	for occupant, old_role in pairs(occupants_updated) do
  1379 	for occupant, old_role in pairs(occupants_updated) do
  1384 		self:publicise_occupant_status(occupant, x, actor, reason);
  1380 		self:publicise_occupant_status(occupant, x, nil, actor, reason);
  1385 		if is_semi_anonymous and
  1381 		if is_semi_anonymous and
  1386 			(old_role == "moderator" and occupant.role ~= "moderator") or
  1382 			(old_role == "moderator" and occupant.role ~= "moderator") or
  1387 			(old_role ~= "moderator" and occupant.role == "moderator") then -- Has gained or lost moderator status
  1383 			(old_role ~= "moderator" and occupant.role == "moderator") then -- Has gained or lost moderator status
  1388 			-- Send everyone else's presences (as jid visibility has changed)
  1384 			-- Send everyone else's presences (as jid visibility has changed)
  1389 			for real_jid in occupant:each_session() do
  1385 			for real_jid in occupant:each_session() do
  1440 	if not role then
  1436 	if not role then
  1441 		x:tag("status", {code = "307"}):up();
  1437 		x:tag("status", {code = "307"}):up();
  1442 	end
  1438 	end
  1443 	occupant.role = role;
  1439 	occupant.role = role;
  1444 	self:save_occupant(occupant);
  1440 	self:save_occupant(occupant);
  1445 	self:publicise_occupant_status(occupant, x, actor, reason);
  1441 	self:publicise_occupant_status(occupant, x, nil, actor, reason);
  1446 	return true;
  1442 	return true;
  1447 end
  1443 end
  1448 
  1444 
  1449 local name = module:require "muc/name";
  1445 local name = module:require "muc/name";
  1450 room_mt.get_name = name.get;
  1446 room_mt.get_name = name.get;