diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index 3f560d0ec4..1e36b061d0 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -710,7 +710,7 @@ namespace OpenSim.Framework
/// The scene agent for this client. This will only be set if the client has an agent in a scene (i.e. if it
/// is connected).
///
- ISceneAgent SceneAgent { get; }
+ ISceneAgent SceneAgent { get; set; }
UUID SessionId { get; }
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index cd81df5e68..98996693e0 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -384,7 +384,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
set { m_startpos = value; }
}
public UUID AgentId { get { return m_agentId; } }
- public ISceneAgent SceneAgent { get; private set; }
+ public ISceneAgent SceneAgent { get; set; }
public UUID ActiveGroupId { get { return m_activeGroupID; } }
public string ActiveGroupName { get { return m_activeGroupName; } }
public ulong ActiveGroupPowers { get { return m_activeGroupPowers; } }
@@ -695,7 +695,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public virtual void Start()
{
- SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
+ m_scene.AddNewClient(this, PresenceType.User);
RefreshGroupMembership();
}
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
index d1a1af0888..f3982ea8e7 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs
@@ -57,7 +57,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
public UUID PrincipalID;
public FriendInfo[] Friends;
- public int Refcount;
public bool IsFriend(string friend)
{
@@ -255,6 +254,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnNewClient(IClientAPI client)
{
+ if (client.SceneAgent.IsChildAgent)
+ return;
+
client.OnInstantMessage += OnInstantMessage;
client.OnApproveFriendRequest += OnApproveFriendRequest;
client.OnDenyFriendRequest += OnDenyFriendRequest;
@@ -281,23 +283,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
UUID agentID = client.AgentId;
lock (m_Friends)
{
- UserFriendData friendsData;
- if (m_Friends.TryGetValue(agentID, out friendsData))
- {
- friendsData.Refcount++;
- return false;
- }
- else
- {
- friendsData = new UserFriendData();
- friendsData.PrincipalID = agentID;
- friendsData.Friends = GetFriendsFromService(client);
- friendsData.Refcount = 1;
+ UserFriendData friendsData = new UserFriendData();
+ friendsData.PrincipalID = agentID;
+ friendsData.Friends = GetFriendsFromService(client);
- m_Friends[agentID] = friendsData;
- return true;
- }
+ m_Friends[agentID] = friendsData;
}
+
+ return true;
}
private void OnClientClosed(UUID agentID, Scene scene)
@@ -307,23 +300,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
// do this for root agents closing out
StatusChange(agentID, false);
- }
- lock (m_Friends)
- {
- UserFriendData friendsData;
- if (m_Friends.TryGetValue(agentID, out friendsData))
- {
- friendsData.Refcount--;
- if (friendsData.Refcount <= 0)
- m_Friends.Remove(agentID);
- }
+ lock (m_Friends)
+ m_Friends.Remove(agentID);
}
}
private void OnMakeRootAgent(ScenePresence sp)
{
- RecacheFriends(sp.ControllingClient);
+ // 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.
+ CacheFriends(sp.ControllingClient);
}
private void OnClientLogin(IClientAPI client)
@@ -623,7 +610,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
StoreFriendships(client.AgentId, friendID);
// Update the local cache.
- RecacheFriends(client);
+ CacheFriends(client);
//
// Notify the friend
@@ -685,7 +672,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.SendAlertMessage("Unable to terminate friendship on this sim.");
// Update local cache
- RecacheFriends(client);
+ CacheFriends(client);
client.SendTerminateFriend(exfriendID);
@@ -799,7 +786,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendClient.SendInstantMessage(im);
// Update the local cache
- RecacheFriends(friendClient);
+ CacheFriends(friendClient);
// we're done
return true;
@@ -832,7 +819,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// the friend in this sim as root agent
friendClient.SendTerminateFriend(exfriendID);
// update local cache
- RecacheFriends(friendClient);
+ CacheFriends(friendClient);
// we're done
return true;
}
@@ -933,19 +920,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return FriendsService.GetFriends(client.AgentId);
}
- 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.
- UUID agentID = client.AgentId;
- lock (m_Friends)
- {
- UserFriendData friendsData;
- if (m_Friends.TryGetValue(agentID, out friendsData))
- friendsData.Friends = GetFriendsFromService(client);
- }
- }
-
///
/// Are friends cached on this simulator for a particular user?
///
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
index e50a84a76e..7bc30181a0 100644
--- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs
@@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{
UUID agentID = client.AgentId;
// we do this only for the root agent
- if (m_Friends[agentID].Refcount == 1)
+ if (!client.SceneAgent.IsChildAgent)
{
// We need to preload the user management cache with the names
// of foreign friends, just like we do with SOPs' creators
@@ -426,14 +426,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);
+ CacheFriends(agentClient);
}
if (friendClient != null)
{
friendClientCircuit = ((Scene)(friendClient.Scene)).AuthenticateHandler.GetAgentCircuitData(friendClient.CircuitCode);
friendUUI = Util.ProduceUserUniversalIdentifier(friendClientCircuit);
friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString();
- RecacheFriends(friendClient);
+ CacheFriends(friendClient);
}
m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}",
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index 7993abed72..fe3438e175 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -71,6 +71,7 @@ namespace OpenSim.Region.Framework.Scenes
/// Triggered when a new client is added to the scene.
///
///
+ /// This is triggered for both child and root agent client connections.
/// Triggered before OnClientLogin.
///
public event OnNewClientDelegate OnNewClient;
@@ -191,7 +192,7 @@ namespace OpenSim.Region.Framework.Scenes
public delegate void ClientClosed(UUID clientID, Scene scene);
///
- /// Fired when a client is removed from a scene.
+ /// Fired when a client is removed from a scene whether it's a child or a root agent.
///
///
/// At the point of firing, the scene still contains the client's scene presence.
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index c887b4ed09..60fe48fe64 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2670,6 +2670,7 @@ namespace OpenSim.Region.Framework.Scenes
sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
}
+ client.SceneAgent = sp;
m_LastLogin = Util.EnvironmentTickCount();
// Cache the user's name
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 5cf478ac10..43548e673f 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
private UUID m_agentID = UUID.Random();
- public ISceneAgent SceneAgent { get; private set; }
+ public ISceneAgent SceneAgent { get; set; }
private string m_username;
private string m_nick;
@@ -895,7 +895,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
public void Start()
{
- SceneAgent = m_scene.AddNewClient(this, PresenceType.User);
+ m_scene.AddNewClient(this, PresenceType.User);
// Mimicking LLClientView which gets always set appearance from client.
AvatarAppearance appearance;
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 16ec34f62c..5ea5af74a2 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -72,7 +72,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC
get { return m_ownerID; }
}
- public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } }
+ public ISceneAgent SceneAgent { get; set; }
public void Say(string message)
{
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 455b51e595..d6e72005b5 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -327,7 +327,7 @@ namespace OpenSim.Tests.Common.Mock
///
private UUID m_agentId;
- public ISceneAgent SceneAgent { get { throw new NotImplementedException(); } }
+ public ISceneAgent SceneAgent { get; set; }
///
/// The last caps seed url that this client was given.