diff options
author | John Hurliman | 2010-09-09 14:45:10 -0700 |
---|---|---|
committer | John Hurliman | 2010-09-09 14:45:10 -0700 |
commit | 8415b988063234ab7686b873520708891bca50a6 (patch) | |
tree | 136312e2ceca296731dbedf6109528497a53ebe1 /OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC_OLD-8415b988063234ab7686b873520708891bca50a6.zip opensim-SC_OLD-8415b988063234ab7686b873520708891bca50a6.tar.gz opensim-SC_OLD-8415b988063234ab7686b873520708891bca50a6.tar.bz2 opensim-SC_OLD-8415b988063234ab7686b873520708891bca50a6.tar.xz |
Over a dozen thread safety fixes in FriendsModule
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 330 |
1 files changed, 163 insertions, 167 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 1c1ba2d..4e4eee9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | |||
@@ -54,7 +54,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
54 | public UUID PrincipalID; | 54 | public UUID PrincipalID; |
55 | public FriendInfo[] Friends; | 55 | public FriendInfo[] Friends; |
56 | public int Refcount; | 56 | public int Refcount; |
57 | public UUID RegionID; | ||
58 | 57 | ||
59 | public bool IsFriend(string friend) | 58 | public bool IsFriend(string friend) |
60 | { | 59 | { |
@@ -67,7 +66,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
67 | return false; | 66 | return false; |
68 | } | 67 | } |
69 | } | 68 | } |
70 | 69 | ||
70 | private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; | ||
71 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 71 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
72 | 72 | ||
73 | protected List<Scene> m_Scenes = new List<Scene>(); | 73 | protected List<Scene> m_Scenes = new List<Scene>(); |
@@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
79 | protected Dictionary<UUID, UserFriendData> m_Friends = | 79 | protected Dictionary<UUID, UserFriendData> m_Friends = |
80 | new Dictionary<UUID, UserFriendData>(); | 80 | new Dictionary<UUID, UserFriendData>(); |
81 | 81 | ||
82 | protected List<UUID> m_NeedsListOfFriends = new List<UUID>(); | 82 | protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>(); |
83 | 83 | ||
84 | protected IPresenceService PresenceService | 84 | protected IPresenceService PresenceService |
85 | { | 85 | { |
@@ -146,7 +146,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
146 | // Instantiate the request handler | 146 | // Instantiate the request handler |
147 | IHttpServer server = MainServer.GetHttpServer((uint)mPort); | 147 | IHttpServer server = MainServer.GetHttpServer((uint)mPort); |
148 | server.AddStreamHandler(new FriendsRequestHandler(this)); | 148 | server.AddStreamHandler(new FriendsRequestHandler(this)); |
149 | |||
150 | } | 149 | } |
151 | 150 | ||
152 | if (m_FriendsService == null) | 151 | if (m_FriendsService == null) |
@@ -173,7 +172,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
173 | scene.EventManager.OnNewClient += OnNewClient; | 172 | scene.EventManager.OnNewClient += OnNewClient; |
174 | scene.EventManager.OnClientClosed += OnClientClosed; | 173 | scene.EventManager.OnClientClosed += OnClientClosed; |
175 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; | 174 | scene.EventManager.OnMakeRootAgent += OnMakeRootAgent; |
176 | scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; | ||
177 | scene.EventManager.OnClientLogin += OnClientLogin; | 175 | scene.EventManager.OnClientLogin += OnClientLogin; |
178 | } | 176 | } |
179 | 177 | ||
@@ -198,16 +196,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
198 | 196 | ||
199 | public uint GetFriendPerms(UUID principalID, UUID friendID) | 197 | public uint GetFriendPerms(UUID principalID, UUID friendID) |
200 | { | 198 | { |
201 | if (!m_Friends.ContainsKey(principalID)) | 199 | FriendInfo[] friends = GetFriends(principalID); |
202 | return 0; | 200 | foreach (FriendInfo fi in friends) |
203 | |||
204 | UserFriendData data = m_Friends[principalID]; | ||
205 | |||
206 | foreach (FriendInfo fi in data.Friends) | ||
207 | { | 201 | { |
208 | if (fi.Friend == friendID.ToString()) | 202 | if (fi.Friend == friendID.ToString()) |
209 | return (uint)fi.TheirFlags; | 203 | return (uint)fi.TheirFlags; |
210 | } | 204 | } |
205 | |||
211 | return 0; | 206 | return 0; |
212 | } | 207 | } |
213 | 208 | ||
@@ -217,73 +212,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
217 | client.OnApproveFriendRequest += OnApproveFriendRequest; | 212 | client.OnApproveFriendRequest += OnApproveFriendRequest; |
218 | client.OnDenyFriendRequest += OnDenyFriendRequest; | 213 | client.OnDenyFriendRequest += OnDenyFriendRequest; |
219 | client.OnTerminateFriendship += OnTerminateFriendship; | 214 | client.OnTerminateFriendship += OnTerminateFriendship; |
220 | |||
221 | client.OnGrantUserRights += OnGrantUserRights; | 215 | client.OnGrantUserRights += OnGrantUserRights; |
222 | 216 | ||
223 | lock (m_Friends) | 217 | // Asynchronously fetch the friends list or increment the refcount for the existing |
224 | { | 218 | // friends list |
225 | if (m_Friends.ContainsKey(client.AgentId)) | 219 | Util.FireAndForget( |
220 | delegate(object o) | ||
226 | { | 221 | { |
227 | m_Friends[client.AgentId].Refcount++; | 222 | lock (m_Friends) |
228 | return; | 223 | { |
229 | } | 224 | UserFriendData friendsData; |
230 | 225 | if (m_Friends.TryGetValue(client.AgentId, out friendsData)) | |
231 | UserFriendData newFriends = new UserFriendData(); | 226 | { |
232 | 227 | friendsData.Refcount++; | |
233 | newFriends.PrincipalID = client.AgentId; | 228 | } |
234 | newFriends.Friends = m_FriendsService.GetFriends(client.AgentId); | 229 | else |
235 | newFriends.Refcount = 1; | 230 | { |
236 | newFriends.RegionID = UUID.Zero; | 231 | friendsData = new UserFriendData(); |
232 | friendsData.PrincipalID = client.AgentId; | ||
233 | friendsData.Friends = FriendsService.GetFriends(client.AgentId); | ||
234 | friendsData.Refcount = 1; | ||
237 | 235 | ||
238 | m_Friends.Add(client.AgentId, newFriends); | 236 | m_Friends[client.AgentId] = friendsData; |
239 | } | 237 | } |
240 | 238 | } | |
239 | } | ||
240 | ); | ||
241 | } | 241 | } |
242 | 242 | ||
243 | private void OnClientClosed(UUID agentID, Scene scene) | 243 | private void OnClientClosed(UUID agentID, Scene scene) |
244 | { | 244 | { |
245 | ScenePresence sp = scene.GetScenePresence(agentID); | 245 | ScenePresence sp = scene.GetScenePresence(agentID); |
246 | if (sp != null && !sp.IsChildAgent) | 246 | if (sp != null && !sp.IsChildAgent) |
247 | { | ||
247 | // do this for root agents closing out | 248 | // do this for root agents closing out |
248 | StatusChange(agentID, false); | 249 | StatusChange(agentID, false); |
250 | } | ||
249 | 251 | ||
250 | lock (m_Friends) | 252 | lock (m_Friends) |
251 | if (m_Friends.ContainsKey(agentID)) | 253 | { |
254 | UserFriendData friendsData; | ||
255 | if (m_Friends.TryGetValue(agentID, out friendsData)) | ||
252 | { | 256 | { |
253 | if (m_Friends[agentID].Refcount == 1) | 257 | friendsData.Refcount--; |
258 | if (friendsData.Refcount <= 0) | ||
254 | m_Friends.Remove(agentID); | 259 | m_Friends.Remove(agentID); |
255 | else | ||
256 | m_Friends[agentID].Refcount--; | ||
257 | } | 260 | } |
258 | } | ||
259 | |||
260 | private void OnMakeRootAgent(ScenePresence sp) | ||
261 | { | ||
262 | UUID agentID = sp.ControllingClient.AgentId; | ||
263 | |||
264 | if (m_Friends.ContainsKey(agentID)) | ||
265 | { | ||
266 | // This is probably an overkill, but just | ||
267 | // to make sure we have the latest and greatest | ||
268 | // friends list -- always pull OnMakeRoot | ||
269 | m_Friends[agentID].Friends = | ||
270 | m_FriendsService.GetFriends(agentID); | ||
271 | |||
272 | m_Friends[agentID].RegionID = | ||
273 | sp.ControllingClient.Scene.RegionInfo.RegionID; | ||
274 | } | 261 | } |
275 | } | 262 | } |
276 | 263 | ||
277 | 264 | private void OnMakeRootAgent(ScenePresence sp) | |
278 | private void OnMakeChildAgent(ScenePresence sp) | ||
279 | { | 265 | { |
280 | UUID agentID = sp.ControllingClient.AgentId; | 266 | UUID agentID = sp.ControllingClient.AgentId; |
281 | 267 | UpdateFriendsCache(agentID); | |
282 | if (m_Friends.ContainsKey(agentID)) | ||
283 | { | ||
284 | if (m_Friends[agentID].RegionID == sp.ControllingClient.Scene.RegionInfo.RegionID) | ||
285 | m_Friends[agentID].RegionID = UUID.Zero; | ||
286 | } | ||
287 | } | 268 | } |
288 | 269 | ||
289 | private void OnClientLogin(IClientAPI client) | 270 | private void OnClientLogin(IClientAPI client) |
@@ -295,72 +276,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
295 | 276 | ||
296 | // Register that we need to send the list of online friends to this user | 277 | // Register that we need to send the list of online friends to this user |
297 | lock (m_NeedsListOfFriends) | 278 | lock (m_NeedsListOfFriends) |
298 | if (!m_NeedsListOfFriends.Contains(agentID)) | 279 | m_NeedsListOfFriends.Add(agentID); |
299 | { | ||
300 | m_NeedsListOfFriends.Add(agentID); | ||
301 | } | ||
302 | } | 280 | } |
303 | 281 | ||
304 | public void SendFriendsOnlineIfNeeded(IClientAPI client) | 282 | public void SendFriendsOnlineIfNeeded(IClientAPI client) |
305 | { | 283 | { |
306 | UUID agentID = client.AgentId; | 284 | UUID agentID = client.AgentId; |
307 | if (m_NeedsListOfFriends.Contains(agentID)) | 285 | |
286 | // Check if the online friends list is needed | ||
287 | lock (m_NeedsListOfFriends) | ||
308 | { | 288 | { |
309 | if (!m_Friends.ContainsKey(agentID)) | 289 | if (!m_NeedsListOfFriends.Remove(agentID)) |
310 | { | ||
311 | m_log.DebugFormat("[FRIENDS MODULE]: agent {0} not found in local cache", agentID); | ||
312 | return; | 290 | return; |
313 | } | 291 | } |
314 | |||
315 | // | ||
316 | // Send the friends online | ||
317 | // | ||
318 | List<UUID> online = GetOnlineFriends(agentID); | ||
319 | if (online.Count > 0) | ||
320 | { | ||
321 | m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count); | ||
322 | client.SendAgentOnline(online.ToArray()); | ||
323 | } | ||
324 | |||
325 | // | ||
326 | // Send outstanding friendship offers | ||
327 | // | ||
328 | if (m_Friends.ContainsKey(agentID)) | ||
329 | { | ||
330 | List<string> outstanding = new List<string>(); | ||
331 | 292 | ||
332 | foreach (FriendInfo fi in m_Friends[agentID].Friends) | 293 | // Send the friends online |
333 | if (fi.TheirFlags == -1) | 294 | List<UUID> online = GetOnlineFriends(agentID); |
334 | outstanding.Add(fi.Friend); | 295 | if (online.Count > 0) |
296 | { | ||
297 | m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count); | ||
298 | client.SendAgentOnline(online.ToArray()); | ||
299 | } | ||
335 | 300 | ||
336 | GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, "", agentID, (byte)InstantMessageDialog.FriendshipOffered, "Will you be my friend?", true, Vector3.Zero); | 301 | // Send outstanding friendship offers |
337 | foreach (string fid in outstanding) | 302 | List<string> outstanding = new List<string>(); |
338 | { | 303 | FriendInfo[] friends = GetFriends(agentID); |
339 | try | 304 | foreach (FriendInfo fi in friends) |
340 | { | 305 | { |
341 | im.fromAgentID = new Guid(fid); | 306 | if (fi.TheirFlags == -1) |
342 | } | 307 | outstanding.Add(fi.Friend); |
343 | catch | 308 | } |
344 | { | ||
345 | continue; | ||
346 | } | ||
347 | 309 | ||
348 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, new UUID(im.fromAgentID)); | 310 | GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered, |
349 | im.fromAgentName = account.FirstName + " " + account.LastName; | 311 | "Will you be my friend?", true, Vector3.Zero); |
350 | 312 | ||
351 | PresenceInfo presence = PresenceService.GetAgent(new UUID(im.fromAgentID)); | 313 | foreach (string fid in outstanding) |
352 | if (presence != null) | 314 | { |
353 | im.offline = 0; | 315 | UUID fromAgentID; |
316 | if (!UUID.TryParse(fid, out fromAgentID)) | ||
317 | continue; | ||
354 | 318 | ||
355 | im.imSessionID = im.fromAgentID; | 319 | UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID); |
320 | PresenceInfo presence = PresenceService.GetAgent(fromAgentID); | ||
356 | 321 | ||
357 | // Finally | 322 | im.fromAgentID = fromAgentID.Guid; |
358 | LocalFriendshipOffered(agentID, im); | 323 | im.fromAgentName = account.FirstName + " " + account.LastName; |
359 | } | 324 | im.offline = (byte)((presence == null) ? 1 : 0); |
360 | } | 325 | im.imSessionID = im.fromAgentID; |
361 | 326 | ||
362 | lock (m_NeedsListOfFriends) | 327 | // Finally |
363 | m_NeedsListOfFriends.Remove(agentID); | 328 | LocalFriendshipOffered(agentID, im); |
364 | } | 329 | } |
365 | } | 330 | } |
366 | 331 | ||
@@ -369,44 +334,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
369 | List<string> friendList = new List<string>(); | 334 | List<string> friendList = new List<string>(); |
370 | List<UUID> online = new List<UUID>(); | 335 | List<UUID> online = new List<UUID>(); |
371 | 336 | ||
372 | foreach (FriendInfo fi in m_Friends[userID].Friends) | 337 | FriendInfo[] friends = GetFriends(userID); |
338 | foreach (FriendInfo fi in friends) | ||
373 | { | 339 | { |
374 | if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) | 340 | if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) |
375 | friendList.Add(fi.Friend); | 341 | friendList.Add(fi.Friend); |
376 | } | 342 | } |
377 | 343 | ||
378 | if (friendList.Count == 0) | 344 | if (friendList.Count > 0) |
379 | // no friends whatsoever | 345 | { |
380 | return online; | 346 | PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); |
381 | 347 | foreach (PresenceInfo pi in presence) | |
382 | PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); | 348 | { |
383 | 349 | UUID presenceID; | |
384 | foreach (PresenceInfo pi in presence) | 350 | if (UUID.TryParse(pi.UserID, out presenceID)) |
385 | online.Add(new UUID(pi.UserID)); | 351 | online.Add(presenceID); |
386 | //m_log.DebugFormat("[XXX] {0} friend online {1}", userID, pi.UserID); | 352 | } |
353 | } | ||
387 | 354 | ||
388 | return online; | 355 | return online; |
389 | } | 356 | } |
390 | 357 | ||
391 | // | 358 | /// <summary> |
392 | // Find the client for a ID | 359 | /// Find the client for a ID |
393 | // | 360 | /// </summary> |
394 | public IClientAPI LocateClientObject(UUID agentID) | 361 | public IClientAPI LocateClientObject(UUID agentID) |
395 | { | 362 | { |
396 | Scene scene = GetClientScene(agentID); | 363 | Scene scene = GetClientScene(agentID); |
397 | if (scene == null) | 364 | if (scene != null) |
398 | return null; | 365 | { |
399 | 366 | ScenePresence presence = scene.GetScenePresence(agentID); | |
400 | ScenePresence presence = scene.GetScenePresence(agentID); | 367 | if (presence != null) |
401 | if (presence == null) | 368 | return presence.ControllingClient; |
402 | return null; | 369 | } |
403 | 370 | ||
404 | return presence.ControllingClient; | 371 | return null; |
405 | } | 372 | } |
406 | 373 | ||
407 | // | 374 | /// <summary> |
408 | // Find the scene for an agent | 375 | /// Find the scene for an agent |
409 | // | 376 | /// </summary> |
410 | private Scene GetClientScene(UUID agentId) | 377 | private Scene GetClientScene(UUID agentId) |
411 | { | 378 | { |
412 | lock (m_Scenes) | 379 | lock (m_Scenes) |
@@ -414,13 +381,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
414 | foreach (Scene scene in m_Scenes) | 381 | foreach (Scene scene in m_Scenes) |
415 | { | 382 | { |
416 | ScenePresence presence = scene.GetScenePresence(agentId); | 383 | ScenePresence presence = scene.GetScenePresence(agentId); |
417 | if (presence != null) | 384 | if (presence != null && !presence.IsChildAgent) |
418 | { | 385 | return scene; |
419 | if (!presence.IsChildAgent) | ||
420 | return scene; | ||
421 | } | ||
422 | } | 386 | } |
423 | } | 387 | } |
388 | |||
424 | return null; | 389 | return null; |
425 | } | 390 | } |
426 | 391 | ||
@@ -431,35 +396,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
431 | /// <param name="online"></param> | 396 | /// <param name="online"></param> |
432 | private void StatusChange(UUID agentID, bool online) | 397 | private void StatusChange(UUID agentID, bool online) |
433 | { | 398 | { |
434 | //m_log.DebugFormat("[FRIENDS]: StatusChange {0}", online); | 399 | FriendInfo[] friends = GetFriends(agentID); |
435 | if (m_Friends.ContainsKey(agentID)) | 400 | if (friends.Length > 0) |
436 | { | 401 | { |
437 | //m_log.DebugFormat("[FRIENDS]: # of friends: {0}", m_Friends[agentID].Friends.Length); | ||
438 | List<FriendInfo> friendList = new List<FriendInfo>(); | 402 | List<FriendInfo> friendList = new List<FriendInfo>(); |
439 | foreach (FriendInfo fi in m_Friends[agentID].Friends) | 403 | foreach (FriendInfo fi in friends) |
440 | { | 404 | { |
441 | if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) | 405 | if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) |
442 | friendList.Add(fi); | 406 | friendList.Add(fi); |
443 | } | 407 | } |
444 | 408 | ||
445 | Util.FireAndForget(delegate | 409 | Util.FireAndForget( |
446 | { | 410 | delegate |
447 | foreach (FriendInfo fi in friendList) | ||
448 | { | 411 | { |
449 | //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); | 412 | foreach (FriendInfo fi in friendList) |
450 | // Notify about this user status | 413 | { |
451 | StatusNotify(fi, agentID, online); | 414 | //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); |
415 | // Notify about this user status | ||
416 | StatusNotify(fi, agentID, online); | ||
417 | } | ||
452 | } | 418 | } |
453 | }); | 419 | ); |
454 | } | 420 | } |
455 | else | ||
456 | m_log.WarnFormat("[FRIENDS]: {0} not found in cache", agentID); | ||
457 | } | 421 | } |
458 | 422 | ||
459 | private void StatusNotify(FriendInfo friend, UUID userID, bool online) | 423 | private void StatusNotify(FriendInfo friend, UUID userID, bool online) |
460 | { | 424 | { |
461 | UUID friendID = UUID.Zero; | 425 | UUID friendID; |
462 | |||
463 | if (UUID.TryParse(friend.Friend, out friendID)) | 426 | if (UUID.TryParse(friend.Friend, out friendID)) |
464 | { | 427 | { |
465 | // Try local | 428 | // Try local |
@@ -476,12 +439,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
476 | } | 439 | } |
477 | } | 440 | } |
478 | else | 441 | else |
442 | { | ||
479 | m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); | 443 | m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); |
444 | } | ||
480 | } | 445 | } |
481 | 446 | ||
482 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) | 447 | private void OnInstantMessage(IClientAPI client, GridInstantMessage im) |
483 | { | 448 | { |
484 | if (im.dialog == (byte)OpenMetaverse.InstantMessageDialog.FriendshipOffered) | 449 | if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered) |
485 | { | 450 | { |
486 | // we got a friendship offer | 451 | // we got a friendship offer |
487 | UUID principalID = new UUID(im.fromAgentID); | 452 | UUID principalID = new UUID(im.fromAgentID); |
@@ -527,9 +492,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
527 | 492 | ||
528 | FriendsService.StoreFriend(agentID, friendID.ToString(), 1); | 493 | FriendsService.StoreFriend(agentID, friendID.ToString(), 1); |
529 | FriendsService.StoreFriend(friendID, agentID.ToString(), 1); | 494 | FriendsService.StoreFriend(friendID, agentID.ToString(), 1); |
530 | // update the local cache | ||
531 | m_Friends[agentID].Friends = FriendsService.GetFriends(agentID); | ||
532 | 495 | ||
496 | // Update the local cache | ||
497 | UpdateFriendsCache(agentID); | ||
533 | 498 | ||
534 | // | 499 | // |
535 | // Notify the friend | 500 | // Notify the friend |
@@ -584,7 +549,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
584 | FriendsService.Delete(exfriendID, agentID.ToString()); | 549 | FriendsService.Delete(exfriendID, agentID.ToString()); |
585 | 550 | ||
586 | // Update local cache | 551 | // Update local cache |
587 | m_Friends[agentID].Friends = FriendsService.GetFriends(agentID); | 552 | UpdateFriendsCache(agentID); |
588 | 553 | ||
589 | client.SendTerminateFriend(exfriendID); | 554 | client.SendTerminateFriend(exfriendID); |
590 | 555 | ||
@@ -606,16 +571,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
606 | 571 | ||
607 | private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) | 572 | private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) |
608 | { | 573 | { |
609 | if (!m_Friends.ContainsKey(remoteClient.AgentId)) | 574 | FriendInfo[] friends = GetFriends(remoteClient.AgentId); |
575 | if (friends.Length == 0) | ||
610 | return; | 576 | return; |
611 | 577 | ||
612 | m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); | 578 | m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); |
613 | // Let's find the friend in this user's friend list | 579 | // Let's find the friend in this user's friend list |
614 | UserFriendData fd = m_Friends[remoteClient.AgentId]; | ||
615 | FriendInfo friend = null; | 580 | FriendInfo friend = null; |
616 | foreach (FriendInfo fi in fd.Friends) | 581 | foreach (FriendInfo fi in friends) |
582 | { | ||
617 | if (fi.Friend == target.ToString()) | 583 | if (fi.Friend == target.ToString()) |
618 | friend = fi; | 584 | friend = fi; |
585 | } | ||
619 | 586 | ||
620 | if (friend != null) // Found it | 587 | if (friend != null) // Found it |
621 | { | 588 | { |
@@ -672,8 +639,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
672 | GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID, | 639 | GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID, |
673 | (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero); | 640 | (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero); |
674 | friendClient.SendInstantMessage(im); | 641 | friendClient.SendInstantMessage(im); |
675 | // update the local cache | 642 | |
676 | m_Friends[friendID].Friends = FriendsService.GetFriends(friendID); | 643 | // Update the local cache |
644 | UpdateFriendsCache(friendID); | ||
645 | |||
677 | // we're done | 646 | // we're done |
678 | return true; | 647 | return true; |
679 | } | 648 | } |
@@ -687,7 +656,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
687 | if (friendClient != null) | 656 | if (friendClient != null) |
688 | { | 657 | { |
689 | // the prospective friend in this sim as root agent | 658 | // the prospective friend in this sim as root agent |
690 | |||
691 | GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID, | 659 | GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID, |
692 | (byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, userID.ToString(), false, Vector3.Zero); | 660 | (byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, userID.ToString(), false, Vector3.Zero); |
693 | friendClient.SendInstantMessage(im); | 661 | friendClient.SendInstantMessage(im); |
@@ -706,7 +674,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
706 | // the friend in this sim as root agent | 674 | // the friend in this sim as root agent |
707 | friendClient.SendTerminateFriend(exfriendID); | 675 | friendClient.SendTerminateFriend(exfriendID); |
708 | // update local cache | 676 | // update local cache |
709 | m_Friends[exfriendID].Friends = FriendsService.GetFriends(exfriendID); | 677 | UpdateFriendsCache(exfriendID); |
710 | // we're done | 678 | // we're done |
711 | return true; | 679 | return true; |
712 | } | 680 | } |
@@ -735,11 +703,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
735 | 703 | ||
736 | } | 704 | } |
737 | 705 | ||
738 | // update local cache | 706 | // Update local cache |
739 | //m_Friends[friendID].Friends = m_FriendsService.GetFriends(friendID); | 707 | lock (m_Friends) |
740 | foreach (FriendInfo finfo in m_Friends[friendID].Friends) | 708 | { |
741 | if (finfo.Friend == userID.ToString()) | 709 | FriendInfo[] friends = GetFriends(friendID); |
742 | finfo.TheirFlags = rights; | 710 | foreach (FriendInfo finfo in friends) |
711 | { | ||
712 | if (finfo.Friend == userID.ToString()) | ||
713 | finfo.TheirFlags = rights; | ||
714 | } | ||
715 | } | ||
743 | 716 | ||
744 | return true; | 717 | return true; |
745 | } | 718 | } |
@@ -765,7 +738,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
765 | 738 | ||
766 | return false; | 739 | return false; |
767 | } | 740 | } |
741 | |||
768 | #endregion | 742 | #endregion |
769 | 743 | ||
744 | private FriendInfo[] GetFriends(UUID agentID) | ||
745 | { | ||
746 | UserFriendData friendsData; | ||
747 | |||
748 | lock (m_Friends) | ||
749 | { | ||
750 | if (m_Friends.TryGetValue(agentID, out friendsData)) | ||
751 | return friendsData.Friends; | ||
752 | } | ||
753 | |||
754 | return EMPTY_FRIENDS; | ||
755 | } | ||
756 | |||
757 | private void UpdateFriendsCache(UUID agentID) | ||
758 | { | ||
759 | lock (m_Friends) | ||
760 | { | ||
761 | UserFriendData friendsData; | ||
762 | if (m_Friends.TryGetValue(agentID, out friendsData)) | ||
763 | friendsData.Friends = FriendsService.GetFriends(agentID); | ||
764 | } | ||
765 | } | ||
770 | } | 766 | } |
771 | } | 767 | } |