HG Friends working to some extent: friendships offered and accepted correctly handled. Friends list showing correct foreign names. TODO: GrantRights.
parent
6dcc87b1ad
commit
d21e9c755f
|
@ -34,7 +34,7 @@ namespace OpenSim.Data
|
||||||
{
|
{
|
||||||
public class FriendsData
|
public class FriendsData
|
||||||
{
|
{
|
||||||
public UUID PrincipalID;
|
public string PrincipalID;
|
||||||
public string Friend;
|
public string Friend;
|
||||||
public Dictionary<string, string> Data;
|
public Dictionary<string, string> Data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,5 +21,11 @@ INSERT INTO `Friends` SELECT `ownerID`, `friendID`, `friendPerms`, 0 FROM `userf
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
|
:VERSION 3 # -------------------------
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE `Friends` MODIFY COLUMN PrincipalID varchar(255) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000';
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace OpenSim.Data.Null
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
|
||||||
{
|
{
|
||||||
return fdata.PrincipalID == userID;
|
return fdata.PrincipalID == userID.ToString();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (lst != null)
|
if (lst != null)
|
||||||
|
@ -74,7 +74,7 @@ namespace OpenSim.Data.Null
|
||||||
|
|
||||||
public bool Delete(UUID userID, string friendID)
|
public bool Delete(UUID userID, string friendID)
|
||||||
{
|
{
|
||||||
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID; });
|
List<FriendsData> lst = m_Data.FindAll(delegate(FriendsData fdata) { return fdata.PrincipalID == userID.ToString(); });
|
||||||
if (lst != null)
|
if (lst != null)
|
||||||
{
|
{
|
||||||
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
FriendsData friend = lst.Find(delegate(FriendsData fdata) { return fdata.Friend == friendID; });
|
||||||
|
|
|
@ -345,6 +345,7 @@ namespace OpenSim.Framework
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -215,6 +215,12 @@ namespace OpenSim.Framework
|
||||||
set { m_metadata.Temporary = value; }
|
set { m_metadata.Temporary = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string CreatorID
|
||||||
|
{
|
||||||
|
get { return m_metadata.CreatorID; }
|
||||||
|
set { m_metadata.CreatorID = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public AssetFlags Flags
|
public AssetFlags Flags
|
||||||
{
|
{
|
||||||
get { return m_metadata.Flags; }
|
get { return m_metadata.Flags; }
|
||||||
|
|
|
@ -1694,5 +1694,66 @@ namespace OpenSim.Framework
|
||||||
return (T)Enum.Parse(typeof(T), value); ;
|
return (T)Enum.Parse(typeof(T), value); ;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Universal User Identifiers
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">uuid[;endpoint[;name]]</param>
|
||||||
|
/// <param name="uuid"></param>
|
||||||
|
/// <param name="url"></param>
|
||||||
|
/// <param name="firstname"></param>
|
||||||
|
/// <param name="lastname"></param>
|
||||||
|
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname)
|
||||||
|
{
|
||||||
|
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User";
|
||||||
|
|
||||||
|
string[] parts = value.Split(';');
|
||||||
|
if (parts.Length >= 1)
|
||||||
|
if (!UUID.TryParse(parts[0], out uuid))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (parts.Length >= 2)
|
||||||
|
url = parts[1];
|
||||||
|
|
||||||
|
if (parts.Length >= 3)
|
||||||
|
{
|
||||||
|
string[] name = parts[2].Split();
|
||||||
|
if (name.Length == 2)
|
||||||
|
{
|
||||||
|
firstname = name[0];
|
||||||
|
lastname = name[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="acircuit"></param>
|
||||||
|
/// <returns>uuid[;endpoint[;name]]</returns>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return acircuit.AgentID.ToString();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
{
|
{
|
||||||
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
public class FriendsModule : ISharedRegionModule, IFriendsModule
|
||||||
{
|
{
|
||||||
|
protected bool m_Enabled = false;
|
||||||
|
|
||||||
protected class UserFriendData
|
protected class UserFriendData
|
||||||
{
|
{
|
||||||
public UUID PrincipalID;
|
public UUID PrincipalID;
|
||||||
|
@ -130,7 +132,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
public void Initialise(IConfigSource config)
|
public void Initialise(IConfigSource config)
|
||||||
|
{
|
||||||
|
IConfig moduleConfig = config.Configs["Modules"];
|
||||||
|
if (moduleConfig != null)
|
||||||
|
{
|
||||||
|
string name = moduleConfig.GetString("FriendsModule", "FriendsModule");
|
||||||
|
m_log.DebugFormat("[XXX] {0} compared to {1}", name, Name);
|
||||||
|
if (name == Name)
|
||||||
|
{
|
||||||
|
InitModule(config);
|
||||||
|
|
||||||
|
m_Enabled = true;
|
||||||
|
m_log.InfoFormat("[FRIENDS MODULE]: {0} enabled.", Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void InitModule(IConfigSource config)
|
||||||
{
|
{
|
||||||
IConfig friendsConfig = config.Configs["Friends"];
|
IConfig friendsConfig = config.Configs["Friends"];
|
||||||
if (friendsConfig != null)
|
if (friendsConfig != null)
|
||||||
|
@ -153,7 +173,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
|
m_log.Error("[FRIENDS]: No Connector defined in section Friends, or failed to load, cannot continue");
|
||||||
throw new Exception("Connector load error");
|
throw new Exception("Connector load error");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
|
@ -166,6 +185,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
public void AddRegion(Scene scene)
|
public void AddRegion(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
m_Scenes.Add(scene);
|
m_Scenes.Add(scene);
|
||||||
scene.RegisterModuleInterface<IFriendsModule>(this);
|
scene.RegisterModuleInterface<IFriendsModule>(this);
|
||||||
|
|
||||||
|
@ -181,10 +203,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
public void RemoveRegion(Scene scene)
|
public void RemoveRegion(Scene scene)
|
||||||
{
|
{
|
||||||
|
if (!m_Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
m_Scenes.Remove(scene);
|
m_Scenes.Remove(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Name
|
public virtual string Name
|
||||||
{
|
{
|
||||||
get { return "FriendsModule"; }
|
get { return "FriendsModule"; }
|
||||||
}
|
}
|
||||||
|
@ -194,6 +219,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
get { return null; }
|
get { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
public uint GetFriendPerms(UUID principalID, UUID friendID)
|
||||||
{
|
{
|
||||||
FriendInfo[] friends = GetFriends(principalID);
|
FriendInfo[] friends = GetFriends(principalID);
|
||||||
|
@ -214,31 +241,34 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
client.OnTerminateFriendship += OnTerminateFriendship;
|
||||||
client.OnGrantUserRights += OnGrantUserRights;
|
client.OnGrantUserRights += OnGrantUserRights;
|
||||||
|
|
||||||
// Asynchronously fetch the friends list or increment the refcount for the existing
|
Util.FireAndForget(delegate { FetchFriendslist(client.AgentId); });
|
||||||
// friends list
|
}
|
||||||
Util.FireAndForget(
|
|
||||||
delegate(object o)
|
/// Fetch the friends list or increment the refcount for the existing
|
||||||
|
/// friends list
|
||||||
|
/// Returns true if the list was fetched, false if it wasn't
|
||||||
|
protected virtual bool FetchFriendslist(UUID agentID)
|
||||||
{
|
{
|
||||||
lock (m_Friends)
|
lock (m_Friends)
|
||||||
{
|
{
|
||||||
UserFriendData friendsData;
|
UserFriendData friendsData;
|
||||||
if (m_Friends.TryGetValue(client.AgentId, out friendsData))
|
if (m_Friends.TryGetValue(agentID, out friendsData))
|
||||||
{
|
{
|
||||||
friendsData.Refcount++;
|
friendsData.Refcount++;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
friendsData = new UserFriendData();
|
friendsData = new UserFriendData();
|
||||||
friendsData.PrincipalID = client.AgentId;
|
friendsData.PrincipalID = agentID;
|
||||||
friendsData.Friends = FriendsService.GetFriends(client.AgentId);
|
friendsData.Friends = FriendsService.GetFriends(agentID);
|
||||||
friendsData.Refcount = 1;
|
friendsData.Refcount = 1;
|
||||||
|
|
||||||
m_Friends[client.AgentId] = friendsData;
|
m_Friends[agentID] = friendsData;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnClientClosed(UUID agentID, Scene scene)
|
private void OnClientClosed(UUID agentID, Scene scene)
|
||||||
{
|
{
|
||||||
|
@ -313,10 +343,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
foreach (string fid in outstanding)
|
foreach (string fid in outstanding)
|
||||||
{
|
{
|
||||||
UUID fromAgentID;
|
UUID fromAgentID;
|
||||||
if (!UUID.TryParse(fid, out fromAgentID))
|
string firstname = "Unknown", lastname = "User";
|
||||||
|
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
|
|
||||||
|
|
||||||
PresenceInfo presence = null;
|
PresenceInfo presence = null;
|
||||||
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
||||||
|
@ -326,15 +358,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
im.offline = 0;
|
im.offline = 0;
|
||||||
|
|
||||||
im.fromAgentID = fromAgentID.Guid;
|
im.fromAgentID = fromAgentID.Guid;
|
||||||
im.fromAgentName = account.FirstName + " " + account.LastName;
|
im.fromAgentName = firstname + " " + lastname;
|
||||||
im.offline = (byte)((presence == null) ? 1 : 0);
|
im.offline = (byte)((presence == null) ? 1 : 0);
|
||||||
im.imSessionID = im.fromAgentID;
|
im.imSessionID = im.fromAgentID;
|
||||||
|
im.message = FriendshipMessage(fid);
|
||||||
|
|
||||||
// Finally
|
// Finally
|
||||||
LocalFriendshipOffered(agentID, im);
|
LocalFriendshipOffered(agentID, im);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual string FriendshipMessage(string friendID)
|
||||||
|
{
|
||||||
|
return "Will you be my friend?";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||||
|
{
|
||||||
|
first = "Unknown"; last = "User";
|
||||||
|
if (!UUID.TryParse(fid, out agentID))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(scopeID, agentID);
|
||||||
|
if (account != null)
|
||||||
|
{
|
||||||
|
first = account.FirstName;
|
||||||
|
last = account.LastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
List<UUID> GetOnlineFriends(UUID userID)
|
List<UUID> GetOnlineFriends(UUID userID)
|
||||||
{
|
{
|
||||||
List<string> friendList = new List<string>();
|
List<string> friendList = new List<string>();
|
||||||
|
@ -475,23 +529,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
// This user wants to be friends with the other user.
|
// This user wants to be friends with the other user.
|
||||||
// Let's add the relation backwards, in case the other is not online
|
// Let's add the relation backwards, in case the other is not online
|
||||||
FriendsService.StoreFriend(friendID, principalID.ToString(), 0);
|
StoreBackwards(friendID, principalID);
|
||||||
|
|
||||||
// Now let's ask the other user to be friends with this user
|
// Now let's ask the other user to be friends with this user
|
||||||
ForwardFriendshipOffer(principalID, friendID, im);
|
ForwardFriendshipOffer(principalID, friendID, im);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void StoreBackwards(UUID friendID, UUID agentID)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
|
private void ForwardFriendshipOffer(UUID agentID, UUID friendID, GridInstantMessage im)
|
||||||
{
|
{
|
||||||
// !!!!!!!! This is a hack so that we don't have to keep state (transactionID/imSessionID)
|
// !!!!!!!! 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
|
// We stick this agent's ID as imSession, so that it's directly available on the receiving end
|
||||||
im.imSessionID = im.fromAgentID;
|
im.imSessionID = im.fromAgentID;
|
||||||
|
im.fromAgentName = GetFriendshipRequesterName(agentID);
|
||||||
|
|
||||||
// Try the local sim
|
// Try the local sim
|
||||||
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
|
||||||
im.fromAgentName = (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
|
||||||
|
|
||||||
if (LocalFriendshipOffered(friendID, im))
|
if (LocalFriendshipOffered(friendID, im))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -509,12 +566,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
// If the prospective friend is not online, he'll get the message upon login.
|
// If the prospective friend is not online, he'll get the message upon login.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual string GetFriendshipRequesterName(UUID agentID)
|
||||||
|
{
|
||||||
|
UserAccount account = UserAccountService.GetUserAccount(UUID.Zero, agentID);
|
||||||
|
return (account == null) ? "Unknown" : account.FirstName + " " + account.LastName;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
private void OnApproveFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
m_log.DebugFormat("[FRIENDS]: {0} accepted friendship from {1}", agentID, friendID);
|
||||||
|
|
||||||
FriendsService.StoreFriend(agentID, friendID.ToString(), 1);
|
StoreFriendships(agentID, friendID);
|
||||||
FriendsService.StoreFriend(friendID, agentID.ToString(), 1);
|
|
||||||
|
|
||||||
// Update the local cache
|
// Update the local cache
|
||||||
UpdateFriendsCache(agentID);
|
UpdateFriendsCache(agentID);
|
||||||
|
@ -544,6 +606,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void StoreFriendships(UUID agentID, UUID friendID)
|
||||||
|
{
|
||||||
|
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), 1);
|
||||||
|
FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
private void OnDenyFriendRequest(IClientAPI client, UUID agentID, UUID friendID, List<UUID> callingCardFolders)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
m_log.DebugFormat("[FRIENDS]: {0} denied friendship to {1}", agentID, friendID);
|
||||||
|
@ -576,8 +644,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
||||||
{
|
{
|
||||||
FriendsService.Delete(agentID, exfriendID.ToString());
|
DeleteFriendship(agentID, exfriendID);
|
||||||
FriendsService.Delete(exfriendID, agentID.ToString());
|
|
||||||
|
|
||||||
// Update local cache
|
// Update local cache
|
||||||
UpdateFriendsCache(agentID);
|
UpdateFriendsCache(agentID);
|
||||||
|
@ -604,6 +671,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||||
|
{
|
||||||
|
FriendsService.Delete(agentID, exfriendID.ToString());
|
||||||
|
FriendsService.Delete(exfriendID, agentID.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||||
{
|
{
|
||||||
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||||
|
@ -622,7 +695,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
if (friend != null) // Found it
|
if (friend != null) // Found it
|
||||||
{
|
{
|
||||||
// Store it on the DB
|
// Store it on the DB
|
||||||
FriendsService.StoreFriend(requester, target.ToString(), rights);
|
FriendsService.StoreFriend(requester.ToString(), target.ToString(), rights);
|
||||||
|
|
||||||
// Store it in the local cache
|
// Store it in the local cache
|
||||||
int myFlags = friend.MyFlags;
|
int myFlags = friend.MyFlags;
|
||||||
|
@ -780,7 +853,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private FriendInfo[] GetFriends(UUID agentID)
|
protected FriendInfo[] GetFriends(UUID agentID)
|
||||||
{
|
{
|
||||||
UserFriendData friendsData;
|
UserFriendData friendsData;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,438 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using log4net;
|
||||||
|
using Nini.Config;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
using Mono.Addins;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
using OpenSim.Region.Framework.Scenes;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Connectors.Hypergrid;
|
||||||
|
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
|
using PresenceInfo = OpenSim.Services.Interfaces.PresenceInfo;
|
||||||
|
using GridRegion = OpenSim.Services.Interfaces.GridRegion;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
{
|
||||||
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
||||||
|
public class HGFriendsModule : FriendsModule, ISharedRegionModule, IFriendsModule
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
#region ISharedRegionModule
|
||||||
|
public override string Name
|
||||||
|
{
|
||||||
|
get { return "HGFriendsModule"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
//public void SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||||
|
//{
|
||||||
|
// UUID agentID = client.AgentId;
|
||||||
|
|
||||||
|
// // Check if the online friends list is needed
|
||||||
|
// lock (m_NeedsListOfFriends)
|
||||||
|
// {
|
||||||
|
// if (!m_NeedsListOfFriends.Remove(agentID))
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Send the friends online
|
||||||
|
// List<UUID> online = GetOnlineFriends(agentID);
|
||||||
|
// if (online.Count > 0)
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count);
|
||||||
|
// client.SendAgentOnline(online.ToArray());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Send outstanding friendship offers
|
||||||
|
// List<string> outstanding = new List<string>();
|
||||||
|
// FriendInfo[] friends = GetFriends(agentID);
|
||||||
|
// foreach (FriendInfo fi in friends)
|
||||||
|
// {
|
||||||
|
// if (fi.TheirFlags == -1)
|
||||||
|
// outstanding.Add(fi.Friend);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered,
|
||||||
|
// "Will you be my friend?", true, Vector3.Zero);
|
||||||
|
|
||||||
|
// foreach (string fid in outstanding)
|
||||||
|
// {
|
||||||
|
// UUID fromAgentID;
|
||||||
|
// if (!UUID.TryParse(fid, out fromAgentID))
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
|
||||||
|
|
||||||
|
// PresenceInfo presence = null;
|
||||||
|
// PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
|
||||||
|
// if (presences != null && presences.Length > 0)
|
||||||
|
// presence = presences[0];
|
||||||
|
// if (presence != null)
|
||||||
|
// im.offline = 0;
|
||||||
|
|
||||||
|
// im.fromAgentID = fromAgentID.Guid;
|
||||||
|
// im.fromAgentName = account.FirstName + " " + account.LastName;
|
||||||
|
// im.offline = (byte)((presence == null) ? 1 : 0);
|
||||||
|
// im.imSessionID = im.fromAgentID;
|
||||||
|
|
||||||
|
// // Finally
|
||||||
|
// LocalFriendshipOffered(agentID, im);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//List<UUID> GetOnlineFriends(UUID userID)
|
||||||
|
//{
|
||||||
|
// List<string> friendList = new List<string>();
|
||||||
|
// List<UUID> online = new List<UUID>();
|
||||||
|
|
||||||
|
// FriendInfo[] friends = GetFriends(userID);
|
||||||
|
// foreach (FriendInfo fi in friends)
|
||||||
|
// {
|
||||||
|
// if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
|
||||||
|
// friendList.Add(fi.Friend);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (friendList.Count > 0)
|
||||||
|
// {
|
||||||
|
// PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
|
||||||
|
// foreach (PresenceInfo pi in presence)
|
||||||
|
// {
|
||||||
|
// UUID presenceID;
|
||||||
|
// if (UUID.TryParse(pi.UserID, out presenceID))
|
||||||
|
// online.Add(presenceID);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return online;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//private void StatusNotify(FriendInfo friend, UUID userID, bool online)
|
||||||
|
//{
|
||||||
|
// UUID friendID;
|
||||||
|
// if (UUID.TryParse(friend.Friend, out friendID))
|
||||||
|
// {
|
||||||
|
// // Try local
|
||||||
|
// if (LocalStatusNotification(userID, friendID, online))
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// // The friend is not here [as root]. Let's forward.
|
||||||
|
// PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
|
||||||
|
// if (friendSessions != null && friendSessions.Length > 0)
|
||||||
|
// {
|
||||||
|
// PresenceInfo friendSession = null;
|
||||||
|
// foreach (PresenceInfo pinfo in friendSessions)
|
||||||
|
// if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
|
||||||
|
// {
|
||||||
|
// friendSession = pinfo;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (friendSession != null)
|
||||||
|
// {
|
||||||
|
// GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||||
|
// //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
|
||||||
|
// m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // Friend is not online. Ignore.
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
protected override bool FetchFriendslist(UUID agentID)
|
||||||
|
{
|
||||||
|
if (base.FetchFriendslist(agentID))
|
||||||
|
{
|
||||||
|
// We need to preload the user management cache with the names
|
||||||
|
// of foreign friends, just like we do with SOPs' creators
|
||||||
|
foreach (FriendInfo finfo in m_Friends[agentID].Friends)
|
||||||
|
{
|
||||||
|
if (finfo.TheirFlags != -1)
|
||||||
|
{
|
||||||
|
UUID id;
|
||||||
|
if (!UUID.TryParse(finfo.Friend, out id))
|
||||||
|
{
|
||||||
|
string url = string.Empty, first = string.Empty, last = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last))
|
||||||
|
{
|
||||||
|
IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||||
|
uMan.AddUser(id, url + ";" + first + " " + last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||||
|
{
|
||||||
|
first = "Unknown"; last = "User";
|
||||||
|
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// fid is not a UUID...
|
||||||
|
string url = string.Empty;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last))
|
||||||
|
{
|
||||||
|
IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>();
|
||||||
|
userMan.AddUser(agentID, url + ";" + first + " " + last);
|
||||||
|
|
||||||
|
try // our best
|
||||||
|
{
|
||||||
|
string[] parts = userMan.GetUserName(agentID).Split();
|
||||||
|
first = parts[0];
|
||||||
|
last = parts[1];
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string FriendshipMessage(string friendID)
|
||||||
|
{
|
||||||
|
UUID id;
|
||||||
|
if (UUID.TryParse(friendID, out id))
|
||||||
|
return base.FriendshipMessage(friendID);
|
||||||
|
|
||||||
|
return "Please confirm this friendship you made while you were away.";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void StoreBackwards(UUID friendID, UUID agentID)
|
||||||
|
{
|
||||||
|
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||||
|
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||||
|
// Are they both local users?
|
||||||
|
if (account1 != null && account2 != null)
|
||||||
|
{
|
||||||
|
// local grid users
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||||
|
base.StoreBackwards(friendID, agentID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// no provision for this temporary friendship state
|
||||||
|
//FriendsService.StoreFriend(friendID.ToString(), agentID.ToString(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void StoreFriendships(UUID agentID, UUID friendID)
|
||||||
|
{
|
||||||
|
UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
|
||||||
|
UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
|
||||||
|
// Are they both local users?
|
||||||
|
if (agentAccount != null && friendAccount != null)
|
||||||
|
{
|
||||||
|
// local grid users
|
||||||
|
m_log.DebugFormat("[HGFRIENDS MODULE]: Users are both local");
|
||||||
|
base.StoreFriendships(agentID, friendID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ok, at least one of them is foreigner, let's get their data
|
||||||
|
IClientAPI agentClient = LocateClientObject(agentID);
|
||||||
|
IClientAPI friendClient = LocateClientObject(friendID);
|
||||||
|
AgentCircuitData agentClientCircuit = null;
|
||||||
|
AgentCircuitData friendClientCircuit = null;
|
||||||
|
string agentUUI = string.Empty;
|
||||||
|
string friendUUI = string.Empty;
|
||||||
|
string agentFriendService = string.Empty;
|
||||||
|
string friendFriendService = string.Empty;
|
||||||
|
|
||||||
|
if (agentClient != null)
|
||||||
|
{
|
||||||
|
agentClientCircuit = ((Scene)(agentClient.Scene)).AuthenticateHandler.GetAgentCircuitData(agentClient.CircuitCode);
|
||||||
|
agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
|
||||||
|
agentFriendService = agentClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||||
|
}
|
||||||
|
if (friendClient != null)
|
||||||
|
{
|
||||||
|
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
|
||||||
|
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
|
||||||
|
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
|
||||||
|
agentUUI, friendUUI, agentFriendService, friendFriendService);
|
||||||
|
|
||||||
|
if (agentAccount != null) // 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 llok for its information in the friends list itself
|
||||||
|
if (friendUUI == string.Empty)
|
||||||
|
{
|
||||||
|
FriendInfo[] finfos = GetFriends(agentID);
|
||||||
|
foreach (FriendInfo finfo in finfos)
|
||||||
|
{
|
||||||
|
if (finfo.TheirFlags == -1)
|
||||||
|
{
|
||||||
|
if (finfo.Friend.StartsWith(friendID.ToString()))
|
||||||
|
friendUUI = finfo.Friend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store in the local friends service a reference to the foreign friend
|
||||||
|
FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1);
|
||||||
|
// and also the converse
|
||||||
|
FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1);
|
||||||
|
|
||||||
|
if (friendClientCircuit != null)
|
||||||
|
{
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (friendAccount != null) // 'friend' is local, agent is foreigner
|
||||||
|
{
|
||||||
|
// store in the local friends service a reference to the foreign agent
|
||||||
|
FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1);
|
||||||
|
// and also the converse
|
||||||
|
FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1);
|
||||||
|
|
||||||
|
if (agentClientCircuit != null)
|
||||||
|
{
|
||||||
|
// store in the foreign friends service a reference to the local agent
|
||||||
|
HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(agentID, friendUUI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // They're both foreigners!
|
||||||
|
{
|
||||||
|
HGFriendsServicesConnector friendsConn;
|
||||||
|
if (agentClientCircuit != null)
|
||||||
|
{
|
||||||
|
friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(agentID, friendUUI);
|
||||||
|
}
|
||||||
|
if (friendClientCircuit != null)
|
||||||
|
{
|
||||||
|
friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID);
|
||||||
|
friendsConn.NewFriendship(friendID, agentUUI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// my brain hurts now
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void DeleteFriendship(UUID agentID, UUID exfriendID)
|
||||||
|
{
|
||||||
|
base.DeleteFriendship(agentID, exfriendID);
|
||||||
|
// Maybe some of the base deletes will fail.
|
||||||
|
// Let's delete the local friendship with foreign friend
|
||||||
|
FriendInfo[] friends = GetFriends(agentID);
|
||||||
|
foreach (FriendInfo finfo in friends)
|
||||||
|
{
|
||||||
|
if (finfo.Friend != exfriendID.ToString() && finfo.Friend.EndsWith(exfriendID.ToString()))
|
||||||
|
{
|
||||||
|
FriendsService.Delete(agentID, exfriendID.ToString());
|
||||||
|
// TODO: delete the friendship on the other side
|
||||||
|
// Should use the homeurl given in finfo.Friend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||||
|
//{
|
||||||
|
// FriendInfo[] friends = GetFriends(remoteClient.AgentId);
|
||||||
|
// if (friends.Length == 0)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
|
||||||
|
// // Let's find the friend in this user's friend list
|
||||||
|
// FriendInfo friend = null;
|
||||||
|
// foreach (FriendInfo fi in friends)
|
||||||
|
// {
|
||||||
|
// if (fi.Friend == target.ToString())
|
||||||
|
// friend = fi;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (friend != null) // Found it
|
||||||
|
// {
|
||||||
|
// // Store it on the DB
|
||||||
|
// FriendsService.StoreFriend(requester, target.ToString(), rights);
|
||||||
|
|
||||||
|
// // Store it in the local cache
|
||||||
|
// int myFlags = friend.MyFlags;
|
||||||
|
// friend.MyFlags = rights;
|
||||||
|
|
||||||
|
// // Always send this back to the original client
|
||||||
|
// remoteClient.SendChangeUserRights(requester, target, rights);
|
||||||
|
|
||||||
|
// //
|
||||||
|
// // Notify the friend
|
||||||
|
// //
|
||||||
|
|
||||||
|
// // Try local
|
||||||
|
// if (LocalGrantRights(requester, target, myFlags, rights))
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
|
||||||
|
// if (friendSessions != null && friendSessions.Length > 0)
|
||||||
|
// {
|
||||||
|
// PresenceInfo friendSession = friendSessions[0];
|
||||||
|
// if (friendSession != null)
|
||||||
|
// {
|
||||||
|
// GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||||
|
// // TODO: You might want to send the delta to save the lookup
|
||||||
|
// // on the other end!!
|
||||||
|
// m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -141,6 +141,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
|
void HandleUUIDNameRequest(UUID uuid, IClientAPI remote_client)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0}", uuid);
|
||||||
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
if (m_Scenes[0].LibraryService != null && (m_Scenes[0].LibraryService.LibraryRootFolder.Owner == uuid))
|
||||||
{
|
{
|
||||||
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
|
remote_client.SendNameReply(uuid, "Mr", "OpenSim");
|
||||||
|
@ -210,6 +211,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public string GetUserName(UUID uuid)
|
public string GetUserName(UUID uuid)
|
||||||
{
|
{
|
||||||
|
m_log.DebugFormat("[XXX] GetUserName {0}", uuid);
|
||||||
string[] names = GetUserNames(uuid);
|
string[] names = GetUserNames(uuid);
|
||||||
if (names.Length == 2)
|
if (names.Length == 2)
|
||||||
{
|
{
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid
|
||||||
|
|
||||||
new UserAgentServerConnector(m_Config, MainServer.Instance);
|
new UserAgentServerConnector(m_Config, MainServer.Instance);
|
||||||
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
|
new HeloServiceInConnector(m_Config, MainServer.Instance, "HeloService");
|
||||||
|
new HGFriendsServerConnector(m_Config, MainServer.Instance, "HGFriendsService");
|
||||||
}
|
}
|
||||||
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
|
scene.RegisterModuleInterface<IGatekeeperService>(m_HypergridHandler.GateKeeper);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,14 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
if (serverConfig == null)
|
if (serverConfig == null)
|
||||||
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
throw new Exception(String.Format("No section {0} in config file", m_ConfigName));
|
||||||
|
|
||||||
string gridService = serverConfig.GetString("LocalServiceModule",
|
string theService = serverConfig.GetString("LocalServiceModule",
|
||||||
String.Empty);
|
String.Empty);
|
||||||
|
|
||||||
if (gridService == String.Empty)
|
if (theService == String.Empty)
|
||||||
throw new Exception("No LocalServiceModule in config file");
|
throw new Exception("No LocalServiceModule in config file");
|
||||||
|
|
||||||
Object[] args = new Object[] { config };
|
Object[] args = new Object[] { config };
|
||||||
m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(gridService, args);
|
m_FriendsService = ServerUtils.LoadPlugin<IFriendsService>(theService, args);
|
||||||
|
|
||||||
server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
|
server.AddStreamHandler(new FriendsServerPostHandler(m_FriendsService));
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,7 +138,7 @@ namespace OpenSim.Server.Handlers.Friends
|
||||||
{
|
{
|
||||||
FriendInfo friend = new FriendInfo(request);
|
FriendInfo friend = new FriendInfo(request);
|
||||||
|
|
||||||
bool success = m_FriendsService.StoreFriend(friend.PrincipalID, friend.Friend, friend.MyFlags);
|
bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, friend.MyFlags);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
return SuccessResult();
|
return SuccessResult();
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenSim.Server.Handlers.Base;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
|
{
|
||||||
|
public class HGFriendsServerConnector : ServiceConnector
|
||||||
|
{
|
||||||
|
private IFriendsService m_FriendsService;
|
||||||
|
private IUserAgentService m_UserAgentService;
|
||||||
|
private string m_ConfigName = "HGFriendsService";
|
||||||
|
|
||||||
|
public HGFriendsServerConnector(IConfigSource config, IHttpServer server, string configName) :
|
||||||
|
base(config, server, configName)
|
||||||
|
{
|
||||||
|
if (configName != string.Empty)
|
||||||
|
m_ConfigName = configName;
|
||||||
|
|
||||||
|
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<IFriendsService>(theService, args);
|
||||||
|
|
||||||
|
theService = serverConfig.GetString("UserAgentService", string.Empty);
|
||||||
|
if (theService == String.Empty)
|
||||||
|
throw new Exception("No UserAgentService in " + m_ConfigName);
|
||||||
|
|
||||||
|
m_UserAgentService = ServerUtils.LoadPlugin<IUserAgentService>(theService, args);
|
||||||
|
|
||||||
|
server.AddStreamHandler(new HGFriendsServerPostHandler(m_FriendsService, m_UserAgentService));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,242 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using log4net;
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Servers.HttpServer;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Server.Handlers.Hypergrid
|
||||||
|
{
|
||||||
|
public class HGFriendsServerPostHandler : BaseStreamHandler
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private IFriendsService m_FriendsService;
|
||||||
|
private IUserAgentService m_UserAgentService;
|
||||||
|
|
||||||
|
public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
|
||||||
|
base("POST", "/hgfriends")
|
||||||
|
{
|
||||||
|
m_FriendsService = service;
|
||||||
|
m_UserAgentService = uservice;
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte[] Handle(string path, Stream requestData,
|
||||||
|
OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
StreamReader sr = new StreamReader(requestData);
|
||||||
|
string body = sr.ReadToEnd();
|
||||||
|
sr.Close();
|
||||||
|
body = body.Trim();
|
||||||
|
|
||||||
|
//m_log.DebugFormat("[XXX]: query String: {0}", body);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Dictionary<string, object> request =
|
||||||
|
ServerUtils.ParseQueryString(body);
|
||||||
|
|
||||||
|
if (!request.ContainsKey("METHOD"))
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
string method = request["METHOD"].ToString();
|
||||||
|
|
||||||
|
switch (method)
|
||||||
|
{
|
||||||
|
case "getfriends":
|
||||||
|
return GetFriends(request);
|
||||||
|
|
||||||
|
case "newfriendship":
|
||||||
|
return NewFriendship(request);
|
||||||
|
|
||||||
|
}
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FailureResult();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Method-specific handlers
|
||||||
|
|
||||||
|
byte[] GetFriends(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
UUID principalID = UUID.Zero;
|
||||||
|
if (request.ContainsKey("PRINCIPALID"))
|
||||||
|
UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friends");
|
||||||
|
|
||||||
|
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
|
||||||
|
//m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count);
|
||||||
|
|
||||||
|
Dictionary<string, object> result = new Dictionary<string, object>();
|
||||||
|
if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
|
||||||
|
result["result"] = "null";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
foreach (FriendInfo finfo in finfos)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> rinfoDict = finfo.ToKeyValuePairs();
|
||||||
|
result["friend" + i] = rinfoDict;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string xmlString = ServerUtils.BuildXmlResponse(result);
|
||||||
|
//m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString);
|
||||||
|
UTF8Encoding encoding = new UTF8Encoding();
|
||||||
|
return encoding.GetBytes(xmlString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] NewFriendship(Dictionary<string, object> request)
|
||||||
|
{
|
||||||
|
if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
string serviceKey = request["KEY"].ToString();
|
||||||
|
string sessionStr = request["SESSIONID"].ToString();
|
||||||
|
UUID sessionID;
|
||||||
|
UUID.TryParse(sessionStr, out sessionID);
|
||||||
|
|
||||||
|
if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_log.DebugFormat("[XXX] Verification ok");
|
||||||
|
// OK, can proceed
|
||||||
|
FriendInfo friend = new FriendInfo(request);
|
||||||
|
|
||||||
|
// the user needs to confirm when he gets home
|
||||||
|
bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
|
||||||
|
//if (success)
|
||||||
|
// m_FriendsService.StoreFriend(friend.Friend, friend.PrincipalID.ToString(), 1);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
return SuccessResult();
|
||||||
|
else
|
||||||
|
return FailureResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Misc
|
||||||
|
|
||||||
|
private byte[] SuccessResult()
|
||||||
|
{
|
||||||
|
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("Success"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] FailureResult()
|
||||||
|
{
|
||||||
|
return FailureResult(String.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] FailureResult(string msg)
|
||||||
|
{
|
||||||
|
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("Failure"));
|
||||||
|
|
||||||
|
rootElement.AppendChild(result);
|
||||||
|
|
||||||
|
XmlElement message = doc.CreateElement("", "Message", "");
|
||||||
|
message.AppendChild(doc.CreateTextNode(msg));
|
||||||
|
|
||||||
|
rootElement.AppendChild(message);
|
||||||
|
|
||||||
|
return DocToBytes(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] DocToBytes(XmlDocument doc)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
XmlTextWriter xw = new XmlTextWriter(ms, null);
|
||||||
|
xw.Formatting = Formatting.Indented;
|
||||||
|
doc.WriteTo(xw);
|
||||||
|
xw.Flush();
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
using OpenSim.Server.Base;
|
using OpenSim.Server.Base;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Services.Connectors
|
namespace OpenSim.Services.Connectors.Friends
|
||||||
{
|
{
|
||||||
public class FriendsServicesConnector : IFriendsService
|
public class FriendsServicesConnector : IFriendsService
|
||||||
{
|
{
|
||||||
|
@ -144,10 +144,17 @@ namespace OpenSim.Services.Connectors
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
|
public bool StoreFriend(string PrincipalID, string Friend, int flags)
|
||||||
{
|
{
|
||||||
FriendInfo finfo = new FriendInfo();
|
FriendInfo finfo = new FriendInfo();
|
||||||
finfo.PrincipalID = PrincipalID;
|
try
|
||||||
|
{
|
||||||
|
finfo.PrincipalID = new UUID(PrincipalID);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
finfo.Friend = Friend;
|
finfo.Friend = Friend;
|
||||||
finfo.MyFlags = flags;
|
finfo.MyFlags = flags;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* 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 log4net;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Connectors.Friends;
|
||||||
|
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
|
using OpenSim.Server.Base;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Services.Connectors.Hypergrid
|
||||||
|
{
|
||||||
|
public class HGFriendsServicesConnector
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(
|
||||||
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private string m_ServerURI = String.Empty;
|
||||||
|
private string m_ServiceKey = String.Empty;
|
||||||
|
private UUID m_SessionID;
|
||||||
|
|
||||||
|
public HGFriendsServicesConnector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public HGFriendsServicesConnector(string serverURI, UUID sessionID, string serviceKey)
|
||||||
|
{
|
||||||
|
m_ServerURI = serverURI.TrimEnd('/');
|
||||||
|
m_ServiceKey = serviceKey;
|
||||||
|
m_SessionID = sessionID;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IFriendsService
|
||||||
|
|
||||||
|
public FriendInfo[] GetFriends(UUID PrincipalID)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> sendData = new Dictionary<string, object>();
|
||||||
|
|
||||||
|
sendData["PRINCIPALID"] = PrincipalID.ToString();
|
||||||
|
sendData["METHOD"] = "getfriends";
|
||||||
|
sendData["KEY"] = m_ServiceKey;
|
||||||
|
sendData["SESSIONID"] = m_SessionID.ToString();
|
||||||
|
|
||||||
|
string reqString = ServerUtils.BuildQueryString(sendData);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||||
|
m_ServerURI + "/hgfriends",
|
||||||
|
reqString);
|
||||||
|
if (reply != string.Empty)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
|
||||||
|
|
||||||
|
if (replyData != null)
|
||||||
|
{
|
||||||
|
if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null"))
|
||||||
|
{
|
||||||
|
return new FriendInfo[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
List<FriendInfo> finfos = new List<FriendInfo>();
|
||||||
|
Dictionary<string, object>.ValueCollection finfosList = replyData.Values;
|
||||||
|
//m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count);
|
||||||
|
foreach (object f in finfosList)
|
||||||
|
{
|
||||||
|
if (f is Dictionary<string, object>)
|
||||||
|
{
|
||||||
|
FriendInfo finfo = new FriendInfo((Dictionary<string, object>)f);
|
||||||
|
finfos.Add(finfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}",
|
||||||
|
PrincipalID, f.GetType());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Success
|
||||||
|
return finfos.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received null response",
|
||||||
|
PrincipalID);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FriendInfo[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool NewFriendship(UUID PrincipalID, string Friend)
|
||||||
|
{
|
||||||
|
FriendInfo finfo = new FriendInfo();
|
||||||
|
finfo.PrincipalID = PrincipalID;
|
||||||
|
finfo.Friend = Friend;
|
||||||
|
|
||||||
|
Dictionary<string, object> sendData = finfo.ToKeyValuePairs();
|
||||||
|
|
||||||
|
sendData["METHOD"] = "newfriendship";
|
||||||
|
sendData["KEY"] = m_ServiceKey;
|
||||||
|
sendData["SESSIONID"] = m_SessionID.ToString();
|
||||||
|
|
||||||
|
string reply = string.Empty;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reply = SynchronousRestFormsRequester.MakeRequest("POST",
|
||||||
|
m_ServerURI + "/hgfriends",
|
||||||
|
ServerUtils.BuildQueryString(sendData));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply != string.Empty)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
|
||||||
|
|
||||||
|
if ((replyData != null) && replyData.ContainsKey("Result") && (replyData["Result"] != null))
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
Boolean.TryParse(replyData["Result"].ToString(), out success);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend {0} {1} received null response",
|
||||||
|
PrincipalID, Friend);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: StoreFriend received null reply");
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -127,7 +127,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StoreFriend(UUID principalID, string friend, int flags)
|
public bool StoreFriend(string principalID, string friend, int flags)
|
||||||
{
|
{
|
||||||
if (String.IsNullOrEmpty(m_serverUrl))
|
if (String.IsNullOrEmpty(m_serverUrl))
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -43,17 +43,16 @@ namespace OpenSim.Services.Friends
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public FriendInfo[] GetFriends(UUID PrincipalID)
|
public virtual FriendInfo[] GetFriends(UUID PrincipalID)
|
||||||
{
|
{
|
||||||
FriendsData[] data = m_Database.GetFriends(PrincipalID);
|
FriendsData[] data = m_Database.GetFriends(PrincipalID);
|
||||||
|
|
||||||
List<FriendInfo> info = new List<FriendInfo>();
|
List<FriendInfo> info = new List<FriendInfo>();
|
||||||
|
|
||||||
foreach (FriendsData d in data)
|
foreach (FriendsData d in data)
|
||||||
{
|
{
|
||||||
FriendInfo i = new FriendInfo();
|
FriendInfo i = new FriendInfo();
|
||||||
|
|
||||||
i.PrincipalID = d.PrincipalID;
|
i.PrincipalID = new UUID(d.PrincipalID);
|
||||||
i.Friend = d.Friend;
|
i.Friend = d.Friend;
|
||||||
i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
|
i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
|
||||||
i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
|
i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
|
||||||
|
@ -64,7 +63,7 @@ namespace OpenSim.Services.Friends
|
||||||
return info.ToArray();
|
return info.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StoreFriend(UUID PrincipalID, string Friend, int flags)
|
public virtual bool StoreFriend(string PrincipalID, string Friend, int flags)
|
||||||
{
|
{
|
||||||
FriendsData d = new FriendsData();
|
FriendsData d = new FriendsData();
|
||||||
|
|
||||||
|
@ -76,7 +75,7 @@ namespace OpenSim.Services.Friends
|
||||||
return m_Database.Store(d);
|
return m_Database.Store(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Delete(UUID PrincipalID, string Friend)
|
public virtual bool Delete(UUID PrincipalID, string Friend)
|
||||||
{
|
{
|
||||||
return m_Database.Delete(PrincipalID, Friend);
|
return m_Database.Delete(PrincipalID, Friend);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenSim.Services.Interfaces;
|
||||||
|
using OpenSim.Services.Friends;
|
||||||
|
using OpenSim.Data;
|
||||||
|
using Nini.Config;
|
||||||
|
using log4net;
|
||||||
|
using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
|
||||||
|
|
||||||
|
namespace OpenSim.Services.HypergridService
|
||||||
|
{
|
||||||
|
public class HGFriendsService : FriendsService, IFriendsService
|
||||||
|
{
|
||||||
|
public HGFriendsService(IConfigSource config) : base(config)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides base.
|
||||||
|
/// Storing new friendships from the outside is a tricky, sensitive operation, and it
|
||||||
|
/// needs to be done under certain restrictions.
|
||||||
|
/// First of all, if the friendship already exists, this is a no-op. In other words,
|
||||||
|
/// we cannot change just the flags, it needs to be a new friendship.
|
||||||
|
/// Second, we store it as flags=0 always, independent of what the caller sends. The
|
||||||
|
/// owner of the friendship needs to confirm when it gets back home.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="PrincipalID"></param>
|
||||||
|
/// <param name="Friend"></param>
|
||||||
|
/// <param name="flags"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool StoreFriend(string PrincipalID, string Friend, int flags)
|
||||||
|
{
|
||||||
|
UUID userID;
|
||||||
|
if (UUID.TryParse(PrincipalID, out userID))
|
||||||
|
{
|
||||||
|
FriendsData[] friendsData = m_Database.GetFriends(userID);
|
||||||
|
List<FriendsData> fList = new List<FriendsData>(friendsData);
|
||||||
|
if (fList.Find(delegate(FriendsData fdata)
|
||||||
|
{
|
||||||
|
return fdata.Friend == Friend;
|
||||||
|
}) != null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FriendsData d = new FriendsData();
|
||||||
|
d.PrincipalID = PrincipalID;
|
||||||
|
d.Friend = Friend;
|
||||||
|
d.Data = new Dictionary<string, string>();
|
||||||
|
d.Data["Flags"] = "0";
|
||||||
|
|
||||||
|
return m_Database.Store(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides base. Cannot delete friendships while away from home.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="PrincipalID"></param>
|
||||||
|
/// <param name="Friend"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool Delete(UUID PrincipalID, string Friend)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,7 +74,7 @@ namespace OpenSim.Services.Interfaces
|
||||||
public interface IFriendsService
|
public interface IFriendsService
|
||||||
{
|
{
|
||||||
FriendInfo[] GetFriends(UUID PrincipalID);
|
FriendInfo[] GetFriends(UUID PrincipalID);
|
||||||
bool StoreFriend(UUID PrincipalID, string Friend, int flags);
|
bool StoreFriend(string PrincipalID, string Friend, int flags);
|
||||||
bool Delete(UUID PrincipalID, string Friend);
|
bool Delete(UUID PrincipalID, string Friend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,7 +621,19 @@ namespace OpenSim.Services.LLLoginService
|
||||||
if (finfo.TheirFlags == -1)
|
if (finfo.TheirFlags == -1)
|
||||||
continue;
|
continue;
|
||||||
LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
|
LLLoginResponse.BuddyList.BuddyInfo buddyitem = new LLLoginResponse.BuddyList.BuddyInfo(finfo.Friend);
|
||||||
|
// finfo.Friend may not be a simple uuid
|
||||||
|
UUID friendID = UUID.Zero;
|
||||||
|
if (UUID.TryParse(finfo.Friend, out friendID))
|
||||||
buddyitem.BuddyID = finfo.Friend;
|
buddyitem.BuddyID = finfo.Friend;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
string tmp;
|
||||||
|
if (Util.ParseUniversalUserIdentifier(finfo.Friend, out friendID, out tmp, out tmp, out tmp))
|
||||||
|
buddyitem.BuddyID = friendID.ToString();
|
||||||
|
else
|
||||||
|
// junk entry
|
||||||
|
continue;
|
||||||
|
}
|
||||||
buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
|
buddyitem.BuddyRightsHave = (int)finfo.TheirFlags;
|
||||||
buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
|
buddyitem.BuddyRightsGiven = (int)finfo.MyFlags;
|
||||||
buddylistreturn.AddNewBuddy(buddyitem);
|
buddylistreturn.AddNewBuddy(buddyitem);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
AvatarServices = "LocalAvatarServicesConnector"
|
AvatarServices = "LocalAvatarServicesConnector"
|
||||||
EntityTransferModule = "HGEntityTransferModule"
|
EntityTransferModule = "HGEntityTransferModule"
|
||||||
InventoryAccessModule = "HGInventoryAccessModule"
|
InventoryAccessModule = "HGInventoryAccessModule"
|
||||||
|
FriendsModule = "HGFriendsModule"
|
||||||
|
|
||||||
InventoryServiceInConnector = true
|
InventoryServiceInConnector = true
|
||||||
AssetServiceInConnector = true
|
AssetServiceInConnector = true
|
||||||
|
@ -140,6 +141,10 @@
|
||||||
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService"
|
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGAssetService"
|
||||||
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
|
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
|
||||||
|
|
||||||
|
[HGFriendsService]
|
||||||
|
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGFriendsService"
|
||||||
|
UserAgentService = "OpenSim.Services.HypergridService.dll:UserAgentService"
|
||||||
|
|
||||||
;; This should always be the very last thing on this file
|
;; This should always be the very last thing on this file
|
||||||
[Includes]
|
[Includes]
|
||||||
Include-Common = "config-include/StandaloneCommon.ini"
|
Include-Common = "config-include/StandaloneCommon.ini"
|
||||||
|
|
|
@ -1256,6 +1256,7 @@
|
||||||
<Reference name="OpenSim.Services.Interfaces"/>
|
<Reference name="OpenSim.Services.Interfaces"/>
|
||||||
<Reference name="OpenSim.Services.Base"/>
|
<Reference name="OpenSim.Services.Base"/>
|
||||||
<Reference name="OpenSim.Services.AssetService"/>
|
<Reference name="OpenSim.Services.AssetService"/>
|
||||||
|
<Reference name="OpenSim.Services.FriendsService"/>
|
||||||
<Reference name="OpenSim.Services.InventoryService"/>
|
<Reference name="OpenSim.Services.InventoryService"/>
|
||||||
<Reference name="OpenSim.Services.Connectors"/>
|
<Reference name="OpenSim.Services.Connectors"/>
|
||||||
<Reference name="OpenSim.Data"/>
|
<Reference name="OpenSim.Data"/>
|
||||||
|
|
Loading…
Reference in New Issue