aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs431
1 files changed, 195 insertions, 236 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index ca0b7ad..a49e71e 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 {
@@ -68,6 +67,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
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,17 +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 string searchFor = friendID.ToString();
207 foreach (FriendInfo fi in data.Friends)
208 { 201 {
209 if (fi.Friend == searchFor) 202 if (fi.Friend == friendID.ToString())
210 return (uint)fi.TheirFlags; 203 return (uint)fi.TheirFlags;
211 } 204 }
205
212 return 0; 206 return 0;
213 } 207 }
214 208
@@ -218,73 +212,59 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
218 client.OnApproveFriendRequest += OnApproveFriendRequest; 212 client.OnApproveFriendRequest += OnApproveFriendRequest;
219 client.OnDenyFriendRequest += OnDenyFriendRequest; 213 client.OnDenyFriendRequest += OnDenyFriendRequest;
220 client.OnTerminateFriendship += OnTerminateFriendship; 214 client.OnTerminateFriendship += OnTerminateFriendship;
221
222 client.OnGrantUserRights += OnGrantUserRights; 215 client.OnGrantUserRights += OnGrantUserRights;
223 216
224 lock (m_Friends) 217 // Asynchronously fetch the friends list or increment the refcount for the existing
225 { 218 // friends list
226 if (m_Friends.ContainsKey(client.AgentId)) 219 Util.FireAndForget(
220 delegate(object o)
227 { 221 {
228 m_Friends[client.AgentId].Refcount++; 222 lock (m_Friends)
229 return; 223 {
230 } 224 UserFriendData friendsData;
231 225 if (m_Friends.TryGetValue(client.AgentId, out friendsData))
232 UserFriendData newFriends = new UserFriendData(); 226 {
233 227 friendsData.Refcount++;
234 newFriends.PrincipalID = client.AgentId; 228 }
235 newFriends.Friends = m_FriendsService.GetFriends(client.AgentId); 229 else
236 newFriends.Refcount = 1; 230 {
237 newFriends.RegionID = UUID.Zero; 231 friendsData = new UserFriendData();
232 friendsData.PrincipalID = client.AgentId;
233 friendsData.Friends = FriendsService.GetFriends(client.AgentId);
234 friendsData.Refcount = 1;
238 235
239 m_Friends.Add(client.AgentId, newFriends); 236 m_Friends[client.AgentId] = friendsData;
240 } 237 }
241 238 }
239 }
240 );
242 } 241 }
243 242
244 private void OnClientClosed(UUID agentID, Scene scene) 243 private void OnClientClosed(UUID agentID, Scene scene)
245 { 244 {
246 ScenePresence sp = scene.GetScenePresence(agentID); 245 ScenePresence sp = scene.GetScenePresence(agentID);
247 if (sp != null && !sp.IsChildAgent) 246 if (sp != null && !sp.IsChildAgent)
247 {
248 // do this for root agents closing out 248 // do this for root agents closing out
249 StatusChange(agentID, false); 249 StatusChange(agentID, false);
250 }
250 251
251 lock (m_Friends) 252 lock (m_Friends)
252 if (m_Friends.ContainsKey(agentID)) 253 {
254 UserFriendData friendsData;
255 if (m_Friends.TryGetValue(agentID, out friendsData))
253 { 256 {
254 if (m_Friends[agentID].Refcount == 1) 257 friendsData.Refcount--;
258 if (friendsData.Refcount <= 0)
255 m_Friends.Remove(agentID); 259 m_Friends.Remove(agentID);
256 else
257 m_Friends[agentID].Refcount--;
258 } 260 }
259 }
260
261 private void OnMakeRootAgent(ScenePresence sp)
262 {
263 UUID agentID = sp.ControllingClient.AgentId;
264
265 if (m_Friends.ContainsKey(agentID))
266 {
267 // This is probably an overkill, but just
268 // to make sure we have the latest and greatest
269 // friends list -- always pull OnMakeRoot
270 m_Friends[agentID].Friends =
271 m_FriendsService.GetFriends(agentID);
272
273 m_Friends[agentID].RegionID =
274 sp.ControllingClient.Scene.RegionInfo.RegionID;
275 } 261 }
276 } 262 }
277 263
278 264 private void OnMakeRootAgent(ScenePresence sp)
279 private void OnMakeChildAgent(ScenePresence sp)
280 { 265 {
281 UUID agentID = sp.ControllingClient.AgentId; 266 UUID agentID = sp.ControllingClient.AgentId;
282 267 UpdateFriendsCache(agentID);
283 if (m_Friends.ContainsKey(agentID))
284 {
285 if (m_Friends[agentID].RegionID == sp.ControllingClient.Scene.RegionInfo.RegionID)
286 m_Friends[agentID].RegionID = UUID.Zero;
287 }
288 } 268 }
289 269
290 private void OnClientLogin(IClientAPI client) 270 private void OnClientLogin(IClientAPI client)
@@ -296,75 +276,56 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
296 276
297 // 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
298 lock (m_NeedsListOfFriends) 278 lock (m_NeedsListOfFriends)
299 if (!m_NeedsListOfFriends.Contains(agentID)) 279 m_NeedsListOfFriends.Add(agentID);
300 {
301 m_NeedsListOfFriends.Add(agentID);
302 }
303 } 280 }
304 281
305 public void SendFriendsOnlineIfNeeded(IClientAPI client) 282 public void SendFriendsOnlineIfNeeded(IClientAPI client)
306 { 283 {
307 UUID agentID = client.AgentId; 284 UUID agentID = client.AgentId;
308 if (m_NeedsListOfFriends.Contains(agentID)) 285
286 // Check if the online friends list is needed
287 lock (m_NeedsListOfFriends)
309 { 288 {
310 if (!m_Friends.ContainsKey(agentID)) 289 if (!m_NeedsListOfFriends.Remove(agentID))
311 {
312 m_log.DebugFormat("[FRIENDS MODULE]: agent {0} not found in local cache", agentID);
313 return; 290 return;
314 } 291 }
315
316 //
317 // Send the friends online
318 //
319 List<UUID> online = GetOnlineFriends(agentID);
320 if (online.Count > 0)
321 {
322 m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count);
323 client.SendAgentOnline(online.ToArray());
324 }
325
326 //
327 // Send outstanding friendship offers
328 //
329 if (m_Friends.ContainsKey(agentID))
330 {
331 List<string> outstanding = new List<string>();
332 292
333 foreach (FriendInfo fi in m_Friends[agentID].Friends) 293 // Send the friends online
334 if (fi.TheirFlags == -1) 294 List<UUID> online = GetOnlineFriends(agentID);
335 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 }
336 300
337 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
338 foreach (string fid in outstanding) 302 List<string> outstanding = new List<string>();
339 { 303 FriendInfo[] friends = GetFriends(agentID);
340 try 304 foreach (FriendInfo fi in friends)
341 { 305 {
342 im.fromAgentID = new Guid(fid); 306 if (fi.TheirFlags == -1)
343 } 307 outstanding.Add(fi.Friend);
344 catch 308 }
345 {
346 continue;
347 }
348 309
349 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,
350 im.fromAgentName = account.FirstName + " " + account.LastName; 311 "Will you be my friend?", true, Vector3.Zero);
351 312
352 PresenceInfo presence = null; 313 foreach (string fid in outstanding)
353 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); 314 {
354 if (presences != null && presences.Length > 0) 315 UUID fromAgentID;
355 presence = presences[0]; 316 if (!UUID.TryParse(fid, out fromAgentID))
356 if (presence != null) 317 continue;
357 im.offline = 0;
358 318
359 im.imSessionID = im.fromAgentID; 319 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
320 PresenceInfo presence = PresenceService.GetAgent(fromAgentID);
360 321
361 // Finally 322 im.fromAgentID = fromAgentID.Guid;
362 LocalFriendshipOffered(agentID, im); 323 im.fromAgentName = account.FirstName + " " + account.LastName;
363 } 324 im.offline = (byte)((presence == null) ? 1 : 0);
364 } 325 im.imSessionID = im.fromAgentID;
365 326
366 lock (m_NeedsListOfFriends) 327 // Finally
367 m_NeedsListOfFriends.Remove(agentID); 328 LocalFriendshipOffered(agentID, im);
368 } 329 }
369 } 330 }
370 331
@@ -373,44 +334,46 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
373 List<string> friendList = new List<string>(); 334 List<string> friendList = new List<string>();
374 List<UUID> online = new List<UUID>(); 335 List<UUID> online = new List<UUID>();
375 336
376 foreach (FriendInfo fi in m_Friends[userID].Friends) 337 FriendInfo[] friends = GetFriends(userID);
338 foreach (FriendInfo fi in friends)
377 { 339 {
378 if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1)) 340 if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
379 friendList.Add(fi.Friend); 341 friendList.Add(fi.Friend);
380 } 342 }
381 343
382 if (friendList.Count == 0) 344 if (friendList.Count > 0)
383 // no friends whatsoever 345 {
384 return online; 346 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
385 347 foreach (PresenceInfo pi in presence)
386 PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray()); 348 {
387 349 UUID presenceID;
388 foreach (PresenceInfo pi in presence) 350 if (UUID.TryParse(pi.UserID, out presenceID))
389 online.Add(new UUID(pi.UserID)); 351 online.Add(presenceID);
390 //m_log.DebugFormat("[XXX] {0} friend online {1}", userID, pi.UserID); 352 }
353 }
391 354
392 return online; 355 return online;
393 } 356 }
394 357
395 // 358 /// <summary>
396 // Find the client for a ID 359 /// Find the client for a ID
397 // 360 /// </summary>
398 public IClientAPI LocateClientObject(UUID agentID) 361 public IClientAPI LocateClientObject(UUID agentID)
399 { 362 {
400 Scene scene = GetClientScene(agentID); 363 Scene scene = GetClientScene(agentID);
401 if (scene == null) 364 if (scene != null)
402 return null; 365 {
403 366 ScenePresence presence = scene.GetScenePresence(agentID);
404 ScenePresence presence = scene.GetScenePresence(agentID); 367 if (presence != null)
405 if (presence == null) 368 return presence.ControllingClient;
406 return null; 369 }
407 370
408 return presence.ControllingClient; 371 return null;
409 } 372 }
410 373
411 // 374 /// <summary>
412 // Find the scene for an agent 375 /// Find the scene for an agent
413 // 376 /// </summary>
414 private Scene GetClientScene(UUID agentId) 377 private Scene GetClientScene(UUID agentId)
415 { 378 {
416 lock (m_Scenes) 379 lock (m_Scenes)
@@ -418,13 +381,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
418 foreach (Scene scene in m_Scenes) 381 foreach (Scene scene in m_Scenes)
419 { 382 {
420 ScenePresence presence = scene.GetScenePresence(agentId); 383 ScenePresence presence = scene.GetScenePresence(agentId);
421 if (presence != null) 384 if (presence != null && !presence.IsChildAgent)
422 { 385 return scene;
423 if (!presence.IsChildAgent)
424 return scene;
425 }
426 } 386 }
427 } 387 }
388
428 return null; 389 return null;
429 } 390 }
430 391
@@ -435,35 +396,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
435 /// <param name="online"></param> 396 /// <param name="online"></param>
436 private void StatusChange(UUID agentID, bool online) 397 private void StatusChange(UUID agentID, bool online)
437 { 398 {
438 //m_log.DebugFormat("[FRIENDS]: StatusChange {0}", online); 399 FriendInfo[] friends = GetFriends(agentID);
439 if (m_Friends.ContainsKey(agentID)) 400 if (friends.Length > 0)
440 { 401 {
441 //m_log.DebugFormat("[FRIENDS]: # of friends: {0}", m_Friends[agentID].Friends.Length);
442 List<FriendInfo> friendList = new List<FriendInfo>(); 402 List<FriendInfo> friendList = new List<FriendInfo>();
443 foreach (FriendInfo fi in m_Friends[agentID].Friends) 403 foreach (FriendInfo fi in friends)
444 { 404 {
445 if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) 405 if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1))
446 friendList.Add(fi); 406 friendList.Add(fi);
447 } 407 }
448 408
449 Util.FireAndForget(delegate 409 Util.FireAndForget(
450 { 410 delegate
451 foreach (FriendInfo fi in friendList)
452 { 411 {
453 //m_log.DebugFormat("[FRIENDS]: Notifying {0}", fi.PrincipalID); 412 foreach (FriendInfo fi in friendList)
454 // Notify about this user status 413 {
455 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 }
456 } 418 }
457 }); 419 );
458 } 420 }
459 else
460 m_log.WarnFormat("[FRIENDS]: {0} not found in cache", agentID);
461 } 421 }
462 422
463 private void StatusNotify(FriendInfo friend, UUID userID, bool online) 423 private void StatusNotify(FriendInfo friend, UUID userID, bool online)
464 { 424 {
465 UUID friendID = UUID.Zero; 425 UUID friendID;
466
467 if (UUID.TryParse(friend.Friend, out friendID)) 426 if (UUID.TryParse(friend.Friend, out friendID))
468 { 427 {
469 // Try local 428 // Try local
@@ -471,35 +430,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
471 return; 430 return;
472 431
473 // The friend is not here [as root]. Let's forward. 432 // The friend is not here [as root]. Let's forward.
474 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 433 PresenceInfo friendSession = PresenceService.GetAgent(friendID);
475 if (friendSessions != null && friendSessions.Length > 0) 434 if (friendSession != null && friendSession.RegionID != UUID.Zero) // let's guard against sessions-gone-bad with the RegionID check
476 { 435 {
477 PresenceInfo friendSession = null; 436 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
478 foreach (PresenceInfo pinfo in friendSessions) 437 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
479 if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad 438 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
480 {
481 friendSession = pinfo;
482 break;
483 }
484
485 if (friendSession != null)
486 {
487 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
488 //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
489 m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
490 }
491 } 439 }
492
493 // Friend is not online. Ignore.
494 } 440 }
495 else 441 else
442 {
496 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend); 443 m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
444 }
497 } 445 }
498 446
499 private void OnInstantMessage(IClientAPI client, GridInstantMessage im) 447 private void OnInstantMessage(IClientAPI client, GridInstantMessage im)
500 { 448 {
501 if (im.dialog == (byte)OpenMetaverse.InstantMessageDialog.FriendshipOffered) 449 if ((InstantMessageDialog)im.dialog == InstantMessageDialog.FriendshipOffered)
502 { 450 {
503 // we got a friendship offer 451 // we got a friendship offer
504 UUID principalID = new UUID(im.fromAgentID); 452 UUID principalID = new UUID(im.fromAgentID);
505 UUID friendID = new UUID(im.toAgentID); 453 UUID friendID = new UUID(im.toAgentID);
@@ -529,15 +477,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
529 return; 477 return;
530 478
531 // The prospective friend is not here [as root]. Let's forward. 479 // The prospective friend is not here [as root]. Let's forward.
532 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 480 PresenceInfo friendSession = PresenceService.GetAgent(friendID);
533 if (friendSessions != null && friendSessions.Length > 0) 481 if (friendSession != null)
534 { 482 {
535 PresenceInfo friendSession = friendSessions[0]; 483 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
536 if (friendSession != null) 484 m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
537 {
538 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
539 m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
540 }
541 } 485 }
542 // If the prospective friend is not online, he'll get the message upon login. 486 // If the prospective friend is not online, he'll get the message upon login.
543 } 487 }
@@ -548,9 +492,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
548 492
549 FriendsService.StoreFriend(agentID, friendID.ToString(), 1); 493 FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
550 FriendsService.StoreFriend(friendID, agentID.ToString(), 1); 494 FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
551 // update the local cache
552 m_Friends[agentID].Friends = FriendsService.GetFriends(agentID);
553 495
496 // Update the local cache
497 UpdateFriendsCache(agentID);
554 498
555 // 499 //
556 // Notify the friend 500 // Notify the friend
@@ -564,16 +508,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
564 } 508 }
565 509
566 // The friend is not here 510 // The friend is not here
567 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 511 PresenceInfo friendSession = PresenceService.GetAgent(friendID);
568 if (friendSessions != null && friendSessions.Length > 0) 512 if (friendSession != null)
569 { 513 {
570 PresenceInfo friendSession = friendSessions[0]; 514 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
571 if (friendSession != null) 515 m_FriendsSimConnector.FriendshipApproved(region, agentID, client.Name, friendID);
572 { 516 client.SendAgentOnline(new UUID[] { friendID });
573 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
574 m_FriendsSimConnector.FriendshipApproved(region, agentID, client.Name, friendID);
575 client.SendAgentOnline(new UUID[] { friendID });
576 }
577 } 517 }
578 } 518 }
579 519
@@ -592,18 +532,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
592 if (LocalFriendshipDenied(agentID, client.Name, friendID)) 532 if (LocalFriendshipDenied(agentID, client.Name, friendID))
593 return; 533 return;
594 534
595 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 535 PresenceInfo friendSession = PresenceService.GetAgent(friendID);
596 if (friendSessions != null && friendSessions.Length > 0) 536 if (friendSession != null)
597 { 537 {
598 PresenceInfo friendSession = friendSessions[0]; 538 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
599 if (friendSession != null) 539 if (region != null)
600 { 540 m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID);
601 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 541 else
602 if (region != null) 542 m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID);
603 m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID);
604 else
605 m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID);
606 }
607 } 543 }
608 } 544 }
609 545
@@ -613,7 +549,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
613 FriendsService.Delete(exfriendID, agentID.ToString()); 549 FriendsService.Delete(exfriendID, agentID.ToString());
614 550
615 // Update local cache 551 // Update local cache
616 m_Friends[agentID].Friends = FriendsService.GetFriends(agentID); 552 UpdateFriendsCache(agentID);
617 553
618 client.SendTerminateFriend(exfriendID); 554 client.SendTerminateFriend(exfriendID);
619 555
@@ -625,30 +561,28 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
625 if (LocalFriendshipTerminated(exfriendID)) 561 if (LocalFriendshipTerminated(exfriendID))
626 return; 562 return;
627 563
628 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { exfriendID.ToString() }); 564 PresenceInfo friendSession = PresenceService.GetAgent(exfriendID);
629 if (friendSessions != null && friendSessions.Length > 0) 565 if (friendSession != null)
630 { 566 {
631 PresenceInfo friendSession = friendSessions[0]; 567 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
632 if (friendSession != null) 568 m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID);
633 {
634 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
635 m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID);
636 }
637 } 569 }
638 } 570 }
639 571
640 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 572 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
641 { 573 {
642 if (!m_Friends.ContainsKey(remoteClient.AgentId)) 574 FriendInfo[] friends = GetFriends(remoteClient.AgentId);
575 if (friends.Length == 0)
643 return; 576 return;
644 577
645 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);
646 // Let's find the friend in this user's friend list 579 // Let's find the friend in this user's friend list
647 UserFriendData fd = m_Friends[remoteClient.AgentId];
648 FriendInfo friend = null; 580 FriendInfo friend = null;
649 foreach (FriendInfo fi in fd.Friends) 581 foreach (FriendInfo fi in friends)
582 {
650 if (fi.Friend == target.ToString()) 583 if (fi.Friend == target.ToString())
651 friend = fi; 584 friend = fi;
585 }
652 586
653 if (friend != null) // Found it 587 if (friend != null) // Found it
654 { 588 {
@@ -670,17 +604,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
670 if (LocalGrantRights(requester, target, myFlags, rights)) 604 if (LocalGrantRights(requester, target, myFlags, rights))
671 return; 605 return;
672 606
673 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); 607 PresenceInfo friendSession = PresenceService.GetAgent(target);
674 if (friendSessions != null && friendSessions.Length > 0) 608 if (friendSession != null)
675 { 609 {
676 PresenceInfo friendSession = friendSessions[0]; 610 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
677 if (friendSession != null) 611 // TODO: You might want to send the delta to save the lookup
678 { 612 // on the other end!!
679 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 613 m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
680 // TODO: You might want to send the delta to save the lookup
681 // on the other end!!
682 m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
683 }
684 } 614 }
685 } 615 }
686 } 616 }
@@ -709,8 +639,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
709 GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID, 639 GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID,
710 (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero); 640 (byte)OpenMetaverse.InstantMessageDialog.FriendshipAccepted, userID.ToString(), false, Vector3.Zero);
711 friendClient.SendInstantMessage(im); 641 friendClient.SendInstantMessage(im);
712 // update the local cache 642
713 m_Friends[friendID].Friends = FriendsService.GetFriends(friendID); 643 // Update the local cache
644 UpdateFriendsCache(friendID);
645
714 // we're done 646 // we're done
715 return true; 647 return true;
716 } 648 }
@@ -724,7 +656,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
724 if (friendClient != null) 656 if (friendClient != null)
725 { 657 {
726 // the prospective friend in this sim as root agent 658 // the prospective friend in this sim as root agent
727
728 GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID, 659 GridInstantMessage im = new GridInstantMessage(Scene, userID, userName, friendID,
729 (byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, userID.ToString(), false, Vector3.Zero); 660 (byte)OpenMetaverse.InstantMessageDialog.FriendshipDeclined, userID.ToString(), false, Vector3.Zero);
730 friendClient.SendInstantMessage(im); 661 friendClient.SendInstantMessage(im);
@@ -743,7 +674,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
743 // the friend in this sim as root agent 674 // the friend in this sim as root agent
744 friendClient.SendTerminateFriend(exfriendID); 675 friendClient.SendTerminateFriend(exfriendID);
745 // update local cache 676 // update local cache
746 m_Friends[exfriendID].Friends = FriendsService.GetFriends(exfriendID); 677 UpdateFriendsCache(exfriendID);
747 // we're done 678 // we're done
748 return true; 679 return true;
749 } 680 }
@@ -772,11 +703,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
772 703
773 } 704 }
774 705
775 // update local cache 706 // Update local cache
776 //m_Friends[friendID].Friends = m_FriendsService.GetFriends(friendID); 707 lock (m_Friends)
777 foreach (FriendInfo finfo in m_Friends[friendID].Friends) 708 {
778 if (finfo.Friend == userID.ToString()) 709 FriendInfo[] friends = GetFriends(friendID);
779 finfo.TheirFlags = rights; 710 foreach (FriendInfo finfo in friends)
711 {
712 if (finfo.Friend == userID.ToString())
713 finfo.TheirFlags = rights;
714 }
715 }
780 716
781 return true; 717 return true;
782 } 718 }
@@ -802,7 +738,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
802 738
803 return false; 739 return false;
804 } 740 }
741
805 #endregion 742 #endregion
806 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 }
807 } 766 }
808} 767}