diff options
author | Melanie | 2012-03-21 00:26:02 +0000 |
---|---|---|
committer | Melanie | 2012-03-21 00:26:02 +0000 |
commit | ee9210f656f754e2caa40cb6ff39463cbf286347 (patch) | |
tree | 8097bad8a37e210bfbdeff113a9ab00d853ad9ac /OpenSim | |
parent | Merge branch 'master' into careminster (diff) | |
parent | Refix the fixed fix! (diff) | |
download | opensim-SC_OLD-ee9210f656f754e2caa40cb6ff39463cbf286347.zip opensim-SC_OLD-ee9210f656f754e2caa40cb6ff39463cbf286347.tar.gz opensim-SC_OLD-ee9210f656f754e2caa40cb6ff39463cbf286347.tar.bz2 opensim-SC_OLD-ee9210f656f754e2caa40cb6ff39463cbf286347.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
Diffstat (limited to '')
16 files changed, 1018 insertions, 296 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; | |||
35 | using System.IO.Compression; | 35 | using System.IO.Compression; |
36 | using System.Net; | 36 | using System.Net; |
37 | using System.Net.Sockets; | 37 | using System.Net.Sockets; |
38 | using System.Reflection; | 38 | using System.Reflection; |
39 | using System.Runtime.InteropServices; | 39 | using System.Runtime.InteropServices; |
40 | using System.Runtime.Serialization; | 40 | using System.Runtime.Serialization; |
41 | using System.Runtime.Serialization.Formatters.Binary; | 41 | using 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/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/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; | |||
39 | using OpenSim.Server.Base; | 39 | using OpenSim.Server.Base; |
40 | using OpenSim.Services.Interfaces; | 40 | using OpenSim.Services.Interfaces; |
41 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; | 41 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; |
42 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
42 | using OpenSim.Framework; | 43 | using OpenSim.Framework; |
43 | using OpenSim.Framework.Servers.HttpServer; | 44 | using OpenSim.Framework.Servers.HttpServer; |
44 | using OpenMetaverse; | 45 | using 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 | ||
41 | namespace OpenSim.Services.Connectors.Hypergrid | 41 | namespace 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 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Net; | ||
31 | using System.Reflection; | ||
32 | |||
33 | using OpenSim.Framework; | ||
34 | using OpenSim.Services.Connectors.Friends; | ||
35 | using OpenSim.Services.Connectors.Hypergrid; | ||
36 | using OpenSim.Services.Interfaces; | ||
37 | using GridRegion = OpenSim.Services.Interfaces.GridRegion; | ||
38 | using OpenSim.Server.Base; | ||
39 | using FriendInfo = OpenSim.Services.Interfaces.FriendInfo; | ||
40 | |||
41 | using OpenMetaverse; | ||
42 | using log4net; | ||
43 | using Nini.Config; | ||
44 | |||
45 | namespace 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 |