plugins/mod_muc.lua

changeset 824
b6ee70721783
parent 822
a82eadc415ff
child 827
e74045238ee3
equal deleted inserted replaced
822:a82eadc415ff 824:b6ee70721783
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 or "nil", current_nick or "nil", stanza:top_tag()); 229 log("debug", "room: %s, current_nick: %s, stanza: %s", room or "nil", current_nick or "nil", stanza:top_tag());
230 if stanza.name == "presence" then 230 if stanza.name == "presence" then
231 local pr = get_filtered_presence(stanza); 231 local pr = get_filtered_presence(stanza);
232 pr.attr.from = to; 232 pr.attr.from = current_nick;
233 if type == "error" then -- error, kick em out! 233 if type == "error" then -- error, kick em out!
234 if current_nick then 234 if current_nick then
235 log("debug", "kicking %s from %s", current_nick, room); 235 log("debug", "kicking %s from %s", current_nick, room);
236 local data = rooms:get(room, current_nick); 236 local data = rooms:get(room, current_nick);
237 data.role = 'none'; 237 data.role = 'none';
244 jid_nick:remove(from, room); 244 jid_nick:remove(from, room);
245 end 245 end
246 elseif type == "unavailable" then -- unavailable 246 elseif type == "unavailable" then -- unavailable
247 if current_nick then 247 if current_nick then
248 log("debug", "%s leaving %s", current_nick, room); 248 log("debug", "%s leaving %s", current_nick, room);
249 -- log("debug", "rooms: %s", require "util.serialization".serialize(rooms.data));
250 -- log("debug", "jid_nick: %s", require "util.serialization".serialize(jid_nick.data));
249 local data = rooms:get(room, current_nick); 251 local data = rooms:get(room, current_nick);
250 data.role = 'none'; 252 data.role = 'none';
251 broadcast_presence_stanza(room, pr); 253 broadcast_presence_stanza(room, pr);
252 --broadcast_presence('unavailable', current_nick, room); 254 --broadcast_presence('unavailable', current_nick, room);
253 rooms:remove(room, current_nick); 255 rooms:remove(room, current_nick);
254 jid_nick:remove(from, room); 256 jid_nick:remove(from, room);
255 end 257 end
256 elseif not type then -- available 258 elseif not type then -- available
257 if current_nick then 259 if current_nick then
258 if current_nick == to then -- simple presence 260 if #pr == #stanza then
259 if #pr == #stanza then 261 if current_nick == to then -- simple presence
260 log("debug", "%s broadcasted presence", current_nick); 262 log("debug", "%s broadcasted presence", current_nick);
263 rooms:get(room, current_nick).sessions[from] = pr;
261 broadcast_presence_stanza(room, pr); 264 broadcast_presence_stanza(room, pr);
262 else -- possible rejoin 265 else -- change nick
263 log("debug", "%s had connection replaced", current_nick); 266 if rooms:get(room, to) then
264 local pr_ = st.presence({type='unavailable', from=from, to=current_nick}):tag('status'):text('Replaced by new connection'); 267 log("debug", "%s couldn't change nick", current_nick);
265 handle_to_occupant(origin, pr_); -- send unavailable 268 origin.send(st.error_reply(stanza, "cancel", "conflict"));
266 handle_to_occupant(origin, pr); -- resend available
267 end
268 else -- change nick
269 if rooms:get(room, to) then
270 log("debug", "%s couldn't change nick", current_nick);
271 origin.send(st.error_reply(stanza, "cancel", "conflict"));
272 else
273 local data = rooms:get(room, current_nick);
274 local to_nick = select(3, jid_split(to));
275 if to_nick then
276 log("debug", "%s changing nick to %s", current_nick, to_nick);
277 local p = st.presence({type='unavailable', from=current_nick});
278 --[[:tag('x', {xmlns='http://jabber.org/protocol/muc#user'})
279 :tag('item', {affiliation=data.affiliation, role=data.role, nick=to_nick}):up()
280 :tag('status', {code='303'});]]
281 broadcast_presence_stanza(room, p, '303', to_nick);
282 --broadcast_presence('unavailable', current_nick, room, '303', to_nick);
283 rooms:remove(room, current_nick);
284 rooms:set(room, to, data);
285 jid_nick:set(from, room, to);
286 broadcast_presence_stanza(room, pr);
287 --broadcast_presence(nil, to, room, nil);
288 else 269 else
289 --TODO malformed-jid 270 local data = rooms:get(room, current_nick);
271 local to_nick = select(3, jid_split(to));
272 if to_nick then
273 log("debug", "%s (%s) changing nick to %s", current_nick, data.jid, to);
274 -- log("debug", "rooms: %s", require "util.serialization".serialize(rooms.data));
275 -- log("debug", "jid_nick: %s", require "util.serialization".serialize(jid_nick.data));
276 local p = st.presence({type='unavailable', from=current_nick});
277 --[[:tag('x', {xmlns='http://jabber.org/protocol/muc#user'})
278 :tag('item', {affiliation=data.affiliation, role=data.role, nick=to_nick}):up()
279 :tag('status', {code='303'});]]
280 broadcast_presence_stanza(room, p, '303', to_nick);
281 --broadcast_presence('unavailable', current_nick, room, '303', to_nick);
282 rooms:remove(room, current_nick);
283 rooms:set(room, to, data);
284 jid_nick:set(from, room, to);
285 pr.attr.from = to;
286 rooms:get(room, to).sessions[from] = pr;
287 broadcast_presence_stanza(room, pr);
288 -- log("debug", "rooms: %s", require "util.serialization".serialize(rooms.data));
289 -- log("debug", "jid_nick: %s", require "util.serialization".serialize(jid_nick.data));
290 --broadcast_presence(nil, to, room, nil);
291 else
292 --TODO malformed-jid
293 end
290 end 294 end
291 end 295 end
296 else -- possible rejoin
297 log("debug", "%s had connection replaced", current_nick);
298 local pr_ = st.presence({type='unavailable', from=from, to=current_nick}):tag('status'):text('Replaced by new connection');
299 handle_to_occupant(origin, pr_); -- send unavailable
300 handle_to_occupant(origin, stanza); -- resend available
292 end 301 end
293 else -- enter room 302 else -- enter room
294 local new_nick = to; 303 local new_nick = to;
295 if rooms:get(room, to) then 304 if rooms:get(room, to) then
296 new_nick = nil; 305 new_nick = nil;
321 :tag("item", {affiliation=o_data.affiliation, role=o_data.role}):up(); 330 :tag("item", {affiliation=o_data.affiliation, role=o_data.role}):up();
322 core_route_stanza(component, pres); 331 core_route_stanza(component, pres);
323 end 332 end
324 end 333 end
325 end 334 end
335 pr.attr.from = to;
326 broadcast_presence_stanza(room, pr); 336 broadcast_presence_stanza(room, pr);
327 --broadcast_presence(nil, to, room); 337 --broadcast_presence(nil, to, room);
328 local history = rooms_info:get(room, 'history'); -- send discussion history 338 local history = rooms_info:get(room, 'history'); -- send discussion history
329 if history then 339 if history then
330 for _, msg in ipairs(history) do 340 for _, msg in ipairs(history) do

mercurial