diff options
author | Justin Clark-Casey (justincc) | 2012-05-17 23:33:26 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-05-17 23:33:26 +0100 |
commit | 4d34763f8c90dfe87a8a5930bf05fe36b86d15df (patch) | |
tree | 639b53816b54241e75b809c006ce77866acf3a92 | |
parent | minor: improve method doc for TestSameSimulatorSeparatedRegionsCreateAgentFai... (diff) | |
download | opensim-SC_OLD-4d34763f8c90dfe87a8a5930bf05fe36b86d15df.zip opensim-SC_OLD-4d34763f8c90dfe87a8a5930bf05fe36b86d15df.tar.gz opensim-SC_OLD-4d34763f8c90dfe87a8a5930bf05fe36b86d15df.tar.bz2 opensim-SC_OLD-4d34763f8c90dfe87a8a5930bf05fe36b86d15df.tar.xz |
Check agent limit against root agent count rather than both root and child agents
From sl docs such as http://community.secondlife.com/t5/English-Knowledge-Base/Managing-Private-Regions/ta-p/700115
agent should apply to avatars only.
This makes sense from a user perspective, and also from a code perspective since child agents with no physics or actions take up a fraction of root agent resources.
As such, the check is now only performed in Scene.QueryAccess() - cross and teleport check this before allowing an agent to translocate.
This also removes an off-by-one error that could occur in certain circumstances on teleport when a new child agent was double counted when a pre-teleport agent update was performed.
This does not affect an existing bug where limits or other QueryAccess() checks are not applied to avatars logging directly into a region.
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 47 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 13 |
3 files changed, 43 insertions, 22 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2bf3638..3cce370 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2646,7 +2646,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2646 | if (sp == null) | 2646 | if (sp == null) |
2647 | { | 2647 | { |
2648 | m_log.DebugFormat( | 2648 | m_log.DebugFormat( |
2649 | "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos); | 2649 | "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}", |
2650 | client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos); | ||
2650 | 2651 | ||
2651 | m_clientManager.Add(client); | 2652 | m_clientManager.Add(client); |
2652 | SubscribeToClientEvents(client); | 2653 | SubscribeToClientEvents(client); |
@@ -3905,8 +3906,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3905 | 3906 | ||
3906 | // XPTO: if this agent is not allowed here as root, always return false | 3907 | // XPTO: if this agent is not allowed here as root, always return false |
3907 | 3908 | ||
3908 | // We have to wait until the viewer contacts this region after receiving EAC. | 3909 | // TODO: This check should probably be in QueryAccess(). |
3909 | // That calls AddNewClient, which finally creates the ScenePresence | ||
3910 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); | 3910 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); |
3911 | if (nearestParcel == null) | 3911 | if (nearestParcel == null) |
3912 | { | 3912 | { |
@@ -3917,14 +3917,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3917 | return false; | 3917 | return false; |
3918 | } | 3918 | } |
3919 | 3919 | ||
3920 | int num = m_sceneGraph.GetNumberOfScenePresences(); | 3920 | // We have to wait until the viewer contacts this region after receiving EAC. |
3921 | 3921 | // That calls AddNewClient, which finally creates the ScenePresence | |
3922 | if (num >= RegionInfo.RegionSettings.AgentLimit) | ||
3923 | { | ||
3924 | if (!Permissions.IsAdministrator(cAgentData.AgentID)) | ||
3925 | return false; | ||
3926 | } | ||
3927 | |||
3928 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); | 3922 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); |
3929 | 3923 | ||
3930 | if (childAgentUpdate != null) | 3924 | if (childAgentUpdate != null) |
@@ -3968,14 +3962,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3968 | return false; | 3962 | return false; |
3969 | } | 3963 | } |
3970 | 3964 | ||
3965 | /// <summary> | ||
3966 | /// Poll until the requested ScenePresence appears or we timeout. | ||
3967 | /// </summary> | ||
3968 | /// <returns>The scene presence is found, else null.</returns> | ||
3969 | /// <param name='agentID'></param> | ||
3971 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) | 3970 | protected virtual ScenePresence WaitGetScenePresence(UUID agentID) |
3972 | { | 3971 | { |
3973 | int ntimes = 10; | 3972 | int ntimes = 10; |
3974 | ScenePresence childAgentUpdate = null; | 3973 | ScenePresence sp = null; |
3975 | while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0)) | 3974 | while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0)) |
3976 | Thread.Sleep(1000); | 3975 | Thread.Sleep(1000); |
3977 | return childAgentUpdate; | ||
3978 | 3976 | ||
3977 | if (sp == null) | ||
3978 | m_log.WarnFormat( | ||
3979 | "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", | ||
3980 | agentID, RegionInfo.RegionName); | ||
3981 | // else | ||
3982 | // m_log.DebugFormat( | ||
3983 | // "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits", | ||
3984 | // sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes); | ||
3985 | |||
3986 | return sp; | ||
3979 | } | 3987 | } |
3980 | 3988 | ||
3981 | public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) | 3989 | public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) |
@@ -5177,13 +5185,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
5177 | // child agent creation, thereby emulating the SL behavior. | 5185 | // child agent creation, thereby emulating the SL behavior. |
5178 | public bool QueryAccess(UUID agentID, Vector3 position, out string reason) | 5186 | public bool QueryAccess(UUID agentID, Vector3 position, out string reason) |
5179 | { | 5187 | { |
5180 | int num = m_sceneGraph.GetNumberOfScenePresences(); | 5188 | // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. |
5189 | // However, the long term fix is to make sure root agent count is always accurate. | ||
5190 | m_sceneGraph.RecalculateStats(); | ||
5191 | |||
5192 | int num = m_sceneGraph.GetRootAgentCount(); | ||
5181 | 5193 | ||
5182 | if (num >= RegionInfo.RegionSettings.AgentLimit) | 5194 | if (num >= RegionInfo.RegionSettings.AgentLimit) |
5183 | { | 5195 | { |
5184 | if (!Permissions.IsAdministrator(agentID)) | 5196 | if (!Permissions.IsAdministrator(agentID)) |
5185 | { | 5197 | { |
5186 | reason = "The region is full"; | 5198 | reason = "The region is full"; |
5199 | |||
5200 | m_log.DebugFormat( | ||
5201 | "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}", | ||
5202 | agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit); | ||
5203 | |||
5187 | return false; | 5204 | return false; |
5188 | } | 5205 | } |
5189 | } | 5206 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 4815922..ddf1550 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -779,11 +779,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
779 | return m_scenePresenceArray; | 779 | return m_scenePresenceArray; |
780 | } | 780 | } |
781 | 781 | ||
782 | public int GetNumberOfScenePresences() | ||
783 | { | ||
784 | return m_scenePresenceArray.Count; | ||
785 | } | ||
786 | |||
787 | /// <summary> | 782 | /// <summary> |
788 | /// Request a scene presence by UUID. Fast, indexed lookup. | 783 | /// Request a scene presence by UUID. Fast, indexed lookup. |
789 | /// </summary> | 784 | /// </summary> |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bdcef71..558fd9c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1169,6 +1169,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1169 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); | 1169 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); |
1170 | m_callbackURI = null; | 1170 | m_callbackURI = null; |
1171 | } | 1171 | } |
1172 | // else | ||
1173 | // { | ||
1174 | // m_log.DebugFormat( | ||
1175 | // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", | ||
1176 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); | ||
1177 | // } | ||
1172 | 1178 | ||
1173 | ValidateAndSendAppearanceAndAgentData(); | 1179 | ValidateAndSendAppearanceAndAgentData(); |
1174 | 1180 | ||
@@ -2508,7 +2514,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2508 | // If we are using the the cached appearance then send it out to everyone | 2514 | // If we are using the the cached appearance then send it out to everyone |
2509 | if (cachedappearance) | 2515 | if (cachedappearance) |
2510 | { | 2516 | { |
2511 | m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); | 2517 | m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); |
2512 | 2518 | ||
2513 | // If the avatars baked textures are all in the cache, then we have a | 2519 | // If the avatars baked textures are all in the cache, then we have a |
2514 | // complete appearance... send it out, if not, then we'll send it when | 2520 | // complete appearance... send it out, if not, then we'll send it when |
@@ -2970,7 +2976,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2970 | 2976 | ||
2971 | public void ChildAgentDataUpdate(AgentData cAgentData) | 2977 | public void ChildAgentDataUpdate(AgentData cAgentData) |
2972 | { | 2978 | { |
2973 | //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); | 2979 | // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); |
2974 | if (!IsChildAgent) | 2980 | if (!IsChildAgent) |
2975 | return; | 2981 | return; |
2976 | 2982 | ||
@@ -3110,6 +3116,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3110 | m_originRegionID = cAgent.RegionID; | 3116 | m_originRegionID = cAgent.RegionID; |
3111 | 3117 | ||
3112 | m_callbackURI = cAgent.CallbackURI; | 3118 | m_callbackURI = cAgent.CallbackURI; |
3119 | // m_log.DebugFormat( | ||
3120 | // "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", | ||
3121 | // Name, m_scene.RegionInfo.RegionName, m_callbackURI); | ||
3113 | 3122 | ||
3114 | m_pos = cAgent.Position; | 3123 | m_pos = cAgent.Position; |
3115 | m_velocity = cAgent.Velocity; | 3124 | m_velocity = cAgent.Velocity; |