aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorDiva Canto2012-03-20 17:14:19 -0700
committerDiva Canto2012-03-20 17:14:19 -0700
commitd08ad6459a03a6a5a6a551fd2b275f1c7da94d8e (patch)
tree62075048f4773a00593c658285b269459e9fcdfb /OpenSim/Region
parentAdded GetUUID(first, last) on UserAgentsService so that we can finally make d... (diff)
downloadopensim-SC-d08ad6459a03a6a5a6a551fd2b275f1c7da94d8e.zip
opensim-SC-d08ad6459a03a6a5a6a551fd2b275f1c7da94d8e.tar.gz
opensim-SC-d08ad6459a03a6a5a6a551fd2b275f1c7da94d8e.tar.bz2
opensim-SC-d08ad6459a03a6a5a6a551fd2b275f1c7da94d8e.tar.xz
HG Friends: allow the establishment of HG friendships without requiring co-presence in the same sim. Using avatar picker, users can now search for names such as "first.last@grid.com:9000", find them, and request friendship. Friendship requests are stored if target user is offline. TESTED ON STANDALONE ONLY.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs31
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs290
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs76
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs20
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs26
5 files changed, 276 insertions, 167 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index c266fe5..f6a31b5 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -550,7 +550,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
550 UUID principalID = new UUID(im.fromAgentID); 550 UUID principalID = new UUID(im.fromAgentID);
551 UUID friendID = new UUID(im.toAgentID); 551 UUID friendID = new UUID(im.toAgentID);
552 552
553 m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID); 553 m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
554
555 // Check that the friendship doesn't exist yet
556 FriendInfo[] finfos = GetFriends(principalID);
557 if (finfos != null)
558 {
559 FriendInfo f = GetFriend(finfos, friendID);
560 if (f != null)
561 {
562 client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
563 return;
564 }
565 }
554 566
555 // This user wants to be friends with the other user. 567 // This user wants to be friends with the other user.
556 // Let's add the relation backwards, in case the other is not online 568 // Let's add the relation backwards, in case the other is not online
@@ -561,7 +573,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
561 } 573 }
562 } 574 }
563 575
564 private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) 576 protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
565 { 577 {
566 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 578 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
567 // We stick this agent's ID as imSession, so that it's directly available on the receiving end 579 // We stick this agent's ID as imSession, so that it's directly available on the receiving end
@@ -570,7 +582,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
570 582
571 // Try the local sim 583 // Try the local sim
572 if (LocalFriendshipOffered(friendID, im)) 584 if (LocalFriendshipOffered(friendID, im))
573 return; 585 {
586 m_log.DebugFormat("[XXX]: LocalFriendshipOffered successes");
587 return true;
588 }
574 589
575 // The prospective friend is not here [as root]. Let's forward. 590 // The prospective friend is not here [as root]. Let's forward.
576 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); 591 PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -581,9 +596,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
581 { 596 {
582 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); 597 GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
583 m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); 598 m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
599 return true;
584 } 600 }
585 } 601 }
586 // If the prospective friend is not online, he'll get the message upon login. 602 // If the prospective friend is not online, he'll get the message upon login.
603 return false;
587 } 604 }
588 605
589 protected virtual string GetFriendshipRequesterName(UUID agentID) 606 protected virtual string GetFriendshipRequesterName(UUID agentID)
@@ -592,7 +609,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
592 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName; 609 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
593 } 610 }
594 611
595 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 612 protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
596 { 613 {
597 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID); 614 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
598 615
@@ -603,7 +620,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
603 { 620 {
604 StoreFriendships(client.AgentId, friendID); 621 StoreFriendships(client.AgentId, friendID);
605 622
606 // Update the local cache 623 // Update the local cache.
607 RecacheFriends(client); 624 RecacheFriends(client);
608 625
609 // 626 //
@@ -756,7 +773,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
756 773
757 #region Local 774 #region Local
758 775
759 public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) 776 public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
760 { 777 {
761 IClientAPI friendClient = LocateClientObject(toID); 778 IClientAPI friendClient = LocateClientObject(toID);
762 if (friendClient != null) 779 if (friendClient != null)
@@ -912,7 +929,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
912 return FriendsService.GetFriends(client.AgentId); 929 return FriendsService.GetFriends(client.AgentId);
913 } 930 }
914 931
915 private void RecacheFriends(IClientAPI client) 932 protected void RecacheFriends(IClientAPI client)
916 { 933 {
917 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event 934 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
918 // is on the critical path for transferring an avatar from one region to another. 935 // is on the critical path for transferring an avatar from one region to another.
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index 9c53fc4..0fe1134 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -61,6 +61,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
61 } 61 }
62 } 62 }
63 63
64 protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector();
65
64 #region ISharedRegionModule 66 #region ISharedRegionModule
65 public override string Name 67 public override string Name
66 { 68 {
@@ -94,6 +96,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
94 96
95 #endregion 97 #endregion
96 98
99 protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
100 {
101 // Update the local cache. Yes, we need to do it right here
102 // because the HGFriendsService placed something on the DB
103 // from under the sim
104 base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders);
105 }
106
97 protected override bool CacheFriends(IClientAPI client) 107 protected override bool CacheFriends(IClientAPI client)
98 { 108 {
99// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name); 109// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
@@ -183,91 +193,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
183// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID); 193// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
184 } 194 }
185 195
186 //protected override void GetOnlineFriends(UUID userID, List<string> friendList, /*collector*/ List<UUID> online)
187 //{
188 // // Let's single out the UUIs
189 // List<string> localFriends = new List<string>();
190 // List<string> foreignFriends = new List<string>();
191 // string tmp = string.Empty;
192
193 // foreach (string s in friendList)
194 // {
195 // UUID id;
196 // if (UUID.TryParse(s, out id))
197 // localFriends.Add(s);
198 // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
199 // {
200 // foreignFriends.Add(s);
201 // // add it here too, who knows maybe the foreign friends happens to be on this grid
202 // localFriends.Add(id.ToString());
203 // }
204 // }
205
206 // // OK, see who's present on this grid
207 // List<string> toBeRemoved = new List<string>();
208 // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
209 // foreach (PresenceInfo pi in presence)
210 // {
211 // UUID presenceID;
212 // if (UUID.TryParse(pi.UserID, out presenceID))
213 // {
214 // online.Add(presenceID);
215 // foreach (string s in foreignFriends)
216 // if (s.StartsWith(pi.UserID))
217 // toBeRemoved.Add(s);
218 // }
219 // }
220
221 // foreach (string s in toBeRemoved)
222 // foreignFriends.Remove(s);
223
224 // // OK, let's send this up the stack, and leave a closure here
225 // // collecting online friends in other grids
226 // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
227
228 //}
229
230 //private void CollectOnlineFriendsElsewhere(UUID userID, List<string> foreignFriends)
231 //{
232 // // let's divide the friends on a per-domain basis
233 // Dictionary<string, List<string>> friendsPerDomain = new Dictionary<string, List<string>>();
234 // foreach (string friend in foreignFriends)
235 // {
236 // UUID friendID;
237 // if (!UUID.TryParse(friend, out friendID))
238 // {
239 // // it's a foreign friend
240 // string url = string.Empty, tmp = string.Empty;
241 // if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
242 // {
243 // if (!friendsPerDomain.ContainsKey(url))
244 // friendsPerDomain[url] = new List<string>();
245 // friendsPerDomain[url].Add(friend);
246 // }
247 // }
248 // }
249
250 // // Now, call those worlds
251
252 // foreach (KeyValuePair<string, List<string>> kvp in friendsPerDomain)
253 // {
254 // List<string> ids = new List<string>();
255 // foreach (string f in kvp.Value)
256 // ids.Add(f);
257 // UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
258 // List<UUID> online = uConn.GetOnlineFriends(userID, ids);
259 // // Finally send the notifications to the user
260 // // this whole process may take a while, so let's check at every
261 // // iteration that the user is still here
262 // IClientAPI client = LocateClientObject(userID);
263 // if (client != null)
264 // client.SendAgentOnline(online.ToArray());
265 // else
266 // break;
267 // }
268
269 //}
270
271 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online) 196 protected override void StatusNotify(List<FriendInfo> friendList, UUID userID, bool online)
272 { 197 {
273// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID); 198// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
@@ -335,12 +260,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
335 return true; 260 return true;
336 261
337 // fid is not a UUID... 262 // fid is not a UUID...
338 string url = string.Empty, tmp = string.Empty; 263 string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty;
339 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) 264 m_log.DebugFormat("[YYY]: FID {0}", fid);
265 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp))
340 { 266 {
341 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 267 m_log.DebugFormat("[YYY]: Adding user {0} {1} {2}", f, l, url);
342 userMan.AddUser(agentID, first, last, url); 268 m_uMan.AddUser(agentID, f, l, url);
343 269
270 string name = m_uMan.GetUserName(agentID);
271 string[] parts = name.Trim().Split(new char[] {' '});
272 if (parts.Length == 2)
273 {
274 first = parts[0];
275 last = parts[1];
276 }
277 else
278 {
279 first = f;
280 last = l;
281 }
344 return true; 282 return true;
345 } 283 }
346 return false; 284 return false;
@@ -348,13 +286,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
348 286
349 protected override string GetFriendshipRequesterName(UUID agentID) 287 protected override string GetFriendshipRequesterName(UUID agentID)
350 { 288 {
351 // For the time being we assume that HG friendship requests can only happen 289 return m_uMan.GetUserName(agentID);
352 // when avies are on the same region.
353 IClientAPI client = LocateClientObject(agentID);
354 if (client != null)
355 return client.FirstName + " " + client.LastName;
356 else
357 return base.GetFriendshipRequesterName(agentID);
358 } 290 }
359 291
360 protected override string FriendshipMessage(string friendID) 292 protected override string FriendshipMessage(string friendID)
@@ -392,10 +324,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
392 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); 324 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
393 if (agentClientCircuit != null) 325 if (agentClientCircuit != null)
394 { 326 {
395 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); 327 //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
396 328
397 finfos = FriendsService.GetFriends(agentUUI); 329 finfos = FriendsService.GetFriends(client.AgentId.ToString());
398 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); 330 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
399 } 331 }
400 332
401// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name); 333// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
@@ -454,16 +386,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
454 friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); 386 friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
455 } 387 }
456 388
457 // Are they both local users? 389 // Is the requester a local user?
458 if (agentIsLocal && friendIsLocal) 390 if (agentIsLocal)
459 { 391 {
460 // local grid users 392 // local grid users
461 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local"); 393 m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards.");
394
462 base.StoreBackwards(friendID, agentID); 395 base.StoreBackwards(friendID, agentID);
463 return; 396 return;
464 } 397 }
465 398
466 // no provision for this temporary friendship state 399 // no provision for this temporary friendship state when user is not local
467 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0); 400 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
468 } 401 }
469 402
@@ -501,12 +434,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
501 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode); 434 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
502 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); 435 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
503 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 436 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
437 RecacheFriends(agentClient);
504 } 438 }
505 if (friendClient != null) 439 if (friendClient != null)
506 { 440 {
507 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode); 441 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
508 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit); 442 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
509 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 443 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
444 RecacheFriends(friendClient);
510 } 445 }
511 446
512 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", 447 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
@@ -515,14 +450,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
515 // Generate a random 8-character hex number that will sign this friendship 450 // Generate a random 8-character hex number that will sign this friendship
516 string secret = UUID.Random().ToString().Substring(0, 8); 451 string secret = UUID.Random().ToString().Substring(0, 8);
517 452
453 string theFriendUUID = friendUUI + ";" + secret;
454 string agentUUID = agentUUI + ";" + secret;
455
518 if (agentIsLocal) // agent is local, 'friend' is foreigner 456 if (agentIsLocal) // agent is local, 'friend' is foreigner
519 { 457 {
520 // This may happen when the agent returned home, in which case the friend is not there 458 // This may happen when the agent returned home, in which case the friend is not there
521 // We need to look for its information in the friends list itself 459 // We need to look for its information in the friends list itself
460 FriendInfo[] finfos = null;
522 bool confirming = false; 461 bool confirming = false;
523 if (friendUUI == string.Empty) 462 if (friendUUI == string.Empty)
524 { 463 {
525 FriendInfo[] finfos = GetFriends(agentID); 464 finfos = GetFriends(agentID);
526 foreach (FriendInfo finfo in finfos) 465 foreach (FriendInfo finfo in finfos)
527 { 466 {
528 if (finfo.TheirFlags == -1) 467 if (finfo.TheirFlags == -1)
@@ -530,29 +469,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
530 if (finfo.Friend.StartsWith(friendID.ToString())) 469 if (finfo.Friend.StartsWith(friendID.ToString()))
531 { 470 {
532 friendUUI = finfo.Friend; 471 friendUUI = finfo.Friend;
472 theFriendUUID = friendUUI;
473 UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty;
474 // If it's confirming the friendship, we already have the full UUI with the secret
475 if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
476 {
477 agentUUID = agentUUI + ";" + secret;
478 m_uMan.AddUser(utmp, first, last, url);
479 }
533 confirming = true; 480 confirming = true;
481 break;
534 } 482 }
535 } 483 }
536 } 484 }
537 } 485 if (!confirming)
486 {
487 friendUUI = m_uMan.GetUserUUI(friendID);
488 theFriendUUID = friendUUI + ";" + secret;
489 }
490
491 friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
538 492
539 // If it's confirming the friendship, we already have the full friendUUI with the secret 493 // m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
540 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; 494 // agentUUI, friendUUI, agentFriendService, friendFriendService);
495
496 }
497
498 // Delete any previous friendship relations
499 DeletePreviousRelations(agentID, friendID);
541 500
542 // store in the local friends service a reference to the foreign friend 501 // store in the local friends service a reference to the foreign friend
543 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); 502 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
544 // and also the converse 503 // and also the converse
545 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); 504 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
546 505
547 if (!confirming && friendClientCircuit != null) 506 //if (!confirming)
548 { 507 //{
549 // store in the foreign friends service a reference to the local agent 508 // store in the foreign friends service a reference to the local agent
550 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); 509 HGFriendsServicesConnector friendsConn = null;
551 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); 510 if (friendClientCircuit != null) // the friend is here, validate session
552 } 511 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
512 else // the friend is not here, he initiated the request in his home world
513 friendsConn = new HGFriendsServicesConnector(friendFriendService);
514
515 friendsConn.NewFriendship(friendID, agentUUID);
516 //}
553 } 517 }
554 else if (friendIsLocal) // 'friend' is local, agent is foreigner 518 else if (friendIsLocal) // 'friend' is local, agent is foreigner
555 { 519 {
520 // Delete any previous friendship relations
521 DeletePreviousRelations(agentID, friendID);
522
556 // store in the local friends service a reference to the foreign agent 523 // store in the local friends service a reference to the foreign agent
557 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); 524 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
558 // and also the converse 525 // and also the converse
@@ -582,6 +549,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
582 // my brain hurts now 549 // my brain hurts now
583 } 550 }
584 551
552 private void DeletePreviousRelations(UUID a1, UUID a2)
553 {
554 // Delete any previous friendship relations
555 FriendInfo[] finfos = null;
556 FriendInfo f = null;
557 finfos = GetFriends(a1);
558 if (finfos != null)
559 {
560 f = GetFriend(finfos, a2);
561 if (f != null)
562 {
563 FriendsService.Delete(a1, f.Friend);
564 // and also the converse
565 FriendsService.Delete(f.Friend, a1.ToString());
566 }
567 }
568
569 finfos = GetFriends(a2);
570 if (finfos != null)
571 {
572 f = GetFriend(finfos, a1);
573 if (f != null)
574 {
575 FriendsService.Delete(a2, f.Friend);
576 // and also the converse
577 FriendsService.Delete(f.Friend, a2.ToString());
578 }
579 }
580 }
581
585 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) 582 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
586 { 583 {
587 Boolean agentIsLocal = true; 584 Boolean agentIsLocal = true;
@@ -684,5 +681,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
684 friendConn.DeleteFriendship(foreignUser, localUser, secret); 681 friendConn.DeleteFriendship(foreignUser, localUser, secret);
685 } 682 }
686 } 683 }
684
685 protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
686 {
687 if (base.ForwardFriendshipOffer(agentID, friendID, im))
688 return true;
689
690 // OK, that didn't work, so let's try to find this user somewhere
691 if (!m_uMan.IsLocalGridUser(friendID))
692 {
693 string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
694 if (friendsURL != string.Empty)
695 {
696 m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL);
697 GridRegion region = new GridRegion();
698 region.ServerURI = friendsURL;
699
700 string name = im.fromAgentName;
701 if (m_uMan.IsLocalGridUser(agentID))
702 {
703 IClientAPI agentClient = LocateClientObject(agentID);
704 AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
705 string agentHomeService = string.Empty;
706 try
707 {
708 agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString();
709 string lastname = "@" + new Uri(agentHomeService).Authority;
710 string firstname = im.fromAgentName.Replace(" ", ".");
711 name = firstname + lastname;
712 }
713 catch (KeyNotFoundException)
714 {
715 m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID);
716 return false;
717 }
718 catch (NullReferenceException)
719 {
720 m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID);
721 return false;
722 }
723 catch (UriFormatException)
724 {
725 m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID);
726 return false;
727 }
728 }
729
730 m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name);
731
732 return true;
733 }
734 }
735
736 return false;
737 }
738
739 public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
740 {
741 if (base.LocalFriendshipOffered(toID, im))
742 {
743 if (im.fromAgentName.Contains("@"))
744 {
745 string[] parts = im.fromAgentName.Split(new char[] { '@' });
746 if (parts.Length == 2)
747 m_uMan.AddUser(new UUID(im.fromAgentID), parts[0], "http://" + parts[1]);
748 }
749 return true;
750 }
751 return false;
752 }
687 } 753 }
688} \ No newline at end of file 754} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 66de8e4..4eecaa2 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -71,43 +71,52 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
71 71
72 protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users) 72 protected override void AddAdditionalUsers(UUID avatarID, string query, List<UserData> users)
73 { 73 {
74 string[] words = query.Split(new char[] { ' ' }); 74 if (query.Contains("@")) // First.Last@foo.com, maybe?
75
76 for (int i = 0; i < words.Length; i++)
77 { 75 {
78 if (words[i].Length < 3) 76 string[] words = query.Split(new char[] { '@' });
77 if (words.Length != 2)
79 { 78 {
80 if (i != words.Length - 1) 79 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", query);
81 Array.Copy(words, i + 1, words, i, words.Length - i - 1); 80 return;
82 Array.Resize(ref words, words.Length - 1);
83 } 81 }
84 }
85 82
86 if (words.Length == 0 || words.Length > 2) 83 words[0] = words[0].Trim(); // it has at least 1
87 return; 84 words[1] = words[1].Trim();
88 85
89 if (words.Length == 2) // First.Last @foo.com, maybe? 86 if (words[0] == String.Empty) // query was @foo.com?
90 { 87 {
91 bool found = false; 88 foreach (UserData d in m_UserCache.Values)
89 {
90 if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
91 users.Add(d);
92 }
93
94 // We're done
95 return;
96 }
97
98 // words.Length == 2 and words[0] != string.empty
99 // first.last@foo.com ?
92 foreach (UserData d in m_UserCache.Values) 100 foreach (UserData d in m_UserCache.Values)
93 { 101 {
94 if (d.LastName.StartsWith("@") && 102 if (d.LastName.StartsWith("@") &&
95 d.FirstName.ToLower().Equals(words[0].ToLower()) && 103 d.FirstName.ToLower().Equals(words[0].ToLower()) &&
96 d.LastName.ToLower().Equals(words[1].ToLower())) 104 d.LastName.ToLower().Equals("@" + words[1].ToLower()))
97 { 105 {
98 users.Add(d); 106 users.Add(d);
99 found = true; 107 // It's cached. We're done
100 break; 108 return;
101 } 109 }
102 } 110 }
103 111
104 if (!found && words[1].StartsWith("@") && words[0].Contains(".")) // This is it! Let's ask the other world 112 // This is it! Let's ask the other world
113 if (words[0].Contains("."))
105 { 114 {
106 string[] names = words[0].Split(new char[] { '.' }); 115 string[] names = words[0].Split(new char[] { '.' });
107 if (names.Length >= 2) 116 if (names.Length >= 2)
108 { 117 {
109 118
110 string uriStr = "http://" + words[1].Substring(1); // remove the @ 119 string uriStr = "http://" + words[1];
111 // Let's check that the last name is a valid address 120 // Let's check that the last name is a valid address
112 try 121 try
113 { 122 {
@@ -115,6 +124,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
115 } 124 }
116 catch (UriFormatException) 125 catch (UriFormatException)
117 { 126 {
127 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
118 return; 128 return;
119 } 129 }
120 130
@@ -125,26 +135,26 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
125 UserData ud = new UserData(); 135 UserData ud = new UserData();
126 ud.Id = userID; 136 ud.Id = userID;
127 ud.FirstName = words[0]; 137 ud.FirstName = words[0];
128 ud.LastName = words[1]; 138 ud.LastName = "@" + words[1];
129 users.Add(ud); 139 users.Add(ud);
130 AddUser(userID, ud.FirstName, ud.LastName, uriStr); 140 AddUser(userID, names[0], names[1], uriStr);
131 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0} {1} found", words[0], words[1]); 141 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
132 } 142 }
133 else 143 else
134 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0} {1} not found", words[0], words[1]); 144 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
135 } 145 }
136 } 146 }
137 } 147 }
138 else 148 //else
139 { 149 //{
140 foreach (UserData d in m_UserCache.Values) 150 // foreach (UserData d in m_UserCache.Values)
141 { 151 // {
142 if (d.LastName.StartsWith("@") && 152 // if (d.LastName.StartsWith("@") &&
143 (d.FirstName.ToLower().StartsWith(query.ToLower()) || 153 // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
144 d.LastName.ToLower().StartsWith(query.ToLower()))) 154 // d.LastName.ToLower().StartsWith(query.ToLower())))
145 users.Add(d); 155 // users.Add(d);
146 } 156 // }
147 } 157 //}
148 } 158 }
149 159
150 } 160 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index cb562a2..0397478 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -299,7 +299,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
299 299
300 public string GetUserName(UUID uuid) 300 public string GetUserName(UUID uuid)
301 { 301 {
302 //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
303 string[] names = GetUserNames(uuid); 302 string[] names = GetUserNames(uuid);
304 if (names.Length == 2) 303 if (names.Length == 2)
305 { 304 {
@@ -340,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
340 339
341 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) 340 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
342 { 341 {
343 m_log.DebugFormat( 342 //m_log.DebugFormat(
344 "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}", 343 // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
345 serverType, userdata.HomeURL, userID); 344 // serverType, userdata.HomeURL, userID);
346 345
347 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); 346 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
348 userdata.ServerURLs = uConn.GetServerURLs(userID); 347 userdata.ServerURLs = uConn.GetServerURLs(userID);
@@ -401,11 +400,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
401 400
402 public void AddUser(UUID uuid, string first, string last, string homeURL) 401 public void AddUser(UUID uuid, string first, string last, string homeURL)
403 { 402 {
403 // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
404
404 AddUser(uuid, homeURL + ";" + first + " " + last); 405 AddUser(uuid, homeURL + ";" + first + " " + last);
405 } 406 }
406 407
407 public void AddUser (UUID id, string creatorData) 408 public void AddUser (UUID id, string creatorData)
408 { 409 {
410 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
411
409 UserData oldUser; 412 UserData oldUser;
410 //lock the whole block - prevent concurrent update 413 //lock the whole block - prevent concurrent update
411 lock (m_UserCache) 414 lock (m_UserCache)
@@ -431,9 +434,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
431 return; 434 return;
432 } 435 }
433 } 436 }
434// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
435 437
436 UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id); 438 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
437 439
438 if (account != null) 440 if (account != null)
439 { 441 {
@@ -482,9 +484,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
482 lock (m_UserCache) 484 lock (m_UserCache)
483 m_UserCache[user.Id] = user; 485 m_UserCache[user.Id] = user;
484 486
485// m_log.DebugFormat( 487 //m_log.DebugFormat(
486// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", 488 // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
487// user.Id, user.FirstName, user.LastName, user.HomeURL); 489 // user.Id, user.FirstName, user.LastName, user.HomeURL);
488 } 490 }
489 491
490 public bool IsLocalGridUser(UUID uuid) 492 public bool IsLocalGridUser(UUID uuid)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index 89abbb2..8df1c7b 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -48,8 +48,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
48 private static bool m_Enabled = false; 48 private static bool m_Enabled = false;
49 49
50 private IConfigSource m_Config; 50 private IConfigSource m_Config;
51 bool m_Registered = false; 51 private bool m_Registered = false;
52 GatekeeperServiceInConnector m_HypergridHandler; 52 private string m_LocalServiceDll = String.Empty;
53 private GatekeeperServiceInConnector m_HypergridHandler;
54 private UserAgentServerConnector m_UASHandler;
53 55
54 #region IRegionModule interface 56 #region IRegionModule interface
55 57
@@ -63,6 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
63 if (m_Enabled) 65 if (m_Enabled)
64 { 66 {
65 m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled"); 67 m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled");
68 IConfig fconfig = config.Configs["FriendsService"];
69 if (fconfig != null)
70 {
71 m_LocalServiceDll = fconfig.GetString("LocalServiceModule", m_LocalServiceDll);
72 if (m_LocalServiceDll == String.Empty)
73 m_log.WarnFormat("[HGGRID IN CONNECTOR]: Friends LocalServiceModule config missing");
74 }
66 } 75 }
67 76
68 } 77 }
@@ -91,7 +100,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
91 { 100 {
92 if (!m_Enabled) 101 if (!m_Enabled)
93 return; 102 return;
94
95 } 103 }
96 104
97 public void RemoveRegion(Scene scene) 105 public void RemoveRegion(Scene scene)
@@ -112,14 +120,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
112 m_log.Info("[HypergridService]: Starting..."); 120 m_log.Info("[HypergridService]: Starting...");
113 121
114 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>(); 122 ISimulationService simService = scene.RequestModuleInterface<ISimulationService>();
123 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>();
124 Object[] args = new Object[] { m_Config };
125 IFriendsService friendsService = ServerUtils.LoadPlugin<IFriendsService>(m_LocalServiceDll, args);
126
115 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); 127 m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
116 128
117 IFriendsSimConnector friendsConn = scene.RequestModuleInterface<IFriendsSimConnector>(); 129 m_UASHandler = new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
118 new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn); 130
119 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); 131 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
120 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService"); 132
133 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService", friendsConn);
121 } 134 }
122 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); 135 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
136 scene.RegisterModuleInterface<IUserAgentService>(m_UASHandler.HomeUsersService);
123 } 137 }
124 138
125 #endregion 139 #endregion