From 4d34763f8c90dfe87a8a5930bf05fe36b86d15df Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 17 May 2012 23:33:26 +0100
Subject: 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.
---
OpenSim/Region/Framework/Scenes/Scene.cs | 47 ++++++++++++++++++++++----------
1 file changed, 32 insertions(+), 15 deletions(-)
(limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
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
if (sp == null)
{
m_log.DebugFormat(
- "[SCENE]: Adding new child scene presence {0} to scene {1} at pos {2}", client.Name, RegionInfo.RegionName, client.StartPos);
+ "[SCENE]: Adding new child scene presence {0} {1} to scene {2} at pos {3}",
+ client.Name, client.AgentId, RegionInfo.RegionName, client.StartPos);
m_clientManager.Add(client);
SubscribeToClientEvents(client);
@@ -3905,8 +3906,7 @@ namespace OpenSim.Region.Framework.Scenes
// XPTO: if this agent is not allowed here as root, always return false
- // We have to wait until the viewer contacts this region after receiving EAC.
- // That calls AddNewClient, which finally creates the ScenePresence
+ // TODO: This check should probably be in QueryAccess().
ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
if (nearestParcel == null)
{
@@ -3917,14 +3917,8 @@ namespace OpenSim.Region.Framework.Scenes
return false;
}
- int num = m_sceneGraph.GetNumberOfScenePresences();
-
- if (num >= RegionInfo.RegionSettings.AgentLimit)
- {
- if (!Permissions.IsAdministrator(cAgentData.AgentID))
- return false;
- }
-
+ // We have to wait until the viewer contacts this region after receiving EAC.
+ // That calls AddNewClient, which finally creates the ScenePresence
ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
if (childAgentUpdate != null)
@@ -3968,14 +3962,28 @@ namespace OpenSim.Region.Framework.Scenes
return false;
}
+ ///
+ /// Poll until the requested ScenePresence appears or we timeout.
+ ///
+ /// The scene presence is found, else null.
+ ///
protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
{
int ntimes = 10;
- ScenePresence childAgentUpdate = null;
- while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0))
+ ScenePresence sp = null;
+ while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
Thread.Sleep(1000);
- return childAgentUpdate;
+ if (sp == null)
+ m_log.WarnFormat(
+ "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
+ agentID, RegionInfo.RegionName);
+// else
+// m_log.DebugFormat(
+// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
+// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
+
+ return sp;
}
public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent)
@@ -5177,13 +5185,22 @@ namespace OpenSim.Region.Framework.Scenes
// child agent creation, thereby emulating the SL behavior.
public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
{
- int num = m_sceneGraph.GetNumberOfScenePresences();
+ // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check.
+ // However, the long term fix is to make sure root agent count is always accurate.
+ m_sceneGraph.RecalculateStats();
+
+ int num = m_sceneGraph.GetRootAgentCount();
if (num >= RegionInfo.RegionSettings.AgentLimit)
{
if (!Permissions.IsAdministrator(agentID))
{
reason = "The region is full";
+
+ m_log.DebugFormat(
+ "[SCENE]: Denying presence with id {0} entry into {1} since region is at agent limit of {2}",
+ agentID, RegionInfo.RegionName, RegionInfo.RegionSettings.AgentLimit);
+
return false;
}
}
--
cgit v1.1