-- Prosody IM
-- Copyright (C) 2008-2010 Matthew Wild
-- Copyright (C) 2008-2010 Waqas Hussain
---
+--
-- This project is MIT/X11 licensed. Please see the
-- COPYING file in the source package for more information.
--
end
stanza.attr.to = to;
if historic then -- add to history
- local history = self._data['history'];
- if not history then history = {}; self._data['history'] = history; end
- stanza = st.clone(stanza);
- stanza.attr.to = "";
- local stamp = datetime.datetime();
- stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = stamp}):up(); -- XEP-0203
- stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated)
- local entry = { stanza = stanza, stamp = stamp };
- t_insert(history, entry);
- while #history > (self._data.history_length or default_history_length) do t_remove(history, 1) end
+ return self:save_to_history(stanza)
end
end
+function room_mt:save_to_history(stanza)
+ local history = self._data['history'];
+ if not history then history = {}; self._data['history'] = history; end
+ stanza = st.clone(stanza);
+ stanza.attr.to = "";
+ local stamp = datetime.datetime();
+ stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = stamp}):up(); -- XEP-0203
+ stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated)
+ local entry = { stanza = stanza, stamp = stamp };
+ t_insert(history, entry);
+ while #history > (self._data.history_length or default_history_length) do t_remove(history, 1) end
+end
function room_mt:broadcast_except_nick(stanza, nick)
for rnick, occupant in pairs(self._occupants) do
if rnick ~= nick then
if history then
local x_tag = stanza and stanza:get_child("x", "http://jabber.org/protocol/muc");
local history_tag = x_tag and x_tag:get_child("history", "http://jabber.org/protocol/muc");
-
+
local maxchars = history_tag and tonumber(history_tag.attr.maxchars);
if maxchars then maxchars = math.floor(maxchars); end
-
+
local maxstanzas = math.floor(history_tag and tonumber(history_tag.attr.maxstanzas) or #history);
if not history_tag then maxstanzas = 20; end
local n = 0;
local charcount = 0;
-
+
for i=#history,1,-1 do
local entry = history[i];
if maxchars then
self:_route_stanza(msg);
end
end
+end
+function room_mt:send_subject(to)
if self._data['subject'] then
self:_route_stanza(st.message({type='groupchat', from=self._data['subject_from'] or self.jid, to=to}):tag("subject"):text(self._data['subject']));
end
:tag("feature", {var=self._data.whois ~= "anyone" and "muc_semianonymous" or "muc_nonanonymous"}):up()
:add_child(dataform.new({
{ name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/muc#roominfo" },
- { name = "muc#roominfo_description", label = "Description"},
+ { name = "muc#roominfo_description", label = "Description", value = "" },
{ name = "muc#roominfo_occupants", label = "Number of occupants", value = tostring(count) }
}):form({["muc#roominfo_description"] = self:get_description()}, 'result'))
;
local from_nick = room._jid_nick[from_jid];
local occupant = room._occupants[to_nick];
local to_jid = occupant.jid;
-
+
return from_nick, to_jid, base64.encode(to_jid.."\0"..stanza.attr.id.."\0"..md5(from_jid));
end
local function deconstruct_stanza_id(room, stanza)
log("debug", "%s joining as %s", from, to);
if not next(self._affiliations) then -- new room, no owners
self._affiliations[jid_bare(from)] = "owner";
+ if self.locked and not stanza:get_child("x", "http://jabber.org/protocol/muc") then
+ self.locked = nil; -- Older groupchat protocol doesn't lock
+ end
+ elseif self.locked then -- Deny entry
+ origin.send(st.error_reply(stanza, "cancel", "item-not-found"));
+ return;
end
local affiliation = self:get_affiliation(from);
local role = self:get_default_role(affiliation)
if self._data.whois == 'anyone' then
pr:tag("status", {code='100'}):up();
end
+ if self.locked then
+ pr:tag("status", {code='201'}):up();
+ end
pr.attr.to = from;
self:_route_stanza(pr);
self:send_history(from, stanza);
+ self:send_subject(from);
elseif not affiliation then -- registration required for entering members-only room
local reply = st.error_reply(stanza, "auth", "registration-required"):up();
reply.tags[1].attr.code = "407";
end
stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id;
else -- message
+ stanza:tag("x", { xmlns = "http://jabber.org/protocol/muc#user" }):up();
stanza.attr.from = current_nick;
for jid in pairs(o_data.sessions) do
stanza.attr.to = jid;
handle_option("password", "muc#roomconfig_roomsecret");
if self.save then self:save(true); end
+ if self.locked then
+ module:fire_event("muc-room-unlocked", { room = self });
+ self.locked = nil;
+ end
origin.send(st.reply(stanza));
if next(changed) then
if actor_jid == true then return true; end
local actor = self._occupants[self._jid_nick[actor_jid]];
- if actor.role == "moderator" then
+ if actor and actor.role == "moderator" then
if occupant.affiliation ~= "owner" and occupant.affiliation ~= "admin" then
if actor.affiliation == "owner" or actor.affiliation == "admin" then
return true;