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 /OpenSim/Region/Framework/Scenes/Scene.cs | |
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.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 47 |
1 files changed, 32 insertions, 15 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 | } |