aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorDiva Canto2011-05-19 16:54:46 -0700
committerDiva Canto2011-05-19 16:54:46 -0700
commitd21e9c755f004d8fe03b11bc57b810dbd401435a (patch)
tree1efd9e48308192d21ca73d8ff12d6a48c186077c /OpenSim
parentAccidentally committed too early (diff)
downloadopensim-SC-d21e9c755f004d8fe03b11bc57b810dbd401435a.zip
opensim-SC-d21e9c755f004d8fe03b11bc57b810dbd401435a.tar.gz
opensim-SC-d21e9c755f004d8fe03b11bc57b810dbd401435a.tar.bz2
opensim-SC-d21e9c755f004d8fe03b11bc57b810dbd401435a.tar.xz
HG Friends working to some extent: friendships offered and accepted correctly handled. Friends list showing correct foreign names. TODO: GrantRights.
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Data/IFriendsData.cs2
-rw-r--r--OpenSim/Data/MySQL/Resources/FriendsStore.migrations6
-rw-r--r--OpenSim/Data/Null/NullFriendsData.cs4
-rw-r--r--OpenSim/Framework/AgentCircuitData.cs1
-rw-r--r--OpenSim/Framework/AssetBase.cs6
-rw-r--r--OpenSim/Framework/Util.cs61
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs151
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs438
-rw-r--r--OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs2
-rw-r--r--OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs1
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendServerConnector.cs6
-rw-r--r--OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs2
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs71
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs242
-rw-r--r--OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs13
-rw-r--r--OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs175
-rw-r--r--OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs2
-rw-r--r--OpenSim/Services/Friends/FriendsService.cs9
-rw-r--r--OpenSim/Services/HypergridService/HGFriendsService.cs95
-rw-r--r--OpenSim/Services/Interfaces/IFriendsService.cs2
-rw-r--r--OpenSim/Services/LLLoginService/LLLoginResponse.cs14
21 files changed, 1246 insertions, 57 deletions
diff --git a/OpenSim/Data/IFriendsData.cs b/OpenSim/Data/IFriendsData.cs
index 1f1a031..4da567e 100644
--- a/OpenSim/Data/IFriendsData.cs
+++ b/OpenSim/Data/IFriendsData.cs
@@ -34,7 +34,7 @@ namespace OpenSim.Data
34{ 34{
35 public class FriendsData 35 public class FriendsData
36 { 36 {
37 public UUID PrincipalID; 37 public string PrincipalID;
38 public string Friend; 38 public string Friend;
39 public Dictionary<string, string> Data; 39 public Dictionary<string, string> Data;
40 } 40 }
diff --git a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
index ce713bd..35e5e93 100644
--- a/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/FriendsStore.migrations
@@ -21,5 +21,11 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf
21 21
22COMMIT; 22COMMIT;
23 23
24:VERSION 3 # -------------------------
24 25
26BEGIN;
27
28ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
29
30COMMIT;
25 31
diff --git a/OpenSim/Data/Null/NullFriendsData.cs b/OpenSim/Data/Null/NullFriendsData.cs
index e7f7fd3..0c69bb1 100644
--- a/OpenSim/Data/Null/NullFriendsData.cs
+++ b/OpenSim/Data/Null/NullFriendsData.cs
@@ -53,7 +53,7 @@ namespace OpenSim.Data.Null
53 { 53 {
54 List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata) 54 List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
55 { 55 {
56 return fdata.PrincipalID == userID; 56 return fdata.PrincipalID == userID.ToString();
57 }); 57 });
58 58
59 if (lst != null) 59 if (lst != null)
@@ -74,7 +74,7 @@ namespace OpenSim.Data.Null
74 74
75 public bool Delete(UUID userID, string friendID) 75 public bool Delete(UUID userID, string friendID)
76 { 76 {
77 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; }); 77 List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
78 if (lst != null) 78 if (lst != null)
79 { 79 {
80 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; }); 80 FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs
index dbd47d3..125910e 100644
--- a/OpenSim/Framework/AgentCircuitData.cs
+++ b/OpenSim/Framework/AgentCircuitData.cs
@@ -345,6 +345,7 @@ namespace OpenSim.Framework
345 } 345 }
346 } 346 }
347 } 347 }
348
348 } 349 }
349 350
350 351
diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs
index 53d28be..5f68cda 100644
--- a/OpenSim/Framework/AssetBase.cs
+++ b/OpenSim/Framework/AssetBase.cs
@@ -215,6 +215,12 @@ namespace OpenSim.Framework
215 set { m_metadata.Temporary = value; } 215 set { m_metadata.Temporary = value; }
216 } 216 }
217 217
218 public string CreatorID
219 {
220 get { return m_metadata.CreatorID; }
221 set { m_metadata.CreatorID = value; }
222 }
223
218 public AssetFlags Flags 224 public AssetFlags Flags
219 { 225 {
220 get { return m_metadata.Flags; } 226 get { return m_metadata.Flags; }
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index aaa2724..af21cb5 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1694,5 +1694,66 @@ namespace OpenSim.Framework
1694 return (T)Enum.Parse(typeof(T), value); ; 1694 return (T)Enum.Parse(typeof(T), value); ;
1695 } 1695 }
1696 #endregion 1696 #endregion
1697
1698 #region Universal User Identifiers
1699 /// <summary>
1700 /// </summary>
1701 /// <param name="value">uuid[;endpoint[;name]]</param>
1702 /// <param name="uuid"></param>
1703 /// <param name="url"></param>
1704 /// <param name="firstname"></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)
1707 {
1708 uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User";
1709
1710 string[] parts = value.Split(';');
1711 if (parts.Length >= 1)
1712 if (!UUID.TryParse(parts[0], out uuid))
1713 return false;
1714
1715 if (parts.Length >= 2)
1716 url = parts[1];
1717
1718 if (parts.Length >= 3)
1719 {
1720 string[] name = parts[2].Split();
1721 if (name.Length == 2)
1722 {
1723 firstname = name[0];
1724 lastname = name[1];
1725 }
1726 }
1727
1728 return true;
1729 }
1730
1731 /// <summary>
1732 ///
1733 /// </summary>
1734 /// <param name="acircuit"></param>
1735 /// <returns>uuid[;endpoint[;name]]</returns>
1736 public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
1737 {
1738 if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
1739 {
1740 string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
1741 if (!agentsURI.EndsWith("/"))
1742 agentsURI += "/";
1743
1744 // This is ugly, but there's no other way, given that the name is changed
1745 // in the agent circuit data for foreigners
1746 if (acircuit.lastname.Contains("@"))
1747 {
1748 string[] parts = acircuit.firstname.Split(new char[] { '.' });
1749 if (parts.Length == 2)
1750 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
1751 }
1752 return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
1753 }
1754 else
1755 return acircuit.AgentID.ToString();
1756 }
1757 #endregion
1697 } 1758 }
1698} 1759}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 5baf078..21cd924 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
49{ 49{
50 public class FriendsModule : ISharedRegionModule, IFriendsModule 50 public class FriendsModule : ISharedRegionModule, IFriendsModule
51 { 51 {
52 protected bool m_Enabled = false;
53
52 protected class UserFriendData 54 protected class UserFriendData
53 { 55 {
54 public UUID PrincipalID; 56 public UUID PrincipalID;
@@ -130,8 +132,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
130 } 132 }
131 } 133 }
132 134
135 #region ISharedRegionModule
133 public void Initialise(IConfigSource config) 136 public void Initialise(IConfigSource config)
134 { 137 {
138 IConfig moduleConfig = config.Configs["Modules"];
139 if (moduleConfig != null)
140 {
141 string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
142 m_log.DebugFormat("[XXX] {0} compared to {1}", name, Name);
143 if (name == Name)
144 {
145 InitModule(config);
146
147 m_Enabled = true;
148 m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
149 }
150 }
151 }
152
153 protected void InitModule(IConfigSource config)
154 {
135 IConfig friendsConfig = config.Configs["Friends"]; 155 IConfig friendsConfig = config.Configs["Friends"];
136 if (friendsConfig != null) 156 if (friendsConfig != null)
137 { 157 {
@@ -153,7 +173,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
153 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue"); 173 m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
154 throw new Exception("Connector load error"); 174 throw new Exception("Connector load error");
155 } 175 }
156
157 } 176 }
158 177
159 public void PostInitialise() 178 public void PostInitialise()
@@ -166,6 +185,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
166 185
167 public void AddRegion(Scene scene) 186 public void AddRegion(Scene scene)
168 { 187 {
188 if (!m_Enabled)
189 return;
190
169 m_Scenes.Add(scene); 191 m_Scenes.Add(scene);
170 scene.RegisterModuleInterface<IFriendsModule>(this); 192 scene.RegisterModuleInterface<IFriendsModule>(this);
171 193
@@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
181 203
182 public void RemoveRegion(Scene scene) 204 public void RemoveRegion(Scene scene)
183 { 205 {
206 if (!m_Enabled)
207 return;
208
184 m_Scenes.Remove(scene); 209 m_Scenes.Remove(scene);
185 } 210 }
186 211
187 public string Name 212 public virtual string Name
188 { 213 {
189 get { return "FriendsModule"; } 214 get { return "FriendsModule"; }
190 } 215 }
@@ -194,6 +219,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
194 get { return null; } 219 get { return null; }
195 } 220 }
196 221
222 #endregion
223
197 public uint GetFriendPerms(UUID principalID, UUID friendID) 224 public uint GetFriendPerms(UUID principalID, UUID friendID)
198 { 225 {
199 FriendInfo[] friends = GetFriends(principalID); 226 FriendInfo[] friends = GetFriends(principalID);
@@ -214,30 +241,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
214 client.OnTerminateFriendship += OnTerminateFriendship; 241 client.OnTerminateFriendship += OnTerminateFriendship;
215 client.OnGrantUserRights += OnGrantUserRights; 242 client.OnGrantUserRights += OnGrantUserRights;
216 243
217 // Asynchronously fetch the friends list or increment the refcount for the existing 244 Util.FireAndForget(delegate { FetchFriendslist(client.AgentId); });
218 // friends list 245 }
219 Util.FireAndForget( 246
220 delegate(object o) 247 /// Fetch the friends list or increment the refcount for the existing
248 /// friends list
249 /// Returns true if the list was fetched, false if it wasn't
250 protected virtual bool FetchFriendslist(UUID agentID)
251 {
252 lock (m_Friends)
253 {
254 UserFriendData friendsData;
255 if (m_Friends.TryGetValue(agentID, out friendsData))
221 { 256 {
222 lock (m_Friends) 257 friendsData.Refcount++;
223 { 258 return false;
224 UserFriendData friendsData; 259 }
225 if (m_Friends.TryGetValue(client.AgentId, out friendsData)) 260 else
226 { 261 {
227 friendsData.Refcount++; 262 friendsData = new UserFriendData();
228 } 263 friendsData.PrincipalID = agentID;
229 else 264 friendsData.Friends = FriendsService.GetFriends(agentID);
230 { 265 friendsData.Refcount = 1;
231 friendsData = new UserFriendData();
232 friendsData.PrincipalID = client.AgentId;
233 friendsData.Friends = FriendsService.GetFriends(client.AgentId);
234 friendsData.Refcount = 1;
235 266
236 m_Friends[client.AgentId] = friendsData; 267 m_Friends[agentID] = friendsData;
237 } 268 return true;
238 }
239 } 269 }
240 ); 270 }
241 } 271 }
242 272
243 private void OnClientClosed(UUID agentID, Scene scene) 273 private void OnClientClosed(UUID agentID, Scene scene)
@@ -313,10 +343,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
313 foreach (string fid in outstanding) 343 foreach (string fid in outstanding)
314 { 344 {
315 UUID fromAgentID; 345 UUID fromAgentID;
316 if (!UUID.TryParse(fid, out fromAgentID)) 346 string firstname = "Unknown", lastname = "User";
347 if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
348 {
349 m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
317 continue; 350 continue;
318 351 }
319 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
320 352
321 PresenceInfo presence = null; 353 PresenceInfo presence = null;
322 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); 354 PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
@@ -326,15 +358,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
326 im.offline = 0; 358 im.offline = 0;
327 359
328 im.fromAgentID = fromAgentID.Guid; 360 im.fromAgentID = fromAgentID.Guid;
329 im.fromAgentName = account.FirstName + " " + account.LastName; 361 im.fromAgentName = firstname + " " + lastname;
330 im.offline = (byte)((presence == null) ? 1 : 0); 362 im.offline = (byte)((presence == null) ? 1 : 0);
331 im.imSessionID = im.fromAgentID; 363 im.imSessionID = im.fromAgentID;
364 im.message = FriendshipMessage(fid);
332 365
333 // Finally 366 // Finally
334 LocalFriendshipOffered(agentID, im); 367 LocalFriendshipOffered(agentID, im);
335 } 368 }
336 } 369 }
337 370
371 protected virtual string FriendshipMessage(string friendID)
372 {
373 return "Will you be my friend?";
374 }
375
376 protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
377 {
378 first = "Unknown"; last = "User";
379 if (!UUID.TryParse(fid, out agentID))
380 return false;
381
382 UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
383 if (account != null)
384 {
385 first = account.FirstName;
386 last = account.LastName;
387 }
388
389 return true;
390 }
391
338 List<UUID> GetOnlineFriends(UUID userID) 392 List<UUID> GetOnlineFriends(UUID userID)
339 { 393 {
340 List<string> friendList = new List<string>(); 394 List<string> friendList = new List<string>();
@@ -475,23 +529,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
475 529
476 // This user wants to be friends with the other user. 530 // This user wants to be friends with the other user.
477 // Let's add the relation backwards, in case the other is not online 531 // Let's add the relation backwards, in case the other is not online
478 FriendsService.StoreFriend(friendID, principalID.ToString(), 0); 532 StoreBackwards(friendID, principalID);
479 533
480 // Now let's ask the other user to be friends with this user 534 // Now let's ask the other user to be friends with this user
481 ForwardFriendshipOffer(principalID, friendID, im); 535 ForwardFriendshipOffer(principalID, friendID, im);
482 } 536 }
483 } 537 }
484 538
539 protected virtual void StoreBackwards(UUID friendID, UUID agentID)
540 {
541 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
542 }
543
485 private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im) 544 private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
486 { 545 {
487 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID) 546 // !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
488 // We stick this agent's ID as imSession, so that it's directly available on the receiving end 547 // We stick this agent's ID as imSession, so that it's directly available on the receiving end
489 im.imSessionID = im.fromAgentID; 548 im.imSessionID = im.fromAgentID;
549 im.fromAgentName = GetFriendshipRequesterName(agentID);
490 550
491 // Try the local sim 551 // Try the local sim
492 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
493 im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
494
495 if (LocalFriendshipOffered(friendID, im)) 552 if (LocalFriendshipOffered(friendID, im))
496 return; 553 return;
497 554
@@ -509,12 +566,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
509 // If the prospective friend is not online, he'll get the message upon login. 566 // If the prospective friend is not online, he'll get the message upon login.
510 } 567 }
511 568
569 protected virtual string GetFriendshipRequesterName(UUID agentID)
570 {
571 UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
572 return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
573 }
574
512 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 575 private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
513 { 576 {
514 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID); 577 m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
515 578
516 FriendsService.StoreFriend(agentID, friendID.ToString(), 1); 579 StoreFriendships(agentID, friendID);
517 FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
518 580
519 // Update the local cache 581 // Update the local cache
520 UpdateFriendsCache(agentID); 582 UpdateFriendsCache(agentID);
@@ -544,6 +606,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
544 } 606 }
545 } 607 }
546 608
609 protected virtual void StoreFriendships(UUID agentID, UUID friendID)
610 {
611 FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
612 FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
613 }
614
547 private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders) 615 private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
548 { 616 {
549 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID); 617 m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
@@ -576,8 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
576 644
577 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID) 645 private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
578 { 646 {
579 FriendsService.Delete(agentID, exfriendID.ToString()); 647 DeleteFriendship(agentID, exfriendID);
580 FriendsService.Delete(exfriendID, agentID.ToString());
581 648
582 // Update local cache 649 // Update local cache
583 UpdateFriendsCache(agentID); 650 UpdateFriendsCache(agentID);
@@ -604,6 +671,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
604 } 671 }
605 } 672 }
606 673
674 protected virtual void DeleteFriendship(UUID agentID, UUID exfriendID)
675 {
676 FriendsService.Delete(agentID, exfriendID.ToString());
677 FriendsService.Delete(exfriendID, agentID.ToString());
678 }
679
607 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) 680 private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
608 { 681 {
609 FriendInfo[] friends = GetFriends(remoteClient.AgentId); 682 FriendInfo[] friends = GetFriends(remoteClient.AgentId);
@@ -622,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
622 if (friend != null) // Found it 695 if (friend != null) // Found it
623 { 696 {
624 // Store it on the DB 697 // Store it on the DB
625 FriendsService.StoreFriend(requester, target.ToString(), rights); 698 FriendsService.StoreFriend(requester.ToString(), target.ToString(), rights);
626 699
627 // Store it in the local cache 700 // Store it in the local cache
628 int myFlags = friend.MyFlags; 701 int myFlags = friend.MyFlags;
@@ -780,7 +853,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
780 853
781 #endregion 854 #endregion
782 855
783 private FriendInfo[] GetFriends(UUID agentID) 856 protected FriendInfo[] GetFriends(UUID agentID)
784 { 857 {
785 UserFriendData friendsData; 858 UserFriendData friendsData;
786 859
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
new file mode 100644
index 0000000..645ecdc
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -0,0 +1,438 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Reflection;
32using log4net;
33using Nini.Config;
34using Nwc.XmlRpc;
35using Mono.Addins;
36using OpenMetaverse;
37using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Services.Interfaces;
41using OpenSim.Services.Connectors.Hypergrid;
42using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
43using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
44using GridRegion = OpenSim.Services.Interfaces.GridRegion;
45
46namespace OpenSim.Region.CoreModules.Avatar.Friends
47{
48 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
49 public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule
50 {
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52
53 #region ISharedRegionModule
54 public override string Name
55 {
56 get { return "HGFriendsModule"; }
57 }
58
59 #endregion
60
61 //public void SendFriendsOnlineIfNeeded(IClientAPI client)
62 //{
63 // UUID agentID = client.AgentId;
64
65 // // Check if the online friends list is needed
66 // lock (m_NeedsListOfFriends)
67 // {
68 // if (!m_NeedsListOfFriends.Remove(agentID))
69 // return;
70 // }
71
72 // // Send the friends online
73 // List<UUID> online = GetOnlineFriends(agentID);
74 // if (online.Count > 0)
75 // {
76 // m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count);
77 // client.SendAgentOnline(online.ToArray());
78 // }
79
80 // // Send outstanding friendship offers
81 // List<string> outstanding = new List<string>();
82 // FriendInfo[] friends = GetFriends(agentID);
83 // foreach (FriendInfo fi in friends)
84 // {
85 // if (fi.TheirFlags == -1)
86 // outstanding.Add(fi.Friend);
87 // }
88
89 // GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered,
90 // "Will you be my friend?", true, Vector3.Zero);
91
92 // foreach (string fid in outstanding)
93 // {
94 // UUID fromAgentID;
95 // if (!UUID.TryParse(fid, out fromAgentID))
96 // continue;
97
98 // UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
99
100 // PresenceInfo presence = null;
101 // PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
102 // if (presences != null && presences.Length > 0)
103 // presence = presences[0];
104 // if (presence != null)
105 // im.offline = 0;
106
107 // im.fromAgentID = fromAgentID.Guid;
108 // im.fromAgentName = account.FirstName + " " + account.LastName;
109 // im.offline = (byte)((presence == null) ? 1 : 0);
110 // im.imSessionID = im.fromAgentID;
111
112 // // Finally
113 // LocalFriendshipOffered(agentID, im);
114 // }
115 //}
116
117 //List<UUID> GetOnlineFriends(UUID userID)
118 //{
119 // List<string> friendList = new List<string>();
120 // List<UUID> online = new List<UUID>();
121
122 // FriendInfo[] friends = GetFriends(userID);
123 // foreach (FriendInfo fi in friends)
124 // {
125 // if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
126 // friendList.Add(fi.Friend);
127 // }
128
129 // if (friendList.Count > 0)
130 // {
131 // PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
132 // foreach (PresenceInfo pi in presence)
133 // {
134 // UUID presenceID;
135 // if (UUID.TryParse(pi.UserID, out presenceID))
136 // online.Add(presenceID);
137 // }
138 // }
139
140 // return online;
141 //}
142
143 //private void StatusNotify(FriendInfo friend, UUID userID, bool online)
144 //{
145 // UUID friendID;
146 // if (UUID.TryParse(friend.Friend, out friendID))
147 // {
148 // // Try local
149 // if (LocalStatusNotification(userID, friendID, online))
150 // return;
151
152 // // The friend is not here [as root]. Let's forward.
153 // PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
154 // if (friendSessions != null && friendSessions.Length > 0)
155 // {
156 // PresenceInfo friendSession = null;
157 // foreach (PresenceInfo pinfo in friendSessions)
158 // if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
159 // {
160 // friendSession = pinfo;
161 // break;
162 // }
163
164 // if (friendSession != null)
165 // {
166 // GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
167 // //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
168 // m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
169 // }
170 // }
171
172 // // Friend is not online. Ignore.
173 // }
174 // else
175 // {
176 // m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
177 // }
178 //}
179
180 protected override bool FetchFriendslist(UUID agentID)
181 {
182 if (base.FetchFriendslist(agentID))
183 {
184 // We need to preload the user management cache with the names
185 // of foreign friends, just like we do with SOPs' creators
186 foreach (FriendInfo finfo in m_Friends[agentID].Friends)
187 {
188 if (finfo.TheirFlags != -1)
189 {
190 UUID id;
191 if (!UUID.TryParse(finfo.Friend, out id))
192 {
193 string url = string.Empty, first = string.Empty, last = string.Empty;
194 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last))
195 {
196 IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
197 uMan.AddUser(id, url + ";" + first + " " + last);
198 }
199 }
200 }
201 }
202 return true;
203 }
204 return false;
205 }
206
207 protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
208 {
209 first = "Unknown"; last = "User";
210 if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
211 return true;
212
213 // fid is not a UUID...
214 string url = string.Empty;
215 if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last))
216 {
217 IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
218 userMan.AddUser(agentID, url + ";" + first + " " + last);
219
220 try // our best
221 {
222 string[] parts = userMan.GetUserName(agentID).Split();
223 first = parts[0];
224 last = parts[1];
225 }
226 catch { }
227 return true;
228 }
229 return false;
230 }
231
232 protected override string GetFriendshipRequesterName(UUID agentID)
233 {
234 // For the time being we assume that HG friendship requests can only happen
235 // when avies are on the same region.
236 IClientAPI client = LocateClientObject(agentID);
237 if (client != null)
238 return client.FirstName + " " + client.LastName;
239 else
240 return base.GetFriendshipRequesterName(agentID);
241 }
242
243 protected override string FriendshipMessage(string friendID)
244 {
245 UUID id;
246 if (UUID.TryParse(friendID, out id))
247 return base.FriendshipMessage(friendID);
248
249 return "Please confirm this friendship you made while you were away.";
250 }
251
252 protected override void StoreBackwards(UUID friendID, UUID agentID)
253 {
254 UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
255 UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
256 // Are they both local users?
257 if (account1 != null && account2 != null)
258 {
259 // local grid users
260 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
261 base.StoreBackwards(friendID, agentID);
262 return;
263 }
264
265 // no provision for this temporary friendship state
266 //FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
267 }
268
269 protected override void StoreFriendships(UUID agentID, UUID friendID)
270 {
271 UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
272 UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
273 // Are they both local users?
274 if (agentAccount != null && friendAccount != null)
275 {
276 // local grid users
277 m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
278 base.StoreFriendships(agentID, friendID);
279 return;
280 }
281
282
283 // ok, at least one of them is foreigner, let's get their data
284 IClientAPI agentClient = LocateClientObject(agentID);
285 IClientAPI friendClient = LocateClientObject(friendID);
286 AgentCircuitData agentClientCircuit = null;
287 AgentCircuitData friendClientCircuit = null;
288 string agentUUI = string.Empty;
289 string friendUUI = string.Empty;
290 string agentFriendService = string.Empty;
291 string friendFriendService = string.Empty;
292
293 if (agentClient != null)
294 {
295 agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
296 agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
297 agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
298 }
299 if (friendClient != null)
300 {
301 friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
302 friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
303 friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
304 }
305
306 m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
307 agentUUI, friendUUI, agentFriendService, friendFriendService);
308
309 if (agentAccount != null) // agent is local, 'friend' is foreigner
310 {
311 // This may happen when the agent returned home, in which case the friend is not there
312 // We need to llok for its information in the friends list itself
313 if (friendUUI == string.Empty)
314 {
315 FriendInfo[] finfos = GetFriends(agentID);
316 foreach (FriendInfo finfo in finfos)
317 {
318 if (finfo.TheirFlags == -1)
319 {
320 if (finfo.Friend.StartsWith(friendID.ToString()))
321 friendUUI = finfo.Friend;
322 }
323 }
324 }
325
326 // store in the local friends service a reference to the foreign friend
327 FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1);
328 // and also the converse
329 FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1);
330
331 if (friendClientCircuit != null)
332 {
333 // store in the foreign friends service a reference to the local agent
334 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
335 friendsConn.NewFriendship(friendID, agentUUI);
336 }
337 }
338 else if (friendAccount != null) // 'friend' is local, agent is foreigner
339 {
340 // store in the local friends service a reference to the foreign agent
341 FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1);
342 // and also the converse
343 FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1);
344
345 if (agentClientCircuit != null)
346 {
347 // store in the foreign friends service a reference to the local agent
348 HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
349 friendsConn.NewFriendship(agentID, friendUUI);
350 }
351 }
352 else // They're both foreigners!
353 {
354 HGFriendsServicesConnector friendsConn;
355 if (agentClientCircuit != null)
356 {
357 friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
358 friendsConn.NewFriendship(agentID, friendUUI);
359 }
360 if (friendClientCircuit != null)
361 {
362 friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
363 friendsConn.NewFriendship(friendID, agentUUI);
364 }
365 }
366 // my brain hurts now
367 }
368
369 protected override void DeleteFriendship(UUID agentID, UUID exfriendID)
370 {
371 base.DeleteFriendship(agentID, exfriendID);
372 // Maybe some of the base deletes will fail.
373 // Let's delete the local friendship with foreign friend
374 FriendInfo[] friends = GetFriends(agentID);
375 foreach (FriendInfo finfo in friends)
376 {
377 if (finfo.Friend != exfriendID.ToString() && finfo.Friend.EndsWith(exfriendID.ToString()))
378 {
379 FriendsService.Delete(agentID, exfriendID.ToString());
380 // TODO: delete the friendship on the other side
381 // Should use the homeurl given in finfo.Friend
382 }
383 }
384 }
385
386 //private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
387 //{
388 // FriendInfo[] friends = GetFriends(remoteClient.AgentId);
389 // if (friends.Length == 0)
390 // return;
391
392 // m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
393 // // Let's find the friend in this user's friend list
394 // FriendInfo friend = null;
395 // foreach (FriendInfo fi in friends)
396 // {
397 // if (fi.Friend == target.ToString())
398 // friend = fi;
399 // }
400
401 // if (friend != null) // Found it
402 // {
403 // // Store it on the DB
404 // FriendsService.StoreFriend(requester, target.ToString(), rights);
405
406 // // Store it in the local cache
407 // int myFlags = friend.MyFlags;
408 // friend.MyFlags = rights;
409
410 // // Always send this back to the original client
411 // remoteClient.SendChangeUserRights(requester, target, rights);
412
413 // //
414 // // Notify the friend
415 // //
416
417 // // Try local
418 // if (LocalGrantRights(requester, target, myFlags, rights))
419 // return;
420
421 // PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
422 // if (friendSessions != null && friendSessions.Length > 0)
423 // {
424 // PresenceInfo friendSession = friendSessions[0];
425 // if (friendSession != null)
426 // {
427 // GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
428 // // TODO: You might want to send the delta to save the lookup
429 // // on the other end!!
430 // m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
431 // }
432 // }
433 // }
434 //}
435
436
437 }
438}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 4cc6905..795de09 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -141,6 +141,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
141 141
142 void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client) 142 void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
143 { 143 {
144 m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0}", uuid);
144 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid)) 145 if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
145 { 146 {
146 remote_client.SendNameReply(uuid, "Mr", "OpenSim"); 147 remote_client.SendNameReply(uuid, "Mr", "OpenSim");
@@ -210,6 +211,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
210 211
211 public string GetUserName(UUID uuid) 212 public string GetUserName(UUID uuid)
212 { 213 {
214 m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
213 string[] names = GetUserNames(uuid); 215 string[] names = GetUserNames(uuid);
214 if (names.Length == 2) 216 if (names.Length == 2)
215 { 217 {
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index d2343c9..f5b6817 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -115,6 +115,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
115 115
116 new UserAgentServerConnector(m_Config, MainServer.Instance); 116 new UserAgentServerConnector(m_Config, MainServer.Instance);
117 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService"); 117 new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
118 new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
118 } 119 }
119 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper); 120 scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
120 } 121 }
diff --git a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
index 074f869..5784bdf 100644
--- a/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendServerConnector.cs
@@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
46 if (serverConfig == null) 46 if (serverConfig == null)
47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName)); 47 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
48 48
49 string gridService = serverConfig.GetString("LocalServiceModule", 49 string theService = serverConfig.GetString("LocalServiceModule",
50 String.Empty); 50 String.Empty);
51 51
52 if (gridService == String.Empty) 52 if (theService == String.Empty)
53 throw new Exception("No LocalServiceModule in config file"); 53 throw new Exception("No LocalServiceModule in config file");
54 54
55 Object[] args = new Object[] { config }; 55 Object[] args = new Object[] { config };
56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(gridService, args); 56 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
57 57
58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService)); 58 server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
59 } 59 }
diff --git a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
index b168bb3..64002e1 100644
--- a/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Friends/FriendsServerPostHandler.cs
@@ -138,7 +138,7 @@ namespace OpenSim.Server.Handlers.Friends
138 { 138 {
139 FriendInfo friend = new FriendInfo(request); 139 FriendInfo friend = new FriendInfo(request);
140 140
141 bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags); 141 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, friend.MyFlags);
142 142
143 if (success) 143 if (success)
144 return SuccessResult(); 144 return SuccessResult();
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
new file mode 100644
index 0000000..82a7220
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using Nini.Config;
30using OpenSim.Server.Base;
31using OpenSim.Services.Interfaces;
32using OpenSim.Framework.Servers.HttpServer;
33using OpenSim.Server.Handlers.Base;
34
35namespace OpenSim.Server.Handlers.Hypergrid
36{
37 public class HGFriendsServerConnector : ServiceConnector
38 {
39 private IFriendsService m_FriendsService;
40 private IUserAgentService m_UserAgentService;
41 private string m_ConfigName = "HGFriendsService";
42
43 public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
44 base(config, server, configName)
45 {
46 if (configName != string.Empty)
47 m_ConfigName = configName;
48
49 IConfig serverConfig = config.Configs[m_ConfigName];
50 if (serverConfig == null)
51 throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
52
53 string theService = serverConfig.GetString("LocalServiceModule",
54 String.Empty);
55
56 if (theService == String.Empty)
57 throw new Exception("No LocalServiceModule in config file");
58
59 Object[] args = new Object[] { config };
60 m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
61
62 theService = serverConfig.GetString("UserAgentService", string.Empty);
63 if (theService == String.Empty)
64 throw new Exception("No UserAgentService in " + m_ConfigName);
65
66 m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args);
67
68 server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
69 }
70 }
71}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
new file mode 100644
index 0000000..13d1502
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -0,0 +1,242 @@
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 Nini.Config;
29using log4net;
30using System;
31using System.Reflection;
32using System.IO;
33using System.Net;
34using System.Text;
35using System.Text.RegularExpressions;
36using System.Xml;
37using System.Xml.Serialization;
38using System.Collections.Generic;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class HGFriendsServerPostHandler : BaseStreamHandler
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private IFriendsService m_FriendsService;
53 private IUserAgentService m_UserAgentService;
54
55 public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
56 base("POST", "/hgfriends")
57 {
58 m_FriendsService = service;
59 m_UserAgentService = uservice;
60 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
61 }
62
63 public override byte[] Handle(string path, Stream requestData,
64 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
65 {
66 StreamReader sr = new StreamReader(requestData);
67 string body = sr.ReadToEnd();
68 sr.Close();
69 body = body.Trim();
70
71 //m_log.DebugFormat("[XXX]: query String: {0}", body);
72
73 try
74 {
75 Dictionary<string, object> request =
76 ServerUtils.ParseQueryString(body);
77
78 if (!request.ContainsKey("METHOD"))
79 return FailureResult();
80
81 string method = request["METHOD"].ToString();
82
83 switch (method)
84 {
85 case "getfriends":
86 return GetFriends(request);
87
88 case "newfriendship":
89 return NewFriendship(request);
90
91 }
92 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
93 }
94 catch (Exception e)
95 {
96 m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
97 }
98
99 return FailureResult();
100
101 }
102
103 #region Method-specific handlers
104
105 byte[] GetFriends(Dictionary<string, object> request)
106 {
107 UUID principalID = UUID.Zero;
108 if (request.ContainsKey("PRINCIPALID"))
109 UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
110 else
111 m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friends");
112
113 FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
114 //m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count);
115
116 Dictionary<string, object> result = new Dictionary<string, object>();
117 if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
118 result["result"] = "null";
119 else
120 {
121 int i = 0;
122 foreach (FriendInfo finfo in finfos)
123 {
124 Dictionary<string, object> rinfoDict = finfo.ToKeyValuePairs();
125 result["friend" + i] = rinfoDict;
126 i++;
127 }
128 }
129
130 string xmlString = ServerUtils.BuildXmlResponse(result);
131 //m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString);
132 UTF8Encoding encoding = new UTF8Encoding();
133 return encoding.GetBytes(xmlString);
134
135 }
136
137 byte[] NewFriendship(Dictionary<string, object> request)
138 {
139 if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
140 {
141 m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
142 return FailureResult();
143 }
144
145 string serviceKey = request["KEY"].ToString();
146 string sessionStr = request["SESSIONID"].ToString();
147 UUID sessionID;
148 UUID.TryParse(sessionStr, out sessionID);
149
150 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
151 {
152 m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
153 return FailureResult();
154 }
155
156 m_log.DebugFormat("[XXX] Verification ok");
157 // OK, can proceed
158 FriendInfo friend = new FriendInfo(request);
159
160 // the user needs to confirm when he gets home
161 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
162 //if (success)
163 // m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1);
164
165 if (success)
166 return SuccessResult();
167 else
168 return FailureResult();
169 }
170
171 #endregion
172
173 #region Misc
174
175 private byte[] SuccessResult()
176 {
177 XmlDocument doc = new XmlDocument();
178
179 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
180 "", "");
181
182 doc.AppendChild(xmlnode);
183
184 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
185 "");
186
187 doc.AppendChild(rootElement);
188
189 XmlElement result = doc.CreateElement("", "Result", "");
190 result.AppendChild(doc.CreateTextNode("Success"));
191
192 rootElement.AppendChild(result);
193
194 return DocToBytes(doc);
195 }
196
197 private byte[] FailureResult()
198 {
199 return FailureResult(String.Empty);
200 }
201
202 private byte[] FailureResult(string msg)
203 {
204 XmlDocument doc = new XmlDocument();
205
206 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
207 "", "");
208
209 doc.AppendChild(xmlnode);
210
211 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
212 "");
213
214 doc.AppendChild(rootElement);
215
216 XmlElement result = doc.CreateElement("", "Result", "");
217 result.AppendChild(doc.CreateTextNode("Failure"));
218
219 rootElement.AppendChild(result);
220
221 XmlElement message = doc.CreateElement("", "Message", "");
222 message.AppendChild(doc.CreateTextNode(msg));
223
224 rootElement.AppendChild(message);
225
226 return DocToBytes(doc);
227 }
228
229 private byte[] DocToBytes(XmlDocument doc)
230 {
231 MemoryStream ms = new MemoryStream();
232 XmlTextWriter xw = new XmlTextWriter(ms, null);
233 xw.Formatting = Formatting.Indented;
234 doc.WriteTo(xw);
235 xw.Flush();
236
237 return ms.ToArray();
238 }
239
240 #endregion
241 }
242}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
index 861c475..52b80e1 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsServiceConnector.cs
@@ -38,7 +38,7 @@ using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base; 38using OpenSim.Server.Base;
39using OpenMetaverse; 39using OpenMetaverse;
40 40
41namespace OpenSim.Services.Connectors 41namespace OpenSim.Services.Connectors.Friends
42{ 42{
43 public class FriendsServicesConnector : IFriendsService 43 public class FriendsServicesConnector : IFriendsService
44 { 44 {
@@ -144,10 +144,17 @@ namespace OpenSim.Services.Connectors
144 144
145 } 145 }
146 146
147 public bool StoreFriend(UUID PrincipalID, string Friend, int flags) 147 public bool StoreFriend(string PrincipalID, string Friend, int flags)
148 { 148 {
149 FriendInfo finfo = new FriendInfo(); 149 FriendInfo finfo = new FriendInfo();
150 finfo.PrincipalID = PrincipalID; 150 try
151 {
152 finfo.PrincipalID = new UUID(PrincipalID);
153 }
154 catch
155 {
156 return false;
157 }
151 finfo.Friend = Friend; 158 finfo.Friend = Friend;
152 finfo.MyFlags = flags; 159 finfo.MyFlags = flags;
153 160
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
new file mode 100644
index 0000000..76f5f19
--- /dev/null
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
@@ -0,0 +1,175 @@
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 log4net;
29using System;
30using System.Collections.Generic;
31using System.IO;
32using System.Reflection;
33using Nini.Config;
34using OpenSim.Framework;
35using OpenSim.Services.Interfaces;
36using OpenSim.Services.Connectors.Friends;
37using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
38using OpenSim.Server.Base;
39using OpenMetaverse;
40
41namespace OpenSim.Services.Connectors.Hypergrid
42{
43 public class HGFriendsServicesConnector
44 {
45 private static readonly ILog m_log =
46 LogManager.GetLogger(
47 MethodBase.GetCurrentMethod().DeclaringType);
48
49 private string m_ServerURI = String.Empty;
50 private string m_ServiceKey = String.Empty;
51 private UUID m_SessionID;
52
53 public HGFriendsServicesConnector()
54 {
55 }
56
57 public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey)
58 {
59 m_ServerURI = serverURI.TrimEnd('/');
60 m_ServiceKey = serviceKey;
61 m_SessionID = sessionID;
62 }
63
64 #region IFriendsService
65
66 public FriendInfo[] GetFriends(UUID PrincipalID)
67 {
68 Dictionary<string, object> sendData = new Dictionary<string, object>();
69
70 sendData["PRINCIPALID"] = PrincipalID.ToString();
71 sendData["METHOD"] = "getfriends";
72 sendData["KEY"] = m_ServiceKey;
73 sendData["SESSIONID"] = m_SessionID.ToString();
74
75 string reqString = ServerUtils.BuildQueryString(sendData);
76
77 try
78 {
79 string reply = SynchronousRestFormsRequester.MakeRequest("POST",
80 m_ServerURI + "/hgfriends",
81 reqString);
82 if (reply != string.Empty)
83 {
84 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
85
86 if (replyData != null)
87 {
88 if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null"))
89 {
90 return new FriendInfo[0];
91 }
92
93 List<FriendInfo> finfos = new List<FriendInfo>();
94 Dictionary<string, object>.ValueCollection finfosList = replyData.Values;
95 //m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count);
96 foreach (object f in finfosList)
97 {
98 if (f is Dictionary<string, object>)
99 {
100 FriendInfo finfo = new FriendInfo((Dictionary<string, object>)f);
101 finfos.Add(finfo);
102 }
103 else
104 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}",
105 PrincipalID, f.GetType());
106 }
107
108 // Success
109 return finfos.ToArray();
110 }
111
112 else
113 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received null response",
114 PrincipalID);
115
116 }
117 }
118 catch (Exception e)
119 {
120 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
121 }
122
123 return new FriendInfo[0];
124
125 }
126
127 public bool NewFriendship(UUID PrincipalID, string Friend)
128 {
129 FriendInfo finfo = new FriendInfo();
130 finfo.PrincipalID = PrincipalID;
131 finfo.Friend = Friend;
132
133 Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
134
135 sendData["METHOD"] = "newfriendship";
136 sendData["KEY"] = m_ServiceKey;
137 sendData["SESSIONID"] = m_SessionID.ToString();
138
139 string reply = string.Empty;
140 try
141 {
142 reply = SynchronousRestFormsRequester.MakeRequest("POST",
143 m_ServerURI + "/hgfriends",
144 ServerUtils.BuildQueryString(sendData));
145 }
146 catch (Exception e)
147 {
148 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
149 return false;
150 }
151
152 if (reply != string.Empty)
153 {
154 Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
155
156 if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
157 {
158 bool success = false;
159 Boolean.TryParse(replyData["Result"].ToString(), out success);
160 return success;
161 }
162 else
163 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
164 PrincipalID, Friend);
165 }
166 else
167 m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply");
168
169 return false;
170
171 }
172
173 #endregion
174 }
175} \ No newline at end of file
diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
index 6f2d735..f61ab29 100644
--- a/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/SimianGrid/SimianFriendsServiceConnector.cs
@@ -127,7 +127,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
127 return array; 127 return array;
128 } 128 }
129 129
130 public bool StoreFriend(UUID principalID, string friend, int flags) 130 public bool StoreFriend(string principalID, string friend, int flags)
131 { 131 {
132 if (String.IsNullOrEmpty(m_serverUrl)) 132 if (String.IsNullOrEmpty(m_serverUrl))
133 return true; 133 return true;
diff --git a/OpenSim/Services/Friends/FriendsService.cs b/OpenSim/Services/Friends/FriendsService.cs
index 3c64ecc..039dc0b 100644
--- a/OpenSim/Services/Friends/FriendsService.cs
+++ b/OpenSim/Services/Friends/FriendsService.cs
@@ -43,17 +43,16 @@ namespace OpenSim.Services.Friends
43 { 43 {
44 } 44 }
45 45
46 public FriendInfo[] GetFriends(UUID PrincipalID) 46 public virtual FriendInfo[] GetFriends(UUID PrincipalID)
47 { 47 {
48 FriendsData[] data = m_Database.GetFriends(PrincipalID); 48 FriendsData[] data = m_Database.GetFriends(PrincipalID);
49
50 List<FriendInfo> info = new List<FriendInfo>(); 49 List<FriendInfo> info = new List<FriendInfo>();
51 50
52 foreach (FriendsData d in data) 51 foreach (FriendsData d in data)
53 { 52 {
54 FriendInfo i = new FriendInfo(); 53 FriendInfo i = new FriendInfo();
55 54
56 i.PrincipalID = d.PrincipalID; 55 i.PrincipalID = new UUID(d.PrincipalID);
57 i.Friend = d.Friend; 56 i.Friend = d.Friend;
58 i.MyFlags = Convert.ToInt32(d.Data["Flags"]); 57 i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
59 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]); 58 i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
@@ -64,7 +63,7 @@ namespace OpenSim.Services.Friends
64 return info.ToArray(); 63 return info.ToArray();
65 } 64 }
66 65
67 public bool StoreFriend(UUID PrincipalID, string Friend, int flags) 66 public virtual bool StoreFriend(string PrincipalID, string Friend, int flags)
68 { 67 {
69 FriendsData d = new FriendsData(); 68 FriendsData d = new FriendsData();
70 69
@@ -76,7 +75,7 @@ namespace OpenSim.Services.Friends
76 return m_Database.Store(d); 75 return m_Database.Store(d);
77 } 76 }
78 77
79 public bool Delete(UUID PrincipalID, string Friend) 78 public virtual bool Delete(UUID PrincipalID, string Friend)
80 { 79 {
81 return m_Database.Delete(PrincipalID, Friend); 80 return m_Database.Delete(PrincipalID, Friend);
82 } 81 }
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs
new file mode 100644
index 0000000..fa4ec5d
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGFriendsService.cs
@@ -0,0 +1,95 @@
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);
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
74 FriendsData d = new FriendsData();
75 d.PrincipalID = PrincipalID;
76 d.Friend = Friend;
77 d.Data = new Dictionary<string, string>();
78 d.Data["Flags"] = "0";
79
80 return m_Database.Store(d);
81 }
82
83 /// <summary>
84 /// Overrides base. Cannot delete friendships while away from home.
85 /// </summary>
86 /// <param name="PrincipalID"></param>
87 /// <param name="Friend"></param>
88 /// <returns></returns>
89 public override bool Delete(UUID PrincipalID, string Friend)
90 {
91 return false;
92 }
93
94 }
95}
diff --git a/OpenSim/Services/Interfaces/IFriendsService.cs b/OpenSim/Services/Interfaces/IFriendsService.cs
index 0ddd5e5..05e85f2 100644
--- a/OpenSim/Services/Interfaces/IFriendsService.cs
+++ b/OpenSim/Services/Interfaces/IFriendsService.cs
@@ -74,7 +74,7 @@ namespace OpenSim.Services.Interfaces
74 public interface IFriendsService 74 public interface IFriendsService
75 { 75 {
76 FriendInfo[] GetFriends(UUID PrincipalID); 76 FriendInfo[] GetFriends(UUID PrincipalID);
77 bool StoreFriend(UUID PrincipalID, string Friend, int flags); 77 bool StoreFriend(string PrincipalID, string Friend, int flags);
78 bool Delete(UUID PrincipalID, string Friend); 78 bool Delete(UUID PrincipalID, string Friend);
79 } 79 }
80} 80}
diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
index ddc8855..4fac951 100644
--- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs
+++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs
@@ -621,7 +621,19 @@ namespace OpenSim.Services.LLLoginService
621 if (finfo.TheirFlags == -1) 621 if (finfo.TheirFlags == -1)
622 continue; 622 continue;
623 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend); 623 LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
624 buddyitem.BuddyID = finfo.Friend; 624 // finfo.Friend may not be a simple uuid
625 UUID friendID = UUID.Zero;
626 if (UUID.TryParse(finfo.Friend, out friendID))
627 buddyitem.BuddyID = finfo.Friend;
628 else
629 {
630 string tmp;
631 if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp))
632 buddyitem.BuddyID = friendID.ToString();
633 else
634 // junk entry
635 continue;
636 }
625 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags; 637 buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
626 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags; 638 buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
627 buddylistreturn.AddNewBuddy(buddyitem); 639 buddylistreturn.AddNewBuddy(buddyitem);