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; |