plugins/mod_muc.lua

changeset 820
c20545c0dc4d
parent 818
4dda65cd1405
child 822
a82eadc415ff
equal deleted inserted replaced
818:4dda65cd1405 820:c20545c0dc4d
224 function handle_to_occupant(origin, stanza) -- PM, vCards, etc 224 function handle_to_occupant(origin, stanza) -- PM, vCards, etc
225 local from, to = stanza.attr.from, stanza.attr.to; 225 local from, to = stanza.attr.from, stanza.attr.to;
226 local room = jid_bare(to); 226 local room = jid_bare(to);
227 local current_nick = jid_nick:get(from, room); 227 local current_nick = jid_nick:get(from, room);
228 local type = stanza.attr.type; 228 local type = stanza.attr.type;
229 log("debug", "room: %s, current_nick: %s, stanza: %s", room, current_nick, stanza:top_tag());
229 if stanza.name == "presence" then 230 if stanza.name == "presence" then
230 local pr = get_filtered_presence(stanza); 231 local pr = get_filtered_presence(stanza);
231 pr.attr.from = to; 232 pr.attr.from = to;
232 if type == "error" then -- error, kick em out! 233 if type == "error" then -- error, kick em out!
233 if current_nick then 234 if current_nick then
235 log("debug", "kicking %s from %s", current_nick, room);
234 local data = rooms:get(room, current_nick); 236 local data = rooms:get(room, current_nick);
235 data.role = 'none'; 237 data.role = 'none';
236 local pr = st.presence({type='unavailable', from=current_nick}):tag('status'):text('This participant is kicked from the room because he sent an error presence'):up() 238 local pr = st.presence({type='unavailable', from=current_nick}):tag('status'):text('This participant is kicked from the room because he sent an error presence'):up()
237 --:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) 239 --:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
238 --:tag("item", {affiliation=data.affiliation, role=data.role}):up(); 240 --:tag("item", {affiliation=data.affiliation, role=data.role}):up();
241 rooms:remove(room, current_nick); 243 rooms:remove(room, current_nick);
242 jid_nick:remove(from, room); 244 jid_nick:remove(from, room);
243 end 245 end
244 elseif type == "unavailable" then -- unavailable 246 elseif type == "unavailable" then -- unavailable
245 if current_nick then 247 if current_nick then
248 log("debug", "%s leaving %s", current_nick, room);
246 local data = rooms:get(room, current_nick); 249 local data = rooms:get(room, current_nick);
247 data.role = 'none'; 250 data.role = 'none';
248 broadcast_presence_stanza(room, pr); 251 broadcast_presence_stanza(room, pr);
249 --broadcast_presence('unavailable', current_nick, room); 252 --broadcast_presence('unavailable', current_nick, room);
250 rooms:remove(room, current_nick); 253 rooms:remove(room, current_nick);
252 end 255 end
253 elseif not type then -- available 256 elseif not type then -- available
254 if current_nick then 257 if current_nick then
255 if current_nick == to then -- simple presence 258 if current_nick == to then -- simple presence
256 if #pr == #stanza then 259 if #pr == #stanza then
260 log("debug", "%s broadcasted presence", current_nick);
257 broadcast_presence_stanza(room, pr); 261 broadcast_presence_stanza(room, pr);
258 else -- possible rejoin 262 else -- possible rejoin
263 log("debug", "%s had connection replaced", current_nick);
259 local pr_ = st.presence({type='unavailable', from=from, to=current_nick}):tag('status'):text('Replaced by new connection'); 264 local pr_ = st.presence({type='unavailable', from=from, to=current_nick}):tag('status'):text('Replaced by new connection');
260 handle_to_occupant(origin, pr_); -- send unavailable 265 handle_to_occupant(origin, pr_); -- send unavailable
261 handle_to_occupant(origin, pr); -- resend available 266 handle_to_occupant(origin, pr); -- resend available
262 end 267 end
263 else -- change nick 268 else -- change nick
264 if rooms:get(room, to) then 269 if rooms:get(room, to) then
270 log("debug", "%s couldn't change nick", current_nick);
265 origin.send(st.error_reply(stanza, "cancel", "conflict")); 271 origin.send(st.error_reply(stanza, "cancel", "conflict"));
266 else 272 else
267 local data = rooms:get(room, current_nick); 273 local data = rooms:get(room, current_nick);
268 local to_nick = select(3, jid_split(to)); 274 local to_nick = select(3, jid_split(to));
269 if to_nick then 275 if to_nick then
276 log("debug", "%s changing nick to %s", current_nick, to_nick);
270 local p = st.presence({type='unavailable', from=current_nick}); 277 local p = st.presence({type='unavailable', from=current_nick});
271 --[[:tag('x', {xmlns='http://jabber.org/protocol/muc#user'}) 278 --[[:tag('x', {xmlns='http://jabber.org/protocol/muc#user'})
272 :tag('item', {affiliation=data.affiliation, role=data.role, nick=to_nick}):up() 279 :tag('item', {affiliation=data.affiliation, role=data.role, nick=to_nick}):up()
273 :tag('status', {code='303'});]] 280 :tag('status', {code='303'});]]
274 broadcast_presence_stanza(room, p, '303', to_nick); 281 broadcast_presence_stanza(room, p, '303', to_nick);
287 local new_nick = to; 294 local new_nick = to;
288 if rooms:get(room, to) then 295 if rooms:get(room, to) then
289 new_nick = nil; 296 new_nick = nil;
290 end 297 end
291 if not new_nick then 298 if not new_nick then
299 log("debug", "%s couldn't join due to nick conflict: %s", from, to);
292 origin.send(st.error_reply(stanza, "cancel", "conflict")); 300 origin.send(st.error_reply(stanza, "cancel", "conflict"));
293 else 301 else
302 log("debug", "%s joining as %s", from, to);
294 local data; 303 local data;
295 if not rooms:get(room) and not rooms_info:get(room) then -- new room 304 if not rooms:get(room) and not rooms_info:get(room) then -- new room
296 data = {affiliation='owner', role='moderator', jid=from, sessions={[from]=get_filtered_presence(stanza)}}; 305 data = {affiliation='owner', role='moderator', jid=from, sessions={[from]=get_filtered_presence(stanza)}};
297 end 306 end
298 if not data then -- new occupant 307 if not data then -- new occupant
336 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); 345 origin.send(st.error_reply(stanza, "cancel", "not-acceptable"));
337 elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM 346 elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM
338 origin.send(st.error_reply(stanza, "modify", "bad-request")); 347 origin.send(st.error_reply(stanza, "modify", "bad-request"));
339 elseif stanza.name == "message" and type == "error" then 348 elseif stanza.name == "message" and type == "error" then
340 if current_nick then 349 if current_nick then
350 log("debug", "%s kicked from %s for sending an error message", current_nick, room);
341 local data = rooms:get(room, to); 351 local data = rooms:get(room, to);
342 data.role = 'none'; 352 data.role = 'none';
343 local pr = st.presence({type='unavailable', from=current_nick}):tag('status'):text('This participant is kicked from the room because he sent an error message to another occupant'):up() 353 local pr = st.presence({type='unavailable', from=current_nick}):tag('status'):text('This participant is kicked from the room because he sent an error message to another occupant'):up()
344 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) 354 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
345 :tag("item", {affiliation=data.affiliation, role=data.role}):up(); 355 :tag("item", {affiliation=data.affiliation, role=data.role}):up();
348 jid_nick:remove(from, room); 358 jid_nick:remove(from, room);
349 end 359 end
350 else -- private stanza 360 else -- private stanza
351 local o_data = rooms:get(room, to); 361 local o_data = rooms:get(room, to);
352 if o_data then 362 if o_data then
363 log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid);
353 local jid = o_data.jid; 364 local jid = o_data.jid;
354 if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' then jid = jid_bare(jid); end 365 if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' then jid = jid_bare(jid); end
355 stanza.attr.to, stanza.attr.from = jid, current_nick; 366 stanza.attr.to, stanza.attr.from = jid, current_nick;
356 core_route_stanza(component, stanza); 367 core_route_stanza(component, stanza);
357 else -- recipient not in room 368 else -- recipient not in room

mercurial