Software / code / verse
Comparison
plugins/groupchat.lua @ 186:bb34b8bc00ae
plugins.groupchat: Extra options. Route join presence through the room. Option to stamp from attr on outgoing stanzas (useful for components).
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Wed, 19 Jan 2011 20:41:53 +0100 |
| parent | 185:4f897d0e01c4 |
| child | 187:7ad218bd5fde |
comparison
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) |