Software /
code /
prosody
Comparison
plugins/muc/muc.lib.lua @ 2064:1ee862fd1afe
MUC: Include occupants' real JIDs in their presence (semi-anonymous rooms).
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sat, 31 Oct 2009 05:11:56 +0500 |
parent | 2053:f5a198127dd3 |
child | 2172:84dd0fada45b |
comparison
equal
deleted
inserted
replaced
2063:e89594a1bf4a | 2064:1ee862fd1afe |
---|---|
122 self:broadcast_except_nick(stanza, stanza.attr.from); | 122 self:broadcast_except_nick(stanza, stanza.attr.from); |
123 local me = self._occupants[stanza.attr.from]; | 123 local me = self._occupants[stanza.attr.from]; |
124 if me then | 124 if me then |
125 stanza:tag("status", {code='110'}); | 125 stanza:tag("status", {code='110'}); |
126 stanza.attr.to = sid; | 126 stanza.attr.to = sid; |
127 self:route_stanza(stanza); | 127 self:_route_stanza(stanza); |
128 end | 128 end |
129 end | 129 end |
130 function room_mt:broadcast_message(stanza, historic) | 130 function room_mt:broadcast_message(stanza, historic) |
131 for occupant, o_data in pairs(self._occupants) do | 131 for occupant, o_data in pairs(self._occupants) do |
132 for jid in pairs(o_data.sessions) do | 132 for jid in pairs(o_data.sessions) do |
133 stanza.attr.to = jid; | 133 stanza.attr.to = jid; |
134 self:route_stanza(stanza); | 134 self:_route_stanza(stanza); |
135 end | 135 end |
136 end | 136 end |
137 if historic then -- add to history | 137 if historic then -- add to history |
138 local history = self._data['history']; | 138 local history = self._data['history']; |
139 if not history then history = {}; self._data['history'] = history; end | 139 if not history then history = {}; self._data['history'] = history; end |
147 function room_mt:broadcast_except_nick(stanza, nick) | 147 function room_mt:broadcast_except_nick(stanza, nick) |
148 for rnick, occupant in pairs(self._occupants) do | 148 for rnick, occupant in pairs(self._occupants) do |
149 if rnick ~= nick then | 149 if rnick ~= nick then |
150 for jid in pairs(occupant.sessions) do | 150 for jid in pairs(occupant.sessions) do |
151 stanza.attr.to = jid; | 151 stanza.attr.to = jid; |
152 self:route_stanza(stanza); | 152 self:_route_stanza(stanza); |
153 end | 153 end |
154 end | 154 end |
155 end | 155 end |
156 end | 156 end |
157 | 157 |
161 if occupant ~= current_nick then | 161 if occupant ~= current_nick then |
162 local pres = get_filtered_presence(o_data.sessions[o_data.jid]); | 162 local pres = get_filtered_presence(o_data.sessions[o_data.jid]); |
163 pres.attr.to, pres.attr.from = to, occupant; | 163 pres.attr.to, pres.attr.from = to, occupant; |
164 pres:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) | 164 pres:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
165 :tag("item", {affiliation=o_data.affiliation or "none", role=o_data.role or "none"}):up(); | 165 :tag("item", {affiliation=o_data.affiliation or "none", role=o_data.role or "none"}):up(); |
166 self:route_stanza(pres); | 166 self:_route_stanza(pres); |
167 end | 167 end |
168 end | 168 end |
169 end | 169 end |
170 function room_mt:send_history(to) | 170 function room_mt:send_history(to) |
171 local history = self._data['history']; -- send discussion history | 171 local history = self._data['history']; -- send discussion history |
172 if history then | 172 if history then |
173 for _, msg in ipairs(history) do | 173 for _, msg in ipairs(history) do |
174 msg = st.deserialize(msg); | 174 msg = st.deserialize(msg); |
175 msg.attr.to=to; | 175 msg.attr.to=to; |
176 self:route_stanza(msg); | 176 self:_route_stanza(msg); |
177 end | 177 end |
178 end | 178 end |
179 if self._data['subject'] then | 179 if self._data['subject'] then |
180 self:route_stanza(st.message({type='groupchat', from=self.jid, to=to}):tag("subject"):text(self._data['subject'])); | 180 self:_route_stanza(st.message({type='groupchat', from=self.jid, to=to}):tag("subject"):text(self._data['subject'])); |
181 end | 181 end |
182 end | 182 end |
183 | 183 |
184 local function room_get_disco_info(self, stanza) | 184 local function room_get_disco_info(self, stanza) |
185 return st.reply(stanza):query("http://jabber.org/protocol/disco#info") | 185 return st.reply(stanza):query("http://jabber.org/protocol/disco#info") |
232 occupant.sessions[from] = nil; | 232 occupant.sessions[from] = nil; |
233 pr.attr.to = from; | 233 pr.attr.to = from; |
234 pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) | 234 pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
235 :tag("item", {affiliation=occupant.affiliation or "none", role='none'}):up() | 235 :tag("item", {affiliation=occupant.affiliation or "none", role='none'}):up() |
236 :tag("status", {code='110'}); | 236 :tag("status", {code='110'}); |
237 self:route_stanza(pr); | 237 self:_route_stanza(pr); |
238 if jid ~= new_jid then | 238 if jid ~= new_jid then |
239 pr = st.clone(occupant.sessions[new_jid]) | 239 pr = st.clone(occupant.sessions[new_jid]) |
240 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) | 240 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
241 :tag("item", {affiliation=occupant.affiliation or "none", role=occupant.role or "none"}); | 241 :tag("item", {affiliation=occupant.affiliation or "none", role=occupant.role or "none"}); |
242 pr.attr.from = current_nick; | 242 pr.attr.from = current_nick; |
320 pr.attr.from = to; | 320 pr.attr.from = to; |
321 if not is_merge then | 321 if not is_merge then |
322 self:broadcast_presence(pr, from); | 322 self:broadcast_presence(pr, from); |
323 else | 323 else |
324 pr.attr.to = from; | 324 pr.attr.to = from; |
325 self:route_stanza(pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) | 325 self:_route_stanza(pr:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
326 :tag("item", {affiliation=affiliation or "none", role=role or "none"}):up() | 326 :tag("item", {affiliation=affiliation or "none", role=role or "none"}):up() |
327 :tag("status", {code='110'})); | 327 :tag("status", {code='110'})); |
328 end | 328 end |
329 self:send_history(from); | 329 self:send_history(from); |
330 else -- banned | 330 else -- banned |
352 break; | 352 break; |
353 end | 353 end |
354 end | 354 end |
355 if _to then | 355 if _to then |
356 stanza.attr.to, stanza.attr.from, stanza.attr.id = _to, self._jid_nick[_nick], _id; | 356 stanza.attr.to, stanza.attr.from, stanza.attr.id = _to, self._jid_nick[_nick], _id; |
357 self:route_stanza(stanza); | 357 self:_route_stanza(stanza); |
358 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; | 358 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; |
359 end | 359 end |
360 end | 360 end |
361 else | 361 else |
362 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); | 362 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
377 local id = stanza.attr.id; | 377 local id = stanza.attr.id; |
378 if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' and bare ~= jid then | 378 if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' and bare ~= jid then |
379 stanza.attr.to = bare; | 379 stanza.attr.to = bare; |
380 stanza.attr.id = base64.encode(jid.."\0"..id.."\0"..md5(from)); | 380 stanza.attr.id = base64.encode(jid.."\0"..id.."\0"..md5(from)); |
381 end | 381 end |
382 self:route_stanza(stanza); | 382 self:_route_stanza(stanza); |
383 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; | 383 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; |
384 elseif type ~= "error" and type ~= "result" then -- recipient not in room | 384 elseif type ~= "error" and type ~= "result" then -- recipient not in room |
385 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room")); | 385 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room")); |
386 end | 386 end |
387 end | 387 end |
563 :text(_reason or "") | 563 :text(_reason or "") |
564 :up() | 564 :up() |
565 :tag('body') -- Add a plain message for clients which don't support invites | 565 :tag('body') -- Add a plain message for clients which don't support invites |
566 :text(_from..' invited you to the room '.._to..(_reason and (' ('.._reason..')') or "")) | 566 :text(_from..' invited you to the room '.._to..(_reason and (' ('.._reason..')') or "")) |
567 :up(); | 567 :up(); |
568 self:route_stanza(invite); | 568 self:_route_stanza(invite); |
569 else | 569 else |
570 origin.send(st.error_reply(stanza, "cancel", "jid-malformed")); | 570 origin.send(st.error_reply(stanza, "cancel", "jid-malformed")); |
571 end | 571 end |
572 else | 572 else |
573 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | 573 origin.send(st.error_reply(stanza, "cancel", "bad-request")); |
632 end | 632 end |
633 p.attr.from = nick; | 633 p.attr.from = nick; |
634 for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick | 634 for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick |
635 if not role then self._jid_nick[jid] = nil; end | 635 if not role then self._jid_nick[jid] = nil; end |
636 p.attr.to = jid; | 636 p.attr.to = jid; |
637 self:route_stanza(p); | 637 self:_route_stanza(p); |
638 end | 638 end |
639 end | 639 end |
640 end | 640 end |
641 if self.save then self:save(); end | 641 if self.save then self:save(); end |
642 if callback then callback(); end | 642 if callback then callback(); end |
673 else | 673 else |
674 occupant.role = role; | 674 occupant.role = role; |
675 end | 675 end |
676 for jid in pairs(occupant.sessions) do -- send to all sessions of the nick | 676 for jid in pairs(occupant.sessions) do -- send to all sessions of the nick |
677 p.attr.to = jid; | 677 p.attr.to = jid; |
678 self:route_stanza(p); | 678 self:_route_stanza(p); |
679 end | 679 end |
680 if callback then callback(); end | 680 if callback then callback(); end |
681 self:broadcast_except_nick(p, nick); | 681 self:broadcast_except_nick(p, nick); |
682 return true; | 682 return true; |
683 end | |
684 | |
685 function room_mt:_route_stanza(stanza) | |
686 local muc_child; | |
687 local to_occupant = self._occupants[self._jid_nick[stanza.attr.to]]; | |
688 local from_occupant = self._occupants[stanza.attr.from]; | |
689 if stanza.name == "presence" then | |
690 if to_occupant and from_occupant then | |
691 if to_occupant.role == "moderator" or jid_bare(to_occupant.jid) == jid_bare(from_occupant.jid) then | |
692 for i=#stanza.tags,1,-1 do | |
693 local tag = stanza.tags[i]; | |
694 if tag.name == "x" and tag.attr.xmlns == "http://jabber.org/protocol/muc#user" then | |
695 muc_child = tag; | |
696 break; | |
697 end | |
698 end | |
699 end | |
700 end | |
701 end | |
702 if muc_child then | |
703 for _, item in pairs(muc_child.tags) do | |
704 if item.name == "item" then | |
705 if from_occupant == to_occupant then | |
706 item.attr.jid = stanza.attr.to; | |
707 else | |
708 item.attr.jid = from_occupant.jid; | |
709 end | |
710 end | |
711 end | |
712 end | |
713 self:route_stanza(stanza); | |
714 if muc_child then | |
715 for _, item in pairs(muc_child.tags) do | |
716 if item.name == "item" then | |
717 item.attr.jid = nil; | |
718 end | |
719 end | |
720 end | |
683 end | 721 end |
684 | 722 |
685 local _M = {}; -- module "muc" | 723 local _M = {}; -- module "muc" |
686 | 724 |
687 function _M.new_room(jid) | 725 function _M.new_room(jid) |