plugins/muc/muc.lib.lua
changeset 10357 7b602e13c3b6
parent 10298 b61a7173f838
child 10365 6e051bfca12d
equal deleted inserted replaced
10356:dc1e6c2fb50a 10357:7b602e13c3b6
   216 	end
   216 	end
   217 end
   217 end
   218 
   218 
   219 -- Broadcasts an occupant's presence to the whole room
   219 -- Broadcasts an occupant's presence to the whole room
   220 -- Takes the x element that goes into the stanzas
   220 -- Takes the x element that goes into the stanzas
   221 function room_mt:publicise_occupant_status(occupant, x, nick, actor, reason)
   221 function room_mt:publicise_occupant_status(occupant, x, nick, actor, reason, prev_role, force_unavailable)
   222 	local base_x = x.base or x;
   222 	local base_x = x.base or x;
   223 	-- Build real jid and (optionally) occupant jid template presences
   223 	-- Build real jid and (optionally) occupant jid template presences
   224 	local base_presence do
   224 	local base_presence do
   225 		-- Try to use main jid's presence
   225 		-- Try to use main jid's presence
   226 		local pr = occupant:get_presence();
   226 		local pr = occupant:get_presence();
   227 		if pr and (occupant.role ~= nil or pr.attr.type == "unavailable") then
   227 		if pr and (occupant.role ~= nil or pr.attr.type == "unavailable") and not force_unavailable then
   228 			base_presence = st.clone(pr);
   228 			base_presence = st.clone(pr);
   229 		else -- user is leaving but didn't send a leave presence. make one for them
   229 		else -- user is leaving but didn't send a leave presence. make one for them
   230 			base_presence = st.presence {from = occupant.nick; type = "unavailable";};
   230 			base_presence = st.presence {from = occupant.nick; type = "unavailable";};
   231 		end
   231 		end
   232 	end
   232 	end
   277 		-- But not allowed to see actor's
   277 		-- But not allowed to see actor's
   278 		self_x = st.clone(x.self or base_x);
   278 		self_x = st.clone(x.self or base_x);
   279 		self:build_item_list(occupant, self_x, false, nick, actor_nick, nil, reason);
   279 		self:build_item_list(occupant, self_x, false, nick, actor_nick, nil, reason);
   280 		self_p = st.clone(base_presence):add_child(self_x);
   280 		self_p = st.clone(base_presence):add_child(self_x);
   281 	end
   281 	end
       
   282 
       
   283 	local broadcast_roles = self:get_presence_broadcast();
   282 
   284 
   283 	-- General populace
   285 	-- General populace
   284 	for occupant_nick, n_occupant in self:each_occupant() do
   286 	for occupant_nick, n_occupant in self:each_occupant() do
   285 		if occupant_nick ~= occupant.nick then
   287 		if occupant_nick ~= occupant.nick then
   286 			local pr;
   288 			local pr;
   289 			elseif occupant.bare_jid == n_occupant.bare_jid then
   291 			elseif occupant.bare_jid == n_occupant.bare_jid then
   290 				pr = self_p;
   292 				pr = self_p;
   291 			else
   293 			else
   292 				pr = get_anon_p();
   294 				pr = get_anon_p();
   293 			end
   295 			end
   294 			self:route_to_occupant(n_occupant, pr);
   296 			if broadcast_roles[occupant.role or "none"] or force_unavailable then
       
   297 				self:route_to_occupant(n_occupant, pr);
       
   298 			elseif prev_role and broadcast_roles[prev_role] then
       
   299 				pr.attr.type = 'unavailable';
       
   300 				self:route_to_occupant(n_occupant, pr);
       
   301 			end
       
   302 
   295 		end
   303 		end
   296 	end
   304 	end
   297 
   305 
   298 	-- Presences for occupant itself
   306 	-- Presences for occupant itself
   299 	self_x:tag("status", {code = "110";}):up();
   307 	self_x:tag("status", {code = "110";}):up();
   313 
   321 
   314 function room_mt:send_occupant_list(to, filter)
   322 function room_mt:send_occupant_list(to, filter)
   315 	local to_bare = jid_bare(to);
   323 	local to_bare = jid_bare(to);
   316 	local is_anonymous = false;
   324 	local is_anonymous = false;
   317 	local whois = self:get_whois();
   325 	local whois = self:get_whois();
       
   326 	local broadcast_roles = self:get_presence_broadcast();
   318 	if whois ~= "anyone" then
   327 	if whois ~= "anyone" then
   319 		local affiliation = self:get_affiliation(to);
   328 		local affiliation = self:get_affiliation(to);
   320 		if affiliation ~= "admin" and affiliation ~= "owner" then
   329 		if affiliation ~= "admin" and affiliation ~= "owner" then
   321 			local occupant = self:get_occupant_by_real_jid(to);
   330 			local occupant = self:get_occupant_by_real_jid(to);
   322 			if not (occupant and can_see_real_jids(whois, occupant)) then
   331 			if not (occupant and can_see_real_jids(whois, occupant)) then
   329 			local x = st.stanza("x", {xmlns='http://jabber.org/protocol/muc#user'});
   338 			local x = st.stanza("x", {xmlns='http://jabber.org/protocol/muc#user'});
   330 			self:build_item_list(occupant, x, is_anonymous and to_bare ~= occupant.bare_jid); -- can always see your own jids
   339 			self:build_item_list(occupant, x, is_anonymous and to_bare ~= occupant.bare_jid); -- can always see your own jids
   331 			local pres = st.clone(occupant:get_presence());
   340 			local pres = st.clone(occupant:get_presence());
   332 			pres.attr.to = to;
   341 			pres.attr.to = to;
   333 			pres:add_child(x);
   342 			pres:add_child(x);
   334 			self:route_stanza(pres);
   343 			if to_bare == occupant.bare_jid or broadcast_roles[occupant.role or "none"] then
       
   344 				self:route_stanza(pres);
       
   345 			end
   335 		end
   346 		end
   336 	end
   347 	end
   337 end
   348 end
   338 
   349 
   339 function room_mt:get_disco_info(stanza)
   350 function room_mt:get_disco_info(stanza)
  1440 
  1451 
  1441 	local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"});
  1452 	local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"});
  1442 	if not role then
  1453 	if not role then
  1443 		x:tag("status", {code = "307"}):up();
  1454 		x:tag("status", {code = "307"}):up();
  1444 	end
  1455 	end
       
  1456 
       
  1457 	local prev_role = occupant.role;
  1445 	occupant.role = role;
  1458 	occupant.role = role;
  1446 	self:save_occupant(occupant);
  1459 	self:save_occupant(occupant);
  1447 	self:publicise_occupant_status(occupant, x, nil, actor, reason);
  1460 	self:publicise_occupant_status(occupant, x, nil, actor, reason, prev_role);
  1448 	if role == nil then
  1461 	if role == nil then
  1449 		module:fire_event("muc-occupant-left", {
  1462 		module:fire_event("muc-occupant-left", {
  1450 				room = self;
  1463 				room = self;
  1451 				nick = occupant.nick;
  1464 				nick = occupant.nick;
  1452 				occupant = occupant;
  1465 				occupant = occupant;