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) |