Mercurial > prosody-hg
comparison plugins/muc/occupant.lib.lua @ 6210:e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
| author | daurnimator <quae@daurnimator.com> |
|---|---|
| date | Wed, 02 Apr 2014 18:37:52 -0400 |
| parents | e488a90195bc |
| children | 41a5e5205fd9 |
comparison
equal
deleted
inserted
replaced
| 6209:cc00e78e6a31 | 6210:e9d62fff82a8 |
|---|---|
| 34 | 34 |
| 35 -- Deep copy an occupant | 35 -- Deep copy an occupant |
| 36 local function copy_occupant(occupant) | 36 local function copy_occupant(occupant) |
| 37 local sessions = {}; | 37 local sessions = {}; |
| 38 for full_jid, presence_stanza in pairs(occupant.sessions) do | 38 for full_jid, presence_stanza in pairs(occupant.sessions) do |
| 39 if presence_stanza.attr.type ~= "unavailable" then | 39 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session |
| 40 if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then | |
| 40 sessions[full_jid] = presence_stanza; | 41 sessions[full_jid] = presence_stanza; |
| 41 end | 42 end |
| 42 end | 43 end |
| 43 return setmetatable({ | 44 return setmetatable({ |
| 44 bare_jid = occupant.bare_jid; | 45 bare_jid = occupant.bare_jid; |
| 47 role = occupant.role; | 48 role = occupant.role; |
| 48 jid = occupant.jid; | 49 jid = occupant.jid; |
| 49 }, occupant_mt); | 50 }, occupant_mt); |
| 50 end | 51 end |
| 51 | 52 |
| 53 -- finds another session to be the primary (there might not be one) | |
| 54 function occupant_mt:choose_new_primary() | |
| 55 for jid, pr in self:each_session() do | |
| 56 if pr.attr.type ~= "unavailable" then | |
| 57 return jid; | |
| 58 end | |
| 59 end | |
| 60 return nil; | |
| 61 end | |
| 62 | |
| 52 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) | 63 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) |
| 53 local pr = get_filtered_presence(presence_stanza); | 64 local pr = get_filtered_presence(presence_stanza); |
| 54 pr.attr.from = self.nick; | 65 pr.attr.from = self.nick; |
| 55 pr.attr.to = real_jid; | 66 pr.attr.to = real_jid; |
| 56 | 67 |
| 57 self.sessions[real_jid] = pr; | 68 self.sessions[real_jid] = pr; |
| 58 if replace_primary or self.jid == nil then | 69 if replace_primary then |
| 59 self.jid = real_jid; | 70 self.jid = real_jid; |
| 71 elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then | |
| 72 -- Only leave an unavailable presence as primary when there are no other options | |
| 73 self.jid = self:choose_new_primary() or real_jid; | |
| 60 end | 74 end |
| 61 end | 75 end |
| 62 | 76 |
| 63 function occupant_mt:remove_session(real_jid) | 77 function occupant_mt:remove_session(real_jid) |
| 64 -- Delete original session | 78 -- Delete original session |
| 65 local presence_stanza = self.sessions[real_jid]; | |
| 66 self.sessions[real_jid] = nil; | 79 self.sessions[real_jid] = nil; |
| 67 if self.jid == real_jid then | 80 if self.jid == real_jid then |
| 68 -- find another session to be the primary (might be nil) | 81 self.jid = self:choose_new_primary(); |
| 69 self.jid = next(self.sessions); | |
| 70 end | 82 end |
| 71 end | 83 end |
| 72 | 84 |
| 73 function occupant_mt:each_session() | 85 function occupant_mt:each_session() |
| 74 return pairs(self.sessions) | 86 return pairs(self.sessions) |
