5 local jid_split = require "util.jid".split; |
5 local jid_split = require "util.jid".split; |
6 local jid_bare = require "util.jid".bare; |
6 local jid_bare = require "util.jid".bare; |
7 local st = require "util.stanza"; |
7 local st = require "util.stanza"; |
8 local log = require "util.logger".init("mod_muc"); |
8 local log = require "util.logger".init("mod_muc"); |
9 local multitable_new = require "util.multitable".new; |
9 local multitable_new = require "util.multitable".new; |
|
10 local t_insert, t_remove = table.insert, table.remove; |
10 |
11 |
11 if module:get_host_type() ~= "component" then |
12 if module:get_host_type() ~= "component" then |
12 error("MUC should be loaded as a component, please see http://prosody.im/doc/components", 0); |
13 error("MUC should be loaded as a component, please see http://prosody.im/doc/components", 0); |
13 end |
14 end |
14 |
15 |
15 local muc_domain = module:get_host(); |
16 local muc_domain = module:get_host(); |
16 |
|
17 local muc_name = "MUCMUCMUC!!!"; |
17 local muc_name = "MUCMUCMUC!!!"; |
|
18 local history_length = 20; |
18 |
19 |
19 -- room_name -> room |
20 -- room_name -> room |
20 -- occupant_room_nick -> data |
21 -- occupant_room_nick -> data |
21 -- affiliation = ... |
22 -- affiliation = ... |
22 -- role |
23 -- role |
28 -- room_name -> info |
29 -- room_name -> info |
29 -- name - the room's friendly name |
30 -- name - the room's friendly name |
30 -- subject - the room's subject |
31 -- subject - the room's subject |
31 -- non-anonymous = true|nil |
32 -- non-anonymous = true|nil |
32 -- persistent = true|nil |
33 -- persistent = true|nil |
|
34 -- history = {preserialized stanzas} |
33 local rooms_info = multitable_new(); |
35 local rooms_info = multitable_new(); |
34 |
36 |
35 local persist_list = datamanager.load(nil, muc_domain, 'room_list') or {}; |
37 local persist_list = datamanager.load(nil, muc_domain, 'room_list') or {}; |
36 for room in pairs(persist_list) do |
38 for room in pairs(persist_list) do |
37 rooms_info:set(room, datamanager.store(room, muc_domain, 'rooms') or nil); |
39 rooms_info:set(room, datamanager.store(room, muc_domain, 'rooms') or nil); |
128 local r = rooms:get(room); |
130 local r = rooms:get(room); |
129 if r then |
131 if r then |
130 for occupant, o_data in pairs(r) do |
132 for occupant, o_data in pairs(r) do |
131 stanza.attr.to = o_data.jid; |
133 stanza.attr.to = o_data.jid; |
132 core_route_stanza(component, stanza); |
134 core_route_stanza(component, stanza); |
|
135 end |
|
136 if not subject and body then -- add to history |
|
137 local history = rooms_info:get(room, 'history'); |
|
138 if not history then history = {}; rooms_info:set(room, 'history', history); end |
|
139 -- stanza = st.deserialize(st.preserialize(stanza)); |
|
140 stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = datetime.datetime()}):up(); -- XEP-0203 |
|
141 stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) |
|
142 t_insert(history, st.preserialize(stanza)); |
|
143 while #history > history_length do t_remove(history, 1) end |
133 end |
144 end |
134 end |
145 end |
135 end |
146 end |
136 |
147 |
137 function handle_to_occupant(origin, stanza) -- PM, vCards, etc |
148 function handle_to_occupant(origin, stanza) -- PM, vCards, etc |
198 core_route_stanza(component, pres); |
209 core_route_stanza(component, pres); |
199 end |
210 end |
200 end |
211 end |
201 end |
212 end |
202 broadcast_presence(nil, to, room); |
213 broadcast_presence(nil, to, room); |
203 -- TODO send discussion history |
214 local history = rooms_info:get(room, 'history'); -- send discussion history |
|
215 if history then |
|
216 for _, msg in ipairs(history) do |
|
217 msg = st.deserialize(msg); |
|
218 msg.attr.to=from; |
|
219 core_route_stanza(component, msg); |
|
220 end |
|
221 end |
204 if rooms_info:get(room, 'subject') then |
222 if rooms_info:get(room, 'subject') then |
205 core_route_stanza(component, st.message({type='groupchat', from=room, to=from}):tag("subject"):text(rooms_info:get(room, 'subject'))); |
223 core_route_stanza(component, st.message({type='groupchat', from=room, to=from}):tag("subject"):text(rooms_info:get(room, 'subject'))); |
206 end |
224 end |
207 end |
225 end |
208 end |
226 end |