plugins/muc/muc.lib.lua
changeset 6515 ad159be9e9d7
parent 6481 413923bbd1a0
child 6516 3bbd59c03aeb
equal deleted inserted replaced
6514:5f9389af5115 6515:ad159be9e9d7
   129 	end
   129 	end
   130 	stanza.attr.to = to;
   130 	stanza.attr.to = to;
   131 end
   131 end
   132 
   132 
   133 -- actor is the attribute table
   133 -- actor is the attribute table
   134 local function add_item(x, affiliation, role, jid, nick, actor, reason)
   134 local function add_item(x, affiliation, role, jid, nick, actor_nick, actor_jid, reason)
   135 	x:tag("item", {affiliation = affiliation; role = role; jid = jid; nick = nick;})
   135 	x:tag("item", {affiliation = affiliation; role = role; jid = jid; nick = nick;})
   136 	if actor then
   136 	if actor_nick or actor_jid then
   137 		x:tag("actor", actor):up()
   137 		x:tag("actor", {nick = actor_nick; jid = actor_jid;}):up()
   138 	end
   138 	end
   139 	if reason then
   139 	if reason then
   140 		x:tag("reason"):text(reason):up()
   140 		x:tag("reason"):text(reason):up()
   141 	end
   141 	end
   142 	x:up();
   142 	x:up();
   143 	return x
   143 	return x
   144 end
   144 end
   145 
   145 
   146 -- actor is (real) jid
   146 -- actor is (real) jid
   147 function room_mt:build_item_list(occupant, x, is_anonymous, nick, actor, reason)
   147 function room_mt:build_item_list(occupant, x, is_anonymous, nick, actor_nick, actor_jid, reason)
   148 	local affiliation = self:get_affiliation(occupant.bare_jid) or "none";
   148 	local affiliation = self:get_affiliation(occupant.bare_jid) or "none";
   149 	local role = occupant.role or "none";
   149 	local role = occupant.role or "none";
   150 	local actor_attr;
       
   151 	if actor then
       
   152 		actor_attr = {nick = select(3,jid_split(self:get_occupant_jid(actor)))};
       
   153 	end
       
   154 	if is_anonymous then
   150 	if is_anonymous then
   155 		add_item(x, affiliation, role, nil, nick, actor_attr, reason);
   151 		add_item(x, affiliation, role, nil, nick, actor_nick, actor_jid, reason);
   156 	else
   152 	else
   157 		if actor_attr then
       
   158 			actor_attr.jid = actor;
       
   159 		end
       
   160 		for real_jid, session in occupant:each_session() do
   153 		for real_jid, session in occupant:each_session() do
   161 			add_item(x, affiliation, role, real_jid, nick, actor_attr, reason);
   154 			add_item(x, affiliation, role, real_jid, nick, actor_nick, actor_jid, reason);
   162 		end
   155 		end
   163 	end
   156 	end
   164 	return x
   157 	return x
   165 end
   158 end
   166 
   159 
   209 		room = self; stanza = base_presence; x = base_x;
   202 		room = self; stanza = base_presence; x = base_x;
   210 		occupant = occupant; nick = nick; actor = actor;
   203 		occupant = occupant; nick = nick; actor = actor;
   211 		reason = reason;
   204 		reason = reason;
   212 	});
   205 	});
   213 
   206 
   214 	local function get_presence(is_anonymous)
   207 	local whois = self:get_whois();
   215 		local x = st.clone(base_x);
   208 	local actor_nick;
   216 		self:build_item_list(occupant, x, is_anonymous, nick, actor, reason);
   209 	if actor then
   217 		return st.clone(base_presence):add_child(x), x;
   210 		actor_nick = select(3, jid_split(self:get_occupant_jid(actor)));
   218 	end
   211 	end
   219 
   212 
   220 	local full_p, full_x = get_presence(false);
   213 	local full_p, full_x;
   221 
   214 	local function get_full_p()
   222 	-- Create anon_p lazily
   215 		if full_p == nil then
       
   216 			full_x = st.clone(base_x);
       
   217 			self:build_item_list(occupant, full_x, false, nick, actor_nick, actor, reason);
       
   218 			full_p = st.clone(base_presence):add_child(full_x);
       
   219 		end
       
   220 		return full_p, full_x;
       
   221 	end
       
   222 
   223 	local anon_p, anon_x;
   223 	local anon_p, anon_x;
   224 	local function get_anon_p()
   224 	local function get_anon_p()
   225 		if anon_p == nil then
   225 		if anon_p == nil then
   226 			anon_p, anon_x = get_presence(true);
   226 			anon_x = st.clone(base_x);
       
   227 			self:build_item_list(occupant, anon_x, true, nick, actor_nick, nil, reason);
       
   228 			anon_p = st.clone(base_presence):add_child(anon_x);
   227 		end
   229 		end
   228 		return anon_p, anon_x;
   230 		return anon_p, anon_x;
   229 	end
   231 	end
   230 
   232 
   231 	local whois = self:get_whois();
   233 	local self_p, self_x;
       
   234 	if can_see_real_jids(whois, occupant) then
       
   235 		self_p, self_x = get_full_p();
       
   236 	else
       
   237 		-- Can always see your own full jids
       
   238 		-- But not allowed to see actor's
       
   239 		self_x = st.clone(base_x);
       
   240 		self:build_item_list(occupant, self_x, false, nick, actor_nick, nil, reason);
       
   241 		self_p = st.clone(base_presence):add_child(self_x);
       
   242 	end
   232 
   243 
   233 	-- General populance
   244 	-- General populance
   234 	for nick, n_occupant in self:each_occupant() do
   245 	for nick, n_occupant in self:each_occupant() do
   235 		if nick ~= occupant.nick then
   246 		if nick ~= occupant.nick then
   236 			local pr;
   247 			local pr;
   237 			if can_see_real_jids(whois, n_occupant) or occupant.bare_jid == n_occupant.bare_jid then
   248 			if can_see_real_jids(whois, n_occupant) then
   238 				pr = full_p;
   249 				pr = get_full_p();
       
   250 			elseif occupant.bare_jid == n_occupant.bare_jid then
       
   251 				pr = self_p;
   239 			else
   252 			else
   240 				pr = get_anon_p();
   253 				pr = get_anon_p();
   241 			end
   254 			end
   242 			self:route_to_occupant(n_occupant, pr);
   255 			self:route_to_occupant(n_occupant, pr);
   243 		end
   256 		end
   244 	end
   257 	end
   245 
   258 
   246 	-- Presences for occupant itself
   259 	-- Presences for occupant itself
   247 	full_x:tag("status", {code = "110";}):up();
   260 	self_x:tag("status", {code = "110";}):up();
   248 	if occupant.role == nil then
   261 	if occupant.role == nil then
   249 		-- They get an unavailable
   262 		-- They get an unavailable
   250 		self:route_to_occupant(occupant, full_p);
   263 		self:route_to_occupant(occupant, self_p);
   251 	else
   264 	else
   252 		-- use their own presences as templates
   265 		-- use their own presences as templates
   253 		for full_jid, pr in occupant:each_session() do
   266 		for full_jid, pr in occupant:each_session() do
   254 			pr = st.clone(pr);
   267 			pr = st.clone(pr);
   255 			pr.attr.to = full_jid;
   268 			pr.attr.to = full_jid;
   256 			-- You can always see your own full jids
   269 			pr:add_child(self_x);
   257 			pr:add_child(full_x);
       
   258 			self:route_stanza(pr);
   270 			self:route_stanza(pr);
   259 		end
   271 		end
   260 	end
   272 	end
   261 end
   273 end
   262 
   274