50 else |
50 else |
51 core_route_stanza(origin, stanza); |
51 core_route_stanza(origin, stanza); |
52 end |
52 end |
53 end |
53 end |
54 |
54 |
|
55 local function select_top_resources(user) |
|
56 local priority = 0; |
|
57 local recipients = {}; |
|
58 for _, session in pairs(user.sessions) do -- find resource with greatest priority |
|
59 if session.presence then |
|
60 -- TODO check active privacy list for session |
|
61 local p = session.priority; |
|
62 if p > priority then |
|
63 priority = p; |
|
64 recipients = {session}; |
|
65 elseif p == priority then |
|
66 t_insert(recipients, session); |
|
67 end |
|
68 end |
|
69 end |
|
70 return recipients; |
|
71 end |
|
72 local function recalc_resource_map(origin) |
|
73 local user = hosts[origin.host].sessions[origin.username]; |
|
74 user.top_resources = select_top_resources(user); |
|
75 if #user.top_resources == 0 then user.top_resources = nil; end |
|
76 end |
|
77 |
55 function handle_normal_presence(origin, stanza, core_route_stanza) |
78 function handle_normal_presence(origin, stanza, core_route_stanza) |
56 if origin.roster then |
79 if origin.roster then |
57 for jid in pairs(origin.roster) do -- broadcast to all interested contacts |
80 for jid in pairs(origin.roster) do -- broadcast to all interested contacts |
58 local subscription = origin.roster[jid].subscription; |
81 local subscription = origin.roster[jid].subscription; |
59 if subscription == "both" or subscription == "from" then |
82 if subscription == "both" or subscription == "from" then |
102 origin.send(msg); -- FIXME do we need to modify to/from in any way? |
125 origin.send(msg); -- FIXME do we need to modify to/from in any way? |
103 end |
126 end |
104 offlinemanager.deleteAll(node, host); |
127 offlinemanager.deleteAll(node, host); |
105 end |
128 end |
106 end |
129 end |
107 origin.priority = 0; |
|
108 if stanza.attr.type == "unavailable" then |
130 if stanza.attr.type == "unavailable" then |
109 origin.presence = nil; |
131 origin.presence = nil; |
|
132 if origin.priority then |
|
133 origin.priority = nil; |
|
134 recalc_resource_map(origin); |
|
135 end |
110 if origin.directed then |
136 if origin.directed then |
111 local old_from = stanza.attr.from; |
137 local old_from = stanza.attr.from; |
112 stanza.attr.from = origin.full_jid; |
138 stanza.attr.from = origin.full_jid; |
113 for jid in pairs(origin.directed) do |
139 for jid in pairs(origin.directed) do |
114 stanza.attr.to = jid; |
140 stanza.attr.to = jid; |
124 priority = t_concat(priority); |
150 priority = t_concat(priority); |
125 if s_find(priority, "^[+-]?[0-9]+$") then |
151 if s_find(priority, "^[+-]?[0-9]+$") then |
126 priority = tonumber(priority); |
152 priority = tonumber(priority); |
127 if priority < -128 then priority = -128 end |
153 if priority < -128 then priority = -128 end |
128 if priority > 127 then priority = 127 end |
154 if priority > 127 then priority = 127 end |
129 origin.priority = priority; |
155 else priority = 0; end |
130 end |
156 else priority = 0; end |
|
157 if origin.priority ~= priority then |
|
158 origin.priority = priority; |
|
159 recalc_resource_map(origin); |
131 end |
160 end |
132 end |
161 end |
133 stanza.attr.to = nil; -- reset it |
162 stanza.attr.to = nil; -- reset it |
134 else |
163 else |
135 log("warn", "presence recieved from client with no roster"); |
164 log("warn", "presence recieved from client with no roster"); |