Thu, 18 Mar 2010 14:16:05 +0100
groupchat.lua: make the occupant-left event work
tell.lua: double check the room and clear told tellings.
0 | 1 | local events = require "events"; |
2 | local st = require "util.stanza"; | |
3 | ||
4 | local room_mt = {}; | |
5 | room_mt.__index = room_mt; | |
6 | ||
7 | local xmlns_delay = "urn:xmpp:delay"; | |
8 | ||
9 | function riddim.plugins.groupchat(bot) | |
10 | bot.rooms = {}; | |
11 | ||
12 | bot.stream:hook("stanza", function (stanza) | |
13 | local room_jid = jid.bare(stanza.attr.from); | |
14 | local room = bot.rooms[room_jid] | |
15 | if room then | |
16 | local nick = select(3, jid.split(stanza.attr.from)); | |
17 | local body = stanza:get_child("body"); | |
18 | local delay = stanza:get_child("delay", xmlns_delay); | |
19 | local event = { | |
20 | room_jid = room_jid; | |
21 | room = room; | |
22 | sender = room.occupants[nick]; | |
23 | nick = nick; | |
24 | body = (body and body:get_text()) or nil; | |
25 | stanza = stanza; | |
26 | delay = (delay and delay.attr.stamp); | |
27 | }; | |
28 | if stanza.name == "message" then | |
29 | local replied; | |
30 | local r = st.reply(stanza); | |
31 | if stanza.attr.type == "groupchat" then | |
32 | r.attr.type = stanza.attr.type; | |
33 | r.attr.to = jid.bare(stanza.attr.to); | |
34 | end | |
35 | function event:reply(reply) | |
36 | if not reply then reply = "Nothing to say to you"; end | |
37 | if replied then return false; end | |
38 | replied = true; | |
39 | if r.attr.type == "groupchat" then | |
40 | reply = event.sender.nick..": "..reply; | |
41 | end | |
42 | room:send(r:tag("body"):text(reply)); | |
43 | end | |
44 | end | |
45 | local ret; | |
46 | if stanza.name ~= "message" or nick ~= room.nick then | |
47 | ret = room:event(stanza.name, event); | |
48 | end | |
49 | return ret or (stanza.name == "message") or nil; | |
50 | end | |
51 | end, 500); | |
52 | ||
53 | function bot:join_room(jid, nick) | |
54 | nick = nick or bot.config.nick or ("bot"..math.random(10000,99999)); | |
55 | local room = setmetatable({ | |
56 | bot = bot, jid = jid, nick = nick, | |
57 | occupants = {}, | |
58 | events = events.new() }, room_mt); | |
59 | self.rooms[jid] = room; | |
60 | local occupants = room.occupants; | |
61 | room:hook("presence", function (presence) | |
62 | local nick = presence.nick; | |
9
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
63 | if not occupants[nick] and presence.stanza.attr.type ~= "unavailable" then |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
64 | occupants[nick] = { |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
65 | nick = nick; |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
66 | jid = presence.stanza.attr.from; |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
67 | presence = presence.stanza; |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
68 | }; |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
69 | if nick == room.nick then |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
70 | room.bot:event("groupchat/joined", room); |
0 | 71 | else |
9
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
72 | room:event("occupant-joined", occupants[nick]); |
0 | 73 | end |
9
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
74 | elseif occupants[nick] and presence.stanza.attr.type == "unavailable" then |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
75 | occupants[nick].presence = presence.stanza; |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
76 | room:event("occupant-left", occupants[nick]); |
8c3bec93087b
groupchat.lua: make the occupant-left event work
Thilo Cestonaro <thilo@cestona.ro>
parents:
0
diff
changeset
|
77 | occupants[nick] = nil; |
0 | 78 | end |
79 | end); | |
80 | self:send(st.presence({to = jid.."/"..nick})); | |
81 | self:event("groupchat/joining", room); | |
82 | return room; | |
83 | end | |
84 | end | |
85 | ||
86 | function room_mt:send(stanza) | |
87 | if stanza.name == "message" and not stanza.attr.type then | |
88 | stanza.attr.type = "groupchat"; | |
89 | end | |
90 | if stanza.attr.type == "groupchat" then | |
91 | stanza.attr.to = self.jid; | |
92 | end | |
93 | self.bot:send(stanza); | |
94 | end | |
95 | ||
96 | function room_mt:send_message(text) | |
97 | self:send(st.message():tag("body"):text(text)); | |
98 | end | |
99 | ||
100 | function room_mt:leave(message) | |
101 | self.bot:event("groupchat/leaving", room); | |
102 | self:send(st.presence({type="unavailable"})); | |
103 | self.bot:event("groupchat/left", room); | |
104 | end | |
105 | ||
106 | function room_mt:event(name, arg) | |
107 | self.bot.stream:debug("Firing room event: %s", name); | |
108 | return self.events.fire_event(name, arg); | |
109 | end | |
110 | ||
111 | function room_mt:hook(name, callback, priority) | |
112 | return self.events.add_handler(name, callback, priority); | |
113 | end |