diff options
author | Homer Horwitz | 2008-11-01 22:09:48 +0000 |
---|---|---|
committer | Homer Horwitz | 2008-11-01 22:09:48 +0000 |
commit | 38e8853e5761d09a7e8f580dd277d9b99b834696 (patch) | |
tree | 653fe4c9075a03c05a4b5782f7309afa83062e5c /OpenSim/Grid/MessagingServer/MessageService.cs | |
parent | * minor: Remove mono compiler warning (diff) | |
download | opensim-SC-38e8853e5761d09a7e8f580dd277d9b99b834696.zip opensim-SC-38e8853e5761d09a7e8f580dd277d9b99b834696.tar.gz opensim-SC-38e8853e5761d09a7e8f580dd277d9b99b834696.tar.bz2 opensim-SC-38e8853e5761d09a7e8f580dd277d9b99b834696.tar.xz |
Megapatch that fixes/adds: friend offer/deny/accept, friendship termination,
on-/offline updates, calling cards for friends.
This adds methods in the DB layer and changes the MessagingServer, so a full
update (incl. UGAIM) is necessary to get it working. Older regions shouldn't
break, nor should older UGAIM break newer regions, but friends/presence will
only work with all concerned parts (UGAIM, source region and destination
region) at this revision (or later).
I added the DB code for MSSQL, too, but couldn't test that.
BEWARE: May contain bugs.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Grid/MessagingServer/MessageService.cs | 465 |
1 files changed, 162 insertions, 303 deletions
diff --git a/OpenSim/Grid/MessagingServer/MessageService.cs b/OpenSim/Grid/MessagingServer/MessageService.cs index 27892df..0be58e3 100644 --- a/OpenSim/Grid/MessagingServer/MessageService.cs +++ b/OpenSim/Grid/MessagingServer/MessageService.cs | |||
@@ -37,8 +37,6 @@ using Nwc.XmlRpc; | |||
37 | using OpenSim.Data; | 37 | using OpenSim.Data; |
38 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | 39 | ||
40 | //using System.Xml; | ||
41 | |||
42 | namespace OpenSim.Grid.MessagingServer | 40 | namespace OpenSim.Grid.MessagingServer |
43 | { | 41 | { |
44 | public class MessageService | 42 | public class MessageService |
@@ -48,17 +46,11 @@ namespace OpenSim.Grid.MessagingServer | |||
48 | private MessageServerConfig m_cfg; | 46 | private MessageServerConfig m_cfg; |
49 | private UserManager m_userManager; | 47 | private UserManager m_userManager; |
50 | 48 | ||
51 | //A hashtable of all current presences this server knows about | 49 | // a dictionary of all current presences this server knows about |
52 | private Hashtable m_presences = new Hashtable(); | 50 | private Dictionary<UUID, UserPresenceData> m_presences = new Dictionary<UUID,UserPresenceData>(); |
53 | |||
54 | //a hashtable of all current regions this server knows about | ||
55 | private Hashtable m_regionInfoCache = new Hashtable(); | ||
56 | |||
57 | //A hashtable containing lists of UUIDs keyed by UUID for fast backreferencing | ||
58 | private Hashtable m_presence_BackReferences = new Hashtable(); | ||
59 | 51 | ||
60 | // Hashtable containing work units that need to be processed | 52 | // a dictionary of all current regions this server knows about |
61 | // private Hashtable m_unProcessedWorkUnits = new Hashtable(); | 53 | private Dictionary<ulong, RegionProfileData> m_regionInfoCache = new Dictionary<ulong,RegionProfileData>(); |
62 | 54 | ||
63 | public MessageService(MessageServerConfig cfg) | 55 | public MessageService(MessageServerConfig cfg) |
64 | { | 56 | { |
@@ -78,174 +70,99 @@ namespace OpenSim.Grid.MessagingServer | |||
78 | /// Process Friendlist subscriptions for a user | 70 | /// Process Friendlist subscriptions for a user |
79 | /// The login method calls this for a User | 71 | /// The login method calls this for a User |
80 | /// </summary> | 72 | /// </summary> |
81 | /// <param name="userpresence">The Agent we're processing the friendlist subscriptions</param> | 73 | /// <param name="userpresence">The Agent we're processing the friendlist subscriptions for</param> |
82 | public void ProcessFriendListSubscriptions(UserPresenceData userpresence) | 74 | private void ProcessFriendListSubscriptions(UserPresenceData userpresence) |
83 | { | 75 | { |
84 | lock (m_presences) | 76 | lock (m_presences) |
85 | { | 77 | { |
86 | if (!m_presences.Contains(userpresence.agentData.AgentID)) | 78 | m_presences[userpresence.agentData.AgentID] = userpresence; |
87 | m_presences.Add(userpresence.agentData.AgentID, userpresence); | ||
88 | else | ||
89 | m_presences[userpresence.agentData.AgentID] = userpresence; | ||
90 | } | 79 | } |
91 | 80 | ||
92 | List<FriendListItem> uFriendList = userpresence.friendData; | 81 | Dictionary<UUID, FriendListItem> uFriendList = userpresence.friendData; |
93 | for (int i = 0; i < uFriendList.Count; i++) | 82 | foreach (KeyValuePair<UUID, FriendListItem> pair in uFriendList) |
94 | { | 83 | { |
95 | //m_presence_BackReferences.Add(userpresence.agentData.AgentID, uFriendList[i].Friend); | 84 | UserPresenceData friendup = null; |
96 | // m_presence_BackReferences.Add(uFriendList[i].Friend, userpresence.agentData.AgentID); | 85 | lock (m_presences) |
97 | |||
98 | if (m_presences.Contains(uFriendList[i].Friend)) | ||
99 | { | 86 | { |
100 | UserPresenceData friendup = (UserPresenceData)m_presences[uFriendList[i].Friend]; | 87 | m_presences.TryGetValue(pair.Key, out friendup); |
101 | // Add backreference | 88 | } |
102 | 89 | if (friendup != null) | |
103 | SubscribeToPresenceUpdates(userpresence, friendup, uFriendList[i],i); | 90 | { |
91 | SubscribeToPresenceUpdates(userpresence, friendup, pair.Value); | ||
104 | } | 92 | } |
105 | } | 93 | } |
106 | } | 94 | } |
107 | 95 | ||
108 | /// <summary> | 96 | /// <summary> |
109 | /// Does the necessary work to subscribe one agent to another's presence notifications | 97 | /// Enqueues a presence update, sending info about user 'talkingAbout' to user 'receiver'. |
110 | /// Gets called by ProcessFriendListSubscriptions. You shouldn't call this directly | ||
111 | /// unless you know what you're doing | ||
112 | /// </summary> | 98 | /// </summary> |
113 | /// <param name="userpresence">P1</param> | 99 | /// <param name="talkingAbout">We are sending presence information about this user.</param> |
114 | /// <param name="friendpresence">P2</param> | 100 | /// <param name="receiver">We are sending the presence update to this user</param> |
115 | /// <param name="uFriendListItem"></param> | 101 | private void enqueuePresenceUpdate(UserPresenceData talkingAbout, UserPresenceData receiver) |
116 | /// <param name="uFriendListIndex"></param> | ||
117 | public void SubscribeToPresenceUpdates(UserPresenceData userpresence, UserPresenceData friendpresence, | ||
118 | FriendListItem uFriendListItem, int uFriendListIndex) | ||
119 | { | 102 | { |
120 | if ((uFriendListItem.FriendListOwnerPerms & (uint)FriendRights.CanSeeOnline) != 0) | 103 | UserAgentData p2Handle = m_userManager.GetUserAgentData(receiver.agentData.AgentID); |
104 | if (p2Handle != null) | ||
121 | { | 105 | { |
122 | // Subscribe and Send Out updates | 106 | if (receiver.lookupUserRegionYN) |
123 | if (!friendpresence.subscriptionData.Contains(friendpresence.agentData.AgentID)) | ||
124 | { | ||
125 | userpresence.subscriptionData.Add(friendpresence.agentData.AgentID); | ||
126 | //Send Region Notice.... | ||
127 | } | ||
128 | else | ||
129 | { | 107 | { |
130 | // we need to send out online status update, but the user is already subscribed | 108 | receiver.regionData.regionHandle = p2Handle.Handle; |
131 | } | ||
132 | UserAgentData p2Handle = m_userManager.GetUserAgentData(userpresence.agentData.AgentID); | ||
133 | if (p2Handle != null) | ||
134 | { | ||
135 | if (userpresence.lookupUserRegionYN) | ||
136 | { | ||
137 | userpresence.regionData.regionHandle = p2Handle.Handle; | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | userpresence.lookupUserRegionYN = true; | ||
142 | } | ||
143 | PresenceInformer friendlistupdater = new PresenceInformer(); | ||
144 | friendlistupdater.presence1 = friendpresence; | ||
145 | //friendlistupdater.gridserverurl = m_cfg.GridServerURL; | ||
146 | //friendlistupdater.gridserversendkey = m_cfg.GridSendKey; | ||
147 | //friendlistupdater.gridserverrecvkey = m_cfg.GridRecvKey; | ||
148 | friendlistupdater.presence2 = userpresence; | ||
149 | friendlistupdater.OnGetRegionData += GetRegionInfo; | ||
150 | friendlistupdater.OnDone += PresenceUpdateDone; | ||
151 | WaitCallback cb = new WaitCallback(friendlistupdater.go); | ||
152 | ThreadPool.QueueUserWorkItem(cb); | ||
153 | |||
154 | } | 109 | } |
155 | else | 110 | else |
156 | { | 111 | { |
157 | // Skip because we can't find any data on the user | 112 | receiver.lookupUserRegionYN = true; // TODO Huh? |
158 | } | 113 | } |
159 | 114 | ||
160 | //SendRegionPresenceUpdate(friendpresence, userpresence); | 115 | PresenceInformer friendlistupdater = new PresenceInformer(); |
116 | friendlistupdater.presence1 = talkingAbout; | ||
117 | friendlistupdater.presence2 = receiver; | ||
118 | friendlistupdater.OnGetRegionData += GetRegionInfo; | ||
119 | friendlistupdater.OnDone += PresenceUpdateDone; | ||
120 | WaitCallback cb = new WaitCallback(friendlistupdater.go); | ||
121 | ThreadPool.QueueUserWorkItem(cb); | ||
161 | } | 122 | } |
162 | 123 | else | |
163 | if ((uFriendListItem.FriendPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||
164 | { | 124 | { |
165 | if (!friendpresence.subscriptionData.Contains(userpresence.agentData.AgentID)) | 125 | m_log.WarnFormat("no data found for user {0}", receiver.agentData.AgentID); |
166 | { | 126 | // Skip because we can't find any data on the user |
167 | friendpresence.subscriptionData.Add(userpresence.agentData.AgentID); | ||
168 | //Send Region Notice.... | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | // we need to send out online status update, but the user is already subscribed | ||
173 | } | ||
174 | |||
175 | UserAgentData p2Handle = m_userManager.GetUserAgentData(friendpresence.agentData.AgentID); | ||
176 | |||
177 | if (p2Handle != null) | ||
178 | { | ||
179 | |||
180 | friendpresence.regionData.regionHandle = p2Handle.Handle; | ||
181 | PresenceInformer friendlistupdater = new PresenceInformer(); | ||
182 | friendlistupdater.presence1 = userpresence; | ||
183 | friendlistupdater.presence2 = friendpresence; | ||
184 | //friendlistupdater.gridserverurl = m_cfg.GridServerURL; | ||
185 | //friendlistupdater.gridserversendkey = m_cfg.GridSendKey; | ||
186 | //friendlistupdater.gridserverrecvkey = m_cfg.GridRecvKey; | ||
187 | friendlistupdater.OnGetRegionData += GetRegionInfo; | ||
188 | friendlistupdater.OnDone += PresenceUpdateDone; | ||
189 | WaitCallback cb2 = new WaitCallback(friendlistupdater.go); | ||
190 | ThreadPool.QueueUserWorkItem(cb2); | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | // skip, agent doesn't appear to exist anymore | ||
195 | } | ||
196 | |||
197 | |||
198 | |||
199 | //SendRegionPresenceUpdate(userpresence, friendpresence); | ||
200 | } | 127 | } |
201 | } | 128 | } |
202 | 129 | ||
203 | /// <summary> | 130 | /// <summary> |
204 | /// Adds a backreference so presence specific data doesn't have to be | 131 | /// Does the necessary work to subscribe one agent to another's presence notifications |
205 | /// enumerated for each logged in user every time someone logs on or off. | 132 | /// Gets called by ProcessFriendListSubscriptions. You shouldn't call this directly |
133 | /// unless you know what you're doing | ||
206 | /// </summary> | 134 | /// </summary> |
207 | /// <param name="agentID"></param> | 135 | /// <param name="userpresence">P1</param> |
208 | /// <param name="friendID"></param> | 136 | /// <param name="friendpresence">P2</param> |
209 | public void addBackReference(UUID agentID, UUID friendID) | 137 | /// <param name="uFriendListItem"></param> |
138 | private void SubscribeToPresenceUpdates(UserPresenceData userpresence, | ||
139 | UserPresenceData friendpresence, | ||
140 | FriendListItem uFriendListItem) | ||
210 | { | 141 | { |
211 | if (m_presence_BackReferences.Contains(friendID)) | 142 | // Can the friend see me online? |
143 | if ((uFriendListItem.FriendListOwnerPerms & (uint)FriendRights.CanSeeOnline) != 0) | ||
212 | { | 144 | { |
213 | List<UUID> presenseBackReferences = (List<UUID>)m_presence_BackReferences[friendID]; | 145 | // tell user to update friend about user's presence changes |
214 | if (!presenseBackReferences.Contains(agentID)) | 146 | if (!userpresence.subscriptionData.Contains(friendpresence.agentData.AgentID)) |
215 | { | 147 | { |
216 | presenseBackReferences.Add(agentID); | 148 | userpresence.subscriptionData.Add(friendpresence.agentData.AgentID); |
217 | } | 149 | } |
218 | m_presence_BackReferences[friendID] = presenseBackReferences; | 150 | |
219 | } | 151 | // send an update about user's presence to the friend |
220 | else | 152 | enqueuePresenceUpdate(userpresence, friendpresence); |
221 | { | ||
222 | List<UUID> presenceBackReferences = new List<UUID>(); | ||
223 | presenceBackReferences.Add(agentID); | ||
224 | m_presence_BackReferences[friendID] = presenceBackReferences; | ||
225 | } | 153 | } |
226 | } | ||
227 | 154 | ||
228 | /// <summary> | 155 | // Can I see the friend online? |
229 | /// Removes a backreference to free up some memory | 156 | if ((uFriendListItem.FriendPerms & (uint)FriendRights.CanSeeOnline) != 0) |
230 | /// </summary> | ||
231 | /// <param name="agentID"></param> | ||
232 | /// <param name="friendID"></param> | ||
233 | public void removeBackReference(UUID agentID, UUID friendID) | ||
234 | { | ||
235 | if (m_presence_BackReferences.Contains(friendID)) | ||
236 | { | 157 | { |
237 | List<UUID> presenseBackReferences = (List<UUID>)m_presence_BackReferences[friendID]; | 158 | // tell friend to update user about friend's presence changes |
238 | if (presenseBackReferences.Contains(agentID)) | 159 | if (!friendpresence.subscriptionData.Contains(userpresence.agentData.AgentID)) |
239 | { | 160 | { |
240 | presenseBackReferences.Remove(agentID); | 161 | friendpresence.subscriptionData.Add(userpresence.agentData.AgentID); |
241 | } | 162 | } |
242 | 163 | ||
243 | // If there are no more backreferences for this agent, | 164 | // send an update about friend's presence to user. |
244 | // remove it to free up memory. | 165 | enqueuePresenceUpdate(friendpresence, userpresence); |
245 | if (presenseBackReferences.Count == 0) | ||
246 | { | ||
247 | m_presence_BackReferences.Remove(agentID); | ||
248 | } | ||
249 | } | 166 | } |
250 | } | 167 | } |
251 | 168 | ||
@@ -256,90 +173,42 @@ namespace OpenSim.Grid.MessagingServer | |||
256 | private void ProcessLogOff(UUID AgentID) | 173 | private void ProcessLogOff(UUID AgentID) |
257 | { | 174 | { |
258 | m_log.Info("[LOGOFF]: Processing Logoff"); | 175 | m_log.Info("[LOGOFF]: Processing Logoff"); |
259 | UserPresenceData AgentData = null; | 176 | |
260 | List<UUID> AgentsNeedingNotification = new List<UUID>(); | 177 | UserPresenceData userPresence = null; |
261 | UserPresenceData friendd = null; | ||
262 | lock (m_presences) | 178 | lock (m_presences) |
263 | { | 179 | { |
264 | if (m_presences.Contains(AgentID)) | 180 | m_presences.TryGetValue(AgentID, out userPresence); |
265 | { | ||
266 | AgentData = (UserPresenceData)m_presences[AgentID]; | ||
267 | } | ||
268 | } | 181 | } |
269 | 182 | ||
270 | if (AgentData != null) | 183 | if (userPresence != null) // found the user |
271 | { | 184 | { |
272 | AgentsNeedingNotification = AgentData.subscriptionData; | 185 | List<UUID> AgentsNeedingNotification = userPresence.subscriptionData; |
273 | AgentData.OnlineYN = false; | 186 | userPresence.OnlineYN = false; |
274 | //lock (m_presence_BackReferences) | ||
275 | //{ | ||
276 | //if (m_presence_BackReferences.Contains(AgentID)) | ||
277 | //{ | ||
278 | //AgentsNeedingNotification = (List<UUID>)m_presence_BackReferences[AgentID]; | ||
279 | //} | ||
280 | //} | ||
281 | 187 | ||
282 | for (int i = 0; i < AgentsNeedingNotification.Count; i++) | 188 | for (int i = 0; i < AgentsNeedingNotification.Count; i++) |
283 | { | 189 | { |
284 | // TODO: Do Region Notifications | 190 | UserPresenceData friendPresence = null; |
285 | lock (m_presences) | 191 | lock (m_presences) |
286 | { | 192 | { |
287 | if (m_presences.Contains(AgentsNeedingNotification[i])) | 193 | m_presences.TryGetValue(AgentsNeedingNotification[i], out friendPresence); |
288 | { | ||
289 | friendd = (UserPresenceData)m_presences[AgentsNeedingNotification[i]]; | ||
290 | } | ||
291 | } | 194 | } |
292 | 195 | ||
293 | // This might need to be enumerated and checked before we try to remove it. | 196 | // This might need to be enumerated and checked before we try to remove it. |
294 | if (friendd != null) | 197 | if (friendPresence != null) |
295 | { | 198 | { |
296 | lock (friendd) | 199 | lock (friendPresence) |
297 | { | 200 | { |
298 | friendd.subscriptionData.Remove(AgentID); | 201 | // no updates for this user anymore |
202 | friendPresence.subscriptionData.Remove(AgentID); | ||
299 | 203 | ||
300 | List<FriendListItem> fl = friendd.friendData; | 204 | // set user's entry in the friend's list to offline (if it exists) |
301 | for (int j = 0; j < fl.Count; j++) | 205 | if (friendPresence.friendData.ContainsKey(AgentID)) |
302 | { | 206 | { |
303 | if (fl[j].Friend == AgentID) | 207 | friendPresence.friendData[AgentID].onlinestatus = false; |
304 | { | ||
305 | fl[j].onlinestatus = false; | ||
306 | } | ||
307 | } | 208 | } |
308 | |||
309 | friendd.friendData = fl; | ||
310 | m_presences[AgentsNeedingNotification[i]] = friendd; | ||
311 | } | ||
312 | |||
313 | UserAgentData p2Handle = m_userManager.GetUserAgentData(friendd.agentData.AgentID); | ||
314 | if (p2Handle != null) | ||
315 | { | ||
316 | |||
317 | |||
318 | friendd.regionData.regionHandle = p2Handle.Handle; | ||
319 | PresenceInformer friendlistupdater = new PresenceInformer(); | ||
320 | friendlistupdater.presence1 = AgentData; | ||
321 | friendlistupdater.presence2 = friendd; | ||
322 | |||
323 | //friendlistupdater.gridserverurl = m_cfg.GridServerURL; | ||
324 | //friendlistupdater.gridserversendkey = m_cfg.GridSendKey; | ||
325 | //friendlistupdater.gridserverrecvkey = m_cfg.GridRecvKey; | ||
326 | |||
327 | friendlistupdater.OnGetRegionData += GetRegionInfo; | ||
328 | friendlistupdater.OnDone += PresenceUpdateDone; | ||
329 | |||
330 | WaitCallback cb3 = new WaitCallback(friendlistupdater.go); | ||
331 | ThreadPool.QueueUserWorkItem(cb3); | ||
332 | |||
333 | |||
334 | |||
335 | } | ||
336 | else | ||
337 | { | ||
338 | // skip, agent can't be found | ||
339 | } | 209 | } |
340 | //SendRegionPresenceUpdate(AgentData, friendd); | ||
341 | 210 | ||
342 | //removeBackReference(AgentID, AgentsNeedingNotification[i]); | 211 | enqueuePresenceUpdate(userPresence, friendPresence); |
343 | } | 212 | } |
344 | } | 213 | } |
345 | } | 214 | } |
@@ -347,7 +216,7 @@ namespace OpenSim.Grid.MessagingServer | |||
347 | 216 | ||
348 | #endregion | 217 | #endregion |
349 | 218 | ||
350 | public void PresenceUpdateDone(PresenceInformer obj) | 219 | private void PresenceUpdateDone(PresenceInformer obj) |
351 | { | 220 | { |
352 | obj.OnGetRegionData -= GetRegionInfo; | 221 | obj.OnGetRegionData -= GetRegionInfo; |
353 | obj.OnDone -= PresenceUpdateDone; | 222 | obj.OnDone -= PresenceUpdateDone; |
@@ -356,12 +225,13 @@ namespace OpenSim.Grid.MessagingServer | |||
356 | #region UserServer Comms | 225 | #region UserServer Comms |
357 | 226 | ||
358 | /// <summary> | 227 | /// <summary> |
359 | /// Returns a list of FriendsListItems that describe the friends and permissions in the friend relationship for UUID friendslistowner | 228 | /// Returns a list of FriendsListItems that describe the friends and permissions in the friend |
229 | /// relationship for UUID friendslistowner. For faster lookup, we index by friend's UUID. | ||
360 | /// </summary> | 230 | /// </summary> |
361 | /// <param name="friendlistowner">The agent that we're retreiving the friends Data.</param> | 231 | /// <param name="friendlistowner">The agent that we're retreiving the friends Data for.</param> |
362 | public List<FriendListItem> GetUserFriendList(UUID friendlistowner) | 232 | private Dictionary<UUID, FriendListItem> GetUserFriendList(UUID friendlistowner) |
363 | { | 233 | { |
364 | List<FriendListItem> buddylist = new List<FriendListItem>(); | 234 | Dictionary<UUID, FriendListItem> buddies = new Dictionary<UUID,FriendListItem>(); |
365 | 235 | ||
366 | try | 236 | try |
367 | { | 237 | { |
@@ -376,7 +246,7 @@ namespace OpenSim.Grid.MessagingServer | |||
376 | 246 | ||
377 | if (respData.Contains("avcount")) | 247 | if (respData.Contains("avcount")) |
378 | { | 248 | { |
379 | buddylist = ConvertXMLRPCDataToFriendListItemList(respData); | 249 | buddies = ConvertXMLRPCDataToFriendListItemList(respData); |
380 | } | 250 | } |
381 | 251 | ||
382 | } | 252 | } |
@@ -386,7 +256,7 @@ namespace OpenSim.Grid.MessagingServer | |||
386 | e.Message); | 256 | e.Message); |
387 | // Return Empty list (no friends) | 257 | // Return Empty list (no friends) |
388 | } | 258 | } |
389 | return buddylist; | 259 | return buddies; |
390 | } | 260 | } |
391 | 261 | ||
392 | /// <summary> | 262 | /// <summary> |
@@ -394,9 +264,9 @@ namespace OpenSim.Grid.MessagingServer | |||
394 | /// </summary> | 264 | /// </summary> |
395 | /// <param name="data">XMLRPC response data Hashtable</param> | 265 | /// <param name="data">XMLRPC response data Hashtable</param> |
396 | /// <returns></returns> | 266 | /// <returns></returns> |
397 | public List<FriendListItem> ConvertXMLRPCDataToFriendListItemList(Hashtable data) | 267 | public Dictionary<UUID, FriendListItem> ConvertXMLRPCDataToFriendListItemList(Hashtable data) |
398 | { | 268 | { |
399 | List<FriendListItem> buddylist = new List<FriendListItem>(); | 269 | Dictionary<UUID, FriendListItem> buddies = new Dictionary<UUID,FriendListItem>(); |
400 | int buddycount = Convert.ToInt32((string)data["avcount"]); | 270 | int buddycount = Convert.ToInt32((string)data["avcount"]); |
401 | 271 | ||
402 | for (int i = 0; i < buddycount; i++) | 272 | for (int i = 0; i < buddycount; i++) |
@@ -408,10 +278,10 @@ namespace OpenSim.Grid.MessagingServer | |||
408 | buddylistitem.FriendListOwnerPerms = (uint)Convert.ToInt32((string)data["ownerPerms" + i.ToString()]); | 278 | buddylistitem.FriendListOwnerPerms = (uint)Convert.ToInt32((string)data["ownerPerms" + i.ToString()]); |
409 | buddylistitem.FriendPerms = (uint)Convert.ToInt32((string)data["friendPerms" + i.ToString()]); | 279 | buddylistitem.FriendPerms = (uint)Convert.ToInt32((string)data["friendPerms" + i.ToString()]); |
410 | 280 | ||
411 | buddylist.Add(buddylistitem); | 281 | buddies.Add(buddylistitem.Friend, buddylistitem); |
412 | } | 282 | } |
413 | 283 | ||
414 | return buddylist; | 284 | return buddies; |
415 | } | 285 | } |
416 | 286 | ||
417 | /// <summary> | 287 | /// <summary> |
@@ -423,20 +293,8 @@ namespace OpenSim.Grid.MessagingServer | |||
423 | /// <returns></returns> | 293 | /// <returns></returns> |
424 | public XmlRpcResponse UserLoggedOn(XmlRpcRequest request) | 294 | public XmlRpcResponse UserLoggedOn(XmlRpcRequest request) |
425 | { | 295 | { |
426 | m_log.Info("[LOGON]: User logged on, building indexes for user"); | ||
427 | Hashtable requestData = (Hashtable)request.Params[0]; | 296 | Hashtable requestData = (Hashtable)request.Params[0]; |
428 | 297 | ||
429 | //requestData["sendkey"] = serv.sendkey; | ||
430 | //requestData["agentid"] = agentID.ToString(); | ||
431 | //requestData["sessionid"] = sessionID.ToString(); | ||
432 | //requestData["regionid"] = RegionID.ToString(); | ||
433 | //requestData["regionhandle"] = regionhandle.ToString(); | ||
434 | //requestData["positionx"] = positionX.ToString(); | ||
435 | //requestData["positiony"] = positionY.ToString(); | ||
436 | //requestData["positionz"] = positionZ.ToString(); | ||
437 | //requestData["firstname"] = firstname; | ||
438 | //requestData["lastname"] = lastname; | ||
439 | |||
440 | AgentCircuitData agentData = new AgentCircuitData(); | 298 | AgentCircuitData agentData = new AgentCircuitData(); |
441 | agentData.SessionID = new UUID((string)requestData["sessionid"]); | 299 | agentData.SessionID = new UUID((string)requestData["sessionid"]); |
442 | agentData.SecureSessionID = new UUID((string)requestData["secure_session_id"]); | 300 | agentData.SecureSessionID = new UUID((string)requestData["secure_session_id"]); |
@@ -461,12 +319,13 @@ namespace OpenSim.Grid.MessagingServer | |||
461 | 319 | ||
462 | ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); | 320 | ulong regionHandle = Convert.ToUInt64((string)requestData["regionhandle"]); |
463 | 321 | ||
322 | m_log.InfoFormat("[LOGON]: User {0} {1} logged into region {2} as {3} agent, building indexes for user", | ||
323 | agentData.firstname, agentData.lastname, regionHandle, agentData.child ? "child" : "root"); | ||
324 | |||
464 | UserPresenceData up = new UserPresenceData(); | 325 | UserPresenceData up = new UserPresenceData(); |
465 | up.agentData = agentData; | 326 | up.agentData = agentData; |
466 | List<FriendListItem> flData = GetUserFriendList(agentData.AgentID); | 327 | up.friendData = GetUserFriendList(agentData.AgentID); |
467 | up.friendData = flData; | 328 | up.regionData = GetRegionInfo(regionHandle); |
468 | RegionProfileData riData = GetRegionInfo(regionHandle); | ||
469 | up.regionData = riData; | ||
470 | up.OnlineYN = true; | 329 | up.OnlineYN = true; |
471 | up.lookupUserRegionYN = false; | 330 | up.lookupUserRegionYN = false; |
472 | ProcessFriendListSubscriptions(up); | 331 | ProcessFriendListSubscriptions(up); |
@@ -486,7 +345,6 @@ namespace OpenSim.Grid.MessagingServer | |||
486 | Hashtable requestData = (Hashtable)request.Params[0]; | 345 | Hashtable requestData = (Hashtable)request.Params[0]; |
487 | 346 | ||
488 | UUID AgentID = new UUID((string)requestData["agentid"]); | 347 | UUID AgentID = new UUID((string)requestData["agentid"]); |
489 | |||
490 | ProcessLogOff(AgentID); | 348 | ProcessLogOff(AgentID); |
491 | 349 | ||
492 | return new XmlRpcResponse(); | 350 | return new XmlRpcResponse(); |
@@ -494,6 +352,49 @@ namespace OpenSim.Grid.MessagingServer | |||
494 | 352 | ||
495 | #endregion | 353 | #endregion |
496 | 354 | ||
355 | public XmlRpcResponse GetPresenceInfoBulk(XmlRpcRequest request) | ||
356 | { | ||
357 | Hashtable paramHash = (Hashtable)request.Params[0]; | ||
358 | Hashtable result = new Hashtable(); | ||
359 | |||
360 | // TODO check access (recv_key/send_key) | ||
361 | |||
362 | IList list = (IList)paramHash["uuids"]; | ||
363 | |||
364 | // convert into List<UUID> | ||
365 | List<UUID> uuids = new List<UUID>(); | ||
366 | for (int i = 0; i < list.Count; ++i) | ||
367 | { | ||
368 | UUID uuid; | ||
369 | if (UUID.TryParse((string)list[i], out uuid)) | ||
370 | { | ||
371 | uuids.Add(uuid); | ||
372 | } | ||
373 | } | ||
374 | |||
375 | try { | ||
376 | Dictionary<UUID, FriendRegionInfo> infos = m_userManager.GetFriendRegionInfos(uuids); | ||
377 | m_log.DebugFormat("[FRIEND]: Got {0} region entries back.", infos.Count); | ||
378 | int count = 0; | ||
379 | foreach (KeyValuePair<UUID, FriendRegionInfo> pair in infos) | ||
380 | { | ||
381 | result["uuid_" + count] = pair.Key.ToString(); | ||
382 | result["isOnline_" + count] = pair.Value.isOnline; | ||
383 | result["regionHandle_" + count] = pair.Value.regionHandle.ToString(); // XML-RPC doesn't know ulongs | ||
384 | ++count; | ||
385 | } | ||
386 | result["count"] = count; | ||
387 | |||
388 | XmlRpcResponse response = new XmlRpcResponse(); | ||
389 | response.Value = result; | ||
390 | return response; | ||
391 | } | ||
392 | catch(Exception e) { | ||
393 | m_log.Error("Got exception:", e); | ||
394 | throw e; | ||
395 | } | ||
396 | } | ||
397 | |||
497 | #region regioninfo gathering | 398 | #region regioninfo gathering |
498 | 399 | ||
499 | /// <summary> | 400 | /// <summary> |
@@ -506,37 +407,21 @@ namespace OpenSim.Grid.MessagingServer | |||
506 | public RegionProfileData GetRegionInfo(ulong regionhandle) | 407 | public RegionProfileData GetRegionInfo(ulong regionhandle) |
507 | { | 408 | { |
508 | RegionProfileData regionInfo = null; | 409 | RegionProfileData regionInfo = null; |
509 | bool lookup = false; | ||
510 | 410 | ||
511 | lock (m_regionInfoCache) | 411 | lock (m_regionInfoCache) |
512 | { | 412 | { |
513 | if (m_regionInfoCache.Contains(regionhandle)) | 413 | m_regionInfoCache.TryGetValue(regionhandle, out regionInfo); |
514 | { | ||
515 | regionInfo = (RegionProfileData)m_regionInfoCache[regionhandle]; | ||
516 | } | ||
517 | else | ||
518 | { | ||
519 | // Don't lock the cache while we're looking up the region! | ||
520 | lookup = true; | ||
521 | } | ||
522 | } | 414 | } |
523 | 415 | ||
524 | if (lookup) | 416 | if (regionInfo == null) // not found in cache |
525 | { | 417 | { |
526 | regionInfo = RequestRegionInfo(regionhandle); | 418 | regionInfo = RequestRegionInfo(regionhandle); |
527 | 419 | ||
528 | if (regionInfo != null) | 420 | if (regionInfo != null) // lookup was successful |
529 | { | 421 | { |
530 | lock (m_regionInfoCache) | 422 | lock (m_regionInfoCache) |
531 | { | 423 | { |
532 | if (m_regionInfoCache.Contains(regionhandle)) | 424 | m_regionInfoCache[regionhandle] = regionInfo; |
533 | { | ||
534 | m_regionInfoCache[regionhandle] = regionInfo; | ||
535 | } | ||
536 | else | ||
537 | { | ||
538 | m_regionInfoCache.Add(regionhandle, regionInfo); | ||
539 | } | ||
540 | } | 425 | } |
541 | } | 426 | } |
542 | } | 427 | } |
@@ -558,21 +443,25 @@ namespace OpenSim.Grid.MessagingServer | |||
558 | } | 443 | } |
559 | 444 | ||
560 | /// <summary> | 445 | /// <summary> |
561 | /// Get RegionProfileData from the GridServer | 446 | /// Get RegionProfileData from the GridServer. |
562 | /// We'll Cache this information and use it for presence updates | 447 | /// We'll cache this information in GetRegionInfo and use it for presence updates |
563 | /// </summary> | 448 | /// </summary> |
564 | /// <param name="regionHandle"></param> | 449 | /// <param name="regionHandle"></param> |
565 | /// <returns></returns> | 450 | /// <returns></returns> |
566 | public RegionProfileData RequestRegionInfo(ulong regionHandle) | 451 | public RegionProfileData RequestRegionInfo(ulong regionHandle) |
567 | { RegionProfileData regionProfile = null; | 452 | { |
453 | RegionProfileData regionProfile = null; | ||
568 | try | 454 | try |
569 | { | 455 | { |
570 | Hashtable requestData = new Hashtable(); | 456 | Hashtable requestData = new Hashtable(); |
571 | requestData["region_handle"] = regionHandle.ToString(); | 457 | requestData["region_handle"] = regionHandle.ToString(); |
572 | requestData["authkey"] = m_cfg.GridSendKey; | 458 | requestData["authkey"] = m_cfg.GridSendKey; |
459 | |||
573 | ArrayList SendParams = new ArrayList(); | 460 | ArrayList SendParams = new ArrayList(); |
574 | SendParams.Add(requestData); | 461 | SendParams.Add(requestData); |
462 | |||
575 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); | 463 | XmlRpcRequest GridReq = new XmlRpcRequest("simulator_data_request", SendParams); |
464 | |||
576 | XmlRpcResponse GridResp = GridReq.Send(m_cfg.GridServerURL, 3000); | 465 | XmlRpcResponse GridResp = GridReq.Send(m_cfg.GridServerURL, 3000); |
577 | 466 | ||
578 | Hashtable responseData = (Hashtable)GridResp.Value; | 467 | Hashtable responseData = (Hashtable)GridResp.Value; |
@@ -586,9 +475,6 @@ namespace OpenSim.Grid.MessagingServer | |||
586 | uint regX = Convert.ToUInt32((string)responseData["region_locx"]); | 475 | uint regX = Convert.ToUInt32((string)responseData["region_locx"]); |
587 | uint regY = Convert.ToUInt32((string)responseData["region_locy"]); | 476 | uint regY = Convert.ToUInt32((string)responseData["region_locy"]); |
588 | string internalIpStr = (string)responseData["sim_ip"]; | 477 | string internalIpStr = (string)responseData["sim_ip"]; |
589 | // uint port = Convert.ToUInt32(responseData["sim_port"]); | ||
590 | // string externalUri = (string)responseData["sim_uri"]; | ||
591 | // string neighbourExternalUri = externalUri; | ||
592 | 478 | ||
593 | regionProfile = new RegionProfileData(); | 479 | regionProfile = new RegionProfileData(); |
594 | regionProfile.httpPort = (uint)Convert.ToInt32((string)responseData["http_port"]); | 480 | regionProfile.httpPort = (uint)Convert.ToInt32((string)responseData["http_port"]); |
@@ -600,20 +486,12 @@ namespace OpenSim.Grid.MessagingServer | |||
600 | regionProfile.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); | 486 | regionProfile.remotingPort = Convert.ToUInt32((string)responseData["remoting_port"]); |
601 | regionProfile.UUID = new UUID((string)responseData["region_UUID"]); | 487 | regionProfile.UUID = new UUID((string)responseData["region_UUID"]); |
602 | regionProfile.regionName = (string)responseData["region_name"]; | 488 | regionProfile.regionName = (string)responseData["region_name"]; |
603 | lock (m_regionInfoCache) | ||
604 | { | ||
605 | if (!m_regionInfoCache.Contains(regionHandle)) | ||
606 | { | ||
607 | m_regionInfoCache.Add(regionHandle, regionProfile); | ||
608 | } | ||
609 | } | ||
610 | } | 489 | } |
611 | catch (WebException) | 490 | catch (WebException) |
612 | { | 491 | { |
613 | m_log.Error("[GRID]: " + | 492 | m_log.Error("[GRID]: " + |
614 | "Region lookup failed for: " + regionHandle.ToString() + | 493 | "Region lookup failed for: " + regionHandle.ToString() + |
615 | " - Is the GridServer down?"); | 494 | " - Is the GridServer down?"); |
616 | return null; | ||
617 | } | 495 | } |
618 | 496 | ||
619 | return regionProfile; | 497 | return regionProfile; |
@@ -641,29 +519,20 @@ namespace OpenSim.Grid.MessagingServer | |||
641 | SendParams.Add(UserParams); | 519 | SendParams.Add(UserParams); |
642 | 520 | ||
643 | // Send Request | 521 | // Send Request |
644 | XmlRpcRequest UserReq; | ||
645 | XmlRpcResponse UserResp; | ||
646 | try | 522 | try |
647 | { | 523 | { |
648 | UserReq = new XmlRpcRequest("register_messageserver", SendParams); | 524 | XmlRpcRequest UserReq = new XmlRpcRequest("register_messageserver", SendParams); |
649 | UserResp = UserReq.Send(m_cfg.UserServerURL, 16000); | 525 | XmlRpcResponse UserResp = UserReq.Send(m_cfg.UserServerURL, 16000); |
650 | } catch (Exception ex) | ||
651 | { | ||
652 | m_log.Error("Unable to connect to grid. Grid server not running?"); | ||
653 | throw(ex); | ||
654 | } | ||
655 | Hashtable GridRespData = (Hashtable)UserResp.Value; | ||
656 | // Hashtable griddatahash = GridRespData; | ||
657 | |||
658 | // Process Response | ||
659 | if (GridRespData.ContainsKey("responsestring")) | ||
660 | { | ||
661 | 526 | ||
662 | return true; | 527 | // Process Response |
528 | Hashtable GridRespData = (Hashtable)UserResp.Value; | ||
529 | // if we got a response, we were successful | ||
530 | return GridRespData.ContainsKey("responsestring"); | ||
663 | } | 531 | } |
664 | else | 532 | catch (Exception ex) |
665 | { | 533 | { |
666 | return false; | 534 | m_log.Error("Unable to connect to grid. User server not running?"); |
535 | throw(ex); | ||
667 | } | 536 | } |
668 | } | 537 | } |
669 | 538 | ||
@@ -689,30 +558,20 @@ namespace OpenSim.Grid.MessagingServer | |||
689 | SendParams.Add(UserParams); | 558 | SendParams.Add(UserParams); |
690 | 559 | ||
691 | // Send Request | 560 | // Send Request |
692 | XmlRpcRequest UserReq; | ||
693 | XmlRpcResponse UserResp; | ||
694 | try | 561 | try |
695 | { | 562 | { |
696 | UserReq = new XmlRpcRequest("deregister_messageserver", SendParams); | 563 | XmlRpcRequest UserReq = new XmlRpcRequest("deregister_messageserver", SendParams); |
697 | UserResp = UserReq.Send(m_cfg.UserServerURL, 16000); | 564 | XmlRpcResponse UserResp = UserReq.Send(m_cfg.UserServerURL, 16000); |
565 | // Process Response | ||
566 | Hashtable UserRespData = (Hashtable)UserResp.Value; | ||
567 | // if we got a response, we were successful | ||
568 | return UserRespData.ContainsKey("responsestring"); | ||
698 | } | 569 | } |
699 | catch (Exception ex) | 570 | catch (Exception ex) |
700 | { | 571 | { |
701 | m_log.Error("Unable to connect to grid. Grid server not running?"); | 572 | m_log.Error("Unable to connect to grid. User server not running?"); |
702 | throw (ex); | 573 | throw (ex); |
703 | } | 574 | } |
704 | Hashtable UserRespData = (Hashtable)UserResp.Value; | ||
705 | // Hashtable userdatahash = UserRespData; | ||
706 | |||
707 | // Process Response | ||
708 | if (UserRespData.ContainsKey("responsestring")) | ||
709 | { | ||
710 | return true; | ||
711 | } | ||
712 | else | ||
713 | { | ||
714 | return false; | ||
715 | } | ||
716 | } | 575 | } |
717 | 576 | ||
718 | #endregion | 577 | #endregion |