mirror of
https://github.com/opensim/opensim.git
synced 2026-08-11 11:57:03 +08:00
Merge branch 'master' into bigmerge
Conflicts: OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs
This commit is contained in:
@@ -29,6 +29,7 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Nini.Config;
|
||||
using Nwc.XmlRpc;
|
||||
@@ -79,10 +80,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
protected IFriendsService m_FriendsService = null;
|
||||
protected FriendsSimConnector m_FriendsSimConnector;
|
||||
|
||||
protected Dictionary<UUID, UserFriendData> m_Friends =
|
||||
new Dictionary<UUID, UserFriendData>();
|
||||
/// <summary>
|
||||
/// Cache friends lists for users.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a complex and error-prone thing to do. At the moment, we assume that the efficiency gained in
|
||||
/// permissions checks outweighs the disadvantages of that complexity.
|
||||
/// </remarks>
|
||||
protected Dictionary<UUID, UserFriendData> m_Friends = new Dictionary<UUID, UserFriendData>();
|
||||
|
||||
protected HashSet<UUID> m_NeedsListOfFriends = new HashSet<UUID>();
|
||||
/// <summary>
|
||||
/// Maintain a record of viewers that need to be sent notifications for friends that are online. This only
|
||||
/// needs to be done on login. Subsequent online/offline friend changes are sent by a different mechanism.
|
||||
/// </summary>
|
||||
protected HashSet<UUID> m_NeedsListOfOnlineFriends = new HashSet<UUID>();
|
||||
|
||||
protected IPresenceService PresenceService
|
||||
{
|
||||
@@ -189,6 +200,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
{
|
||||
if (!m_Enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
|
||||
|
||||
m_Scenes.Add(scene);
|
||||
@@ -241,16 +253,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
client.OnInstantMessage += OnInstantMessage;
|
||||
client.OnApproveFriendRequest += OnApproveFriendRequest;
|
||||
client.OnDenyFriendRequest += OnDenyFriendRequest;
|
||||
client.OnTerminateFriendship += OnTerminateFriendship;
|
||||
client.OnTerminateFriendship += (thisClient, agentID, exfriendID) => RemoveFriendship(thisClient, exfriendID);
|
||||
client.OnGrantUserRights += OnGrantUserRights;
|
||||
|
||||
Util.FireAndForget(delegate { FetchFriendslist(client); });
|
||||
// Do not do this asynchronously. If we do, then subsequent code can outrace CacheFriends() and
|
||||
// return misleading results from the still empty friends cache.
|
||||
// If we absolutely need to do this asynchronously, then a signalling mechanism is needed so that calls
|
||||
// to GetFriends() will wait until CacheFriends() completes. Locks are insufficient.
|
||||
CacheFriends(client);
|
||||
}
|
||||
|
||||
/// Fetch the friends list or increment the refcount for the existing
|
||||
/// friends list
|
||||
/// <summary>
|
||||
/// Cache the friends list or increment the refcount for the existing friends list.
|
||||
/// </summary>
|
||||
/// <param name="client">
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// Returns true if the list was fetched, false if it wasn't
|
||||
protected virtual bool FetchFriendslist(IClientAPI client)
|
||||
/// </returns>
|
||||
protected virtual bool CacheFriends(IClientAPI client)
|
||||
{
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
@@ -297,7 +318,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
private void OnMakeRootAgent(ScenePresence sp)
|
||||
{
|
||||
RefetchFriends(sp.ControllingClient);
|
||||
RecacheFriends(sp.ControllingClient);
|
||||
}
|
||||
|
||||
private void OnClientLogin(IClientAPI client)
|
||||
@@ -309,8 +330,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
StatusChange(agentID, true);
|
||||
|
||||
// Register that we need to send the list of online friends to this user
|
||||
lock (m_NeedsListOfFriends)
|
||||
m_NeedsListOfFriends.Add(agentID);
|
||||
lock (m_NeedsListOfOnlineFriends)
|
||||
m_NeedsListOfOnlineFriends.Add(agentID);
|
||||
}
|
||||
|
||||
public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
|
||||
@@ -318,9 +339,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
UUID agentID = client.AgentId;
|
||||
|
||||
// Check if the online friends list is needed
|
||||
lock (m_NeedsListOfFriends)
|
||||
lock (m_NeedsListOfOnlineFriends)
|
||||
{
|
||||
if (!m_NeedsListOfFriends.Remove(agentID))
|
||||
if (!m_NeedsListOfOnlineFriends.Remove(agentID))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -328,7 +349,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
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);
|
||||
m_log.DebugFormat(
|
||||
"[FRIENDS MODULE]: User {0} in region {1} has {2} friends online",
|
||||
client.Name, client.Scene.RegionInfo.RegionName, online.Count);
|
||||
|
||||
client.SendAgentOnline(online.ToArray());
|
||||
}
|
||||
|
||||
@@ -586,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
|
||||
// Update the local cache
|
||||
RefetchFriends(client);
|
||||
RecacheFriends(client);
|
||||
|
||||
//
|
||||
// Notify the friend
|
||||
@@ -641,14 +665,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTerminateFriendship(IClientAPI client, UUID agentID, UUID exfriendID)
|
||||
|
||||
public void RemoveFriendship(IClientAPI client, UUID exfriendID)
|
||||
{
|
||||
if (!DeleteFriendship(agentID, exfriendID))
|
||||
if (!DeleteFriendship(client.AgentId, exfriendID))
|
||||
client.SendAlertMessage("Unable to terminate friendship on this sim.");
|
||||
|
||||
// Update local cache
|
||||
RefetchFriends(client);
|
||||
RecacheFriends(client);
|
||||
|
||||
client.SendTerminateFriend(exfriendID);
|
||||
|
||||
@@ -667,9 +691,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (friendSession != null)
|
||||
{
|
||||
GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
|
||||
m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID);
|
||||
m_FriendsSimConnector.FriendshipTerminated(region, client.AgentId, exfriendID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
|
||||
@@ -769,7 +793,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
|
||||
|
||||
// Update the local cache
|
||||
RefetchFriends(friendClient);
|
||||
RecacheFriends(friendClient);
|
||||
|
||||
// we're done
|
||||
return true;
|
||||
@@ -802,7 +826,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
// the friend in this sim as root agent
|
||||
friendClient.SendTerminateFriend(exfriendID);
|
||||
// update local cache
|
||||
RefetchFriends(friendClient);
|
||||
RecacheFriends(friendClient);
|
||||
// we're done
|
||||
return true;
|
||||
}
|
||||
@@ -819,16 +843,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
if (onlineBitChanged)
|
||||
{
|
||||
if ((rights & (int)FriendRights.CanSeeOnline) == 1)
|
||||
friendClient.SendAgentOnline(new UUID[] { new UUID(userID) });
|
||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||
else
|
||||
friendClient.SendAgentOffline(new UUID[] { new UUID(userID) });
|
||||
friendClient.SendAgentOffline(new UUID[] { userID });
|
||||
}
|
||||
else
|
||||
{
|
||||
bool canEditObjectsChanged = ((rights ^ userFlags) & (int)FriendRights.CanModifyObjects) != 0;
|
||||
if (canEditObjectsChanged)
|
||||
friendClient.SendChangeUserRights(userID, friendID, rights);
|
||||
|
||||
}
|
||||
|
||||
// Update local cache
|
||||
@@ -847,7 +870,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
IClientAPI friendClient = LocateClientObject(friendID);
|
||||
if (friendClient != null)
|
||||
{
|
||||
// the friend in this sim as root agent
|
||||
// the friend in this sim as root agent
|
||||
if (online)
|
||||
friendClient.SendAgentOnline(new UUID[] { userID });
|
||||
else
|
||||
@@ -902,8 +925,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||
return FriendsService.GetFriends(client.AgentId);
|
||||
}
|
||||
|
||||
private void RefetchFriends(IClientAPI client)
|
||||
private 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.
|
||||
UUID agentID = client.AgentId;
|
||||
lock (m_Friends)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user