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.0.7.4.1
parent
c45b5a3d1c
commit
4d34763f8c
|
@ -2646,7 +2646,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (sp == null)
|
if (sp == null)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat(
|
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);
|
m_clientManager.Add(client);
|
||||||
SubscribeToClientEvents(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
|
// 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.
|
// TODO: This check should probably be in QueryAccess().
|
||||||
// That calls AddNewClient, which finally creates the ScenePresence
|
|
||||||
ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
|
ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
|
||||||
if (nearestParcel == null)
|
if (nearestParcel == null)
|
||||||
{
|
{
|
||||||
|
@ -3917,14 +3917,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int num = m_sceneGraph.GetNumberOfScenePresences();
|
// We have to wait until the viewer contacts this region after receiving EAC.
|
||||||
|
// That calls AddNewClient, which finally creates the ScenePresence
|
||||||
if (num >= RegionInfo.RegionSettings.AgentLimit)
|
|
||||||
{
|
|
||||||
if (!Permissions.IsAdministrator(cAgentData.AgentID))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
|
ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID);
|
||||||
|
|
||||||
if (childAgentUpdate != null)
|
if (childAgentUpdate != null)
|
||||||
|
@ -3968,14 +3962,28 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Poll until the requested ScenePresence appears or we timeout.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The scene presence is found, else null.</returns>
|
||||||
|
/// <param name='agentID'></param>
|
||||||
protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
|
protected virtual ScenePresence WaitGetScenePresence(UUID agentID)
|
||||||
{
|
{
|
||||||
int ntimes = 10;
|
int ntimes = 10;
|
||||||
ScenePresence childAgentUpdate = null;
|
ScenePresence sp = null;
|
||||||
while ((childAgentUpdate = GetScenePresence(agentID)) == null && (ntimes-- > 0))
|
while ((sp = GetScenePresence(agentID)) == null && (ntimes-- > 0))
|
||||||
Thread.Sleep(1000);
|
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)
|
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.
|
// child agent creation, thereby emulating the SL behavior.
|
||||||
public bool QueryAccess(UUID agentID, Vector3 position, out string reason)
|
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 (num >= RegionInfo.RegionSettings.AgentLimit)
|
||||||
{
|
{
|
||||||
if (!Permissions.IsAdministrator(agentID))
|
if (!Permissions.IsAdministrator(agentID))
|
||||||
{
|
{
|
||||||
reason = "The region is full";
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -779,11 +779,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return m_scenePresenceArray;
|
return m_scenePresenceArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int GetNumberOfScenePresences()
|
|
||||||
{
|
|
||||||
return m_scenePresenceArray.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Request a scene presence by UUID. Fast, indexed lookup.
|
/// Request a scene presence by UUID. Fast, indexed lookup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1169,6 +1169,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
|
Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
|
||||||
m_callbackURI = null;
|
m_callbackURI = null;
|
||||||
}
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
|
||||||
|
// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
|
||||||
|
// }
|
||||||
|
|
||||||
ValidateAndSendAppearanceAndAgentData();
|
ValidateAndSendAppearanceAndAgentData();
|
||||||
|
|
||||||
|
@ -2508,7 +2514,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// If we are using the the cached appearance then send it out to everyone
|
// If we are using the the cached appearance then send it out to everyone
|
||||||
if (cachedappearance)
|
if (cachedappearance)
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name);
|
m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name);
|
||||||
|
|
||||||
// If the avatars baked textures are all in the cache, then we have a
|
// If the avatars baked textures are all in the cache, then we have a
|
||||||
// complete appearance... send it out, if not, then we'll send it when
|
// complete appearance... send it out, if not, then we'll send it when
|
||||||
|
@ -2970,7 +2976,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public void ChildAgentDataUpdate(AgentData cAgentData)
|
public void ChildAgentDataUpdate(AgentData cAgentData)
|
||||||
{
|
{
|
||||||
//m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
|
// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
|
||||||
if (!IsChildAgent)
|
if (!IsChildAgent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3110,6 +3116,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_originRegionID = cAgent.RegionID;
|
m_originRegionID = cAgent.RegionID;
|
||||||
|
|
||||||
m_callbackURI = cAgent.CallbackURI;
|
m_callbackURI = cAgent.CallbackURI;
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
|
||||||
|
// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
|
||||||
|
|
||||||
m_pos = cAgent.Position;
|
m_pos = cAgent.Position;
|
||||||
m_velocity = cAgent.Velocity;
|
m_velocity = cAgent.Velocity;
|
||||||
|
|
Loading…
Reference in New Issue