plugins/groupchat.lua

changeset 186
bb34b8bc00ae
parent 185
4f897d0e01c4
child 187
7ad218bd5fde
equal deleted inserted replaced
185:4f897d0e01c4 186:bb34b8bc00ae
11 stream:add_plugin("presence") 11 stream:add_plugin("presence")
12 stream.rooms = {}; 12 stream.rooms = {};
13 13
14 stream:hook("stanza", function (stanza) 14 stream:hook("stanza", function (stanza)
15 local room_jid = jid.bare(stanza.attr.from); 15 local room_jid = jid.bare(stanza.attr.from);
16 local room = stream.rooms[room_jid] 16 local room = stream.rooms[room_jid] or stream.rooms[stanza.attr.to.." "..room_jid] or nil
17 if room and room.opts.source and stanza.attr.to ~= room.opts.source then return end
17 if room then 18 if room then
18 local nick = select(3, jid.split(stanza.attr.from)); 19 local nick = select(3, jid.split(stanza.attr.from));
19 local body = stanza:get_child("body"); 20 local body = stanza:get_child("body");
20 local delay = stanza:get_child("delay", xmlns_delay); 21 local delay = stanza:get_child("delay", xmlns_delay);
21 local event = { 22 local event = {
30 local ret = room:event(stanza.name, event); 31 local ret = room:event(stanza.name, event);
31 return ret or (stanza.name == "message") or nil; 32 return ret or (stanza.name == "message") or nil;
32 end 33 end
33 end, 500); 34 end, 500);
34 35
35 function stream:join_room(jid, nick) 36 function stream:join_room(jid, nick, opts)
36 if not nick then 37 if not nick then
37 return false, "no nickname supplied" 38 return false, "no nickname supplied"
38 end 39 end
39 local room = setmetatable({ 40 local room = setmetatable({
40 stream = stream, jid = jid, nick = nick, 41 stream = stream, jid = jid, nick = nick,
41 subject = nil, 42 subject = nil,
42 occupants = {}, 43 occupants = {},
44 opts = opts,
43 events = events.new() 45 events = events.new()
44 }, room_mt); 46 }, room_mt);
45 self.rooms[jid] = room; 47 if opts.source then
48 self.rooms[opts.source.." "..jid] = room;
49 else
50 self.rooms[jid] = room;
51 end
46 local occupants = room.occupants; 52 local occupants = room.occupants;
47 room:hook("presence", function (presence) 53 room:hook("presence", function (presence)
48 local nick = presence.nick or nick; 54 local nick = presence.nick or nick;
49 if not occupants[nick] and presence.stanza.attr.type ~= "unavailable" then 55 if not occupants[nick] and presence.stanza.attr.type ~= "unavailable" then
50 occupants[nick] = { 56 occupants[nick] = {
68 room:event("occupant-joined", occupants[nick]); 74 room:event("occupant-joined", occupants[nick]);
69 end 75 end
70 elseif occupants[nick] and presence.stanza.attr.type == "unavailable" then 76 elseif occupants[nick] and presence.stanza.attr.type == "unavailable" then
71 if nick == room.nick then 77 if nick == room.nick then
72 room.stream:event("groupchat/left", room); 78 room.stream:event("groupchat/left", room);
73 self.rooms[room.jid] = nil; 79 if room.opts.source then
80 self.rooms[room.opts.source.." "..jid] = nil;
81 else
82 self.rooms[jid] = nil;
83 end
74 else 84 else
75 occupants[nick].presence = presence.stanza; 85 occupants[nick].presence = presence.stanza;
76 room:event("occupant-left", occupants[nick]); 86 room:event("occupant-left", occupants[nick]);
77 occupants[nick] = nil; 87 occupants[nick] = nil;
78 end 88 end
83 subject = subject and subject:get_text(); 93 subject = subject and subject:get_text();
84 if subject then 94 if subject then
85 room.subject = #subject > 0 and subject or nil; 95 room.subject = #subject > 0 and subject or nil;
86 end 96 end
87 end); 97 end);
88 local join_st = st.presence({to = jid.."/"..nick}) 98 local join_st = st.presence():tag("x",{xmlns = xmlns_muc}):reset();
89 :tag("x",{xmlns = xmlns_muc}):reset();
90 self:event("pre-groupchat/joining", join_st); 99 self:event("pre-groupchat/joining", join_st);
91 self:send(join_st) 100 room:send(join_st)
92 self:event("groupchat/joining", room); 101 self:event("groupchat/joining", room);
93 return room; 102 return room;
94 end 103 end
95 104
96 stream:hook("presence-out", function(presence) 105 stream:hook("presence-out", function(presence)
105 114
106 function room_mt:send(stanza) 115 function room_mt:send(stanza)
107 if stanza.name == "message" and not stanza.attr.type then 116 if stanza.name == "message" and not stanza.attr.type then
108 stanza.attr.type = "groupchat"; 117 stanza.attr.type = "groupchat";
109 end 118 end
119 if stanza.name == "presence" or not stanza.attr.to then
120 stanza.attr.to = self.jid .."/"..self.nick;
121 end
110 if stanza.attr.type == "groupchat" or not stanza.attr.to then 122 if stanza.attr.type == "groupchat" or not stanza.attr.to then
111 stanza.attr.to = self.jid; 123 stanza.attr.to = self.jid;
124 end
125 if self.opts.source then
126 stanza.attr.from = self.opts.source
112 end 127 end
113 self.stream:send(stanza); 128 self.stream:send(stanza);
114 end 129 end
115 130
116 function room_mt:send_message(text) 131 function room_mt:send_message(text)

mercurial