aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorUbitUmarov2012-03-21 02:45:33 +0000
committerUbitUmarov2012-03-21 02:45:33 +0000
commit312f0c69703e5914f377fd05871319c1ed6f3abf (patch)
tree29703861d132c793ec3bbcfbb202006ff6c53415 /OpenSim
parentChanges of PrimShapeType should now work with UbitOde ( almost untested ) (diff)
parentMerge branch 'master' into careminster (diff)
downloadopensim-SC-312f0c69703e5914f377fd05871319c1ed6f3abf.zip
opensim-SC-312f0c69703e5914f377fd05871319c1ed6f3abf.tar.gz
opensim-SC-312f0c69703e5914f377fd05871319c1ed6f3abf.tar.bz2
opensim-SC-312f0c69703e5914f377fd05871319c1ed6f3abf.tar.xz
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Util.cs150
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs29
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs290
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs102
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs21
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs26
-rw-r--r--OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs25
-rw-r--r--OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs27
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs26
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs159
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs37
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs20
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs67
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs61
-rw-r--r--OpenSim/Services/HypergridService/HGFriendsService.cs301
-rw-r--r--OpenSim/Services/HypergridService/UserAgentService.cs10
-rw-r--r--OpenSim/Services/Interfaces/IHypergridServices.cs13
18 files changed, 1042 insertions, 324 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index d89bb3a..728cda0 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -35,7 +35,7 @@ using System.IO;
35using System.IO.Compression; 35using System.IO.Compression;
36using System.Net; 36using System.Net;
37using System.Net.Sockets; 37using System.Net.Sockets;
38using System.Reflection; 38using System.Reflection;
39using System.Runtime.InteropServices; 39using System.Runtime.InteropServices;
40using System.Runtime.Serialization; 40using System.Runtime.Serialization;
41using System.Runtime.Serialization.Formatters.Binary; 41using System.Runtime.Serialization.Formatters.Binary;
@@ -378,20 +378,20 @@ namespace OpenSim.Framework
378 } 378 }
379 379
380 return sb.ToString(); 380 return sb.ToString();
381 } 381 }
382 382
383 /// <summary> 383 /// <summary>
384 /// Is the platform Windows? 384 /// Is the platform Windows?
385 /// </summary> 385 /// </summary>
386 /// <returns>true if so, false otherwise</returns> 386 /// <returns>true if so, false otherwise</returns>
387 public static bool IsWindows() 387 public static bool IsWindows()
388 { 388 {
389 PlatformID platformId = Environment.OSVersion.Platform; 389 PlatformID platformId = Environment.OSVersion.Platform;
390 390
391 return (platformId == PlatformID.Win32NT 391 return (platformId == PlatformID.Win32NT
392 || platformId == PlatformID.Win32S 392 || platformId == PlatformID.Win32S
393 || platformId == PlatformID.Win32Windows 393 || platformId == PlatformID.Win32Windows
394 || platformId == PlatformID.WinCE); 394 || platformId == PlatformID.WinCE);
395 } 395 }
396 396
397 public static bool LoadArchSpecificWindowsDll(string libraryName) 397 public static bool LoadArchSpecificWindowsDll(string libraryName)
@@ -1516,27 +1516,27 @@ namespace OpenSim.Framework
1516 } 1516 }
1517 1517
1518 return data; 1518 return data;
1519 } 1519 }
1520 1520
1521 /// <summary> 1521 /// <summary>
1522 /// Used to trigger an early library load on Windows systems. 1522 /// Used to trigger an early library load on Windows systems.
1523 /// </summary> 1523 /// </summary>
1524 /// <remarks> 1524 /// <remarks>
1525 /// Required to get 32-bit and 64-bit processes to automatically use the 1525 /// Required to get 32-bit and 64-bit processes to automatically use the
1526 /// appropriate native library. 1526 /// appropriate native library.
1527 /// </remarks> 1527 /// </remarks>
1528 /// <param name="dllToLoad"></param> 1528 /// <param name="dllToLoad"></param>
1529 /// <returns></returns> 1529 /// <returns></returns>
1530 [DllImport("kernel32.dll")] 1530 [DllImport("kernel32.dll")]
1531 public static extern IntPtr LoadLibrary(string dllToLoad); 1531 public static extern IntPtr LoadLibrary(string dllToLoad);
1532 1532
1533 /// <summary> 1533 /// <summary>
1534 /// Determine whether the current process is 64 bit 1534 /// Determine whether the current process is 64 bit
1535 /// </summary> 1535 /// </summary>
1536 /// <returns>true if so, false if not</returns> 1536 /// <returns>true if so, false if not</returns>
1537 public static bool Is64BitProcess() 1537 public static bool Is64BitProcess()
1538 { 1538 {
1539 return IntPtr.Size == 8; 1539 return IntPtr.Size == 8;
1540 } 1540 }
1541 1541
1542 #region FireAndForget Threading Pattern 1542 #region FireAndForget Threading Pattern
@@ -1952,11 +1952,12 @@ namespace OpenSim.Framework
1952 #region Universal User Identifiers 1952 #region Universal User Identifiers
1953 /// <summary> 1953 /// <summary>
1954 /// </summary> 1954 /// </summary>
1955 /// <param name="value">uuid[;endpoint[;name]]</param> 1955 /// <param name="value">uuid[;endpoint[;first last[;secret]]]</param>
1956 /// <param name="uuid"></param> 1956 /// <param name="uuid">the uuid part</param>
1957 /// <param name="url"></param> 1957 /// <param name="url">the endpoint part (e.g. http://foo.com)</param>
1958 /// <param name="firstname"></param> 1958 /// <param name="firstname">the first name part (e.g. Test)</param>
1959 /// <param name="lastname"></param> 1959 /// <param name="lastname">the last name part (e.g User)</param>
1960 /// <param name="secret">the secret part</param>
1960 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret) 1961 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
1961 { 1962 {
1962 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty; 1963 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
@@ -1985,31 +1986,64 @@ namespace OpenSim.Framework
1985 } 1986 }
1986 1987
1987 /// <summary> 1988 /// <summary>
1988 /// 1989 /// Produces a universal (HG) system-facing identifier given the information
1989 /// </summary> 1990 /// </summary>
1990 /// <param name="acircuit"></param> 1991 /// <param name="acircuit"></param>
1991 /// <returns>uuid[;endpoint[;name]]</returns> 1992 /// <returns>uuid[;homeURI[;first last]]</returns>
1992 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit) 1993 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
1993 { 1994 {
1994 if (acircuit.ServiceURLs.ContainsKey("HomeURI")) 1995 if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
1996 return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString());
1997 else
1998 return acircuit.AgentID.ToString();
1999 }
2000
2001 /// <summary>
2002 /// Produces a universal (HG) system-facing identifier given the information
2003 /// </summary>
2004 /// <param name="id">UUID of the user</param>
2005 /// <param name="firstName">first name (e.g Test)</param>
2006 /// <param name="lastName">last name (e.g. User)</param>
2007 /// <param name="homeURI">homeURI (e.g. http://foo.com)</param>
2008 /// <returns>a string of the form uuid[;homeURI[;first last]]</returns>
2009 public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI)
2010 {
2011 string agentsURI = homeURI;
2012 if (!agentsURI.EndsWith("/"))
2013 agentsURI += "/";
2014
2015 // This is ugly, but there's no other way, given that the name is changed
2016 // in the agent circuit data for foreigners
2017 if (lastName.Contains("@"))
1995 { 2018 {
1996 string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString(); 2019 string[] parts = firstName.Split(new char[] { '.' });
1997 if (!agentsURI.EndsWith("/")) 2020 if (parts.Length == 2)
1998 agentsURI += "/"; 2021 return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
2022 }
2023 return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
1999 2024
2000 // This is ugly, but there's no other way, given that the name is changed 2025 }
2001 // in the agent circuit data for foreigners 2026
2002 if (acircuit.lastname.Contains("@")) 2027 /// <summary>
2003 { 2028 /// Produces a universal (HG) user-facing name given the information
2004 string[] parts = acircuit.firstname.Split(new char[] { '.' }); 2029 /// </summary>
2005 if (parts.Length == 2) 2030 /// <param name="firstName"></param>
2006 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1]; 2031 /// <param name="lastName"></param>
2007 } 2032 /// <param name="homeURI"></param>
2008 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname; 2033 /// <returns>string of the form first.last @foo.com or first last</returns>
2034 public static string UniversalName(String firstName, String lastName, String homeURI)
2035 {
2036 Uri uri = null;
2037 try
2038 {
2039 uri = new Uri(homeURI);
2009 } 2040 }
2010 else 2041 catch (UriFormatException)
2011 return acircuit.AgentID.ToString(); 2042 {
2012 } 2043 return firstName + " " + lastName;
2044 }
2045 return firstName + "." + lastName + " " + "@" + uri.Authority;
2046 }
2013 #endregion 2047 #endregion
2014 } 2048 }
2015} 2049}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 5d94ff7..ca8d8e6 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
@@ -762,7 +779,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
762 779
763 #region Local 780 #region Local
764 781
765 public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im) 782 public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
766 { 783 {
767 IClientAPI friendClient = LocateClientObject(toID); 784 IClientAPI friendClient = LocateClientObject(toID);
768 if (friendClient != null) 785 if (friendClient != null)
@@ -925,7 +942,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
925 return FriendsService.GetFriends(client.AgentId); 942 return FriendsService.GetFriends(client.AgentId);
926 } 943 }
927 944
928 private void RecacheFriends(IClientAPI client) 945 protected void RecacheFriends(IClientAPI client)
929 { 946 {
930 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event 947 // FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
931 // is on the critical path for transferring an avatar from one region to another. 948 // 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 8077a7a..4eecaa2 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -71,52 +71,90 @@ 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 {
91 bool found = false;
92 foreach (UserData d in m_UserCache.Values)
93 { 87 {
94 if (d.LastName.StartsWith("@") && 88 foreach (UserData d in m_UserCache.Values)
95 (d.FirstName.ToLower().Equals(words[0].ToLower()) ||
96 d.LastName.ToLower().Equals(words[1].ToLower())))
97 { 89 {
98 users.Add(d); 90 if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
99 found = true; 91 users.Add(d);
100 break;
101 } 92 }
93
94 // We're done
95 return;
102 } 96 }
103 if (!found) // This is it! Let's ask the other world 97
104 { 98 // words.Length == 2 and words[0] != string.empty
105 // TODO 99 // first.last@foo.com ?
106 //UserAgentServiceConnector uasConn = new UserAgentServiceConnector(words[0]);
107 //uasConn.GetUserInfo(...);
108 }
109 }
110 else
111 {
112 foreach (UserData d in m_UserCache.Values) 100 foreach (UserData d in m_UserCache.Values)
113 { 101 {
114 if (d.LastName.StartsWith("@") && 102 if (d.LastName.StartsWith("@") &&
115 (d.FirstName.ToLower().StartsWith(query.ToLower()) || 103 d.FirstName.ToLower().Equals(words[0].ToLower()) &&
116 d.LastName.ToLower().StartsWith(query.ToLower()))) 104 d.LastName.ToLower().Equals("@" + words[1].ToLower()))
105 {
117 users.Add(d); 106 users.Add(d);
107 // It's cached. We're done
108 return;
109 }
110 }
111
112 // This is it! Let's ask the other world
113 if (words[0].Contains("."))
114 {
115 string[] names = words[0].Split(new char[] { '.' });
116 if (names.Length >= 2)
117 {
118
119 string uriStr = "http://" + words[1];
120 // Let's check that the last name is a valid address
121 try
122 {
123 new Uri(uriStr);
124 }
125 catch (UriFormatException)
126 {
127 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
128 return;
129 }
130
131 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
132 UUID userID = uasConn.GetUUID(names[0], names[1]);
133 if (!userID.Equals(UUID.Zero))
134 {
135 UserData ud = new UserData();
136 ud.Id = userID;
137 ud.FirstName = words[0];
138 ud.LastName = "@" + words[1];
139 users.Add(ud);
140 AddUser(userID, names[0], names[1], uriStr);
141 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
142 }
143 else
144 m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
145 }
118 } 146 }
119 } 147 }
148 //else
149 //{
150 // foreach (UserData d in m_UserCache.Values)
151 // {
152 // if (d.LastName.StartsWith("@") &&
153 // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
154 // d.LastName.ToLower().StartsWith(query.ToLower())))
155 // users.Add(d);
156 // }
157 //}
120 } 158 }
121 159
122 } 160 }
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 23ef0fc..0397478 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -183,7 +183,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
183 List<UserData> users = new List<UserData>(); 183 List<UserData> users = new List<UserData>();
184 if (accs != null) 184 if (accs != null)
185 { 185 {
186 m_log.DebugFormat("[USER MANAGEMENT MODULE]: Found {0} users", accs.Count);
187 foreach (UserAccount acc in accs) 186 foreach (UserAccount acc in accs)
188 { 187 {
189 UserData ud = new UserData(); 188 UserData ud = new UserData();
@@ -300,7 +299,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
300 299
301 public string GetUserName(UUID uuid) 300 public string GetUserName(UUID uuid)
302 { 301 {
303 //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
304 string[] names = GetUserNames(uuid); 302 string[] names = GetUserNames(uuid);
305 if (names.Length == 2) 303 if (names.Length == 2)
306 { 304 {
@@ -341,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
341 339
342 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty) 340 if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
343 { 341 {
344 m_log.DebugFormat( 342 //m_log.DebugFormat(
345 "[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}",
346 serverType, userdata.HomeURL, userID); 344 // serverType, userdata.HomeURL, userID);
347 345
348 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL); 346 UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
349 userdata.ServerURLs = uConn.GetServerURLs(userID); 347 userdata.ServerURLs = uConn.GetServerURLs(userID);
@@ -402,11 +400,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
402 400
403 public void AddUser(UUID uuid, string first, string last, string homeURL) 401 public void AddUser(UUID uuid, string first, string last, string homeURL)
404 { 402 {
403 // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
404
405 AddUser(uuid, homeURL + ";" + first + " " + last); 405 AddUser(uuid, homeURL + ";" + first + " " + last);
406 } 406 }
407 407
408 public void AddUser (UUID id, string creatorData) 408 public void AddUser (UUID id, string creatorData)
409 { 409 {
410 //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
411
410 UserData oldUser; 412 UserData oldUser;
411 //lock the whole block - prevent concurrent update 413 //lock the whole block - prevent concurrent update
412 lock (m_UserCache) 414 lock (m_UserCache)
@@ -432,9 +434,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
432 return; 434 return;
433 } 435 }
434 } 436 }
435// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
436 437
437 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);
438 439
439 if (account != null) 440 if (account != null)
440 { 441 {
@@ -483,9 +484,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
483 lock (m_UserCache) 484 lock (m_UserCache)
484 m_UserCache[user.Id] = user; 485 m_UserCache[user.Id] = user;
485 486
486// m_log.DebugFormat( 487 //m_log.DebugFormat(
487// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}", 488 // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
488// user.Id, user.FirstName, user.LastName, user.HomeURL); 489 // user.Id, user.FirstName, user.LastName, user.HomeURL);
489 } 490 }
490 491
491 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
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
index f4cca96..8b13b01 100644
--- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
+++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs
@@ -681,28 +681,17 @@ namespace OpenSim.Region.CoreModules.World.Estate
681 TriggerEstateMessage(senderID, senderName, message); 681 TriggerEstateMessage(senderID, senderName, message);
682 } 682 }
683 683
684 private void handleEstateDebugRegionRequest(IClientAPI remote_client, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics) 684 private void handleEstateDebugRegionRequest(
685 IClientAPI remote_client, UUID invoice, UUID senderID,
686 bool disableScripts, bool disableCollisions, bool disablePhysics)
685 { 687 {
686 if (physics) 688 Scene.RegionInfo.RegionSettings.DisablePhysics = disablePhysics;
687 Scene.RegionInfo.RegionSettings.DisablePhysics = true; 689 Scene.RegionInfo.RegionSettings.DisableScripts = disableScripts;
688 else 690 Scene.RegionInfo.RegionSettings.DisableCollisions = disableCollisions;
689 Scene.RegionInfo.RegionSettings.DisablePhysics = false;
690
691 if (scripted)
692 Scene.RegionInfo.RegionSettings.DisableScripts = true;
693 else
694 Scene.RegionInfo.RegionSettings.DisableScripts = false;
695
696 if (collisionEvents)
697 Scene.RegionInfo.RegionSettings.DisableCollisions = true;
698 else
699 Scene.RegionInfo.RegionSettings.DisableCollisions = false;
700
701
702 Scene.RegionInfo.RegionSettings.Save(); 691 Scene.RegionInfo.RegionSettings.Save();
703 TriggerRegionInfoChange(); 692 TriggerRegionInfoChange();
704 693
705 Scene.SetSceneCoreDebug(scripted, collisionEvents, physics); 694 Scene.SetSceneCoreDebug(disableScripts, disableCollisions, disablePhysics);
706 } 695 }
707 696
708 private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) 697 private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey)
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 3efb7dd..4e6bfb8 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -132,7 +132,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
132 data.MapImageId = info.TerrainImage; 132 data.MapImageId = info.TerrainImage;
133 // ugh! V2-3 is very sensitive about the result being 133 // ugh! V2-3 is very sensitive about the result being
134 // exactly the same as the requested name 134 // exactly the same as the requested name
135 if (regionInfos.Count == 1) 135 if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
136 data.Name = mapNameOrig; 136 data.Name = mapNameOrig;
137 else 137 else
138 data.Name = info.RegionName; 138 data.Name = info.RegionName;
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 2a511e4..44ee453 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -193,7 +193,11 @@ namespace OpenSim.Region.Framework.Scenes
193 private int backupMS; 193 private int backupMS;
194 private int terrainMS; 194 private int terrainMS;
195 private int landMS; 195 private int landMS;
196 private int lastCompletedFrame; 196
197 /// <summary>
198 /// Tick at which the last frame was processed.
199 /// </summary>
200 private int m_lastFrameTick;
197 201
198 public bool CombineRegions = false; 202 public bool CombineRegions = false;
199 /// <summary> 203 /// <summary>
@@ -484,7 +488,7 @@ namespace OpenSim.Region.Framework.Scenes
484 public int MonitorBackupTime { get { return backupMS; } } 488 public int MonitorBackupTime { get { return backupMS; } }
485 public int MonitorTerrainTime { get { return terrainMS; } } 489 public int MonitorTerrainTime { get { return terrainMS; } }
486 public int MonitorLandTime { get { return landMS; } } 490 public int MonitorLandTime { get { return landMS; } }
487 public int MonitorLastFrameTick { get { return lastCompletedFrame; } } 491 public int MonitorLastFrameTick { get { return m_lastFrameTick; } }
488 492
489 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } } 493 public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return m_priorityScheme; } }
490 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } } 494 public bool IsReprioritizationEnabled { get { return m_reprioritizationEnabled; } }
@@ -1228,9 +1232,6 @@ namespace OpenSim.Region.Framework.Scenes
1228 1232
1229 while (!shuttingdown) 1233 while (!shuttingdown)
1230 Update(-1); 1234 Update(-1);
1231
1232 m_lastUpdate = Util.EnvironmentTickCount();
1233 m_firstHeartbeat = false;
1234 } 1235 }
1235 finally 1236 finally
1236 { 1237 {
@@ -1250,6 +1251,7 @@ namespace OpenSim.Region.Framework.Scenes
1250 1251
1251 float physicsFPS = 0f; 1252 float physicsFPS = 0f;
1252 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS; 1253 int tmpPhysicsMS, tmpPhysicsMS2, tmpAgentMS, tmpTempOnRezMS, evMS, backMS, terMS;
1254 int previousFrameTick;
1253 int maintc; 1255 int maintc;
1254 List<Vector3> coarseLocations; 1256 List<Vector3> coarseLocations;
1255 List<UUID> avatarUUIDs; 1257 List<UUID> avatarUUIDs;
@@ -1353,10 +1355,9 @@ namespace OpenSim.Region.Framework.Scenes
1353 // UpdateLand(); 1355 // UpdateLand();
1354 // landMS = Util.EnvironmentTickCountSubtract(ldMS); 1356 // landMS = Util.EnvironmentTickCountSubtract(ldMS);
1355 //} 1357 //}
1356 1358
1357 frameMS = Util.EnvironmentTickCountSubtract(maintc); 1359 frameMS = Util.EnvironmentTickCountSubtract(maintc);
1358 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS; 1360 otherMS = tempOnRezMS + eventMS + backupMS + terrainMS + landMS;
1359 lastCompletedFrame = Util.EnvironmentTickCount();
1360 1361
1361 // if (Frame%m_update_avatars == 0) 1362 // if (Frame%m_update_avatars == 0)
1362 // UpdateInWorldTime(); 1363 // UpdateInWorldTime();
@@ -1426,7 +1427,9 @@ namespace OpenSim.Region.Framework.Scenes
1426 // Tell the watchdog that this thread is still alive 1427 // Tell the watchdog that this thread is still alive
1427 Watchdog.UpdateThread(); 1428 Watchdog.UpdateThread();
1428 1429
1429 maintc = Util.EnvironmentTickCountSubtract(maintc); 1430// previousFrameTick = m_lastFrameTick;
1431 m_lastFrameTick = Util.EnvironmentTickCount();
1432 maintc = Util.EnvironmentTickCountSubtract(m_lastFrameTick, maintc);
1430 maintc = (int)(MinFrameTime * 1000) - maintc; 1433 maintc = (int)(MinFrameTime * 1000) - maintc;
1431 1434
1432 m_lastUpdate = Util.EnvironmentTickCount(); 1435 m_lastUpdate = Util.EnvironmentTickCount();
@@ -1435,10 +1438,14 @@ namespace OpenSim.Region.Framework.Scenes
1435 if (maintc > 0) 1438 if (maintc > 0)
1436 Thread.Sleep(maintc); 1439 Thread.Sleep(maintc);
1437 1440
1438// if (frameMS > (int)(MinFrameTime * 1000)) 1441 m_lastUpdate = Util.EnvironmentTickCount();
1442 m_firstHeartbeat = false;
1443
1444 // Optionally warn if a frame takes double the amount of time that it should.
1445// if (Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick) > (int)(MinFrameTime * 1000 * 2))
1439// m_log.WarnFormat( 1446// m_log.WarnFormat(
1440// "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}", 1447// "[SCENE]: Frame took {0} ms (desired max {1} ms) in {2}",
1441// frameMS, 1448// Util.EnvironmentTickCountSubtract(m_lastFrameTick, previousFrameTick),
1442// MinFrameTime * 1000, 1449// MinFrameTime * 1000,
1443// RegionInfo.RegionName); 1450// RegionInfo.RegionName);
1444 } 1451 }
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
index 82a7220..6c79c60 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
@@ -36,36 +36,42 @@ namespace OpenSim.Server.Handlers.Hypergrid
36{ 36{
37 public class HGFriendsServerConnector : ServiceConnector 37 public class HGFriendsServerConnector : ServiceConnector
38 { 38 {
39 private IFriendsService m_FriendsService;
40 private IUserAgentService m_UserAgentService; 39 private IUserAgentService m_UserAgentService;
40 private IHGFriendsService m_TheService;
41 private string m_ConfigName = "HGFriendsService"; 41 private string m_ConfigName = "HGFriendsService";
42 42
43 // Called from Robust
43 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) : 44 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName) 45 this(config, server, configName, null)
45 { 46 {
46 if (configName != string.Empty) 47
48 }
49
50 // Called from standalone configurations
51 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName, IFriendsSimConnector localConn)
52 : base(config, server, configName)
53 {
54 if (configName != string.Empty)
47 m_ConfigName = configName; 55 m_ConfigName = configName;
48 56
57 Object[] args = new Object[] { config, m_ConfigName, localConn };
58
49 IConfig serverConfig = config.Configs[m_ConfigName]; 59 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null) 60 if (serverConfig == null)
51 throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); 61 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
52 62
53 string theService = serverConfig.GetString("LocalServiceModule", 63 string theService = serverConfig.GetString("LocalServiceModule",
54 String.Empty); 64 String.Empty);
55
56 if (theService == String.Empty) 65 if (theService == String.Empty)
57 throw new Exception("No LocalServiceModule in config file"); 66 throw new Exception("No LocalServiceModule in config file");
58 67 m_TheService = ServerUtils.LoadPlugin<IHGFriendsService>(theService, args);
59 Object[] args = new Object[] { config };
60 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
61 68
62 theService = serverConfig.GetString("UserAgentService", string.Empty); 69 theService = serverConfig.GetString("UserAgentService", string.Empty);
63 if (theService == String.Empty) 70 if (theService == String.Empty)
64 throw new Exception("No UserAgentService in " + m_ConfigName); 71 throw new Exception("No UserAgentService in " + m_ConfigName);
72 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, new Object[] { config, localConn });
65 73
66 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args); 74 server.AddStreamHandler(new HGFriendsServerPostHandler(m_TheService, m_UserAgentService, localConn));
67
68 server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
69 } 75 }
70 } 76 }
71} 77}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
index 661507e..ca566f2 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -39,6 +39,7 @@ using System.Collections.Generic;
39using OpenSim.Server.Base; 39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces; 40using OpenSim.Services.Interfaces;
41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; 41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
42using GridRegion = OpenSim.Services.Interfaces.GridRegion;
42using OpenSim.Framework; 43using OpenSim.Framework;
43using OpenSim.Framework.Servers.HttpServer; 44using OpenSim.Framework.Servers.HttpServer;
44using OpenMetaverse; 45using OpenMetaverse;
@@ -49,15 +50,22 @@ namespace OpenSim.Server.Handlers.Hypergrid
49 { 50 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 52
52 private IFriendsService m_FriendsService;
53 private IUserAgentService m_UserAgentService; 53 private IUserAgentService m_UserAgentService;
54 private IFriendsSimConnector m_FriendsLocalSimConnector;
55 private IHGFriendsService m_TheService;
54 56
55 public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) : 57 public HGFriendsServerPostHandler(IHGFriendsService service, IUserAgentService uas, IFriendsSimConnector friendsConn) :
56 base("POST", "/hgfriends") 58 base("POST", "/hgfriends")
57 { 59 {
58 m_FriendsService = service; 60 m_TheService = service;
59 m_UserAgentService = uservice; 61 m_UserAgentService = uas;
60 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On"); 62 m_FriendsLocalSimConnector = friendsConn;
63
64 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On ({0})",
65 (m_FriendsLocalSimConnector == null ? "robust" : "standalone"));
66
67 if (m_TheService == null)
68 m_log.ErrorFormat("[HGFRIENDS HANDLER]: TheService is null!");
61 } 69 }
62 70
63 public override byte[] Handle(string path, Stream requestData, 71 public override byte[] Handle(string path, Stream requestData,
@@ -90,6 +98,26 @@ namespace OpenSim.Server.Handlers.Hypergrid
90 98
91 case "deletefriendship": 99 case "deletefriendship":
92 return DeleteFriendship(request); 100 return DeleteFriendship(request);
101
102 /* Same as inter-sim */
103 case "friendship_offered":
104 return FriendshipOffered(request);
105
106 case "validate_friendship_offered":
107 return ValidateFriendshipOffered(request);
108 /*
109 case "friendship_approved":
110 return FriendshipApproved(request);
111
112 case "friendship_denied":
113 return FriendshipDenied(request);
114
115 case "friendship_terminated":
116 return FriendshipTerminated(request);
117
118 case "grant_rights":
119 return GrantRights(request);
120 */
93 } 121 }
94 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); 122 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
95 } 123 }
@@ -126,39 +154,20 @@ namespace OpenSim.Server.Handlers.Hypergrid
126 return FailureResult(); 154 return FailureResult();
127 } 155 }
128 156
129 FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID); 157 int perms = m_TheService.GetFriendPerms(principalID, friendID);
130 foreach (FriendInfo finfo in friendsInfo) 158 if (perms < 0)
131 { 159 return FailureResult("Friend not found");
132 if (finfo.Friend.StartsWith(friendID.ToString()))
133 return SuccessResult(finfo.TheirFlags.ToString());
134 }
135 160
136 return FailureResult("Friend not found"); 161 return SuccessResult(perms.ToString());
137 } 162 }
138 163
139 byte[] NewFriendship(Dictionary<string, object> request) 164 byte[] NewFriendship(Dictionary<string, object> request)
140 { 165 {
141 if (!VerifyServiceKey(request)) 166 bool verified = VerifyServiceKey(request);
142 return FailureResult();
143 167
144 // OK, can proceed
145 FriendInfo friend = new FriendInfo(request); 168 FriendInfo friend = new FriendInfo(request);
146 UUID friendID;
147 string tmp = string.Empty;
148 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
149 return FailureResult();
150 169
151 170 bool success = m_TheService.NewFriendship(friend, verified);
152 m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
153
154 // If the friendship already exists, return fail
155 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
156 foreach (FriendInfo finfo in finfos)
157 if (finfo.Friend.StartsWith(friendID.ToString()))
158 return FailureResult();
159
160 // the user needs to confirm when he gets home
161 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
162 171
163 if (success) 172 if (success)
164 return SuccessResult(); 173 return SuccessResult();
@@ -174,25 +183,53 @@ namespace OpenSim.Server.Handlers.Hypergrid
174 secret = request["SECRET"].ToString(); 183 secret = request["SECRET"].ToString();
175 184
176 if (secret == string.Empty) 185 if (secret == string.Empty)
177 return FailureResult(); 186 return BoolResult(false);
178 187
179 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID); 188 bool success = m_TheService.DeleteFriendship(friend, secret);
180 foreach (FriendInfo finfo in finfos)
181 {
182 // We check the secret here
183 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
184 {
185 m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
186 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
187 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
188 189
189 return SuccessResult(); 190 return BoolResult(success);
190 } 191 }
191 }
192 192
193 return FailureResult(); 193 byte[] FriendshipOffered(Dictionary<string, object> request)
194 {
195 UUID fromID = UUID.Zero;
196 UUID toID = UUID.Zero;
197 string message = string.Empty;
198 string name = string.Empty;
199
200 m_log.DebugFormat("[HGFRIENDS HANDLER]: Friendship offered");
201 if (!request.ContainsKey("FromID") || !request.ContainsKey("ToID"))
202 return BoolResult(false);
203
204 if (!UUID.TryParse(request["ToID"].ToString(), out toID))
205 return BoolResult(false);
206
207 message = request["Message"].ToString();
208
209 if (!UUID.TryParse(request["FromID"].ToString(), out fromID))
210 return BoolResult(false);
211
212 if (request.ContainsKey("FromName"))
213 name = request["FromName"].ToString();
214
215 bool success = m_TheService.FriendshipOffered(fromID, name, toID, message);
216
217 return BoolResult(success);
194 } 218 }
195 219
220 byte[] ValidateFriendshipOffered(Dictionary<string, object> request)
221 {
222 FriendInfo friend = new FriendInfo(request);
223 UUID friendID = UUID.Zero;
224 if (!UUID.TryParse(friend.Friend, out friendID))
225 return BoolResult(false);
226
227 bool success = m_TheService.ValidateFriendshipOffered(friend.PrincipalID, friendID);
228
229 return BoolResult(success);
230 }
231
232
196 #endregion 233 #endregion
197 234
198 #region Misc 235 #region Misc
@@ -205,10 +242,15 @@ namespace OpenSim.Server.Handlers.Hypergrid
205 return false; 242 return false;
206 } 243 }
207 244
245 if (request["KEY"] == null || request["SESSIONID"] == null)
246 return false;
247
208 string serviceKey = request["KEY"].ToString(); 248 string serviceKey = request["KEY"].ToString();
209 string sessionStr = request["SESSIONID"].ToString(); 249 string sessionStr = request["SESSIONID"].ToString();
250
210 UUID sessionID; 251 UUID sessionID;
211 UUID.TryParse(sessionStr, out sessionID); 252 if (!UUID.TryParse(sessionStr, out sessionID) || serviceKey == string.Empty)
253 return false;
212 254
213 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey)) 255 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
214 { 256 {
@@ -256,7 +298,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
256 298
257 doc.AppendChild(rootElement); 299 doc.AppendChild(rootElement);
258 300
259 XmlElement result = doc.CreateElement("", "Result", ""); 301 XmlElement result = doc.CreateElement("", "RESULT", "");
260 result.AppendChild(doc.CreateTextNode("Success")); 302 result.AppendChild(doc.CreateTextNode("Success"));
261 303
262 rootElement.AppendChild(result); 304 rootElement.AppendChild(result);
@@ -289,7 +331,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
289 331
290 doc.AppendChild(rootElement); 332 doc.AppendChild(rootElement);
291 333
292 XmlElement result = doc.CreateElement("", "Result", ""); 334 XmlElement result = doc.CreateElement("", "RESULT", "");
293 result.AppendChild(doc.CreateTextNode("Failure")); 335 result.AppendChild(doc.CreateTextNode("Failure"));
294 336
295 rootElement.AppendChild(result); 337 rootElement.AppendChild(result);
@@ -302,6 +344,28 @@ namespace OpenSim.Server.Handlers.Hypergrid
302 return DocToBytes(doc); 344 return DocToBytes(doc);
303 } 345 }
304 346
347 private byte[] BoolResult(bool value)
348 {
349 XmlDocument doc = new XmlDocument();
350
351 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
352 "", "");
353
354 doc.AppendChild(xmlnode);
355
356 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
357 "");
358
359 doc.AppendChild(rootElement);
360
361 XmlElement result = doc.CreateElement("", "RESULT", "");
362 result.AppendChild(doc.CreateTextNode(value.ToString()));
363
364 rootElement.AppendChild(result);
365
366 return DocToBytes(doc);
367 }
368
305 private byte[] DocToBytes(XmlDocument doc) 369 private byte[] DocToBytes(XmlDocument doc)
306 { 370 {
307 MemoryStream ms = new MemoryStream(); 371 MemoryStream ms = new MemoryStream();
@@ -313,6 +377,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
313 return ms.ToArray(); 377 return ms.ToArray();
314 } 378 }
315 379
380
316 #endregion 381 #endregion
317 } 382 }
318} 383}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index 1bd3706..9a0e27e 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -52,6 +52,11 @@ namespace OpenSim.Server.Handlers.Hypergrid
52// MethodBase.GetCurrentMethod().DeclaringType); 52// MethodBase.GetCurrentMethod().DeclaringType);
53 53
54 private IUserAgentService m_HomeUsersService; 54 private IUserAgentService m_HomeUsersService;
55 public IUserAgentService HomeUsersService
56 {
57 get { return m_HomeUsersService; }
58 }
59
55 private string[] m_AuthorizedCallers; 60 private string[] m_AuthorizedCallers;
56 61
57 private bool m_VerifyCallers = false; 62 private bool m_VerifyCallers = false;
@@ -96,6 +101,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
96 101
97 server.AddXmlRPCHandler("locate_user", LocateUser, false); 102 server.AddXmlRPCHandler("locate_user", LocateUser, false);
98 server.AddXmlRPCHandler("get_uui", GetUUI, false); 103 server.AddXmlRPCHandler("get_uui", GetUUI, false);
104 server.AddXmlRPCHandler("get_uuid", GetUUID, false);
99 105
100 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler); 106 server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
101 } 107 }
@@ -410,8 +416,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
410 } 416 }
411 417
412 /// <summary> 418 /// <summary>
413 /// Locates the user. 419 /// Returns the UUI of a user given a UUID.
414 /// This is a sensitive operation, only authorized IP addresses can perform it.
415 /// </summary> 420 /// </summary>
416 /// <param name="request"></param> 421 /// <param name="request"></param>
417 /// <param name="remoteClient"></param> 422 /// <param name="remoteClient"></param>
@@ -445,5 +450,33 @@ namespace OpenSim.Server.Handlers.Hypergrid
445 450
446 } 451 }
447 452
453 /// <summary>
454 /// Gets the UUID of a user given First name, Last name.
455 /// </summary>
456 /// <param name="request"></param>
457 /// <param name="remoteClient"></param>
458 /// <returns></returns>
459 public XmlRpcResponse GetUUID(XmlRpcRequest request, IPEndPoint remoteClient)
460 {
461 Hashtable hash = new Hashtable();
462
463 Hashtable requestData = (Hashtable)request.Params[0];
464 //string host = (string)requestData["host"];
465 //string portstr = (string)requestData["port"];
466 if (requestData.ContainsKey("first") && requestData.ContainsKey("last"))
467 {
468 UUID userID = UUID.Zero;
469 string first = (string)requestData["first"];
470
471 string last = (string)requestData["last"];
472 UUID uuid = m_HomeUsersService.GetUUID(first, last);
473 hash["UUID"] = uuid.ToString();
474 }
475
476 XmlRpcResponse response = new XmlRpcResponse();
477 response.Value = hash;
478 return response;
479
480 }
448 } 481 }
449} 482}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
index eea9853..3fd0c53 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
@@ -43,8 +43,18 @@ namespace OpenSim.Services.Connectors.Friends
43 { 43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 45
46 protected virtual string ServicePath()
47 {
48 return "friends";
49 }
50
46 public bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message) 51 public bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message)
47 { 52 {
53 return FriendshipOffered(region, userID, friendID, message, String.Empty);
54 }
55
56 public virtual bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message, string userName)
57 {
48 Dictionary<string, object> sendData = new Dictionary<string, object>(); 58 Dictionary<string, object> sendData = new Dictionary<string, object>();
49 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); 59 //sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
50 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString(); 60 //sendData["VERSIONMAX"] = ProtocolVersions.ClientProtocolVersionMax.ToString();
@@ -53,9 +63,10 @@ namespace OpenSim.Services.Connectors.Friends
53 sendData["FromID"] = userID.ToString(); 63 sendData["FromID"] = userID.ToString();
54 sendData["ToID"] = friendID.ToString(); 64 sendData["ToID"] = friendID.ToString();
55 sendData["Message"] = message; 65 sendData["Message"] = message;
66 if (userName != String.Empty)
67 sendData["FromName"] = userName;
56 68
57 return Call(region, sendData); 69 return Call(region, sendData);
58
59 } 70 }
60 71
61 public bool FriendshipApproved(GridRegion region, UUID userID, string userName, UUID friendID) 72 public bool FriendshipApproved(GridRegion region, UUID userID, string userName, UUID friendID)
@@ -138,8 +149,11 @@ namespace OpenSim.Services.Connectors.Friends
138 if (region == null) 149 if (region == null)
139 return false; 150 return false;
140 151
141 m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: region: {0}", region.ExternalHostName + ":" + region.HttpPort); 152 string path = ServicePath();
142 string uri = "http://" + region.ExternalHostName + ":" + region.HttpPort + "/friends"; 153 if (!region.ServerURI.EndsWith("/"))
154 path = "/" + path;
155 string uri = region.ServerURI + path;
156 m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: calling {0}", uri);
143 157
144 try 158 try
145 { 159 {
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
index af4b0da..e3f3260 100644
--- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
@@ -40,7 +40,7 @@ using OpenMetaverse;
40 40
41namespace OpenSim.Services.Connectors.Hypergrid 41namespace OpenSim.Services.Connectors.Hypergrid
42{ 42{
43 public class HGFriendsServicesConnector 43 public class HGFriendsServicesConnector : FriendsSimConnector
44 { 44 {
45 private static readonly ILog m_log = 45 private static readonly ILog m_log =
46 LogManager.GetLogger( 46 LogManager.GetLogger(
@@ -66,6 +66,11 @@ namespace OpenSim.Services.Connectors.Hypergrid
66 m_SessionID = sessionID; 66 m_SessionID = sessionID;
67 } 67 }
68 68
69 protected override string ServicePath()
70 {
71 return "hgfriends";
72 }
73
69 #region IFriendsService 74 #region IFriendsService
70 75
71 public uint GetFriendPerms(UUID PrincipalID, UUID friendID) 76 public uint GetFriendPerms(UUID PrincipalID, UUID friendID)
@@ -187,23 +192,69 @@ namespace OpenSim.Services.Connectors.Hypergrid
187 { 192 {
188 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); 193 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
189 194
190 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null)) 195 if (replyData.ContainsKey("RESULT"))
191 { 196 {
192 bool success = false; 197 if (replyData["RESULT"].ToString().ToLower() == "true")
193 Boolean.TryParse(replyData["Result"].ToString(), out success); 198 return true;
194 return success; 199 else
200 return false;
195 } 201 }
196 else 202 else
197 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response", 203 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field");
198 PrincipalID, Friend); 204
199 } 205 }
200 else 206 else
201 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply"); 207 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply");
202 208
203 return false; 209 return false;
204 210
205 } 211 }
206 212
213 public bool ValidateFriendshipOffered(UUID fromID, UUID toID)
214 {
215 FriendInfo finfo = new FriendInfo();
216 finfo.PrincipalID = fromID;
217 finfo.Friend = toID.ToString();
218
219 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
220
221 sendData["METHOD"] = "validate_friendship_offered";
222
223 string reply = string.Empty;
224 string uri = m_ServerURI + "/hgfriends";
225 try
226 {
227 reply = SynchronousRestFormsRequester.MakeRequest("POST",
228 uri,
229 ServerUtils.BuildQueryString(sendData));
230 }
231 catch (Exception e)
232 {
233 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message);
234 return false;
235 }
236
237 if (reply != string.Empty)
238 {
239 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
240
241 if (replyData.ContainsKey("RESULT"))
242 {
243 if (replyData["RESULT"].ToString().ToLower() == "true")
244 return true;
245 else
246 return false;
247 }
248 else
249 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field");
250
251 }
252 else
253 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply");
254
255 return false;
256
257 }
207 #endregion 258 #endregion
208 } 259 }
209} \ No newline at end of file 260} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index d617aee..c07c6a6 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -787,13 +787,72 @@ namespace OpenSim.Services.Connectors.Hypergrid
787 } 787 }
788 catch 788 catch
789 { 789 {
790 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response."); 790 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetUUI response.");
791// reason = "Exception: " + e.Message; 791// reason = "Exception: " + e.Message;
792 } 792 }
793 793
794 return uui; 794 return uui;
795 } 795 }
796 796
797 public UUID GetUUID(String first, String last)
798 {
799 Hashtable hash = new Hashtable();
800 hash["first"] = first;
801 hash["last"] = last;
802
803 IList paramList = new ArrayList();
804 paramList.Add(hash);
805
806 XmlRpcRequest request = new XmlRpcRequest("get_uuid", paramList);
807 // string reason = string.Empty;
808
809 // Send and get reply
810 UUID uuid = UUID.Zero;
811 XmlRpcResponse response = null;
812 try
813 {
814 response = request.Send(m_ServerURL, 10000);
815 }
816 catch
817 {
818 m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUID", m_ServerURL);
819 // reason = "Exception: " + e.Message;
820 return uuid;
821 }
822
823 if (response.IsFault)
824 {
825 m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUID returned an error: {1}", m_ServerURL, response.FaultString);
826 // reason = "XMLRPC Fault";
827 return uuid;
828 }
829
830 hash = (Hashtable)response.Value;
831 //foreach (Object o in hash)
832 // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
833 try
834 {
835 if (hash == null)
836 {
837 m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUDI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
838 // reason = "Internal error 1";
839 return uuid;
840 }
841
842 // Here's the actual response
843 if (hash.ContainsKey("UUID"))
844 UUID.TryParse(hash["UUID"].ToString(), out uuid);
845
846 }
847 catch
848 {
849 m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on UUID response.");
850 // reason = "Exception: " + e.Message;
851 }
852
853 return uuid;
854 }
855
797 private bool GetBoolResponse(XmlRpcRequest request, out string reason) 856 private bool GetBoolResponse(XmlRpcRequest request, out string reason)
798 { 857 {
799 //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL); 858 //m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL);
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs
new file mode 100644
index 0000000..19ee3e2
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGFriendsService.cs
@@ -0,0 +1,301 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Net;
31using System.Reflection;
32
33using OpenSim.Framework;
34using OpenSim.Services.Connectors.Friends;
35using OpenSim.Services.Connectors.Hypergrid;
36using OpenSim.Services.Interfaces;
37using GridRegion = OpenSim.Services.Interfaces.GridRegion;
38using OpenSim.Server.Base;
39using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
40
41using OpenMetaverse;
42using log4net;
43using Nini.Config;
44
45namespace OpenSim.Services.HypergridService
46{
47 /// <summary>
48 /// W2W social networking
49 /// </summary>
50 public class HGFriendsService : IHGFriendsService
51 {
52 private static readonly ILog m_log =
53 LogManager.GetLogger(
54 MethodBase.GetCurrentMethod().DeclaringType);
55
56 static bool m_Initialized = false;
57
58 protected static IGridUserService m_GridUserService;
59 protected static IGridService m_GridService;
60 protected static IGatekeeperService m_GatekeeperService;
61 protected static IFriendsService m_FriendsService;
62 protected static IPresenceService m_PresenceService;
63 protected static IUserAccountService m_UserAccountService;
64 protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule
65 protected static FriendsSimConnector m_FriendsSimConnector; // grid
66
67 private static string m_ConfigName = "HGFriendsService";
68
69 public HGFriendsService(IConfigSource config, String configName, IFriendsSimConnector localSimConn)
70 {
71 if (m_FriendsLocalSimConnector == null)
72 m_FriendsLocalSimConnector = localSimConn;
73
74 if (!m_Initialized)
75 {
76 m_Initialized = true;
77
78 if (configName != String.Empty)
79 m_ConfigName = configName;
80
81 Object[] args = new Object[] { config };
82
83 IConfig serverConfig = config.Configs[m_ConfigName];
84 if (serverConfig == null)
85 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
86
87 string theService = serverConfig.GetString("FriendsService", string.Empty);
88 if (theService == String.Empty)
89 throw new Exception("No FriendsService in config file " + m_ConfigName);
90 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
91
92 theService = serverConfig.GetString("UserAccountService", string.Empty);
93 if (theService == String.Empty)
94 throw new Exception("No UserAccountService in " + m_ConfigName);
95 m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(theService, args);
96
97 theService = serverConfig.GetString("GridService", string.Empty);
98 if (theService == String.Empty)
99 throw new Exception("No GridService in " + m_ConfigName);
100 m_GridService = ServerUtils.LoadPlugin<IGridService>(theService, args);
101
102 theService = serverConfig.GetString("PresenceService", string.Empty);
103 if (theService == String.Empty)
104 throw new Exception("No PresenceService in " + m_ConfigName);
105 m_PresenceService = ServerUtils.LoadPlugin<IPresenceService>(theService, args);
106
107 m_FriendsSimConnector = new FriendsSimConnector();
108
109 m_log.DebugFormat("[HGFRIENDS SERVICE]: Starting...");
110
111 }
112 }
113
114 #region IHGFriendsService
115
116 public int GetFriendPerms(UUID userID, UUID friendID)
117 {
118 FriendInfo[] friendsInfo = m_FriendsService.GetFriends(userID);
119 foreach (FriendInfo finfo in friendsInfo)
120 {
121 if (finfo.Friend.StartsWith(friendID.ToString()))
122 return finfo.TheirFlags;
123 }
124 return -1;
125 }
126
127 public bool NewFriendship(FriendInfo friend, bool verified)
128 {
129 UUID friendID;
130 string tmp = string.Empty, url = String.Empty, first = String.Empty, last = String.Empty;
131 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out first, out last, out tmp))
132 return false;
133
134 m_log.DebugFormat("[HGFRIENDS SERVICE]: New friendship {0} {1} ({2})", friend.PrincipalID, friend.Friend, verified);
135
136 // Does the friendship already exist?
137 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
138 foreach (FriendInfo finfo in finfos)
139 {
140 if (finfo.Friend.StartsWith(friendID.ToString()))
141 return false;
142 }
143 // Verified user session. But the user needs to confirm friendship when he gets home
144 if (verified)
145 return m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
146
147 // Does the reverted friendship exist? meaning that this user initiated the request
148 finfos = m_FriendsService.GetFriends(friendID);
149 bool userInitiatedOffer = false;
150 foreach (FriendInfo finfo in finfos)
151 {
152 if (friend.Friend.StartsWith(finfo.PrincipalID.ToString()) && finfo.Friend.StartsWith(friend.PrincipalID.ToString()) && finfo.TheirFlags == -1)
153 {
154 userInitiatedOffer = true;
155 // Let's delete the existing friendship relations that was stored
156 m_FriendsService.Delete(friendID, finfo.Friend);
157 break;
158 }
159 }
160
161 if (userInitiatedOffer)
162 {
163 m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 1);
164 m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1);
165 // notify the user
166 ForwardToSim("ApproveFriendshipRequest", friendID, Util.UniversalName(first, last, url), "", friend.PrincipalID, "");
167 return true;
168 }
169 return false;
170 }
171
172 public bool DeleteFriendship(FriendInfo friend, string secret)
173 {
174 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
175 foreach (FriendInfo finfo in finfos)
176 {
177 // We check the secret here. Or if the friendship request was initiated here, and was declined
178 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
179 {
180 m_log.DebugFormat("[HGFRIENDS SERVICE]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
181 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
182 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
183
184 return true;
185 }
186 }
187
188 return false;
189 }
190
191 public bool FriendshipOffered(UUID fromID, string fromName, UUID toID, string message)
192 {
193 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, toID);
194 if (account == null)
195 return false;
196
197 // OK, we have that user here.
198 // So let's send back the call, but start a thread to continue
199 // with the verification and the actual action.
200
201 Util.FireAndForget(delegate { ProcessFriendshipOffered(fromID, fromName, toID, message); });
202
203 return true;
204 }
205
206 public bool ValidateFriendshipOffered(UUID fromID, UUID toID)
207 {
208 FriendInfo[] finfos = m_FriendsService.GetFriends(toID.ToString());
209 foreach (FriendInfo fi in finfos)
210 {
211 if (fi.Friend.StartsWith(fromID.ToString()) && fi.TheirFlags == -1)
212 return true;
213 }
214 return false;
215 }
216
217 #endregion IHGFriendsService
218
219 #region Aux
220
221 private void ProcessFriendshipOffered(UUID fromID, String fromName, UUID toID, String message)
222 {
223 // Great, it's a genuine request. Let's proceed.
224 // But now we need to confirm that the requester is who he says he is
225 // before we act on the friendship request.
226
227 if (!fromName.Contains("@"))
228 return;
229
230 string[] parts = fromName.Split(new char[] {'@'});
231 if (parts.Length != 2)
232 return;
233
234 string uriStr = "http://" + parts[1];
235 try
236 {
237 new Uri(uriStr);
238 }
239 catch (UriFormatException)
240 {
241 return;
242 }
243
244 UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
245 Dictionary<string, object> servers = uasConn.GetServerURLs(fromID);
246 if (!servers.ContainsKey("FriendsServerURI"))
247 return;
248
249 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(servers["FriendsServerURI"].ToString());
250 if (!friendsConn.ValidateFriendshipOffered(fromID, toID))
251 {
252 m_log.WarnFormat("[HGFRIENDS SERVICE]: Friendship request from {0} to {1} is invalid. Impersonations?", fromID, toID);
253 return;
254 }
255
256 string fromUUI = Util.UniversalIdentifier(fromID, parts[0], "@" + parts[1], uriStr);
257 // OK, we're good!
258 ForwardToSim("FriendshipOffered", fromID, fromName, fromUUI, toID, message);
259 }
260
261 private bool ForwardToSim(string op, UUID fromID, string name, String fromUUI, UUID toID, string message)
262 {
263 PresenceInfo session = null;
264 GridRegion region = null;
265 PresenceInfo[] sessions = m_PresenceService.GetAgents(new string[] { toID.ToString() });
266 if (sessions != null && sessions.Length > 0)
267 session = sessions[0];
268 if (session != null)
269 region = m_GridService.GetRegionByUUID(UUID.Zero, session.RegionID);
270
271 switch (op)
272 {
273 case "FriendshipOffered":
274 // Let's store backwards
275 string secret = UUID.Random().ToString().Substring(0, 8);
276 m_FriendsService.StoreFriend(toID.ToString(), fromUUI + ";" + secret, 0);
277 if (m_FriendsLocalSimConnector != null) // standalone
278 {
279 GridInstantMessage im = new GridInstantMessage(null, fromID, name, toID,
280 (byte)InstantMessageDialog.FriendshipOffered, message, false, Vector3.Zero);
281 // !! HACK
282 im.imSessionID = im.fromAgentID;
283 return m_FriendsLocalSimConnector.LocalFriendshipOffered(toID, im);
284 }
285 else if (region != null) // grid
286 return m_FriendsSimConnector.FriendshipOffered(region, fromID, toID, message, name);
287 break;
288 case "ApproveFriendshipRequest":
289 if (m_FriendsLocalSimConnector != null) // standalone
290 return m_FriendsLocalSimConnector.LocalFriendshipApproved(fromID, name, toID);
291 else if (region != null) //grid
292 return m_FriendsSimConnector.FriendshipApproved(region, fromID, name, toID);
293 break;
294 }
295
296 return false;
297 }
298
299 #endregion Aux
300 }
301}
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 1a839f3..65963d9 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -564,6 +564,16 @@ namespace OpenSim.Services.HypergridService
564 564
565 return string.Empty; 565 return string.Empty;
566 } 566 }
567
568 public UUID GetUUID(String first, String last)
569 {
570 // Let's see if it's a local user
571 UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last);
572 if (account != null)
573 return account.PrincipalID;
574 else
575 return UUID.Zero;
576 }
567 } 577 }
568 578
569 class TravelingAgentInfo 579 class TravelingAgentInfo
diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index 5b293ac..f48b8a9 100644
--- a/OpenSim/Services/Interfaces/IHypergridServices.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Services.Interfaces
62 // on behalf of the userID 62 // on behalf of the userID
63 string GetUUI(UUID userID, UUID targetUserID); 63 string GetUUI(UUID userID, UUID targetUserID);
64 64
65 UUID GetUUID(String first, String last);
66
65 // Returns the local friends online 67 // Returns the local friends online
66 List<UUID> StatusNotification(List<string> friends, UUID userID, bool online); 68 List<UUID> StatusNotification(List<string> friends, UUID userID, bool online);
67 //List<UUID> GetOnlineFriends(UUID userID, List<string> friends); 69 //List<UUID> GetOnlineFriends(UUID userID, List<string> friends);
@@ -79,6 +81,17 @@ namespace OpenSim.Services.Interfaces
79 public interface IFriendsSimConnector 81 public interface IFriendsSimConnector
80 { 82 {
81 bool StatusNotify(UUID userID, UUID friendID, bool online); 83 bool StatusNotify(UUID userID, UUID friendID, bool online);
84 bool LocalFriendshipOffered(UUID toID, GridInstantMessage im);
85 bool LocalFriendshipApproved(UUID userID, string userName, UUID friendID);
86 }
87
88 public interface IHGFriendsService
89 {
90 int GetFriendPerms(UUID userID, UUID friendID);
91 bool NewFriendship(FriendInfo finfo, bool verified);
92 bool DeleteFriendship(FriendInfo finfo, string secret);
93 bool FriendshipOffered(UUID from, string fromName, UUID to, string message);
94 bool ValidateFriendshipOffered(UUID fromID, UUID toID);
82 } 95 }
83 96
84 public interface IInstantMessageSimConnector 97 public interface IInstantMessageSimConnector