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.