Software /
code /
prosody
Comparison
plugins/mod_muc.lua @ 668:50072761e02d
mod_muc: Room subjects stored, and room persistence code in place. First user now the owner.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Wed, 31 Dec 2008 18:17:47 +0500 |
parent | 666:27f76695f43b |
child | 671:c7519f0c9a2c |
comparison
equal
deleted
inserted
replaced
667:4f4d94253547 | 668:50072761e02d |
---|---|
8 local multitable_new = require "util.multitable".new; | 8 local multitable_new = require "util.multitable".new; |
9 | 9 |
10 local muc_domain = "conference."..module:get_host(); | 10 local muc_domain = "conference."..module:get_host(); |
11 local muc_name = "MUCMUCMUC!!!"; | 11 local muc_name = "MUCMUCMUC!!!"; |
12 | 12 |
13 -- room_name -> room | |
14 -- occupant_room_nick -> data | |
15 -- affiliation = ... | |
16 -- role | |
17 -- jid = occupant's real jid | |
13 local rooms = multitable_new(); | 18 local rooms = multitable_new(); |
14 local jid_nick = multitable_new(); | 19 |
20 local jid_nick = multitable_new(); -- real jid -> room's jid -> room nick | |
21 | |
22 -- room_name -> info | |
23 -- name - the room's friendly name | |
24 -- subject - the room's subject | |
25 -- non-anonymous = true|nil | |
26 -- persistent = true|nil | |
15 local rooms_info = multitable_new(); | 27 local rooms_info = multitable_new(); |
28 | |
29 local persist_list = datamanager.load(nil, muc_domain, 'room_list') or {}; | |
30 for room in pairs(persist_list) do | |
31 rooms_info:set(room, datamanager.store(room, muc_domain, 'rooms') or nil); | |
32 end | |
16 | 33 |
17 local component; | 34 local component; |
18 | 35 |
19 function getUsingPath(stanza, path, getText) | 36 function getUsingPath(stanza, path, getText) |
20 local tag = stanza; | 37 local tag = stanza; |
46 :tag("feature", {var="http://jabber.org/protocol/muc"}); -- TODO cache disco reply | 63 :tag("feature", {var="http://jabber.org/protocol/muc"}); -- TODO cache disco reply |
47 end | 64 end |
48 function get_room_disco_items(stanza) | 65 function get_room_disco_items(stanza) |
49 return st.iq({type='result', id=stanza.attr.id, from=stanza.attr.to, to=stanza.attr.from}):query("http://jabber.org/protocol/disco#items"); | 66 return st.iq({type='result', id=stanza.attr.id, from=stanza.attr.to, to=stanza.attr.from}):query("http://jabber.org/protocol/disco#items"); |
50 end -- TODO allow non-private rooms | 67 end -- TODO allow non-private rooms |
68 | |
69 function save_room(room) | |
70 local persistent = rooms_info:get(room, 'persistent'); | |
71 if persistent then | |
72 datamanager.store(room, muc_domain, 'rooms', rooms_info:get(room)); | |
73 end | |
74 if persistent ~= persist_list[room] then | |
75 if not persistent then | |
76 datamanager.store(room, muc_domain, 'rooms', nil); | |
77 end | |
78 persist_list[room] = persistent; | |
79 datamanager.store(nil, muc_domain, 'room_list', persist_list); | |
80 end | |
81 end | |
82 | |
83 function set_subject(current_nick, room, subject) | |
84 -- TODO check nick's authority | |
85 if subject == "" then subject = nil; end | |
86 rooms_info:set(room, 'subject', subject); | |
87 save_room(); | |
88 broadcast_message(current_nick, room, subject or "", nil); | |
89 return true; | |
90 end | |
51 | 91 |
52 function broadcast_presence(type, from, room, code) | 92 function broadcast_presence(type, from, room, code) |
53 local data = rooms:get(room, from); | 93 local data = rooms:get(room, from); |
54 local stanza = st.presence({type=type, from=from}) | 94 local stanza = st.presence({type=type, from=from}) |
55 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) | 95 :tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
126 end | 166 end |
127 else -- enter room | 167 else -- enter room |
128 if rooms:get(room, to) then | 168 if rooms:get(room, to) then |
129 origin.send(st.error_reply(stanza, "cancel", "conflict")); | 169 origin.send(st.error_reply(stanza, "cancel", "conflict")); |
130 else | 170 else |
131 local data = {affiliation='none', role='participant', jid=from}; | 171 local data; |
172 if not rooms:get(room) and not rooms_info:get(room) then -- new room | |
173 data = {affiliation='owner', role='moderator', jid=from}; | |
174 end | |
175 if not data then -- new occupant | |
176 data = {affiliation='none', role='participant', jid=from}; | |
177 end | |
132 rooms:set(room, to, data); | 178 rooms:set(room, to, data); |
133 jid_nick:set(from, room, to); | 179 jid_nick:set(from, room, to); |
134 local r = rooms:get(room); | 180 local r = rooms:get(room); |
135 if r then | 181 if r then |
136 for occupant, o_data in pairs(r) do | 182 for occupant, o_data in pairs(r) do |
141 core_route_stanza(component, pres); | 187 core_route_stanza(component, pres); |
142 end | 188 end |
143 end | 189 end |
144 end | 190 end |
145 broadcast_presence(nil, to, room); | 191 broadcast_presence(nil, to, room); |
192 -- TODO send discussion history | |
193 if rooms_info:get(room, 'subject') then | |
194 broadcast_message(room, room, rooms_info:get(room, 'subject'), nil); | |
195 end | |
146 end | 196 end |
147 end | 197 end |
148 elseif type ~= 'result' then -- bad type | 198 elseif type ~= 'result' then -- bad type |
149 origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error? | 199 origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error? |
150 end | 200 end |
172 local room = jid_bare(to); | 222 local room = jid_bare(to); |
173 local current_nick = jid_nick:get(from, room); | 223 local current_nick = jid_nick:get(from, room); |
174 if not current_nick then -- not in room | 224 if not current_nick then -- not in room |
175 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); | 225 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
176 else | 226 else |
177 broadcast_message(current_nick, room, getText(stanza, {"subject"}), getText(stanza, {"body"})); | 227 local subject = getText(stanza, {"subject"}); |
228 if subject then | |
229 set_subject(current_nick, room, subject); | |
230 else | |
231 broadcast_message(current_nick, room, nil, getText(stanza, {"body"})); | |
232 -- TODO add to discussion history | |
233 end | |
178 end | 234 end |
179 else | 235 else |
180 if type == "error" or type == "result" then return; end | 236 if type == "error" or type == "result" then return; end |
181 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); | 237 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); |
182 end | 238 end |