pr.attr.to = from;
pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
:tag("item", {affiliation=occupant.affiliation or "none", role='none'}):up()
- :tag("status", {code='110'});
+ :tag("status", {code='110'}):up();
self:_route_stanza(pr);
if jid ~= new_jid then
pr = st.clone(occupant.sessions[new_jid])
self._jid_nick[from] = to;
self:send_occupant_list(from);
pr.attr.from = to;
+ pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
+ :tag("item", {affiliation=affiliation or "none", role=role or "none"}):up();
if not is_merge then
- self:broadcast_presence(pr, from);
- else
- pr.attr.to = from;
- self:_route_stanza(pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'})
- :tag("item", {affiliation=affiliation or "none", role=role or "none"}):up()
- :tag("status", {code='110'}));
+ self:broadcast_except_nick(pr, to);
+ end
+ pr:tag("status", {code='110'}):up();
+ if self._data.whois == 'anyone' then
+ pr:tag("status", {code='100'}):up();
end
+ pr.attr.to = from;
+ self:_route_stanza(pr);
self:send_history(from, stanza);
elseif not affiliation then -- registration required for entering members-only room
local reply = st.error_reply(stanza, "auth", "registration-required"):up();
local dirty = false
local name = fields['muc#roomconfig_roomname'];
- if name then
+ if name ~= self:get_name() then
self:set_name(name);
end
local description = fields['muc#roomconfig_roomdesc'];
- if description then
+ if description ~= self:get_description() then
self:set_description(description);
end
:tag('body') -- Add a plain message for clients which don't support invites
:text(_from..' invited you to the room '.._to..(_reason and (' ('.._reason..')') or ""))
:up();
+ if self:is_members_only() and not self:get_affiliation(_invitee) then
+ log("debug", "%s invited %s into members only room %s, granting membership", _from, _invitee, _to);
+ self:set_affiliation(_from, _invitee, "member", nil, "Invited by " .. self._jid_nick[_from])
+ end
self:_route_stanza(invite);
else
origin.send(st.error_reply(stanza, "cancel", "jid-malformed"));
if jid_bare(actor) == jid then return nil, "cancel", "not-allowed"; end
self._affiliations[jid] = affiliation;
local role = self:get_default_role(affiliation);
- local p = st.presence()
- :tag("x", {xmlns = "http://jabber.org/protocol/muc#user"})
+ local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"})
:tag("item", {affiliation=affiliation or "none", role=role or "none"})
:tag("reason"):text(reason or ""):up()
:up();
- local x = p.tags[1];
- local item = x.tags[1];
+ local presence_type = nil;
if not role then -- getting kicked
- p.attr.type = "unavailable";
+ presence_type = "unavailable";
if affiliation == "outcast" then
x:tag("status", {code="301"}):up(); -- banned
else
local modified_nicks = {};
for nick, occupant in pairs(self._occupants) do
if jid_bare(occupant.jid) == jid then
- t_insert(modified_nicks, nick);
if not role then -- getting kicked
self._occupants[nick] = nil;
else
occupant.affiliation, occupant.role = affiliation, role;
end
- p.attr.from = nick;
- for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick
+ for jid,pres in pairs(occupant.sessions) do -- remove for all sessions of the nick
if not role then self._jid_nick[jid] = nil; end
+ local p = st.clone(pres);
+ p.attr.from = nick;
+ p.attr.type = presence_type;
p.attr.to = jid;
+ p:add_child(x);
self:_route_stanza(p);
+ if occupant.jid == jid then
+ modified_nicks[nick] = p;
+ end
end
end
end
if self.save then self:save(); end
if callback then callback(); end
- for _, nick in ipairs(modified_nicks) do
+ for nick,p in pairs(modified_nicks) do
p.attr.from = nick;
self:broadcast_except_nick(p, nick);
end
local allowed, err_type, err_condition = self:can_set_role(actor, occupant_jid, role);
if not allowed then return allowed, err_type, err_condition; end
local occupant = self._occupants[occupant_jid];
- local p = st.presence({from = occupant_jid})
- :tag("x", {xmlns = "http://jabber.org/protocol/muc#user"})
+ local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"})
:tag("item", {affiliation=occupant.affiliation or "none", nick=select(3, jid_split(occupant_jid)), role=role or "none"})
:tag("reason"):text(reason or ""):up()
:up();
+ local presence_type = nil;
if not role then -- kick
- p.attr.type = "unavailable";
+ presence_type = "unavailable";
self._occupants[occupant_jid] = nil;
for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick
self._jid_nick[jid] = nil;
end
- p:tag("status", {code = "307"}):up();
+ x:tag("status", {code = "307"}):up();
else
occupant.role = role;
end
- for jid in pairs(occupant.sessions) do -- send to all sessions of the nick
+ local bp;
+ for jid,pres in pairs(occupant.sessions) do -- send to all sessions of the nick
+ local p = st.clone(pres);
+ p.attr.from = occupant_jid;
+ p.attr.type = presence_type;
p.attr.to = jid;
+ p:add_child(x);
self:_route_stanza(p);
+ if occupant.jid == jid then
+ bp = p;
+ end
end
if callback then callback(); end
- self:broadcast_except_nick(p, occupant_jid);
+ if bp then
+ self:broadcast_except_nick(bp, occupant_jid);
+ end
return true;
end
end
end
end
- if self._data.whois == 'anyone' then
- muc_child:tag('status', { code = '100' }):up();
- end
end
self:route_stanza(stanza);
if muc_child then