aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDiva Canto2011-05-22 16:51:03 -0700
committerDiva Canto2011-05-22 16:51:03 -0700
commit336665e03532cf9d7a1ad65d5071e7050bf6ecd0 (patch)
tree45c7c1145de1b5af3ff198bcb29564a2547e4575
parentFile to be removed (diff)
downloadopensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.zip
opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.tar.gz
opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.tar.bz2
opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.tar.xz
More on HG Friends. Added Delete(string, string) across the board. Added security to friendship identifiers so that they can safely be deleted across worlds. Had to change Get(string) to use LIKE because the secret in the identifier is not always known -- affects only HG visitors. BOTTOM LINE SO FAR: HG friendships established and deleted safely across grids, local rights working but not (yet?) being transmitted back.
-rw-r--r--OpenSim/Data/IFriendsData.cs1
-rw-r--r--OpenSim/Data/MSSQL/MSSQLFriendsData.cs5
-rw-r--r--OpenSim/Data/MySQL/MySQLFriendsData.cs17
-rw-r--r--OpenSim/Data/Null/NullFriendsData.cs7
-rw-r--r--OpenSim/Data/SQLite/SQLiteFriendsData.cs5
-rw-r--r--OpenSim/Framework/Util.cs6
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs107
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs212
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs23
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs43
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs15
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs50
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs7
-rw-r--r--OpenSim/Services/Friends/FriendsService.cs7
-rw-r--r--OpenSim/Services/HypergridService/HGFriendsService.cs86
-rw-r--r--OpenSim/Services/Interfaces/IFriendsService.cs1
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs2
-rw-r--r--bin/config-include/StandaloneHypergrid.ini2
18 files changed, 389 insertions, 207 deletions
diff --git a/OpenSim/Data/IFriendsData.cs b/OpenSim/Data/IFriendsData.cs
index 52e7f14..3fdf87b 100644
--- a/OpenSim/Data/IFriendsData.cs
+++ b/OpenSim/Data/IFriendsData.cs
@@ -46,6 +46,7 @@ namespace OpenSim.Data
46 { 46 {
47 bool Store(FriendsData data); 47 bool Store(FriendsData data);
48 bool Delete(UUID ownerID, string friend); 48 bool Delete(UUID ownerID, string friend);
49 bool Delete(string ownerID, string friend);
49 FriendsData[] GetFriends(UUID principalID); 50 FriendsData[] GetFriends(UUID principalID);
50 FriendsData[] GetFriends(string principalID); 51 FriendsData[] GetFriends(string principalID);
51 } 52 }
diff --git a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
index ba1b085..0b178f1 100644
--- a/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
+++ b/OpenSim/Data/MSSQL/MSSQLFriendsData.cs
@@ -52,6 +52,11 @@ namespace OpenSim.Data.MSSQL
52 52
53 public bool Delete(UUID principalID, string friend) 53 public bool Delete(UUID principalID, string friend)
54 { 54 {
55 return Delete(principalID.ToString(), friend);
56 }
57
58 public bool Delete(string principalID, string friend)
59 {
55 using (SqlConnection conn = new SqlConnection(m_ConnectionString)) 60 using (SqlConnection conn = new SqlConnection(m_ConnectionString))
56 using (SqlCommand cmd = new SqlCommand()) 61 using (SqlCommand cmd = new SqlCommand())
57 { 62 {
diff --git a/OpenSim/Data/MySQL/MySQLFriendsData.cs b/OpenSim/Data/MySQL/MySQLFriendsData.cs
index 69fac9d..130ba5e 100644
--- a/OpenSim/Data/MySQL/MySQLFriendsData.cs
+++ b/OpenSim/Data/MySQL/MySQLFriendsData.cs
@@ -44,6 +44,11 @@ namespace OpenSim.Data.MySQL
44 44
45 public bool Delete(UUID principalID, string friend) 45 public bool Delete(UUID principalID, string friend)
46 { 46 {
47 return Delete(principalID.ToString(), friend);
48 }
49
50 public bool Delete(string principalID, string friend)
51 {
47 MySqlCommand cmd = new MySqlCommand(); 52 MySqlCommand cmd = new MySqlCommand();
48 53
49 cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm); 54 cmd.CommandText = String.Format("delete from {0} where PrincipalID = ?PrincipalID and Friend = ?Friend", m_Realm);
@@ -57,16 +62,20 @@ namespace OpenSim.Data.MySQL
57 62
58 public FriendsData[] GetFriends(UUID principalID) 63 public FriendsData[] GetFriends(UUID principalID)
59 { 64 {
60 return GetFriends(principalID.ToString()); 65 MySqlCommand cmd = new MySqlCommand();
66
67 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm);
68 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString());
69
70 return DoQuery(cmd);
61 } 71 }
62 72
63 public FriendsData[] GetFriends(string principalID) 73 public FriendsData[] GetFriends(string principalID)
64 { 74 {
65 MySqlCommand cmd = new MySqlCommand(); 75 MySqlCommand cmd = new MySqlCommand();
66 76
67 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID = ?PrincipalID", m_Realm); 77 cmd.CommandText = String.Format("select a.*,case when b.Flags is null then -1 else b.Flags end as TheirFlags from {0} as a left join {0} as b on a.PrincipalID = b.Friend and a.Friend = b.PrincipalID where a.PrincipalID LIKE ?PrincipalID", m_Realm);
68 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); 78 cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString() + '%');
69
70 return DoQuery(cmd); 79 return DoQuery(cmd);
71 } 80 }
72 } 81 }
diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs
index 2bfdc7a..d90788a 100644
--- a/OpenSim/Data/Null/NullFriendsData.cs
+++ b/OpenSim/Data/Null/NullFriendsData.cs
@@ -77,7 +77,12 @@ namespace OpenSim.Data.Null
77 return true; 77 return true;
78 } 78 }
79 79
80 public bool Delete(UUID userID, string friendID) 80 public bool Delete(UUID principalID, string friend)
81 {
82 return Delete(principalID.ToString(), friend);
83 }
84
85 public bool Delete(string userID, string friendID)
81 { 86 {
82 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); }); 87 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
83 if (lst != null) 88 if (lst != null)
diff --git a/OpenSim/Data/SQLite/SQLiteFriendsData.cs b/OpenSim/Data/SQLite/SQLiteFriendsData.cs
index d925412..b14c348 100644
--- a/OpenSim/Data/SQLite/SQLiteFriendsData.cs
+++ b/OpenSim/Data/SQLite/SQLiteFriendsData.cs
@@ -64,6 +64,11 @@ namespace OpenSim.Data.SQLite
64 64
65 public bool Delete(UUID principalID, string friend) 65 public bool Delete(UUID principalID, string friend)
66 { 66 {
67 return Delete(principalID.ToString(), friend);
68 }
69
70 public bool Delete(string principalID, string friend)
71 {
67 SqliteCommand cmd = new SqliteCommand(); 72 SqliteCommand cmd = new SqliteCommand();
68 73
69 cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm); 74 cmd.CommandText = String.Format("delete from {0} where PrincipalID = :PrincipalID and Friend = :Friend", m_Realm);
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index af21cb5..e5ff27a 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1703,9 +1703,9 @@ namespace OpenSim.Framework
1703 /// <param name="url"></param> 1703 /// <param name="url"></param>
1704 /// <param name="firstname"></param> 1704 /// <param name="firstname"></param>
1705 /// <param name="lastname"></param> 1705 /// <param name="lastname"></param>
1706 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname) 1706 public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
1707 { 1707 {
1708 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; 1708 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
1709 1709
1710 string[] parts = value.Split(';'); 1710 string[] parts = value.Split(';');
1711 if (parts.Length >= 1) 1711 if (parts.Length >= 1)
@@ -1724,6 +1724,8 @@ namespace OpenSim.Framework
1724 lastname = name[1]; 1724 lastname = name[1];
1725 } 1725 }
1726 } 1726 }
1727 if (parts.Length >= 4)
1728 secret = parts[3];
1727 1729
1728 return true; 1730 return true;
1729 } 1731 }
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 4879d20..7d94813 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -272,11 +272,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
272 } 272 }
273 } 273 }
274 274
275 protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
276 {
277 return FriendsService.GetFriends(client.AgentId);
278 }
279
280 private void OnClientClosed(UUID agentID, Scene scene) 275 private void OnClientClosed(UUID agentID, Scene scene)
281 { 276 {
282 ScenePresence sp = scene.GetScenePresence(agentID); 277 ScenePresence sp = scene.GetScenePresence(agentID);
@@ -300,7 +295,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
300 295
301 private void OnMakeRootAgent(ScenePresence sp) 296 private void OnMakeRootAgent(ScenePresence sp)
302 { 297 {
303 UpdateFriendsCache(sp.ControllingClient); 298 RefetchFriends(sp.ControllingClient);
304 } 299 }
305 300
306 private void OnClientLogin(IClientAPI client) 301 private void OnClientLogin(IClientAPI client)
@@ -544,11 +539,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
544 } 539 }
545 } 540 }
546 541
547 protected virtual void StoreBackwards(UUID friendID, UUID agentID)
548 {
549 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
550 }
551
552 private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) 542 private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
553 { 543 {
554 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 544 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
@@ -587,7 +577,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
587 StoreFriendships(agentID, friendID); 577 StoreFriendships(agentID, friendID);
588 578
589 // Update the local cache 579 // Update the local cache
590 UpdateFriendsCache(client); 580 RefetchFriends(client);
591 581
592 // 582 //
593 // Notify the friend 583 // Notify the friend
@@ -614,18 +604,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
614 } 604 }
615 } 605 }
616 606
617 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
618 {
619 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
620 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
621 }
622
623 private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 607 private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
624 { 608 {
625 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); 609 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
626 610
627 FriendsService.Delete(agentID, friendID.ToString()); 611 DeleteFriendship(agentID, friendID);
628 FriendsService.Delete(friendID, agentID.ToString());
629 612
630 // 613 //
631 // Notify the friend 614 // Notify the friend
@@ -652,10 +635,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
652 635
653 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) 636 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
654 { 637 {
655 DeleteFriendship(agentID, exfriendID); 638 if (!DeleteFriendship(agentID, exfriendID))
639 client.SendAlertMessage("Unable to terminate friendship on this sim.");
656 640
657 // Update local cache 641 // Update local cache
658 UpdateFriendsCache(client); 642 RefetchFriends(client);
659 643
660 client.SendTerminateFriend(exfriendID); 644 client.SendTerminateFriend(exfriendID);
661 645
@@ -679,12 +663,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
679 } 663 }
680 } 664 }
681 665
682 protected virtual void DeleteFriendship(UUID agentID, UUID exfriendID)
683 {
684 FriendsService.Delete(agentID, exfriendID.ToString());
685 FriendsService.Delete(exfriendID, agentID.ToString());
686 }
687
688 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 666 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
689 { 667 {
690 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target); 668 m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
@@ -702,7 +680,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
702 if (friend != null) // Found it 680 if (friend != null) // Found it
703 { 681 {
704 // Store it on the DB 682 // Store it on the DB
705 if (!SimpleStore(requester, target, rights)) 683 if (!StoreRights(requester, target, rights))
706 { 684 {
707 remoteClient.SendAlertMessage("Unable to grant rights."); 685 remoteClient.SendAlertMessage("Unable to grant rights.");
708 return; 686 return;
@@ -740,12 +718,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
740 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester); 718 m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
741 } 719 }
742 720
743 protected virtual bool SimpleStore(UUID agentID, UUID friendID, int rights)
744 {
745 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
746 return true;
747 }
748
749 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) 721 protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
750 { 722 {
751 foreach (FriendInfo fi in friends) 723 foreach (FriendInfo fi in friends)
@@ -782,7 +754,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
782 friendClient.SendInstantMessage(im); 754 friendClient.SendInstantMessage(im);
783 755
784 // Update the local cache 756 // Update the local cache
785 UpdateFriendsCache(friendClient); 757 RefetchFriends(friendClient);
786 758
787 // we're done 759 // we're done
788 return true; 760 return true;
@@ -815,7 +787,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
815 // the friend in this sim as root agent 787 // the friend in this sim as root agent
816 friendClient.SendTerminateFriend(exfriendID); 788 friendClient.SendTerminateFriend(exfriendID);
817 // update local cache 789 // update local cache
818 UpdateFriendsCache(friendClient); 790 RefetchFriends(friendClient);
819 // we're done 791 // we're done
820 return true; 792 return true;
821 } 793 }
@@ -874,6 +846,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
874 846
875 #endregion 847 #endregion
876 848
849 #region Get / Set friends in several flavours
850 /// <summary>
851 /// Get friends from local cache only
852 /// </summary>
853 /// <param name="agentID"></param>
854 /// <returns></returns>
877 protected FriendInfo[] GetFriends(UUID agentID) 855 protected FriendInfo[] GetFriends(UUID agentID)
878 { 856 {
879 UserFriendData friendsData; 857 UserFriendData friendsData;
@@ -887,7 +865,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
887 return EMPTY_FRIENDS; 865 return EMPTY_FRIENDS;
888 } 866 }
889 867
890 private void UpdateFriendsCache(IClientAPI client) 868 /// <summary>
869 /// Update loca cache only
870 /// </summary>
871 /// <param name="userID"></param>
872 /// <param name="friendID"></param>
873 /// <param name="rights"></param>
874 protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
875 {
876 // Update local cache
877 lock (m_Friends)
878 {
879 FriendInfo[] friends = GetFriends(friendID);
880 FriendInfo finfo = GetFriend(friends, userID);
881 finfo.TheirFlags = rights;
882 }
883 }
884
885 protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
886 {
887 return FriendsService.GetFriends(client.AgentId);
888 }
889
890 private void RefetchFriends(IClientAPI client)
891 { 891 {
892 UUID agentID = client.AgentId; 892 UUID agentID = client.AgentId;
893 lock (m_Friends) 893 lock (m_Friends)
@@ -898,15 +898,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
898 } 898 }
899 } 899 }
900 900
901 protected void UpdateLocalCache(UUID userID, UUID friendID, int rights) 901 protected virtual bool StoreRights(UUID agentID, UUID friendID, int rights)
902 { 902 {
903 // Update local cache 903 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
904 lock (m_Friends) 904 return true;
905 {
906 FriendInfo[] friends = GetFriends(friendID);
907 FriendInfo finfo = GetFriend(friends, userID);
908 finfo.TheirFlags = rights;
909 }
910 } 905 }
906
907 protected virtual void StoreBackwards(UUID friendID, UUID agentID)
908 {
909 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
910 }
911
912 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
913 {
914 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
915 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
916 }
917
918 protected virtual bool DeleteFriendship(UUID agentID, UUID exfriendID)
919 {
920 FriendsService.Delete(agentID, exfriendID.ToString());
921 FriendsService.Delete(exfriendID, agentID.ToString());
922 return true;
923 }
924
925 #endregion
911 } 926 }
912} 927}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index abffb94..c55839f 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -72,8 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
72 UUID id; 72 UUID id;
73 if (!UUID.TryParse(finfo.Friend, out id)) 73 if (!UUID.TryParse(finfo.Friend, out id))
74 { 74 {
75 string url = string.Empty, first = string.Empty, last = string.Empty; 75 string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty;
76 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last)) 76 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp))
77 { 77 {
78 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 78 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
79 uMan.AddUser(id, url + ";" + first + " " + last); 79 uMan.AddUser(id, url + ";" + first + " " + last);
@@ -103,22 +103,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
103 return false; 103 return false;
104 } 104 }
105 105
106 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
107 {
108 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
109 if (account1 != null)
110 return base.GetFriendsFromService(client);
111
112 // Foreigner
113 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
114 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
115
116 FriendInfo[] finfos = FriendsService.GetFriends(agentUUI);
117 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
118 return finfos;
119 }
120
121
122 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) 106 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
123 { 107 {
124 first = "Unknown"; last = "User"; 108 first = "Unknown"; last = "User";
@@ -126,8 +110,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
126 return true; 110 return true;
127 111
128 // fid is not a UUID... 112 // fid is not a UUID...
129 string url = string.Empty; 113 string url = string.Empty, tmp = string.Empty;
130 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last)) 114 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
131 { 115 {
132 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); 116 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
133 userMan.AddUser(agentID, url + ";" + first + " " + last); 117 userMan.AddUser(agentID, url + ";" + first + " " + last);
@@ -164,7 +148,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
164 return "Please confirm this friendship you made while you were away."; 148 return "Please confirm this friendship you made while you were away.";
165 } 149 }
166 150
167 protected override bool SimpleStore(UUID agentID, UUID friendID, int rights) 151 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
152 {
153 foreach (FriendInfo fi in friends)
154 {
155 if (fi.Friend.StartsWith(friendID.ToString()))
156 return fi;
157 }
158 return null;
159 }
160
161
162 protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
163 {
164 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
165 if (account1 != null)
166 return base.GetFriendsFromService(client);
167
168 FriendInfo[] finfos = new FriendInfo[0];
169 // Foreigner
170 AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
171 if (agentClientCircuit != null)
172 {
173 string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
174
175 m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI);
176 finfos = FriendsService.GetFriends(agentUUI);
177 m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
178 }
179 return finfos;
180 }
181
182 protected override bool StoreRights(UUID agentID, UUID friendID, int rights)
168 { 183 {
169 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); 184 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
170 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); 185 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
@@ -172,30 +187,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
172 if (account1 != null && account2 != null) 187 if (account1 != null && account2 != null)
173 { 188 {
174 // local grid users 189 // local grid users
175 return base.SimpleStore(agentID, friendID, rights); 190 return base.StoreRights(agentID, friendID, rights);
176 } 191 }
177 192
178 if (account1 != null) 193 if (account1 != null) // agent is local, friend is foreigner
179 { 194 {
180 FriendInfo[] finfos = GetFriends(agentID); 195 FriendInfo[] finfos = GetFriends(agentID);
181 if (finfos.Length > 0) 196 FriendInfo finfo = GetFriend(finfos, friendID);
197 if (finfo != null)
182 { 198 {
183 FriendInfo finfo = GetFriend(finfos, friendID);
184 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); 199 FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
185 return true; 200 return true;
186 } 201 }
187 } 202 }
188 if (account2 != null) 203
204 if (account2 != null) // agent is foreigner, friend is local
189 { 205 {
190 IClientAPI client = LocateClientObject(agentID); 206 string agentUUI = GetUUI(friendID, agentID);
191 if (client != null) 207 if (agentUUI != string.Empty)
192 { 208 {
193 AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); 209 FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights);
194 if (acircuit != null) 210 return true;
195 {
196 FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights);
197 return true;
198 }
199 } 211 }
200 } 212 }
201 213
@@ -233,7 +245,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
233 return; 245 return;
234 } 246 }
235 247
236
237 // ok, at least one of them is foreigner, let's get their data 248 // ok, at least one of them is foreigner, let's get their data
238 IClientAPI agentClient = LocateClientObject(agentID); 249 IClientAPI agentClient = LocateClientObject(agentID);
239 IClientAPI friendClient = LocateClientObject(friendID); 250 IClientAPI friendClient = LocateClientObject(friendID);
@@ -257,13 +268,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
257 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); 268 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
258 } 269 }
259 270
260 m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", 271 m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
261 agentUUI, friendUUI, agentFriendService, friendFriendService); 272 agentUUI, friendUUI, agentFriendService, friendFriendService);
262 273
274 // Generate a random 8-character hex number that will sign this friendship
275 string secret = UUID.Random().ToString().Substring(0, 8);
276
263 if (agentAccount != null) // agent is local, 'friend' is foreigner 277 if (agentAccount != null) // agent is local, 'friend' is foreigner
264 { 278 {
265 // This may happen when the agent returned home, in which case the friend is not there 279 // This may happen when the agent returned home, in which case the friend is not there
266 // We need to llok for its information in the friends list itself 280 // We need to look for its information in the friends list itself
281 bool confirming = false;
267 if (friendUUI == string.Empty) 282 if (friendUUI == string.Empty)
268 { 283 {
269 FriendInfo[] finfos = GetFriends(agentID); 284 FriendInfo[] finfos = GetFriends(agentID);
@@ -272,35 +287,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
272 if (finfo.TheirFlags == -1) 287 if (finfo.TheirFlags == -1)
273 { 288 {
274 if (finfo.Friend.StartsWith(friendID.ToString())) 289 if (finfo.Friend.StartsWith(friendID.ToString()))
290 {
275 friendUUI = finfo.Friend; 291 friendUUI = finfo.Friend;
292 confirming = true;
293 }
276 } 294 }
277 } 295 }
278 } 296 }
279 297
298 // If it's confirming the friendship, we already have the full friendUUI with the secret
299 string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
300
280 // store in the local friends service a reference to the foreign friend 301 // store in the local friends service a reference to the foreign friend
281 FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1); 302 FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
282 // and also the converse 303 // and also the converse
283 FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1); 304 FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
284 305
285 if (friendClientCircuit != null) 306 if (!confirming && friendClientCircuit != null)
286 { 307 {
287 // store in the foreign friends service a reference to the local agent 308 // store in the foreign friends service a reference to the local agent
288 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); 309 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
289 friendsConn.NewFriendship(friendID, agentUUI); 310 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
290 } 311 }
291 } 312 }
292 else if (friendAccount != null) // 'friend' is local, agent is foreigner 313 else if (friendAccount != null) // 'friend' is local, agent is foreigner
293 { 314 {
294 // store in the local friends service a reference to the foreign agent 315 // store in the local friends service a reference to the foreign agent
295 FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1); 316 FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
296 // and also the converse 317 // and also the converse
297 FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1); 318 FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1);
298 319
299 if (agentClientCircuit != null) 320 if (agentClientCircuit != null)
300 { 321 {
301 // store in the foreign friends service a reference to the local agent 322 // store in the foreign friends service a reference to the local agent
302 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); 323 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
303 friendsConn.NewFriendship(agentID, friendUUI); 324 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
304 } 325 }
305 } 326 }
306 else // They're both foreigners! 327 else // They're both foreigners!
@@ -309,43 +330,112 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
309 if (agentClientCircuit != null) 330 if (agentClientCircuit != null)
310 { 331 {
311 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); 332 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
312 friendsConn.NewFriendship(agentID, friendUUI); 333 friendsConn.NewFriendship(agentID, friendUUI + ";" + secret);
313 } 334 }
314 if (friendClientCircuit != null) 335 if (friendClientCircuit != null)
315 { 336 {
316 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); 337 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
317 friendsConn.NewFriendship(friendID, agentUUI); 338 friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
318 } 339 }
319 } 340 }
320 // my brain hurts now 341 // my brain hurts now
321 } 342 }
322 343
323 protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) 344 protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
324 { 345 {
325 foreach (FriendInfo fi in friends) 346 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
347 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID);
348 // Are they both local users?
349 if (agentAccount != null && friendAccount != null)
326 { 350 {
327 if (fi.Friend.StartsWith(friendID.ToString())) 351 // local grid users
328 return fi; 352 return base.DeleteFriendship(agentID, exfriendID);
329 } 353 }
330 return null; 354
355 // ok, at least one of them is foreigner, let's get their data
356 string agentUUI = string.Empty;
357 string friendUUI = string.Empty;
358
359 if (agentAccount != null) // agent is local, 'friend' is foreigner
360 {
361 // We need to look for its information in the friends list itself
362 FriendInfo[] finfos = GetFriends(agentID);
363 FriendInfo finfo = GetFriend(finfos, exfriendID);
364 if (finfo != null)
365 {
366 friendUUI = finfo.Friend;
367
368 // delete in the local friends service the reference to the foreign friend
369 FriendsService.Delete(agentID, friendUUI);
370 // and also the converse
371 FriendsService.Delete(friendUUI, agentID.ToString());
372
373 // notify the exfriend's service
374 Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); });
375
376 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI);
377 return true;
378 }
379 }
380 else if (friendAccount != null) // agent is foreigner, 'friend' is local
381 {
382 agentUUI = GetUUI(exfriendID, agentID);
383
384 if (agentUUI != string.Empty)
385 {
386 // delete in the local friends service the reference to the foreign agent
387 FriendsService.Delete(exfriendID, agentUUI);
388 // and also the converse
389 FriendsService.Delete(agentUUI, exfriendID.ToString());
390
391 // notify the agent's service?
392 Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); });
393
394 m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID);
395 return true;
396 }
397 }
398 //else They're both foreigners! Can't handle this
399
400 return false;
331 } 401 }
332 402
333 protected override void DeleteFriendship(UUID agentID, UUID exfriendID) 403 private string GetUUI(UUID localUser, UUID foreignUser)
334 { 404 {
335 base.DeleteFriendship(agentID, exfriendID); 405 // Let's see if the user is here by any chance
336 // Maybe some of the base deletes will fail. 406 FriendInfo[] finfos = GetFriends(localUser);
337 // Let's delete the local friendship with foreign friend 407 if (finfos != EMPTY_FRIENDS) // friend is here, cool
338 FriendInfo[] friends = GetFriends(agentID);
339 foreach (FriendInfo finfo in friends)
340 { 408 {
341 if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString())) 409 FriendInfo finfo = GetFriend(finfos, foreignUser);
410 if (finfo != null)
342 { 411 {
343 FriendsService.Delete(agentID, exfriendID.ToString()); 412 return finfo.Friend;
344 // TODO: delete the friendship on the other side
345 // Should use the homeurl given in finfo.Friend
346 } 413 }
347 } 414 }
415 else // user is not currently on this sim, need to get from the service
416 {
417 finfos = FriendsService.GetFriends(localUser);
418 foreach (FriendInfo finfo in finfos)
419 {
420 if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it!
421 {
422 return finfo.Friend;
423 }
424 }
425 }
426 return string.Empty;
348 } 427 }
349 428
429 private void Delete(UUID foreignUser, UUID localUser, string uui)
430 {
431 UUID id;
432 string url = string.Empty, secret = string.Empty, tmp = string.Empty;
433 if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret))
434 {
435 m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url);
436 HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url);
437 friendConn.DeleteFriendship(foreignUser, localUser, secret);
438 }
439 }
350 } 440 }
351} 441}
diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
index 71c3c73..9969086 100644
--- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
@@ -91,6 +91,9 @@ namespace OpenSim.Server.Handlers.Friends
91 case "deletefriend": 91 case "deletefriend":
92 return DeleteFriend(request); 92 return DeleteFriend(request);
93 93
94 case "deletefriend_string":
95 return DeleteFriendString(request);
96
94 } 97 }
95 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); 98 m_log.DebugFormat("[FRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
96 } 99 }
@@ -184,7 +187,25 @@ namespace OpenSim.Server.Handlers.Friends
184 else 187 else
185 return FailureResult(); 188 return FailureResult();
186 } 189 }
187 190
191 byte[] DeleteFriendString(Dictionary<string, object> request)
192 {
193 string principalID = string.Empty;
194 if (request.ContainsKey("PRINCIPALID"))
195 principalID = request["PRINCIPALID"].ToString();
196 else
197 m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to delete friend");
198 string friend = string.Empty;
199 if (request.ContainsKey("FRIEND"))
200 friend = request["FRIEND"].ToString();
201
202 bool success = m_FriendsService.Delete(principalID, friend);
203 if (success)
204 return SuccessResult();
205 else
206 return FailureResult();
207 }
208
188 #endregion 209 #endregion
189 210
190 #region Misc 211 #region Misc
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
index dde7875..a83d0e8 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -88,6 +88,8 @@ namespace OpenSim.Server.Handlers.Hypergrid
88 case "newfriendship": 88 case "newfriendship":
89 return NewFriendship(request); 89 return NewFriendship(request);
90 90
91 case "deletefriendship":
92 return DeleteFriendship(request);
91 } 93 }
92 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method); 94 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
93 } 95 }
@@ -143,11 +145,21 @@ namespace OpenSim.Server.Handlers.Hypergrid
143 145
144 // OK, can proceed 146 // OK, can proceed
145 FriendInfo friend = new FriendInfo(request); 147 FriendInfo friend = new FriendInfo(request);
148 UUID friendID;
149 string tmp = string.Empty;
150 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
151 return FailureResult();
152
153 m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
154
155 // If the friendship already exists, return fail
156 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
157 foreach (FriendInfo finfo in finfos)
158 if (finfo.Friend.StartsWith(friendID.ToString()))
159 return FailureResult();
146 160
147 // the user needs to confirm when he gets home 161 // the user needs to confirm when he gets home
148 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0); 162 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
149 //if (success)
150 // m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1);
151 163
152 if (success) 164 if (success)
153 return SuccessResult(); 165 return SuccessResult();
@@ -155,6 +167,33 @@ namespace OpenSim.Server.Handlers.Hypergrid
155 return FailureResult(); 167 return FailureResult();
156 } 168 }
157 169
170 byte[] DeleteFriendship(Dictionary<string, object> request)
171 {
172 FriendInfo friend = new FriendInfo(request);
173 string secret = string.Empty;
174 if (request.ContainsKey("SECRET"))
175 secret = request["SECRET"].ToString();
176
177 if (secret == string.Empty)
178 return FailureResult();
179
180 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
181 foreach (FriendInfo finfo in finfos)
182 {
183 // We check the secret here
184 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
185 {
186 m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
187 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
188 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
189
190 return SuccessResult();
191 }
192 }
193
194 return FailureResult();
195 }
196
158 #endregion 197 #endregion
159 198
160 #region Misc 199 #region Misc
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
index d1afea2..08f1dc3 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
@@ -211,6 +211,16 @@ namespace OpenSim.Services.Connectors.Friends
211 211
212 } 212 }
213 213
214 public bool Delete(string PrincipalID, string Friend)
215 {
216 Dictionary<string, object> sendData = new Dictionary<string, object>();
217 sendData["PRINCIPALID"] = PrincipalID.ToString();
218 sendData["FRIEND"] = Friend;
219 sendData["METHOD"] = "deletefriend_string";
220
221 return Delete(sendData, PrincipalID, Friend);
222 }
223
214 public bool Delete(UUID PrincipalID, string Friend) 224 public bool Delete(UUID PrincipalID, string Friend)
215 { 225 {
216 Dictionary<string, object> sendData = new Dictionary<string, object>(); 226 Dictionary<string, object> sendData = new Dictionary<string, object>();
@@ -218,6 +228,11 @@ namespace OpenSim.Services.Connectors.Friends
218 sendData["FRIEND"] = Friend; 228 sendData["FRIEND"] = Friend;
219 sendData["METHOD"] = "deletefriend"; 229 sendData["METHOD"] = "deletefriend";
220 230
231 return Delete(sendData, PrincipalID.ToString(), Friend);
232 }
233
234 public bool Delete(Dictionary<string, object> sendData, string PrincipalID, string Friend)
235 {
221 string reply = string.Empty; 236 string reply = string.Empty;
222 try 237 try
223 { 238 {
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
index f823889..d699f59 100644
--- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
@@ -54,6 +54,11 @@ namespace OpenSim.Services.Connectors.Hypergrid
54 { 54 {
55 } 55 }
56 56
57 public HGFriendsServicesConnector(string serverURI)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 }
61
57 public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey) 62 public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey)
58 { 63 {
59 m_ServerURI = serverURI.TrimEnd('/'); 64 m_ServerURI = serverURI.TrimEnd('/');
@@ -151,6 +156,51 @@ namespace OpenSim.Services.Connectors.Hypergrid
151 156
152 } 157 }
153 158
159 public bool DeleteFriendship(UUID PrincipalID, UUID Friend, string secret)
160 {
161 FriendInfo finfo = new FriendInfo();
162 finfo.PrincipalID = PrincipalID;
163 finfo.Friend = Friend.ToString();
164
165 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
166
167 sendData["METHOD"] = "deletefriendship";
168 sendData["SECRET"] = secret;
169
170 string reply = string.Empty;
171 try
172 {
173 reply = SynchronousRestFormsRequester.MakeRequest("POST",
174 m_ServerURI + "/hgfriends",
175 ServerUtils.BuildQueryString(sendData));
176 }
177 catch (Exception e)
178 {
179 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
180 return false;
181 }
182
183 if (reply != string.Empty)
184 {
185 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
186
187 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
188 {
189 bool success = false;
190 Boolean.TryParse(replyData["Result"].ToString(), out success);
191 return success;
192 }
193 else
194 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response",
195 PrincipalID, Friend);
196 }
197 else
198 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply");
199
200 return false;
201
202 }
203
154 #endregion 204 #endregion
155 } 205 }
156} \ No newline at end of file 206} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
index b1c34dd..7422d94 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -103,7 +103,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
103 if (!UUID.TryParse(principalID, out friend.PrincipalID)) 103 if (!UUID.TryParse(principalID, out friend.PrincipalID))
104 { 104 {
105 string tmp = string.Empty; 105 string tmp = string.Empty;
106 if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp)) 106 if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp, out tmp))
107 // bad record. ignore this entry 107 // bad record. ignore this entry
108 continue; 108 continue;
109 } 109 }
@@ -164,6 +164,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
164 164
165 public bool Delete(UUID principalID, string friend) 165 public bool Delete(UUID principalID, string friend)
166 { 166 {
167 return Delete(principalID.ToString(), friend);
168 }
169
170 public bool Delete(string principalID, string friend)
171 {
167 if (String.IsNullOrEmpty(m_serverUrl)) 172 if (String.IsNullOrEmpty(m_serverUrl))
168 return true; 173 return true;
169 174
diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs
index 4664cb3..e2033ac 100644
--- a/OpenSim/Services/Friends/FriendsService.cs
+++ b/OpenSim/Services/Friends/FriendsService.cs
@@ -75,7 +75,7 @@ namespace OpenSim.Services.Friends
75 if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID)) 75 if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID))
76 { 76 {
77 string tmp = string.Empty; 77 string tmp = string.Empty;
78 if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp)) 78 if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp, out tmp))
79 // bad record. ignore this entry 79 // bad record. ignore this entry
80 continue; 80 continue;
81 } 81 }
@@ -101,6 +101,11 @@ namespace OpenSim.Services.Friends
101 return m_Database.Store(d); 101 return m_Database.Store(d);
102 } 102 }
103 103
104 public bool Delete(string principalID, string friend)
105 {
106 return m_Database.Delete(principalID, friend);
107 }
108
104 public virtual bool Delete(UUID PrincipalID, string Friend) 109 public virtual bool Delete(UUID PrincipalID, string Friend)
105 { 110 {
106 return m_Database.Delete(PrincipalID, Friend); 111 return m_Database.Delete(PrincipalID, Friend);
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs
deleted file mode 100644
index 1829ae3..0000000
--- a/OpenSim/Services/HypergridService/HGFriendsService.cs
+++ /dev/null
@@ -1,86 +0,0 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29using OpenSim.Framework;
30using System;
31using System.Collections.Generic;
32using OpenSim.Services.Interfaces;
33using OpenSim.Services.Friends;
34using OpenSim.Data;
35using Nini.Config;
36using log4net;
37using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38
39namespace OpenSim.Services.HypergridService
40{
41 public class HGFriendsService : FriendsService, IFriendsService
42 {
43 public HGFriendsService(IConfigSource config) : base(config)
44 {
45 }
46
47 /// <summary>
48 /// Overrides base.
49 /// Storing new friendships from the outside is a tricky, sensitive operation, and it
50 /// needs to be done under certain restrictions.
51 /// First of all, if the friendship already exists, this is a no-op. In other words,
52 /// we cannot change just the flags, it needs to be a new friendship.
53 /// Second, we store it as flags=0 always, independent of what the caller sends. The
54 /// owner of the friendship needs to confirm when it gets back home.
55 /// </summary>
56 /// <param name="PrincipalID"></param>
57 /// <param name="Friend"></param>
58 /// <param name="flags"></param>
59 /// <returns></returns>
60 public override bool StoreFriend(string PrincipalID, string Friend, int flags)
61 {
62 UUID userID;
63 if (UUID.TryParse(PrincipalID, out userID))
64 {
65 FriendsData[] friendsData = m_Database.GetFriends(userID.ToString());
66 List<FriendsData> fList = new List<FriendsData>(friendsData);
67 if (fList.Find(delegate(FriendsData fdata)
68 {
69 return fdata.Friend == Friend;
70 }) != null)
71 return false;
72 }
73 else
74 return false;
75
76 FriendsData d = new FriendsData();
77 d.PrincipalID = PrincipalID;
78 d.Friend = Friend;
79 d.Data = new Dictionary<string, string>();
80 d.Data["Flags"] = "0";
81
82 return m_Database.Store(d);
83 }
84
85 }
86}
diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs
index 0a8efad..1664f3b 100644
--- a/OpenSim/Services/Interfaces/IFriendsService.cs
+++ b/OpenSim/Services/Interfaces/IFriendsService.cs
@@ -77,5 +77,6 @@ namespace OpenSim.Services.Interfaces
77 FriendInfo[] GetFriends(string PrincipalID); 77 FriendInfo[] GetFriends(string PrincipalID);
78 bool StoreFriend(string PrincipalID, string Friend, int flags); 78 bool StoreFriend(string PrincipalID, string Friend, int flags);
79 bool Delete(UUID PrincipalID, string Friend); 79 bool Delete(UUID PrincipalID, string Friend);
80 bool Delete(string PrincipalID, string Friend);
80 } 81 }
81} 82}
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index 4fac951..f68c078 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -628,7 +628,7 @@ namespace OpenSim.Services.LLLoginService
628 else 628 else
629 { 629 {
630 string tmp; 630 string tmp;
631 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp)) 631 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
632 buddyitem.BuddyID = friendID.ToString(); 632 buddyitem.BuddyID = friendID.ToString();
633 else 633 else
634 // junk entry 634 // junk entry
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini
index 324c258..f8e8ae2 100644
--- a/bin/config-include/StandaloneHypergrid.ini
+++ b/bin/config-include/StandaloneHypergrid.ini
@@ -142,7 +142,7 @@
142 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService" 142 UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
143 143
144[HGFriendsService] 144[HGFriendsService]
145 LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService" 145 LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService"
146 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService" 146 UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
147 147
148;; This should always be the very last thing on this file 148;; This should always be the very last thing on this file