Software / code / prosody
Comparison
plugins/mod_presence.lua @ 1476:5d6199a9b4f6
mod_presence: Prevented normal presence from non-interested resources from being dropped
| author | Waqas Hussain <waqas20@gmail.com> |
|---|---|
| date | Sun, 05 Jul 2009 12:40:18 +0500 |
| parent | 1475:16c8b1a8f6a7 |
| child | 1477:e0411d6c9bae |
comparison
equal
deleted
inserted
replaced
| 1475:16c8b1a8f6a7 | 1476:5d6199a9b4f6 |
|---|---|
| 60 if #user.top_resources == 0 then user.top_resources = nil; end | 60 if #user.top_resources == 0 then user.top_resources = nil; end |
| 61 end | 61 end |
| 62 | 62 |
| 63 function handle_normal_presence(origin, stanza, core_route_stanza) | 63 function handle_normal_presence(origin, stanza, core_route_stanza) |
| 64 local roster = origin.roster; | 64 local roster = origin.roster; |
| 65 if roster then | 65 for jid, item in pairs(roster) do -- broadcast to all interested contacts |
| 66 for jid, item in pairs(roster) do -- broadcast to all interested contacts | 66 if item.subscription == "both" or item.subscription == "from" then |
| 67 if item.subscription == "both" or item.subscription == "from" then | 67 stanza.attr.to = jid; |
| 68 core_route_stanza(origin, stanza); | |
| 69 end | |
| 70 end | |
| 71 local node, host = origin.username, origin.host; | |
| 72 for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast to all resources | |
| 73 if res ~= origin and res.presence then -- to resource | |
| 74 stanza.attr.to = res.full_jid; | |
| 75 core_route_stanza(origin, stanza); | |
| 76 end | |
| 77 end | |
| 78 if stanza.attr.type == nil and not origin.presence then -- initial presence | |
| 79 local probe = st.presence({from = origin.full_jid, type = "probe"}); | |
| 80 for jid, item in pairs(roster) do -- probe all contacts we are subscribed to | |
| 81 if item.subscription == "both" or item.subscription == "to" then | |
| 82 probe.attr.to = jid; | |
| 83 core_route_stanza(origin, probe); | |
| 84 end | |
| 85 end | |
| 86 for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast from all available resources | |
| 87 if res ~= origin and res.presence then | |
| 88 res.presence.attr.to = origin.full_jid; | |
| 89 core_route_stanza(res, res.presence); | |
| 90 res.presence.attr.to = nil; | |
| 91 end | |
| 92 end | |
| 93 if roster.pending then -- resend incoming subscription requests | |
| 94 for jid in pairs(roster.pending) do | |
| 95 origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original? | |
| 96 end | |
| 97 end | |
| 98 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); | |
| 99 for jid, item in pairs(roster) do -- resend outgoing subscription requests | |
| 100 if item.ask then | |
| 101 request.attr.to = jid; | |
| 102 core_route_stanza(origin, request); | |
| 103 end | |
| 104 end | |
| 105 local offline = offlinemanager.load(node, host); | |
| 106 if offline then | |
| 107 for _, msg in ipairs(offline) do | |
| 108 origin.send(msg); -- FIXME do we need to modify to/from in any way? | |
| 109 end | |
| 110 offlinemanager.deleteAll(node, host); | |
| 111 end | |
| 112 end | |
| 113 if stanza.attr.type == "unavailable" then | |
| 114 origin.presence = nil; | |
| 115 if origin.priority then | |
| 116 origin.priority = nil; | |
| 117 recalc_resource_map(origin); | |
| 118 end | |
| 119 if origin.directed then | |
| 120 for jid in pairs(origin.directed) do | |
| 68 stanza.attr.to = jid; | 121 stanza.attr.to = jid; |
| 69 core_route_stanza(origin, stanza); | 122 core_route_stanza(origin, stanza); |
| 70 end | 123 end |
| 71 end | 124 origin.directed = nil; |
| 72 local node, host = origin.username, origin.host; | 125 end |
| 73 for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast to all resources | 126 else |
| 74 if res ~= origin and res.presence then -- to resource | 127 origin.presence = stanza; |
| 75 stanza.attr.to = res.full_jid; | 128 local priority = stanza:child_with_name("priority"); |
| 76 core_route_stanza(origin, stanza); | 129 if priority and #priority > 0 then |
| 77 end | 130 priority = t_concat(priority); |
| 78 end | 131 if s_find(priority, "^[+-]?[0-9]+$") then |
| 79 if stanza.attr.type == nil and not origin.presence then -- initial presence | 132 priority = tonumber(priority); |
| 80 local probe = st.presence({from = origin.full_jid, type = "probe"}); | 133 if priority < -128 then priority = -128 end |
| 81 for jid, item in pairs(roster) do -- probe all contacts we are subscribed to | 134 if priority > 127 then priority = 127 end |
| 82 if item.subscription == "both" or item.subscription == "to" then | |
| 83 probe.attr.to = jid; | |
| 84 core_route_stanza(origin, probe); | |
| 85 end | |
| 86 end | |
| 87 for _, res in pairs(hosts[host].sessions[node].sessions) do -- broadcast from all available resources | |
| 88 if res ~= origin and res.presence then | |
| 89 res.presence.attr.to = origin.full_jid; | |
| 90 core_route_stanza(res, res.presence); | |
| 91 res.presence.attr.to = nil; | |
| 92 end | |
| 93 end | |
| 94 if roster.pending then -- resend incoming subscription requests | |
| 95 for jid in pairs(roster.pending) do | |
| 96 origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original? | |
| 97 end | |
| 98 end | |
| 99 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); | |
| 100 for jid, item in pairs(roster) do -- resend outgoing subscription requests | |
| 101 if item.ask then | |
| 102 request.attr.to = jid; | |
| 103 core_route_stanza(origin, request); | |
| 104 end | |
| 105 end | |
| 106 local offline = offlinemanager.load(node, host); | |
| 107 if offline then | |
| 108 for _, msg in ipairs(offline) do | |
| 109 origin.send(msg); -- FIXME do we need to modify to/from in any way? | |
| 110 end | |
| 111 offlinemanager.deleteAll(node, host); | |
| 112 end | |
| 113 end | |
| 114 if stanza.attr.type == "unavailable" then | |
| 115 origin.presence = nil; | |
| 116 if origin.priority then | |
| 117 origin.priority = nil; | |
| 118 recalc_resource_map(origin); | |
| 119 end | |
| 120 if origin.directed then | |
| 121 for jid in pairs(origin.directed) do | |
| 122 stanza.attr.to = jid; | |
| 123 core_route_stanza(origin, stanza); | |
| 124 end | |
| 125 origin.directed = nil; | |
| 126 end | |
| 127 else | |
| 128 origin.presence = stanza; | |
| 129 local priority = stanza:child_with_name("priority"); | |
| 130 if priority and #priority > 0 then | |
| 131 priority = t_concat(priority); | |
| 132 if s_find(priority, "^[+-]?[0-9]+$") then | |
| 133 priority = tonumber(priority); | |
| 134 if priority < -128 then priority = -128 end | |
| 135 if priority > 127 then priority = 127 end | |
| 136 else priority = 0; end | |
| 137 else priority = 0; end | 135 else priority = 0; end |
| 138 if origin.priority ~= priority then | 136 else priority = 0; end |
| 139 origin.priority = priority; | 137 if origin.priority ~= priority then |
| 140 recalc_resource_map(origin); | 138 origin.priority = priority; |
| 141 end | 139 recalc_resource_map(origin); |
| 142 end | 140 end |
| 143 stanza.attr.to = nil; -- reset it | 141 end |
| 144 else | 142 stanza.attr.to = nil; -- reset it |
| 145 log("warn", "presence recieved from client with no roster"); | |
| 146 end | |
| 147 end | 143 end |
| 148 | 144 |
| 149 function send_presence_of_available_resources(user, host, jid, recipient_session, core_route_stanza) | 145 function send_presence_of_available_resources(user, host, jid, recipient_session, core_route_stanza) |
| 150 local h = hosts[host]; | 146 local h = hosts[host]; |
| 151 local count = 0; | 147 local count = 0; |