Software /
code /
prosody
Comparison
plugins/mod_muc.lua @ 824:b6ee70721783
MUC: Bug fixes and workarounds
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Thu, 19 Feb 2009 20:17:07 +0500 |
parent | 822:a82eadc415ff |
child | 827:e74045238ee3 |
comparison
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 |