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