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 |