215 end |
213 end |
216 elseif type == "unavailable" then -- unavailable |
214 elseif type == "unavailable" then -- unavailable |
217 if current_nick then |
215 if current_nick then |
218 log("debug", "%s leaving %s", current_nick, room); |
216 log("debug", "%s leaving %s", current_nick, room); |
219 local occupant = self._occupants[current_nick]; |
217 local occupant = self._occupants[current_nick]; |
220 local old_session = occupant.sessions[from]; |
|
221 local new_jid = next(occupant.sessions); |
218 local new_jid = next(occupant.sessions); |
222 if new_jid == from then new_jid = next(occupant.sessions, new_jid); end |
219 if new_jid == from then new_jid = next(occupant.sessions, new_jid); end |
223 if new_jid then |
220 if new_jid then |
|
221 local jid = occupant.jid; |
224 occupant.jid = new_jid; |
222 occupant.jid = new_jid; |
225 occupant.sessions[from] = nil; |
223 occupant.sessions[from] = nil; |
226 local pr = st.clone(occupant[new_jid]) |
224 pr.attr.to = from; |
227 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
225 pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
228 :tag("item", {affiliation=occupant.affiliation, role=occupant.role}); |
226 :tag("item", {affiliation=occupant.affiliation, role='none'}):up() |
229 self:broadcast_except_nick(pr, current_nick); |
227 :tag("status", {code='110'}); |
|
228 self:route_stanza(pr); |
|
229 if jid ~= new_jid then |
|
230 pr = st.clone(occupant.sessions[new_jid]) |
|
231 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
|
232 :tag("item", {affiliation=occupant.affiliation, role=occupant.role}); |
|
233 self:broadcast_except_nick(pr, current_nick); |
|
234 end |
230 else |
235 else |
231 occupant.role = 'none'; |
236 occupant.role = 'none'; |
232 self:broadcast_presence(pr); |
237 self:broadcast_presence(pr, from); |
233 self._occupants[current_nick] = nil; |
238 self._occupants[current_nick] = nil; |
234 end |
239 end |
235 self._jid_nick[from] = nil; |
240 self._jid_nick[from] = nil; |
236 end |
241 end |
237 elseif not type then -- available |
242 elseif not type then -- available |
238 if current_nick then |
243 if current_nick then |
239 --if #pr == #stanza or current_nick ~= to then -- commented because google keeps resending directed presence |
244 --if #pr == #stanza or current_nick ~= to then -- commented because google keeps resending directed presence |
240 if current_nick == to then -- simple presence |
245 if current_nick == to then -- simple presence |
241 log("debug", "%s broadcasted presence", current_nick); |
246 log("debug", "%s broadcasted presence", current_nick); |
242 self._occupants[current_nick].sessions[from] = pr; |
247 self._occupants[current_nick].sessions[from] = pr; |
243 self:broadcast_presence(pr); |
248 self:broadcast_presence(pr, from); |
244 else -- change nick |
249 else -- change nick |
245 if self._occupants[to] then |
250 local occupant = self._occupants[current_nick]; |
|
251 local is_multisession = next(occupant, next(occupant)); |
|
252 if self._occupants[to] or is_multisession then |
246 log("debug", "%s couldn't change nick", current_nick); |
253 log("debug", "%s couldn't change nick", current_nick); |
247 local reply = st.error_reply(stanza, "cancel", "conflict"):up(); |
254 local reply = st.error_reply(stanza, "cancel", "conflict"):up(); |
248 reply.tags[1].attr.code = "409"; |
255 reply.tags[1].attr.code = "409"; |
249 origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"})); |
256 origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"})); |
250 else |
257 else |
251 local data = self._occupants[current_nick]; |
258 local data = self._occupants[current_nick]; |
252 local to_nick = select(3, jid_split(to)); |
259 local to_nick = select(3, jid_split(to)); |
253 if to_nick then |
260 if to_nick then |
254 log("debug", "%s (%s) changing nick to %s", current_nick, data.jid, to); |
261 log("debug", "%s (%s) changing nick to %s", current_nick, data.jid, to); |
255 local p = st.presence({type='unavailable', from=current_nick}); |
262 local p = st.presence({type='unavailable', from=current_nick}); |
256 self:broadcast_presence(p, '303', to_nick); |
263 self:broadcast_presence(p, from, '303', to_nick); |
257 self._occupants[current_nick] = nil; |
264 self._occupants[current_nick] = nil; |
258 self._occupants[to] = data; |
265 self._occupants[to] = data; |
259 self._jid_nick[from] = to; |
266 self._jid_nick[from] = to; |
260 pr.attr.from = to; |
267 pr.attr.from = to; |
261 self._occupants[to].sessions[from] = pr; |
268 self._occupants[to].sessions[from] = pr; |
262 self:broadcast_presence(pr); |
269 self:broadcast_presence(pr, from); |
263 else |
270 else |
264 --TODO malformed-jid |
271 --TODO malformed-jid |
265 end |
272 end |
266 end |
273 end |
267 end |
274 end |
287 self._affiliations[jid_bare(from)] = "owner"; |
298 self._affiliations[jid_bare(from)] = "owner"; |
288 end |
299 end |
289 local affiliation = self:get_affiliation(from); |
300 local affiliation = self:get_affiliation(from); |
290 local role = self:get_default_role(affiliation) |
301 local role = self:get_default_role(affiliation) |
291 if role then -- new occupant |
302 if role then -- new occupant |
292 self._occupants[to] = {affiliation=affiliation, role=role, jid=from, sessions={[from]=get_filtered_presence(stanza)}}; |
303 if not is_merge then |
|
304 self._occupants[to] = {affiliation=affiliation, role=role, jid=from, sessions={[from]=get_filtered_presence(stanza)}}; |
|
305 else |
|
306 self._occupants[to].sessions[from] = get_filtered_presence(stanza); |
|
307 end |
293 self._jid_nick[from] = to; |
308 self._jid_nick[from] = to; |
294 self:send_occupant_list(from); |
309 self:send_occupant_list(from); |
295 pr.attr.from = to; |
310 pr.attr.from = to; |
296 self:broadcast_presence(pr); |
311 if not is_merge then |
|
312 self:broadcast_presence(pr, from); |
|
313 else |
|
314 pr.attr.to = from; |
|
315 self:route_stanza(pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
|
316 :tag("item", {affiliation=affiliation, role=role}):up() |
|
317 :tag("status", {code='110'})); |
|
318 end |
297 self:send_history(from); |
319 self:send_history(from); |
298 else -- banned |
320 else -- banned |
299 local reply = st.error_reply(stanza, "auth", "forbidden"):up(); |
321 local reply = st.error_reply(stanza, "auth", "forbidden"):up(); |
300 reply.tags[1].attr.code = "403"; |
322 reply.tags[1].attr.code = "403"; |
301 origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"})); |
323 origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"})); |