diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index d89bb3a3aa..728cda0d4a 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -35,7 +35,7 @@ using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Sockets;
-using System.Reflection;
+using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
@@ -378,20 +378,20 @@ namespace OpenSim.Framework
}
return sb.ToString();
- }
-
- ///
- /// Is the platform Windows?
- ///
- /// true if so, false otherwise
- public static bool IsWindows()
- {
- PlatformID platformId = Environment.OSVersion.Platform;
-
- return (platformId == PlatformID.Win32NT
- || platformId == PlatformID.Win32S
- || platformId == PlatformID.Win32Windows
- || platformId == PlatformID.WinCE);
+ }
+
+ ///
+ /// Is the platform Windows?
+ ///
+ /// true if so, false otherwise
+ public static bool IsWindows()
+ {
+ PlatformID platformId = Environment.OSVersion.Platform;
+
+ return (platformId == PlatformID.Win32NT
+ || platformId == PlatformID.Win32S
+ || platformId == PlatformID.Win32Windows
+ || platformId == PlatformID.WinCE);
}
public static bool LoadArchSpecificWindowsDll(string libraryName)
@@ -1516,27 +1516,27 @@ namespace OpenSim.Framework
}
return data;
- }
-
- ///
- /// Used to trigger an early library load on Windows systems.
- ///
- ///
- /// Required to get 32-bit and 64-bit processes to automatically use the
- /// appropriate native library.
- ///
- ///
- ///
- [DllImport("kernel32.dll")]
- public static extern IntPtr LoadLibrary(string dllToLoad);
-
- ///
- /// Determine whether the current process is 64 bit
- ///
- /// true if so, false if not
- public static bool Is64BitProcess()
- {
- return IntPtr.Size == 8;
+ }
+
+ ///
+ /// Used to trigger an early library load on Windows systems.
+ ///
+ ///
+ /// Required to get 32-bit and 64-bit processes to automatically use the
+ /// appropriate native library.
+ ///
+ ///
+ ///
+ [DllImport("kernel32.dll")]
+ public static extern IntPtr LoadLibrary(string dllToLoad);
+
+ ///
+ /// Determine whether the current process is 64 bit
+ ///
+ /// true if so, false if not
+ public static bool Is64BitProcess()
+ {
+ return IntPtr.Size == 8;
}
#region FireAndForget Threading Pattern
@@ -1952,11 +1952,12 @@ namespace OpenSim.Framework
#region Universal User Identifiers
///
///
- /// uuid[;endpoint[;name]]
- ///
- ///
- ///
- ///
+ /// uuid[;endpoint[;first last[;secret]]]
+ /// the uuid part
+ /// the endpoint part (e.g. http://foo.com)
+ /// the first name part (e.g. Test)
+ /// the last name part (e.g User)
+ /// the secret part
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
{
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
@@ -1985,31 +1986,64 @@ namespace OpenSim.Framework
}
///
- ///
+ /// Produces a universal (HG) system-facing identifier given the information
///
///
- /// uuid[;endpoint[;name]]
+ /// uuid[;homeURI[;first last]]
public static string ProduceUserUniversalIdentifier(AgentCircuitData acircuit)
{
if (acircuit.ServiceURLs.ContainsKey("HomeURI"))
- {
- string agentsURI = acircuit.ServiceURLs["HomeURI"].ToString();
- if (!agentsURI.EndsWith("/"))
- agentsURI += "/";
-
- // This is ugly, but there's no other way, given that the name is changed
- // in the agent circuit data for foreigners
- if (acircuit.lastname.Contains("@"))
- {
- string[] parts = acircuit.firstname.Split(new char[] { '.' });
- if (parts.Length == 2)
- return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
- }
- return acircuit.AgentID.ToString() + ";" + agentsURI + ";" + acircuit.firstname + " " + acircuit.lastname;
- }
+ return UniversalIdentifier(acircuit.AgentID, acircuit.firstname, acircuit.lastname, acircuit.ServiceURLs["HomeURI"].ToString());
else
return acircuit.AgentID.ToString();
- }
+ }
+
+ ///
+ /// Produces a universal (HG) system-facing identifier given the information
+ ///
+ /// UUID of the user
+ /// first name (e.g Test)
+ /// last name (e.g. User)
+ /// homeURI (e.g. http://foo.com)
+ /// a string of the form uuid[;homeURI[;first last]]
+ public static string UniversalIdentifier(UUID id, String firstName, String lastName, String homeURI)
+ {
+ string agentsURI = homeURI;
+ if (!agentsURI.EndsWith("/"))
+ agentsURI += "/";
+
+ // This is ugly, but there's no other way, given that the name is changed
+ // in the agent circuit data for foreigners
+ if (lastName.Contains("@"))
+ {
+ string[] parts = firstName.Split(new char[] { '.' });
+ if (parts.Length == 2)
+ return id.ToString() + ";" + agentsURI + ";" + parts[0] + " " + parts[1];
+ }
+ return id.ToString() + ";" + agentsURI + ";" + firstName + " " + lastName;
+
+ }
+
+ ///
+ /// Produces a universal (HG) user-facing name given the information
+ ///
+ ///
+ ///
+ ///
+ /// string of the form first.last @foo.com or first last
+ public static string UniversalName(String firstName, String lastName, String homeURI)
+ {
+ Uri uri = null;
+ try
+ {
+ uri = new Uri(homeURI);
+ }
+ catch (UriFormatException)
+ {
+ return firstName + " " + lastName;
+ }
+ return firstName + "." + lastName + " " + "@" + uri.Authority;
+ }
#endregion
}
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index 5d94ff7e1c..ca8d8e64fc 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -550,7 +550,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UUID principalID = new UUID(im.fromAgentID);
UUID friendID = new UUID(im.toAgentID);
- m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2}", principalID, im.fromAgentName, friendID);
+ m_log.DebugFormat("[FRIENDS]: {0} ({1}) offered friendship to {2} ({3})", principalID, client.FirstName + client.LastName, friendID, im.fromAgentName);
+
+ // Check that the friendship doesn't exist yet
+ FriendInfo[] finfos = GetFriends(principalID);
+ if (finfos != null)
+ {
+ FriendInfo f = GetFriend(finfos, friendID);
+ if (f != null)
+ {
+ client.SendAgentAlertMessage("This person is already your friend. Please delete it first if you want to reestablish the friendship.", false);
+ return;
+ }
+ }
// This user wants to be friends with the other user.
// Let's add the relation backwards, in case the other is not online
@@ -561,7 +573,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
- private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
+ protected virtual bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
{
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
@@ -570,7 +582,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Try the local sim
if (LocalFriendshipOffered(friendID, im))
- return;
+ {
+ m_log.DebugFormat("[XXX]: LocalFriendshipOffered successes");
+ return true;
+ }
// The prospective friend is not here [as root]. Let's forward.
PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
@@ -581,9 +596,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message);
+ return true;
}
}
// If the prospective friend is not online, he'll get the message upon login.
+ return false;
}
protected virtual string GetFriendshipRequesterName(UUID agentID)
@@ -592,7 +609,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
}
- private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders)
+ protected virtual void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders)
{
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", client.AgentId, friendID);
@@ -762,7 +779,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#region Local
- public bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
+ public virtual bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
{
IClientAPI friendClient = LocateClientObject(toID);
if (friendClient != null)
@@ -925,7 +942,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return FriendsService.GetFriends(client.AgentId);
}
- private void RecacheFriends(IClientAPI client)
+ protected void RecacheFriends(IClientAPI client)
{
// FIXME: Ideally, we want to avoid doing this here since it sits the EventManager.OnMakeRootAgent event
// is on the critical path for transferring an avatar from one region to another.
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index 9c53fc4ac8..0fe1134d57 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -61,6 +61,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
}
}
+ protected HGFriendsServicesConnector m_HGFriendsConnector = new HGFriendsServicesConnector();
+
#region ISharedRegionModule
public override string Name
{
@@ -94,6 +96,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion
+ protected override void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List callingCardFolders)
+ {
+ // Update the local cache. Yes, we need to do it right here
+ // because the HGFriendsService placed something on the DB
+ // from under the sim
+ base.OnApproveFriendRequest(client, agentID, friendID, callingCardFolders);
+ }
+
protected override bool CacheFriends(IClientAPI client)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entered CacheFriends for {0}", client.Name);
@@ -183,91 +193,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetOnlineFriends for {0}", userID);
}
- //protected override void GetOnlineFriends(UUID userID, List friendList, /*collector*/ List online)
- //{
- // // Let's single out the UUIs
- // List localFriends = new List();
- // List foreignFriends = new List();
- // string tmp = string.Empty;
-
- // foreach (string s in friendList)
- // {
- // UUID id;
- // if (UUID.TryParse(s, out id))
- // localFriends.Add(s);
- // else if (Util.ParseUniversalUserIdentifier(s, out id, out tmp, out tmp, out tmp, out tmp))
- // {
- // foreignFriends.Add(s);
- // // add it here too, who knows maybe the foreign friends happens to be on this grid
- // localFriends.Add(id.ToString());
- // }
- // }
-
- // // OK, see who's present on this grid
- // List toBeRemoved = new List();
- // PresenceInfo[] presence = PresenceService.GetAgents(localFriends.ToArray());
- // foreach (PresenceInfo pi in presence)
- // {
- // UUID presenceID;
- // if (UUID.TryParse(pi.UserID, out presenceID))
- // {
- // online.Add(presenceID);
- // foreach (string s in foreignFriends)
- // if (s.StartsWith(pi.UserID))
- // toBeRemoved.Add(s);
- // }
- // }
-
- // foreach (string s in toBeRemoved)
- // foreignFriends.Remove(s);
-
- // // OK, let's send this up the stack, and leave a closure here
- // // collecting online friends in other grids
- // Util.FireAndForget(delegate { CollectOnlineFriendsElsewhere(userID, foreignFriends); });
-
- //}
-
- //private void CollectOnlineFriendsElsewhere(UUID userID, List foreignFriends)
- //{
- // // let's divide the friends on a per-domain basis
- // Dictionary> friendsPerDomain = new Dictionary>();
- // foreach (string friend in foreignFriends)
- // {
- // UUID friendID;
- // if (!UUID.TryParse(friend, out friendID))
- // {
- // // it's a foreign friend
- // string url = string.Empty, tmp = string.Empty;
- // if (Util.ParseUniversalUserIdentifier(friend, out friendID, out url, out tmp, out tmp, out tmp))
- // {
- // if (!friendsPerDomain.ContainsKey(url))
- // friendsPerDomain[url] = new List();
- // friendsPerDomain[url].Add(friend);
- // }
- // }
- // }
-
- // // Now, call those worlds
-
- // foreach (KeyValuePair> kvp in friendsPerDomain)
- // {
- // List ids = new List();
- // foreach (string f in kvp.Value)
- // ids.Add(f);
- // UserAgentServiceConnector uConn = new UserAgentServiceConnector(kvp.Key);
- // List online = uConn.GetOnlineFriends(userID, ids);
- // // Finally send the notifications to the user
- // // this whole process may take a while, so let's check at every
- // // iteration that the user is still here
- // IClientAPI client = LocateClientObject(userID);
- // if (client != null)
- // client.SendAgentOnline(online.ToArray());
- // else
- // break;
- // }
-
- //}
-
protected override void StatusNotify(List friendList, UUID userID, bool online)
{
// m_log.DebugFormat("[HGFRIENDS MODULE]: Entering StatusNotify for {0}", userID);
@@ -335,12 +260,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return true;
// fid is not a UUID...
- string url = string.Empty, tmp = string.Empty;
- if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp))
+ string url = string.Empty, tmp = string.Empty, f = string.Empty, l = string.Empty;
+ m_log.DebugFormat("[YYY]: FID {0}", fid);
+ if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out f, out l, out tmp))
{
- IUserManagement userMan = m_Scenes[0].RequestModuleInterface();
- userMan.AddUser(agentID, first, last, url);
+ m_log.DebugFormat("[YYY]: Adding user {0} {1} {2}", f, l, url);
+ m_uMan.AddUser(agentID, f, l, url);
+ string name = m_uMan.GetUserName(agentID);
+ string[] parts = name.Trim().Split(new char[] {' '});
+ if (parts.Length == 2)
+ {
+ first = parts[0];
+ last = parts[1];
+ }
+ else
+ {
+ first = f;
+ last = l;
+ }
return true;
}
return false;
@@ -348,13 +286,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
protected override string GetFriendshipRequesterName(UUID agentID)
{
- // For the time being we assume that HG friendship requests can only happen
- // when avies are on the same region.
- IClientAPI client = LocateClientObject(agentID);
- if (client != null)
- return client.FirstName + " " + client.LastName;
- else
- return base.GetFriendshipRequesterName(agentID);
+ return m_uMan.GetUserName(agentID);
}
protected override string FriendshipMessage(string friendID)
@@ -392,10 +324,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (agentClientCircuit != null)
{
- string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
+ //[XXX] string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
- finfos = FriendsService.GetFriends(agentUUI);
- m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
+ finfos = FriendsService.GetFriends(client.AgentId.ToString());
+ m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, client.AgentId.ToString());
}
// m_log.DebugFormat("[HGFRIENDS MODULE]: Exiting GetFriendsFromService for {0}", client.Name);
@@ -454,16 +386,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendIsLocal = UserManagementModule.IsLocalGridUser(friendID);
}
- // Are they both local users?
- if (agentIsLocal && friendIsLocal)
+ // Is the requester a local user?
+ if (agentIsLocal)
{
// local grid users
- m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
+ m_log.DebugFormat("[HGFRIENDS MODULE]: Friendship requester is local. Storing backwards.");
+
base.StoreBackwards(friendID, agentID);
return;
}
- // no provision for this temporary friendship state
+ // no provision for this temporary friendship state when user is not local
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
}
@@ -501,12 +434,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
+ RecacheFriends(agentClient);
}
if (friendClient != null)
{
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
+ RecacheFriends(friendClient);
}
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
@@ -515,14 +450,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Generate a random 8-character hex number that will sign this friendship
string secret = UUID.Random().ToString().Substring(0, 8);
+ string theFriendUUID = friendUUI + ";" + secret;
+ string agentUUID = agentUUI + ";" + secret;
+
if (agentIsLocal) // agent is local, 'friend' is foreigner
{
// This may happen when the agent returned home, in which case the friend is not there
// We need to look for its information in the friends list itself
+ FriendInfo[] finfos = null;
bool confirming = false;
if (friendUUI == string.Empty)
{
- FriendInfo[] finfos = GetFriends(agentID);
+ finfos = GetFriends(agentID);
foreach (FriendInfo finfo in finfos)
{
if (finfo.TheirFlags == -1)
@@ -530,29 +469,57 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
if (finfo.Friend.StartsWith(friendID.ToString()))
{
friendUUI = finfo.Friend;
+ theFriendUUID = friendUUI;
+ UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty;
+ // If it's confirming the friendship, we already have the full UUI with the secret
+ if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret))
+ {
+ agentUUID = agentUUI + ";" + secret;
+ m_uMan.AddUser(utmp, first, last, url);
+ }
confirming = true;
+ break;
}
}
}
- }
+ if (!confirming)
+ {
+ friendUUI = m_uMan.GetUserUUI(friendID);
+ theFriendUUID = friendUUI + ";" + secret;
+ }
- // If it's confirming the friendship, we already have the full friendUUI with the secret
- string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret;
+ friendFriendService = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
+
+ // m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
+ // agentUUI, friendUUI, agentFriendService, friendFriendService);
+
+ }
+
+ // Delete any previous friendship relations
+ DeletePreviousRelations(agentID, friendID);
// store in the local friends service a reference to the foreign friend
FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1);
// and also the converse
FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1);
- if (!confirming && friendClientCircuit != null)
- {
+ //if (!confirming)
+ //{
// store in the foreign friends service a reference to the local agent
- HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
- friendsConn.NewFriendship(friendID, agentUUI + ";" + secret);
- }
+ HGFriendsServicesConnector friendsConn = null;
+ if (friendClientCircuit != null) // the friend is here, validate session
+ friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
+ else // the friend is not here, he initiated the request in his home world
+ friendsConn = new HGFriendsServicesConnector(friendFriendService);
+
+ friendsConn.NewFriendship(friendID, agentUUID);
+ //}
}
else if (friendIsLocal) // 'friend' is local, agent is foreigner
{
+ // Delete any previous friendship relations
+ DeletePreviousRelations(agentID, friendID);
+
// store in the local friends service a reference to the foreign agent
FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1);
// and also the converse
@@ -582,6 +549,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// my brain hurts now
}
+ private void DeletePreviousRelations(UUID a1, UUID a2)
+ {
+ // Delete any previous friendship relations
+ FriendInfo[] finfos = null;
+ FriendInfo f = null;
+ finfos = GetFriends(a1);
+ if (finfos != null)
+ {
+ f = GetFriend(finfos, a2);
+ if (f != null)
+ {
+ FriendsService.Delete(a1, f.Friend);
+ // and also the converse
+ FriendsService.Delete(f.Friend, a1.ToString());
+ }
+ }
+
+ finfos = GetFriends(a2);
+ if (finfos != null)
+ {
+ f = GetFriend(finfos, a1);
+ if (f != null)
+ {
+ FriendsService.Delete(a2, f.Friend);
+ // and also the converse
+ FriendsService.Delete(f.Friend, a2.ToString());
+ }
+ }
+ }
+
protected override bool DeleteFriendship(UUID agentID, UUID exfriendID)
{
Boolean agentIsLocal = true;
@@ -684,5 +681,74 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendConn.DeleteFriendship(foreignUser, localUser, secret);
}
}
+
+ protected override bool ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
+ {
+ if (base.ForwardFriendshipOffer(agentID, friendID, im))
+ return true;
+
+ // OK, that didn't work, so let's try to find this user somewhere
+ if (!m_uMan.IsLocalGridUser(friendID))
+ {
+ string friendsURL = m_uMan.GetUserServerURL(friendID, "FriendsServerURI");
+ if (friendsURL != string.Empty)
+ {
+ m_log.DebugFormat("[HGFRIENDS MODULE]: Forwading friendship from {0} to {1} @ {2}", agentID, friendID, friendsURL);
+ GridRegion region = new GridRegion();
+ region.ServerURI = friendsURL;
+
+ string name = im.fromAgentName;
+ if (m_uMan.IsLocalGridUser(agentID))
+ {
+ IClientAPI agentClient = LocateClientObject(agentID);
+ AgentCircuitData agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
+ string agentHomeService = string.Empty;
+ try
+ {
+ agentHomeService = agentClientCircuit.ServiceURLs["HomeURI"].ToString();
+ string lastname = "@" + new Uri(agentHomeService).Authority;
+ string firstname = im.fromAgentName.Replace(" ", ".");
+ name = firstname + lastname;
+ }
+ catch (KeyNotFoundException)
+ {
+ m_log.DebugFormat("[HGFRIENDS MODULE]: Key HomeURI not found for user {0}", agentID);
+ return false;
+ }
+ catch (NullReferenceException)
+ {
+ m_log.DebugFormat("[HGFRIENDS MODULE]: Null HomeUri for local user {0}", agentID);
+ return false;
+ }
+ catch (UriFormatException)
+ {
+ m_log.DebugFormat("[HGFRIENDS MODULE]: Malformed HomeUri {0} for local user {1}", agentHomeService, agentID);
+ return false;
+ }
+ }
+
+ m_HGFriendsConnector.FriendshipOffered(region, agentID, friendID, im.message, name);
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public override bool LocalFriendshipOffered(UUID toID, GridInstantMessage im)
+ {
+ if (base.LocalFriendshipOffered(toID, im))
+ {
+ if (im.fromAgentName.Contains("@"))
+ {
+ string[] parts = im.fromAgentName.Split(new char[] { '@' });
+ if (parts.Length == 2)
+ m_uMan.AddUser(new UUID(im.fromAgentID), parts[0], "http://" + parts[1]);
+ }
+ return true;
+ }
+ return false;
+ }
}
}
\ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
index 8077a7a53b..4eecaa2080 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/HGUserManagementModule.cs
@@ -71,52 +71,90 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
protected override void AddAdditionalUsers(UUID avatarID, string query, List users)
{
- string[] words = query.Split(new char[] { ' ' });
-
- for (int i = 0; i < words.Length; i++)
+ if (query.Contains("@")) // First.Last@foo.com, maybe?
{
- if (words[i].Length < 3)
+ string[] words = query.Split(new char[] { '@' });
+ if (words.Length != 2)
{
- if (i != words.Length - 1)
- Array.Copy(words, i + 1, words, i, words.Length - i - 1);
- Array.Resize(ref words, words.Length - 1);
+ m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", query);
+ return;
}
- }
- if (words.Length == 0 || words.Length > 2)
- return;
+ words[0] = words[0].Trim(); // it has at least 1
+ words[1] = words[1].Trim();
- if (words.Length == 2) // First.Last @foo.com, maybe?
- {
- bool found = false;
+ if (words[0] == String.Empty) // query was @foo.com?
+ {
+ foreach (UserData d in m_UserCache.Values)
+ {
+ if (d.LastName.ToLower().StartsWith("@" + words[1].ToLower()))
+ users.Add(d);
+ }
+
+ // We're done
+ return;
+ }
+
+ // words.Length == 2 and words[0] != string.empty
+ // first.last@foo.com ?
foreach (UserData d in m_UserCache.Values)
{
- if (d.LastName.StartsWith("@") &&
- (d.FirstName.ToLower().Equals(words[0].ToLower()) ||
- d.LastName.ToLower().Equals(words[1].ToLower())))
+ if (d.LastName.StartsWith("@") &&
+ d.FirstName.ToLower().Equals(words[0].ToLower()) &&
+ d.LastName.ToLower().Equals("@" + words[1].ToLower()))
{
users.Add(d);
- found = true;
- break;
+ // It's cached. We're done
+ return;
}
}
- if (!found) // This is it! Let's ask the other world
+
+ // This is it! Let's ask the other world
+ if (words[0].Contains("."))
{
- // TODO
- //UserAgentServiceConnector uasConn = new UserAgentServiceConnector(words[0]);
- //uasConn.GetUserInfo(...);
- }
- }
- else
- {
- foreach (UserData d in m_UserCache.Values)
- {
- if (d.LastName.StartsWith("@") &&
- (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
- d.LastName.ToLower().StartsWith(query.ToLower())))
- users.Add(d);
+ string[] names = words[0].Split(new char[] { '.' });
+ if (names.Length >= 2)
+ {
+
+ string uriStr = "http://" + words[1];
+ // Let's check that the last name is a valid address
+ try
+ {
+ new Uri(uriStr);
+ }
+ catch (UriFormatException)
+ {
+ m_log.DebugFormat("[USER MANAGEMENT MODULE]: Malformed address {0}", uriStr);
+ return;
+ }
+
+ UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
+ UUID userID = uasConn.GetUUID(names[0], names[1]);
+ if (!userID.Equals(UUID.Zero))
+ {
+ UserData ud = new UserData();
+ ud.Id = userID;
+ ud.FirstName = words[0];
+ ud.LastName = "@" + words[1];
+ users.Add(ud);
+ AddUser(userID, names[0], names[1], uriStr);
+ m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} found", words[0], words[1]);
+ }
+ else
+ m_log.DebugFormat("[USER MANAGEMENT MODULE]: User {0}@{1} not found", words[0], words[1]);
+ }
}
}
+ //else
+ //{
+ // foreach (UserData d in m_UserCache.Values)
+ // {
+ // if (d.LastName.StartsWith("@") &&
+ // (d.FirstName.ToLower().StartsWith(query.ToLower()) ||
+ // d.LastName.ToLower().StartsWith(query.ToLower())))
+ // users.Add(d);
+ // }
+ //}
}
}
diff --git a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
index 23ef0fc98d..039747812d 100644
--- a/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/UserManagement/UserManagementModule.cs
@@ -183,7 +183,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
List users = new List();
if (accs != null)
{
- m_log.DebugFormat("[USER MANAGEMENT MODULE]: Found {0} users", accs.Count);
foreach (UserAccount acc in accs)
{
UserData ud = new UserData();
@@ -300,7 +299,6 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public string GetUserName(UUID uuid)
{
- //m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
string[] names = GetUserNames(uuid);
if (names.Length == 2)
{
@@ -341,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
if (userdata.HomeURL != null && userdata.HomeURL != string.Empty)
{
- m_log.DebugFormat(
- "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
- serverType, userdata.HomeURL, userID);
+ //m_log.DebugFormat(
+ // "[USER MANAGEMENT MODULE]: Did not find url type {0} so requesting urls from '{1}' for {2}",
+ // serverType, userdata.HomeURL, userID);
UserAgentServiceConnector uConn = new UserAgentServiceConnector(userdata.HomeURL);
userdata.ServerURLs = uConn.GetServerURLs(userID);
@@ -402,11 +400,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
public void AddUser(UUID uuid, string first, string last, string homeURL)
{
+ // m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, first {1}, last {2}, url {3}", uuid, first, last, homeURL);
+
AddUser(uuid, homeURL + ";" + first + " " + last);
}
public void AddUser (UUID id, string creatorData)
{
+ //m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
+
UserData oldUser;
//lock the whole block - prevent concurrent update
lock (m_UserCache)
@@ -432,9 +434,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
return;
}
}
-// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Adding user with id {0}, creatorData {1}", id, creatorData);
- UserAccount account = m_Scenes [0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
+ UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount (m_Scenes [0].RegionInfo.ScopeID, id);
if (account != null)
{
@@ -483,9 +484,9 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
lock (m_UserCache)
m_UserCache[user.Id] = user;
-// m_log.DebugFormat(
-// "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
-// user.Id, user.FirstName, user.LastName, user.HomeURL);
+ //m_log.DebugFormat(
+ // "[USER MANAGEMENT MODULE]: Added user {0} {1} {2} {3}",
+ // user.Id, user.FirstName, user.LastName, user.HomeURL);
}
public bool IsLocalGridUser(UUID uuid)
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
index 89abbb225b..8df1c7b49c 100644
--- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
+++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs
@@ -48,8 +48,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
private static bool m_Enabled = false;
private IConfigSource m_Config;
- bool m_Registered = false;
- GatekeeperServiceInConnector m_HypergridHandler;
+ private bool m_Registered = false;
+ private string m_LocalServiceDll = String.Empty;
+ private GatekeeperServiceInConnector m_HypergridHandler;
+ private UserAgentServerConnector m_UASHandler;
#region IRegionModule interface
@@ -63,6 +65,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
if (m_Enabled)
{
m_log.Info("[HGGRID IN CONNECTOR]: Hypergrid Service In Connector enabled");
+ IConfig fconfig = config.Configs["FriendsService"];
+ if (fconfig != null)
+ {
+ m_LocalServiceDll = fconfig.GetString("LocalServiceModule", m_LocalServiceDll);
+ if (m_LocalServiceDll == String.Empty)
+ m_log.WarnFormat("[HGGRID IN CONNECTOR]: Friends LocalServiceModule config missing");
+ }
}
}
@@ -91,7 +100,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
{
if (!m_Enabled)
return;
-
}
public void RemoveRegion(Scene scene)
@@ -112,14 +120,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
m_log.Info("[HypergridService]: Starting...");
ISimulationService simService = scene.RequestModuleInterface();
+ IFriendsSimConnector friendsConn = scene.RequestModuleInterface();
+ Object[] args = new Object[] { m_Config };
+ IFriendsService friendsService = ServerUtils.LoadPlugin(m_LocalServiceDll, args);
+
m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService);
- IFriendsSimConnector friendsConn = scene.RequestModuleInterface();
- new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
+ m_UASHandler = new UserAgentServerConnector(m_Config, MainServer.Instance, friendsConn);
+
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
- new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
+
+ new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService", friendsConn);
}
scene.RegisterModuleInterface(m_HypergridHandler.GateKeeper);
+ scene.RegisterModuleInterface(m_UASHandler.HomeUsersService);
}
#endregion
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
index 3efb7ddbe3..4e6bfb88a1 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs
@@ -132,7 +132,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
data.MapImageId = info.TerrainImage;
// ugh! V2-3 is very sensitive about the result being
// exactly the same as the requested name
- if (regionInfos.Count == 1)
+ if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+"))
data.Name = mapNameOrig;
else
data.Name = info.RegionName;
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
index 82a72206d3..6c79c607af 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendServerConnector.cs
@@ -36,36 +36,42 @@ namespace OpenSim.Server.Handlers.Hypergrid
{
public class HGFriendsServerConnector : ServiceConnector
{
- private IFriendsService m_FriendsService;
private IUserAgentService m_UserAgentService;
+ private IHGFriendsService m_TheService;
private string m_ConfigName = "HGFriendsService";
+ // Called from Robust
public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
- base(config, server, configName)
+ this(config, server, configName, null)
{
- if (configName != string.Empty)
+
+ }
+
+ // Called from standalone configurations
+ public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName, IFriendsSimConnector localConn)
+ : base(config, server, configName)
+ {
+ if (configName != string.Empty)
m_ConfigName = configName;
+ Object[] args = new Object[] { config, m_ConfigName, localConn };
+
IConfig serverConfig = config.Configs[m_ConfigName];
if (serverConfig == null)
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
string theService = serverConfig.GetString("LocalServiceModule",
String.Empty);
-
if (theService == String.Empty)
throw new Exception("No LocalServiceModule in config file");
-
- Object[] args = new Object[] { config };
- m_FriendsService = ServerUtils.LoadPlugin(theService, args);
+ m_TheService = ServerUtils.LoadPlugin(theService, args);
theService = serverConfig.GetString("UserAgentService", string.Empty);
if (theService == String.Empty)
throw new Exception("No UserAgentService in " + m_ConfigName);
+ m_UserAgentService = ServerUtils.LoadPlugin(theService, new Object[] { config, localConn });
- m_UserAgentService = ServerUtils.LoadPlugin(theService, args);
-
- server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
+ server.AddStreamHandler(new HGFriendsServerPostHandler(m_TheService, m_UserAgentService, localConn));
}
}
}
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
index 661507e7e4..ca566f2857 100644
--- a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -39,6 +39,7 @@ using System.Collections.Generic;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
+using GridRegion = OpenSim.Services.Interfaces.GridRegion;
using OpenSim.Framework;
using OpenSim.Framework.Servers.HttpServer;
using OpenMetaverse;
@@ -49,15 +50,22 @@ namespace OpenSim.Server.Handlers.Hypergrid
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private IFriendsService m_FriendsService;
private IUserAgentService m_UserAgentService;
+ private IFriendsSimConnector m_FriendsLocalSimConnector;
+ private IHGFriendsService m_TheService;
- public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
+ public HGFriendsServerPostHandler(IHGFriendsService service, IUserAgentService uas, IFriendsSimConnector friendsConn) :
base("POST", "/hgfriends")
{
- m_FriendsService = service;
- m_UserAgentService = uservice;
- m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
+ m_TheService = service;
+ m_UserAgentService = uas;
+ m_FriendsLocalSimConnector = friendsConn;
+
+ m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On ({0})",
+ (m_FriendsLocalSimConnector == null ? "robust" : "standalone"));
+
+ if (m_TheService == null)
+ m_log.ErrorFormat("[HGFRIENDS HANDLER]: TheService is null!");
}
public override byte[] Handle(string path, Stream requestData,
@@ -90,6 +98,26 @@ namespace OpenSim.Server.Handlers.Hypergrid
case "deletefriendship":
return DeleteFriendship(request);
+
+ /* Same as inter-sim */
+ case "friendship_offered":
+ return FriendshipOffered(request);
+
+ case "validate_friendship_offered":
+ return ValidateFriendshipOffered(request);
+ /*
+ case "friendship_approved":
+ return FriendshipApproved(request);
+
+ case "friendship_denied":
+ return FriendshipDenied(request);
+
+ case "friendship_terminated":
+ return FriendshipTerminated(request);
+
+ case "grant_rights":
+ return GrantRights(request);
+ */
}
m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
}
@@ -126,39 +154,20 @@ namespace OpenSim.Server.Handlers.Hypergrid
return FailureResult();
}
- FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
- foreach (FriendInfo finfo in friendsInfo)
- {
- if (finfo.Friend.StartsWith(friendID.ToString()))
- return SuccessResult(finfo.TheirFlags.ToString());
- }
+ int perms = m_TheService.GetFriendPerms(principalID, friendID);
+ if (perms < 0)
+ return FailureResult("Friend not found");
- return FailureResult("Friend not found");
+ return SuccessResult(perms.ToString());
}
byte[] NewFriendship(Dictionary request)
{
- if (!VerifyServiceKey(request))
- return FailureResult();
+ bool verified = VerifyServiceKey(request);
- // OK, can proceed
FriendInfo friend = new FriendInfo(request);
- UUID friendID;
- string tmp = string.Empty;
- if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
- return FailureResult();
-
- m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
-
- // If the friendship already exists, return fail
- FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
- foreach (FriendInfo finfo in finfos)
- if (finfo.Friend.StartsWith(friendID.ToString()))
- return FailureResult();
-
- // the user needs to confirm when he gets home
- bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
+ bool success = m_TheService.NewFriendship(friend, verified);
if (success)
return SuccessResult();
@@ -174,25 +183,53 @@ namespace OpenSim.Server.Handlers.Hypergrid
secret = request["SECRET"].ToString();
if (secret == string.Empty)
- return FailureResult();
+ return BoolResult(false);
- FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
- foreach (FriendInfo finfo in finfos)
- {
- // We check the secret here
- if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
- {
- m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
- m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
- m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
+ bool success = m_TheService.DeleteFriendship(friend, secret);
- return SuccessResult();
- }
- }
-
- return FailureResult();
+ return BoolResult(success);
}
+ byte[] FriendshipOffered(Dictionary request)
+ {
+ UUID fromID = UUID.Zero;
+ UUID toID = UUID.Zero;
+ string message = string.Empty;
+ string name = string.Empty;
+
+ m_log.DebugFormat("[HGFRIENDS HANDLER]: Friendship offered");
+ if (!request.ContainsKey("FromID") || !request.ContainsKey("ToID"))
+ return BoolResult(false);
+
+ if (!UUID.TryParse(request["ToID"].ToString(), out toID))
+ return BoolResult(false);
+
+ message = request["Message"].ToString();
+
+ if (!UUID.TryParse(request["FromID"].ToString(), out fromID))
+ return BoolResult(false);
+
+ if (request.ContainsKey("FromName"))
+ name = request["FromName"].ToString();
+
+ bool success = m_TheService.FriendshipOffered(fromID, name, toID, message);
+
+ return BoolResult(success);
+ }
+
+ byte[] ValidateFriendshipOffered(Dictionary request)
+ {
+ FriendInfo friend = new FriendInfo(request);
+ UUID friendID = UUID.Zero;
+ if (!UUID.TryParse(friend.Friend, out friendID))
+ return BoolResult(false);
+
+ bool success = m_TheService.ValidateFriendshipOffered(friend.PrincipalID, friendID);
+
+ return BoolResult(success);
+ }
+
+
#endregion
#region Misc
@@ -205,10 +242,15 @@ namespace OpenSim.Server.Handlers.Hypergrid
return false;
}
+ if (request["KEY"] == null || request["SESSIONID"] == null)
+ return false;
+
string serviceKey = request["KEY"].ToString();
string sessionStr = request["SESSIONID"].ToString();
+
UUID sessionID;
- UUID.TryParse(sessionStr, out sessionID);
+ if (!UUID.TryParse(sessionStr, out sessionID) || serviceKey == string.Empty)
+ return false;
if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
{
@@ -256,7 +298,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
doc.AppendChild(rootElement);
- XmlElement result = doc.CreateElement("", "Result", "");
+ XmlElement result = doc.CreateElement("", "RESULT", "");
result.AppendChild(doc.CreateTextNode("Success"));
rootElement.AppendChild(result);
@@ -289,7 +331,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
doc.AppendChild(rootElement);
- XmlElement result = doc.CreateElement("", "Result", "");
+ XmlElement result = doc.CreateElement("", "RESULT", "");
result.AppendChild(doc.CreateTextNode("Failure"));
rootElement.AppendChild(result);
@@ -302,6 +344,28 @@ namespace OpenSim.Server.Handlers.Hypergrid
return DocToBytes(doc);
}
+ private byte[] BoolResult(bool value)
+ {
+ XmlDocument doc = new XmlDocument();
+
+ XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
+ "", "");
+
+ doc.AppendChild(xmlnode);
+
+ XmlElement rootElement = doc.CreateElement("", "ServerResponse",
+ "");
+
+ doc.AppendChild(rootElement);
+
+ XmlElement result = doc.CreateElement("", "RESULT", "");
+ result.AppendChild(doc.CreateTextNode(value.ToString()));
+
+ rootElement.AppendChild(result);
+
+ return DocToBytes(doc);
+ }
+
private byte[] DocToBytes(XmlDocument doc)
{
MemoryStream ms = new MemoryStream();
@@ -313,6 +377,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
return ms.ToArray();
}
+
#endregion
}
}
diff --git a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
index 1bd37062db..9a0e27e2f1 100644
--- a/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
+++ b/OpenSim/Server/Handlers/Hypergrid/UserAgentServerConnector.cs
@@ -52,6 +52,11 @@ namespace OpenSim.Server.Handlers.Hypergrid
// MethodBase.GetCurrentMethod().DeclaringType);
private IUserAgentService m_HomeUsersService;
+ public IUserAgentService HomeUsersService
+ {
+ get { return m_HomeUsersService; }
+ }
+
private string[] m_AuthorizedCallers;
private bool m_VerifyCallers = false;
@@ -96,6 +101,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
server.AddXmlRPCHandler("locate_user", LocateUser, false);
server.AddXmlRPCHandler("get_uui", GetUUI, false);
+ server.AddXmlRPCHandler("get_uuid", GetUUID, false);
server.AddHTTPHandler("/homeagent/", new HomeAgentHandler(m_HomeUsersService, loginServerIP, proxy).Handler);
}
@@ -410,8 +416,7 @@ namespace OpenSim.Server.Handlers.Hypergrid
}
///
- /// Locates the user.
- /// This is a sensitive operation, only authorized IP addresses can perform it.
+ /// Returns the UUI of a user given a UUID.
///
///
///
@@ -445,5 +450,33 @@ namespace OpenSim.Server.Handlers.Hypergrid
}
+ ///
+ /// Gets the UUID of a user given First name, Last name.
+ ///
+ ///
+ ///
+ ///
+ public XmlRpcResponse GetUUID(XmlRpcRequest request, IPEndPoint remoteClient)
+ {
+ Hashtable hash = new Hashtable();
+
+ Hashtable requestData = (Hashtable)request.Params[0];
+ //string host = (string)requestData["host"];
+ //string portstr = (string)requestData["port"];
+ if (requestData.ContainsKey("first") && requestData.ContainsKey("last"))
+ {
+ UUID userID = UUID.Zero;
+ string first = (string)requestData["first"];
+
+ string last = (string)requestData["last"];
+ UUID uuid = m_HomeUsersService.GetUUID(first, last);
+ hash["UUID"] = uuid.ToString();
+ }
+
+ XmlRpcResponse response = new XmlRpcResponse();
+ response.Value = hash;
+ return response;
+
+ }
}
}
diff --git a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
index eea9853463..3fd0c53633 100644
--- a/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
+++ b/OpenSim/Services/Connectors/Friends/FriendsSimConnector.cs
@@ -43,7 +43,17 @@ namespace OpenSim.Services.Connectors.Friends
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+ protected virtual string ServicePath()
+ {
+ return "friends";
+ }
+
public bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message)
+ {
+ return FriendshipOffered(region, userID, friendID, message, String.Empty);
+ }
+
+ public virtual bool FriendshipOffered(GridRegion region, UUID userID, UUID friendID, string message, string userName)
{
Dictionary sendData = new Dictionary();
//sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString();
@@ -53,9 +63,10 @@ namespace OpenSim.Services.Connectors.Friends
sendData["FromID"] = userID.ToString();
sendData["ToID"] = friendID.ToString();
sendData["Message"] = message;
+ if (userName != String.Empty)
+ sendData["FromName"] = userName;
return Call(region, sendData);
-
}
public bool FriendshipApproved(GridRegion region, UUID userID, string userName, UUID friendID)
@@ -138,8 +149,11 @@ namespace OpenSim.Services.Connectors.Friends
if (region == null)
return false;
- m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: region: {0}", region.ExternalHostName + ":" + region.HttpPort);
- string uri = "http://" + region.ExternalHostName + ":" + region.HttpPort + "/friends";
+ string path = ServicePath();
+ if (!region.ServerURI.EndsWith("/"))
+ path = "/" + path;
+ string uri = region.ServerURI + path;
+ m_log.DebugFormat("[FRIENDS SIM CONNECTOR]: calling {0}", uri);
try
{
diff --git a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
index af4b0daf9b..e3f326037c 100644
--- a/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/HGFriendsServiceConnector.cs
@@ -40,7 +40,7 @@ using OpenMetaverse;
namespace OpenSim.Services.Connectors.Hypergrid
{
- public class HGFriendsServicesConnector
+ public class HGFriendsServicesConnector : FriendsSimConnector
{
private static readonly ILog m_log =
LogManager.GetLogger(
@@ -66,6 +66,11 @@ namespace OpenSim.Services.Connectors.Hypergrid
m_SessionID = sessionID;
}
+ protected override string ServicePath()
+ {
+ return "hgfriends";
+ }
+
#region IFriendsService
public uint GetFriendPerms(UUID PrincipalID, UUID friendID)
@@ -187,23 +192,69 @@ namespace OpenSim.Services.Connectors.Hypergrid
{
Dictionary replyData = ServerUtils.ParseXmlResponse(reply);
- if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
+ if (replyData.ContainsKey("RESULT"))
{
- bool success = false;
- Boolean.TryParse(replyData["Result"].ToString(), out success);
- return success;
+ if (replyData["RESULT"].ToString().ToLower() == "true")
+ return true;
+ else
+ return false;
}
else
- m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Delete {0} {1} received null response",
- PrincipalID, Friend);
+ m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field");
+
}
else
- m_log.DebugFormat("[HGFRIENDS CONNECTOR]: DeleteFriend received null reply");
+ m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply");
return false;
}
+ public bool ValidateFriendshipOffered(UUID fromID, UUID toID)
+ {
+ FriendInfo finfo = new FriendInfo();
+ finfo.PrincipalID = fromID;
+ finfo.Friend = toID.ToString();
+
+ Dictionary sendData = finfo.ToKeyValuePairs();
+
+ sendData["METHOD"] = "validate_friendship_offered";
+
+ string reply = string.Empty;
+ string uri = m_ServerURI + "/hgfriends";
+ try
+ {
+ reply = SynchronousRestFormsRequester.MakeRequest("POST",
+ uri,
+ ServerUtils.BuildQueryString(sendData));
+ }
+ catch (Exception e)
+ {
+ m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server at {0}: {1}", uri, e.Message);
+ return false;
+ }
+
+ if (reply != string.Empty)
+ {
+ Dictionary replyData = ServerUtils.ParseXmlResponse(reply);
+
+ if (replyData.ContainsKey("RESULT"))
+ {
+ if (replyData["RESULT"].ToString().ToLower() == "true")
+ return true;
+ else
+ return false;
+ }
+ else
+ m_log.DebugFormat("[HGFRIENDS CONNECTOR]: reply data does not contain result field");
+
+ }
+ else
+ m_log.DebugFormat("[HGFRIENDS CONNECTOR]: received empty reply");
+
+ return false;
+
+ }
#endregion
}
}
\ No newline at end of file
diff --git a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
index d617aee04b..c07c6a6aa7 100644
--- a/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
+++ b/OpenSim/Services/Connectors/Hypergrid/UserAgentServiceConnector.cs
@@ -787,13 +787,72 @@ namespace OpenSim.Services.Connectors.Hypergrid
}
catch
{
- m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on LocateUser response.");
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on GetUUI response.");
// reason = "Exception: " + e.Message;
}
return uui;
}
+ public UUID GetUUID(String first, String last)
+ {
+ Hashtable hash = new Hashtable();
+ hash["first"] = first;
+ hash["last"] = last;
+
+ IList paramList = new ArrayList();
+ paramList.Add(hash);
+
+ XmlRpcRequest request = new XmlRpcRequest("get_uuid", paramList);
+ // string reason = string.Empty;
+
+ // Send and get reply
+ UUID uuid = UUID.Zero;
+ XmlRpcResponse response = null;
+ try
+ {
+ response = request.Send(m_ServerURL, 10000);
+ }
+ catch
+ {
+ m_log.DebugFormat("[USER AGENT CONNECTOR]: Unable to contact remote server {0} for GetUUID", m_ServerURL);
+ // reason = "Exception: " + e.Message;
+ return uuid;
+ }
+
+ if (response.IsFault)
+ {
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: remote call to {0} for GetUUID returned an error: {1}", m_ServerURL, response.FaultString);
+ // reason = "XMLRPC Fault";
+ return uuid;
+ }
+
+ hash = (Hashtable)response.Value;
+ //foreach (Object o in hash)
+ // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value);
+ try
+ {
+ if (hash == null)
+ {
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: GetUUDI Got null response from {0}! THIS IS BAAAAD", m_ServerURL);
+ // reason = "Internal error 1";
+ return uuid;
+ }
+
+ // Here's the actual response
+ if (hash.ContainsKey("UUID"))
+ UUID.TryParse(hash["UUID"].ToString(), out uuid);
+
+ }
+ catch
+ {
+ m_log.ErrorFormat("[USER AGENT CONNECTOR]: Got exception on UUID response.");
+ // reason = "Exception: " + e.Message;
+ }
+
+ return uuid;
+ }
+
private bool GetBoolResponse(XmlRpcRequest request, out string reason)
{
//m_log.Debug("[USER AGENT CONNECTOR]: GetBoolResponse from/to " + m_ServerURL);
diff --git a/OpenSim/Services/HypergridService/HGFriendsService.cs b/OpenSim/Services/HypergridService/HGFriendsService.cs
new file mode 100644
index 0000000000..19ee3e27f9
--- /dev/null
+++ b/OpenSim/Services/HypergridService/HGFriendsService.cs
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Reflection;
+
+using OpenSim.Framework;
+using OpenSim.Services.Connectors.Friends;
+using OpenSim.Services.Connectors.Hypergrid;
+using OpenSim.Services.Interfaces;
+using GridRegion = OpenSim.Services.Interfaces.GridRegion;
+using OpenSim.Server.Base;
+using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
+
+using OpenMetaverse;
+using log4net;
+using Nini.Config;
+
+namespace OpenSim.Services.HypergridService
+{
+ ///
+ /// W2W social networking
+ ///
+ public class HGFriendsService : IHGFriendsService
+ {
+ private static readonly ILog m_log =
+ LogManager.GetLogger(
+ MethodBase.GetCurrentMethod().DeclaringType);
+
+ static bool m_Initialized = false;
+
+ protected static IGridUserService m_GridUserService;
+ protected static IGridService m_GridService;
+ protected static IGatekeeperService m_GatekeeperService;
+ protected static IFriendsService m_FriendsService;
+ protected static IPresenceService m_PresenceService;
+ protected static IUserAccountService m_UserAccountService;
+ protected static IFriendsSimConnector m_FriendsLocalSimConnector; // standalone, points to HGFriendsModule
+ protected static FriendsSimConnector m_FriendsSimConnector; // grid
+
+ private static string m_ConfigName = "HGFriendsService";
+
+ public HGFriendsService(IConfigSource config, String configName, IFriendsSimConnector localSimConn)
+ {
+ if (m_FriendsLocalSimConnector == null)
+ m_FriendsLocalSimConnector = localSimConn;
+
+ if (!m_Initialized)
+ {
+ m_Initialized = true;
+
+ if (configName != String.Empty)
+ m_ConfigName = configName;
+
+ Object[] args = new Object[] { config };
+
+ IConfig serverConfig = config.Configs[m_ConfigName];
+ if (serverConfig == null)
+ throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
+
+ string theService = serverConfig.GetString("FriendsService", string.Empty);
+ if (theService == String.Empty)
+ throw new Exception("No FriendsService in config file " + m_ConfigName);
+ m_FriendsService = ServerUtils.LoadPlugin(theService, args);
+
+ theService = serverConfig.GetString("UserAccountService", string.Empty);
+ if (theService == String.Empty)
+ throw new Exception("No UserAccountService in " + m_ConfigName);
+ m_UserAccountService = ServerUtils.LoadPlugin(theService, args);
+
+ theService = serverConfig.GetString("GridService", string.Empty);
+ if (theService == String.Empty)
+ throw new Exception("No GridService in " + m_ConfigName);
+ m_GridService = ServerUtils.LoadPlugin(theService, args);
+
+ theService = serverConfig.GetString("PresenceService", string.Empty);
+ if (theService == String.Empty)
+ throw new Exception("No PresenceService in " + m_ConfigName);
+ m_PresenceService = ServerUtils.LoadPlugin(theService, args);
+
+ m_FriendsSimConnector = new FriendsSimConnector();
+
+ m_log.DebugFormat("[HGFRIENDS SERVICE]: Starting...");
+
+ }
+ }
+
+ #region IHGFriendsService
+
+ public int GetFriendPerms(UUID userID, UUID friendID)
+ {
+ FriendInfo[] friendsInfo = m_FriendsService.GetFriends(userID);
+ foreach (FriendInfo finfo in friendsInfo)
+ {
+ if (finfo.Friend.StartsWith(friendID.ToString()))
+ return finfo.TheirFlags;
+ }
+ return -1;
+ }
+
+ public bool NewFriendship(FriendInfo friend, bool verified)
+ {
+ UUID friendID;
+ string tmp = string.Empty, url = String.Empty, first = String.Empty, last = String.Empty;
+ if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out url, out first, out last, out tmp))
+ return false;
+
+ m_log.DebugFormat("[HGFRIENDS SERVICE]: New friendship {0} {1} ({2})", friend.PrincipalID, friend.Friend, verified);
+
+ // Does the friendship already exist?
+ FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
+ foreach (FriendInfo finfo in finfos)
+ {
+ if (finfo.Friend.StartsWith(friendID.ToString()))
+ return false;
+ }
+ // Verified user session. But the user needs to confirm friendship when he gets home
+ if (verified)
+ return m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
+
+ // Does the reverted friendship exist? meaning that this user initiated the request
+ finfos = m_FriendsService.GetFriends(friendID);
+ bool userInitiatedOffer = false;
+ foreach (FriendInfo finfo in finfos)
+ {
+ if (friend.Friend.StartsWith(finfo.PrincipalID.ToString()) && finfo.Friend.StartsWith(friend.PrincipalID.ToString()) && finfo.TheirFlags == -1)
+ {
+ userInitiatedOffer = true;
+ // Let's delete the existing friendship relations that was stored
+ m_FriendsService.Delete(friendID, finfo.Friend);
+ break;
+ }
+ }
+
+ if (userInitiatedOffer)
+ {
+ m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 1);
+ m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1);
+ // notify the user
+ ForwardToSim("ApproveFriendshipRequest", friendID, Util.UniversalName(first, last, url), "", friend.PrincipalID, "");
+ return true;
+ }
+ return false;
+ }
+
+ public bool DeleteFriendship(FriendInfo friend, string secret)
+ {
+ FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
+ foreach (FriendInfo finfo in finfos)
+ {
+ // We check the secret here. Or if the friendship request was initiated here, and was declined
+ if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
+ {
+ m_log.DebugFormat("[HGFRIENDS SERVICE]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
+ m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
+ m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public bool FriendshipOffered(UUID fromID, string fromName, UUID toID, string message)
+ {
+ UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, toID);
+ if (account == null)
+ return false;
+
+ // OK, we have that user here.
+ // So let's send back the call, but start a thread to continue
+ // with the verification and the actual action.
+
+ Util.FireAndForget(delegate { ProcessFriendshipOffered(fromID, fromName, toID, message); });
+
+ return true;
+ }
+
+ public bool ValidateFriendshipOffered(UUID fromID, UUID toID)
+ {
+ FriendInfo[] finfos = m_FriendsService.GetFriends(toID.ToString());
+ foreach (FriendInfo fi in finfos)
+ {
+ if (fi.Friend.StartsWith(fromID.ToString()) && fi.TheirFlags == -1)
+ return true;
+ }
+ return false;
+ }
+
+ #endregion IHGFriendsService
+
+ #region Aux
+
+ private void ProcessFriendshipOffered(UUID fromID, String fromName, UUID toID, String message)
+ {
+ // Great, it's a genuine request. Let's proceed.
+ // But now we need to confirm that the requester is who he says he is
+ // before we act on the friendship request.
+
+ if (!fromName.Contains("@"))
+ return;
+
+ string[] parts = fromName.Split(new char[] {'@'});
+ if (parts.Length != 2)
+ return;
+
+ string uriStr = "http://" + parts[1];
+ try
+ {
+ new Uri(uriStr);
+ }
+ catch (UriFormatException)
+ {
+ return;
+ }
+
+ UserAgentServiceConnector uasConn = new UserAgentServiceConnector(uriStr);
+ Dictionary servers = uasConn.GetServerURLs(fromID);
+ if (!servers.ContainsKey("FriendsServerURI"))
+ return;
+
+ HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(servers["FriendsServerURI"].ToString());
+ if (!friendsConn.ValidateFriendshipOffered(fromID, toID))
+ {
+ m_log.WarnFormat("[HGFRIENDS SERVICE]: Friendship request from {0} to {1} is invalid. Impersonations?", fromID, toID);
+ return;
+ }
+
+ string fromUUI = Util.UniversalIdentifier(fromID, parts[0], "@" + parts[1], uriStr);
+ // OK, we're good!
+ ForwardToSim("FriendshipOffered", fromID, fromName, fromUUI, toID, message);
+ }
+
+ private bool ForwardToSim(string op, UUID fromID, string name, String fromUUI, UUID toID, string message)
+ {
+ PresenceInfo session = null;
+ GridRegion region = null;
+ PresenceInfo[] sessions = m_PresenceService.GetAgents(new string[] { toID.ToString() });
+ if (sessions != null && sessions.Length > 0)
+ session = sessions[0];
+ if (session != null)
+ region = m_GridService.GetRegionByUUID(UUID.Zero, session.RegionID);
+
+ switch (op)
+ {
+ case "FriendshipOffered":
+ // Let's store backwards
+ string secret = UUID.Random().ToString().Substring(0, 8);
+ m_FriendsService.StoreFriend(toID.ToString(), fromUUI + ";" + secret, 0);
+ if (m_FriendsLocalSimConnector != null) // standalone
+ {
+ GridInstantMessage im = new GridInstantMessage(null, fromID, name, toID,
+ (byte)InstantMessageDialog.FriendshipOffered, message, false, Vector3.Zero);
+ // !! HACK
+ im.imSessionID = im.fromAgentID;
+ return m_FriendsLocalSimConnector.LocalFriendshipOffered(toID, im);
+ }
+ else if (region != null) // grid
+ return m_FriendsSimConnector.FriendshipOffered(region, fromID, toID, message, name);
+ break;
+ case "ApproveFriendshipRequest":
+ if (m_FriendsLocalSimConnector != null) // standalone
+ return m_FriendsLocalSimConnector.LocalFriendshipApproved(fromID, name, toID);
+ else if (region != null) //grid
+ return m_FriendsSimConnector.FriendshipApproved(region, fromID, name, toID);
+ break;
+ }
+
+ return false;
+ }
+
+ #endregion Aux
+ }
+}
diff --git a/OpenSim/Services/HypergridService/UserAgentService.cs b/OpenSim/Services/HypergridService/UserAgentService.cs
index 1a839f3338..65963d9820 100644
--- a/OpenSim/Services/HypergridService/UserAgentService.cs
+++ b/OpenSim/Services/HypergridService/UserAgentService.cs
@@ -564,6 +564,16 @@ namespace OpenSim.Services.HypergridService
return string.Empty;
}
+
+ public UUID GetUUID(String first, String last)
+ {
+ // Let's see if it's a local user
+ UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, first, last);
+ if (account != null)
+ return account.PrincipalID;
+ else
+ return UUID.Zero;
+ }
}
class TravelingAgentInfo
diff --git a/OpenSim/Services/Interfaces/IHypergridServices.cs b/OpenSim/Services/Interfaces/IHypergridServices.cs
index 5b293acbee..f48b8a9a76 100644
--- a/OpenSim/Services/Interfaces/IHypergridServices.cs
+++ b/OpenSim/Services/Interfaces/IHypergridServices.cs
@@ -62,6 +62,8 @@ namespace OpenSim.Services.Interfaces
// on behalf of the userID
string GetUUI(UUID userID, UUID targetUserID);
+ UUID GetUUID(String first, String last);
+
// Returns the local friends online
List StatusNotification(List friends, UUID userID, bool online);
//List GetOnlineFriends(UUID userID, List friends);
@@ -79,6 +81,17 @@ namespace OpenSim.Services.Interfaces
public interface IFriendsSimConnector
{
bool StatusNotify(UUID userID, UUID friendID, bool online);
+ bool LocalFriendshipOffered(UUID toID, GridInstantMessage im);
+ bool LocalFriendshipApproved(UUID userID, string userName, UUID friendID);
+ }
+
+ public interface IHGFriendsService
+ {
+ int GetFriendPerms(UUID userID, UUID friendID);
+ bool NewFriendship(FriendInfo finfo, bool verified);
+ bool DeleteFriendship(FriendInfo finfo, string secret);
+ bool FriendshipOffered(UUID from, string fromName, UUID to, string message);
+ bool ValidateFriendshipOffered(UUID fromID, UUID toID);
}
public interface IInstantMessageSimConnector
diff --git a/bin/config-include/StandaloneHypergrid.ini b/bin/config-include/StandaloneHypergrid.ini
index ee51067fed..75c478803b 100644
--- a/bin/config-include/StandaloneHypergrid.ini
+++ b/bin/config-include/StandaloneHypergrid.ini
@@ -159,8 +159,12 @@
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
[HGFriendsService]
- LocalServiceModule = "OpenSim.Services.FriendsService.dll:FriendsService"
+ LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService"
UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
+ FriendsService = "OpenSim.Services.FriendsService.dll:FriendsService"
+ UserAccountService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
+ GridService = "OpenSim.Services.GridService.dll:GridService"
+ PresenceService = "OpenSim.Services.PresenceService.dll:PresenceService"
[HGInstantMessageService]
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInstantMessageService"