aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs823
1 files changed, 529 insertions, 294 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index b189599..55766cf 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -151,7 +151,7 @@ namespace OpenSim.Region.Framework.Scenes
151 public SynchronizeSceneHandler SynchronizeScene; 151 public SynchronizeSceneHandler SynchronizeScene;
152 152
153 /// <summary> 153 /// <summary>
154 /// Used to prevent simultaneous calls to RemoveClient() for the same agent from interfering with each other. 154 /// Used to prevent simultaneous calls to code that adds and removes agents.
155 /// </summary> 155 /// </summary>
156 private object m_removeClientLock = new object(); 156 private object m_removeClientLock = new object();
157 157
@@ -230,6 +230,8 @@ namespace OpenSim.Region.Framework.Scenes
230 public bool m_seeIntoBannedRegion = false; 230 public bool m_seeIntoBannedRegion = false;
231 public int MaxUndoCount = 5; 231 public int MaxUndoCount = 5;
232 232
233 public bool SeeIntoRegion { get; set; }
234
233 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet; 235 // Using this for RegionReady module to prevent LoginsDisabled from changing under our feet;
234 public bool LoginLock = false; 236 public bool LoginLock = false;
235 237
@@ -396,10 +398,12 @@ namespace OpenSim.Region.Framework.Scenes
396 if (value) 398 if (value)
397 { 399 {
398 if (!m_active) 400 if (!m_active)
399 Start(); 401 Start(false);
400 } 402 }
401 else 403 else
402 { 404 {
405 // This appears assymetric with Start() above but is not - setting m_active = false stops the loops
406 // XXX: Possibly this should be in an explicit Stop() method for symmetry.
403 m_active = false; 407 m_active = false;
404 } 408 }
405 } 409 }
@@ -747,6 +751,7 @@ namespace OpenSim.Region.Framework.Scenes
747 m_config = config; 751 m_config = config;
748 MinFrameTime = 0.089f; 752 MinFrameTime = 0.089f;
749 MinMaintenanceTime = 1; 753 MinMaintenanceTime = 1;
754 SeeIntoRegion = true;
750 755
751 Random random = new Random(); 756 Random random = new Random();
752 757
@@ -859,9 +864,12 @@ namespace OpenSim.Region.Framework.Scenes
859 //Animation states 864 //Animation states
860 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 865 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
861 866
867 SeeIntoRegion = startupConfig.GetBoolean("see_into_region", SeeIntoRegion);
868
869 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
870
862 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 871 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
863 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 872 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
864
865 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); 873 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
866 if (RegionInfo.NonphysPrimMin > 0) 874 if (RegionInfo.NonphysPrimMin > 0)
867 { 875 {
@@ -1332,7 +1340,7 @@ namespace OpenSim.Region.Framework.Scenes
1332 Thread.Sleep(500); 1340 Thread.Sleep(500);
1333 1341
1334 // Stop all client threads. 1342 // Stop all client threads.
1335 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); 1343 ForEachScenePresence(delegate(ScenePresence avatar) { CloseAgent(avatar.UUID, false); });
1336 1344
1337 m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); 1345 m_log.Debug("[SCENE]: TriggerSceneShuttingDown");
1338 EventManager.TriggerSceneShuttingDown(this); 1346 EventManager.TriggerSceneShuttingDown(this);
@@ -1361,10 +1369,18 @@ namespace OpenSim.Region.Framework.Scenes
1361 } 1369 }
1362 } 1370 }
1363 1371
1372 public override void Start()
1373 {
1374 Start(true);
1375 }
1376
1364 /// <summary> 1377 /// <summary>
1365 /// Start the scene 1378 /// Start the scene
1366 /// </summary> 1379 /// </summary>
1367 public void Start() 1380 /// <param name='startScripts'>
1381 /// Start the scripts within the scene.
1382 /// </param>
1383 public void Start(bool startScripts)
1368 { 1384 {
1369 m_active = true; 1385 m_active = true;
1370 1386
@@ -1401,6 +1417,8 @@ namespace OpenSim.Region.Framework.Scenes
1401 m_heartbeatThread 1417 m_heartbeatThread
1402 = Watchdog.StartThread( 1418 = Watchdog.StartThread(
1403 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); 1419 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
1420
1421 StartScripts();
1404 } 1422 }
1405 1423
1406 /// <summary> 1424 /// <summary>
@@ -1557,6 +1575,8 @@ namespace OpenSim.Region.Framework.Scenes
1557 1575
1558 try 1576 try
1559 { 1577 {
1578 EventManager.TriggerRegionHeartbeatStart(this);
1579
1560 // Apply taints in terrain module to terrain in physics scene 1580 // Apply taints in terrain module to terrain in physics scene
1561 if (Frame % m_update_terrain == 0) 1581 if (Frame % m_update_terrain == 0)
1562 { 1582 {
@@ -1996,6 +2016,11 @@ namespace OpenSim.Region.Framework.Scenes
1996 2016
1997 GridRegion region = new GridRegion(RegionInfo); 2017 GridRegion region = new GridRegion(RegionInfo);
1998 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); 2018 string error = GridService.RegisterRegion(RegionInfo.ScopeID, region);
2019 m_log.DebugFormat("{0} RegisterRegionWithGrid. name={1},id={2},loc=<{3},{4}>,size=<{5},{6}>",
2020 LogHeader, m_regionName,
2021 RegionInfo.RegionID,
2022 RegionInfo.RegionLocX, RegionInfo.RegionLocY,
2023 RegionInfo.RegionSizeX, RegionInfo.RegionSizeY);
1999 if (error != String.Empty) 2024 if (error != String.Empty)
2000 throw new Exception(error); 2025 throw new Exception(error);
2001 } 2026 }
@@ -2935,14 +2960,15 @@ namespace OpenSim.Region.Framework.Scenes
2935 2960
2936 #region Add/Remove Avatar Methods 2961 #region Add/Remove Avatar Methods
2937 2962
2938 public override ISceneAgent AddNewClient(IClientAPI client, PresenceType type) 2963 public override ISceneAgent AddNewAgent(IClientAPI client, PresenceType type)
2939 { 2964 {
2940 ScenePresence sp; 2965 ScenePresence sp;
2941 bool vialogin; 2966 bool vialogin;
2967 bool reallyNew = true;
2942 2968
2943 // Validation occurs in LLUDPServer 2969 // Validation occurs in LLUDPServer
2944 // 2970 //
2945 // XXX: A race condition exists here where two simultaneous calls to AddNewClient can interfere with 2971 // XXX: A race condition exists here where two simultaneous calls to AddNewAgent can interfere with
2946 // each other. In practice, this does not currently occur in the code. 2972 // each other. In practice, this does not currently occur in the code.
2947 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode); 2973 AgentCircuitData aCircuit = m_authenticateHandler.GetAgentCircuitData(client.CircuitCode);
2948 2974
@@ -2950,9 +2976,9 @@ namespace OpenSim.Region.Framework.Scenes
2950 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point 2976 // and a simultaneous one that removes it (as can happen if the client is closed at a particular point
2951 // whilst connecting). 2977 // whilst connecting).
2952 // 2978 //
2953 // It would be easier to lock across all NewUserConnection(), AddNewClient() and 2979 // It would be easier to lock across all NewUserConnection(), AddNewAgent() and
2954 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service 2980 // RemoveClient() calls for all agents, but this would allow a slow call (e.g. because of slow service
2955 // response in some module listening to AddNewClient()) from holding up unrelated agent calls. 2981 // response in some module listening to AddNewAgent()) from holding up unrelated agent calls.
2956 // 2982 //
2957 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all 2983 // In practice, the lock (this) in LLUDPServer.AddNewClient() currently lock across all
2958 // AddNewClient() operations (though not other ops). 2984 // AddNewClient() operations (though not other ops).
@@ -2969,7 +2995,7 @@ namespace OpenSim.Region.Framework.Scenes
2969 2995
2970 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this 2996 // XXX: Not sure how good it is to add a new client if a scene presence already exists. Possibly this
2971 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause 2997 // could occur if a viewer crashes and relogs before the old client is kicked out. But this could cause
2972 // other problems, and possible the code calling AddNewClient() should ensure that no client is already 2998 // other problems, and possibly the code calling AddNewAgent() should ensure that no client is already
2973 // connected. 2999 // connected.
2974 if (sp == null) 3000 if (sp == null)
2975 { 3001 {
@@ -2997,16 +3023,24 @@ namespace OpenSim.Region.Framework.Scenes
2997 m_log.WarnFormat( 3023 m_log.WarnFormat(
2998 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 3024 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence",
2999 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName); 3025 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
3026 reallyNew = false;
3000 } 3027 }
3001 3028
3002 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3029 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
3003 // client is for a root or child agent. 3030 // client is for a root or child agent.
3031 // XXX: This may be better set for a new client before that client is added to the client manager.
3032 // But need to know what happens in the case where a ScenePresence is already present (and if this
3033 // actually occurs).
3004 client.SceneAgent = sp; 3034 client.SceneAgent = sp;
3005 3035
3006 // Cache the user's name 3036 // This is currently also being done earlier in NewUserConnection for real users to see if this
3037 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
3038 // places. However, we still need to do it here for NPCs.
3007 CacheUserName(sp, aCircuit); 3039 CacheUserName(sp, aCircuit);
3008 3040
3009 EventManager.TriggerOnNewClient(client); 3041 if (reallyNew)
3042 EventManager.TriggerOnNewClient(client);
3043
3010 if (vialogin) 3044 if (vialogin)
3011 EventManager.TriggerOnClientLogin(client); 3045 EventManager.TriggerOnClientLogin(client);
3012 } 3046 }
@@ -3027,7 +3061,7 @@ namespace OpenSim.Region.Framework.Scenes
3027 { 3061 {
3028 string first = aCircuit.firstname, last = aCircuit.lastname; 3062 string first = aCircuit.firstname, last = aCircuit.lastname;
3029 3063
3030 if (sp.PresenceType == PresenceType.Npc) 3064 if (sp != null && sp.PresenceType == PresenceType.Npc)
3031 { 3065 {
3032 UserManagementModule.AddUser(aCircuit.AgentID, first, last); 3066 UserManagementModule.AddUser(aCircuit.AgentID, first, last);
3033 } 3067 }
@@ -3105,7 +3139,8 @@ namespace OpenSim.Region.Framework.Scenes
3105 if (sp != null) 3139 if (sp != null)
3106 { 3140 {
3107 PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 3141 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
3108 sp.ControllingClient.Close(); 3142
3143 CloseAgent(sp.UUID, false);
3109 } 3144 }
3110 3145
3111 // BANG! SLASH! 3146 // BANG! SLASH!
@@ -3244,8 +3279,6 @@ namespace OpenSim.Region.Framework.Scenes
3244 { 3279 {
3245 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 3280 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
3246 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 3281 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
3247 client.OnSetStartLocationRequest += SetHomeRezPoint;
3248 client.OnRegionHandleRequest += RegionHandleRequest;
3249 } 3282 }
3250 3283
3251 public virtual void SubscribeToClientNetworkEvents(IClientAPI client) 3284 public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
@@ -3371,8 +3404,6 @@ namespace OpenSim.Region.Framework.Scenes
3371 { 3404 {
3372 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; 3405 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
3373 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 3406 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
3374 client.OnSetStartLocationRequest -= SetHomeRezPoint;
3375 client.OnRegionHandleRequest -= RegionHandleRequest;
3376 } 3407 }
3377 3408
3378 public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client) 3409 public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
@@ -3498,33 +3529,6 @@ namespace OpenSim.Region.Framework.Scenes
3498 } 3529 }
3499 3530
3500 /// <summary> 3531 /// <summary>
3501 /// Sets the Home Point. The LoginService uses this to know where to put a user when they log-in
3502 /// </summary>
3503 /// <param name="remoteClient"></param>
3504 /// <param name="regionHandle"></param>
3505 /// <param name="position"></param>
3506 /// <param name="lookAt"></param>
3507 /// <param name="flags"></param>
3508 public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags)
3509 {
3510 //Add half the avatar's height so that the user doesn't fall through prims
3511 ScenePresence presence;
3512 if (TryGetScenePresence(remoteClient.AgentId, out presence))
3513 {
3514 if (presence.Appearance != null)
3515 {
3516 position.Z = position.Z + (presence.Appearance.AvatarHeight / 2);
3517 }
3518 }
3519
3520 if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt))
3521 // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot.
3522 m_dialogModule.SendAlertToUser(remoteClient, "Home position set.");
3523 else
3524 m_dialogModule.SendAlertToUser(remoteClient, "Set Home request Failed.");
3525 }
3526
3527 /// <summary>
3528 /// Get the avatar apperance for the given client. 3532 /// Get the avatar apperance for the given client.
3529 /// </summary> 3533 /// </summary>
3530 /// <param name="client"></param> 3534 /// <param name="client"></param>
@@ -3548,63 +3552,69 @@ namespace OpenSim.Region.Framework.Scenes
3548 } 3552 }
3549 } 3553 }
3550 3554
3551 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3555 /// <summary>
3556 /// Remove the given client from the scene.
3557 /// </summary>
3558 /// <remarks>
3559 /// Only clientstack code should call this directly. All other code should call IncomingCloseAgent() instead
3560 /// to properly operate the state machine and avoid race conditions with other close requests (such as directly
3561 /// from viewers).
3562 /// </remarks>
3563 /// <param name='agentID'>ID of agent to close</param>
3564 /// <param name='closeChildAgents'>
3565 /// Close the neighbour child agents associated with this client.
3566 /// </param>
3567 public void RemoveClient(UUID agentID, bool closeChildAgents)
3552 { 3568 {
3553// CheckHeartbeat(); 3569 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3554 bool isChildAgent = false;
3555 AgentCircuitData acd;
3556 3570
3557 lock (m_removeClientLock) 3571 // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3572 // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3573 // However, will keep for now just in case.
3574 if (acd == null)
3558 { 3575 {
3559 acd = m_authenticateHandler.GetAgentCircuitData(agentID); 3576 m_log.ErrorFormat(
3577 "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name);
3560 3578
3561 if (acd == null) 3579 return;
3562 { 3580 }
3563 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID); 3581 else
3564 return; 3582 {
3565 } 3583 m_authenticateHandler.RemoveCircuit(agentID);
3566 else
3567 {
3568 // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred
3569 // simultaneously.
3570 // We also need to remove by agent ID since NPCs will have no circuit code.
3571 m_authenticateHandler.RemoveCircuit(agentID);
3572 }
3573 } 3584 }
3574 3585
3586 // TODO: Can we now remove this lock?
3575 lock (acd) 3587 lock (acd)
3576 { 3588 {
3589 bool isChildAgent = false;
3590
3577 ScenePresence avatar = GetScenePresence(agentID); 3591 ScenePresence avatar = GetScenePresence(agentID);
3578 3592
3593 // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3594 // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3595 // However, will keep for now just in case.
3579 if (avatar == null) 3596 if (avatar == null)
3580 { 3597 {
3581 m_log.WarnFormat( 3598 m_log.ErrorFormat(
3582 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); 3599 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3583 3600
3584 return; 3601 return;
3585 } 3602 }
3586 3603
3587 try 3604 try
3588 { 3605 {
3589 isChildAgent = avatar.IsChildAgent; 3606 isChildAgent = avatar.IsChildAgent;
3590 3607
3591 m_log.DebugFormat( 3608 m_log.DebugFormat(
3592 "[SCENE]: Removing {0} agent {1} {2} from {3}", 3609 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3593 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); 3610 isChildAgent ? "child" : "root", avatar.Name, agentID, Name);
3594 3611
3595 // Don't do this to root agents, it's not nice for the viewer 3612 // Don't do this to root agents, it's not nice for the viewer
3596 if (closeChildAgents && isChildAgent) 3613 if (closeChildAgents && isChildAgent)
3597 { 3614 {
3598 // Tell a single agent to disconnect from the region. 3615 // Tell a single agent to disconnect from the region.
3599 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3616 // Let's do this via UDP
3600 if (eq != null) 3617 avatar.ControllingClient.SendShutdownConnectionNotice();
3601 {
3602 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3603 }
3604 else
3605 {
3606 avatar.ControllingClient.SendShutdownConnectionNotice();
3607 }
3608 } 3618 }
3609 3619
3610 // Only applies to root agents. 3620 // Only applies to root agents.
@@ -3620,16 +3630,13 @@ namespace OpenSim.Region.Framework.Scenes
3620 if (closeChildAgents && CapsModule != null) 3630 if (closeChildAgents && CapsModule != null)
3621 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode); 3631 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
3622 3632
3623// // REFACTORING PROBLEM -- well not really a problem, but just to point out that whatever
3624// // this method is doing is HORRIBLE!!!
3625 // Commented pending deletion since this method no longer appears to do anything at all
3626// avatar.Scene.NeedSceneCacheClear(avatar.UUID);
3627
3628 if (closeChildAgents && !isChildAgent) 3633 if (closeChildAgents && !isChildAgent)
3629 { 3634 {
3630 List<ulong> regions = avatar.KnownRegionHandles; 3635 List<ulong> regions = avatar.KnownRegionHandles;
3631 regions.Remove(RegionInfo.RegionHandle); 3636 regions.Remove(RegionInfo.RegionHandle);
3632 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3637
3638 // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
3639 m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions);
3633 } 3640 }
3634 3641
3635 m_eventManager.TriggerClientClosed(agentID, this); 3642 m_eventManager.TriggerClientClosed(agentID, this);
@@ -3646,7 +3653,7 @@ namespace OpenSim.Region.Framework.Scenes
3646 delegate(IClientAPI client) 3653 delegate(IClientAPI client)
3647 { 3654 {
3648 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3655 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway
3649 try { client.SendKillObject(avatar.RegionHandle, new List<uint> { avatar.LocalId }); } 3656 try { client.SendKillObject(new List<uint> { avatar.LocalId }); }
3650 catch (NullReferenceException) { } 3657 catch (NullReferenceException) { }
3651 }); 3658 });
3652 } 3659 }
@@ -3727,7 +3734,8 @@ namespace OpenSim.Region.Framework.Scenes
3727 } 3734 }
3728 deleteIDs.Add(localID); 3735 deleteIDs.Add(localID);
3729 } 3736 }
3730 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); }); 3737
3738 ForEachClient(c => c.SendKillObject(deleteIDs));
3731 } 3739 }
3732 3740
3733 #endregion 3741 #endregion
@@ -3763,13 +3771,13 @@ namespace OpenSim.Region.Framework.Scenes
3763 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of 3771 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3764 /// the LLUDP stack). 3772 /// the LLUDP stack).
3765 /// </remarks> 3773 /// </remarks>
3766 /// <param name="agent">CircuitData of the agent who is connecting</param> 3774 /// <param name="acd">CircuitData of the agent who is connecting</param>
3767 /// <param name="reason">Outputs the reason for the false response on this string</param> 3775 /// <param name="reason">Outputs the reason for the false response on this string</param>
3768 /// <param name="requirePresenceLookup">True for normal presence. False for NPC 3776 /// <param name="requirePresenceLookup">True for normal presence. False for NPC
3769 /// or other applications where a full grid/Hypergrid presence may not be required.</param> 3777 /// or other applications where a full grid/Hypergrid presence may not be required.</param>
3770 /// <returns>True if the region accepts this agent. False if it does not. False will 3778 /// <returns>True if the region accepts this agent. False if it does not. False will
3771 /// also return a reason.</returns> 3779 /// also return a reason.</returns>
3772 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) 3780 public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, out string reason, bool requirePresenceLookup)
3773 { 3781 {
3774 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || 3782 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
3775 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); 3783 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
@@ -3789,15 +3797,15 @@ namespace OpenSim.Region.Framework.Scenes
3789 m_log.DebugFormat( 3797 m_log.DebugFormat(
3790 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", 3798 "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})",
3791 RegionInfo.RegionName, 3799 RegionInfo.RegionName,
3792 (agent.child ? "child" : "root"), 3800 (acd.child ? "child" : "root"),
3793 agent.firstname, 3801 acd.firstname,
3794 agent.lastname, 3802 acd.lastname,
3795 agent.AgentID, 3803 acd.AgentID,
3796 agent.circuitcode, 3804 acd.circuitcode,
3797 agent.IPAddress, 3805 acd.IPAddress,
3798 agent.Viewer, 3806 acd.Viewer,
3799 ((TPFlags)teleportFlags).ToString(), 3807 ((TPFlags)teleportFlags).ToString(),
3800 agent.startpos 3808 acd.startpos
3801 ); 3809 );
3802 3810
3803 if (!LoginsEnabled) 3811 if (!LoginsEnabled)
@@ -3815,7 +3823,7 @@ namespace OpenSim.Region.Framework.Scenes
3815 { 3823 {
3816 foreach (string viewer in m_AllowedViewers) 3824 foreach (string viewer in m_AllowedViewers)
3817 { 3825 {
3818 if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) 3826 if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower())
3819 { 3827 {
3820 ViewerDenied = false; 3828 ViewerDenied = false;
3821 break; 3829 break;
@@ -3832,7 +3840,7 @@ namespace OpenSim.Region.Framework.Scenes
3832 { 3840 {
3833 foreach (string viewer in m_BannedViewers) 3841 foreach (string viewer in m_BannedViewers)
3834 { 3842 {
3835 if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) 3843 if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower())
3836 { 3844 {
3837 ViewerDenied = true; 3845 ViewerDenied = true;
3838 break; 3846 break;
@@ -3844,54 +3852,129 @@ namespace OpenSim.Region.Framework.Scenes
3844 { 3852 {
3845 m_log.DebugFormat( 3853 m_log.DebugFormat(
3846 "[SCENE]: Access denied for {0} {1} using {2}", 3854 "[SCENE]: Access denied for {0} {1} using {2}",
3847 agent.firstname, agent.lastname, agent.Viewer); 3855 acd.firstname, acd.lastname, acd.Viewer);
3848 reason = "Access denied, your viewer is banned by the region owner"; 3856 reason = "Access denied, your viewer is banned by the region owner";
3849 return false; 3857 return false;
3850 } 3858 }
3851 3859
3852 ScenePresence sp = GetScenePresence(agent.AgentID); 3860 ILandObject land;
3861 ScenePresence sp;
3853 3862
3854 // If we have noo presence here or if that presence is a zombie root 3863 lock (m_removeClientLock)
3855 // presence that will be kicled, we need a new CAPS object.
3856 if (sp == null || (sp != null && !sp.IsChildAgent))
3857 { 3864 {
3858 if (CapsModule != null) 3865 sp = GetScenePresence(acd.AgentID);
3866
3867 // We need to ensure that we are not already removing the scene presence before we ask it not to be
3868 // closed.
3869 if (sp != null && sp.IsChildAgent
3870 && (sp.LifecycleState == ScenePresenceState.Running
3871 || sp.LifecycleState == ScenePresenceState.PreRemove))
3859 { 3872 {
3860 lock (agent) 3873 m_log.DebugFormat(
3874 "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}",
3875 sp.Name, sp.LifecycleState, Name);
3876
3877 // In the case where, for example, an A B C D region layout, an avatar may
3878 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
3879 // renews the lease on the child agent at B, we must make sure that the close from A does not succeed.
3880 //
3881 // XXX: In the end, this should not be necessary if child agents are closed without delay on
3882 // teleport, since realistically, the close request should always be processed before any other
3883 // region tried to re-establish a child agent. This is much simpler since the logic below is
3884 // vulnerable to an issue when a viewer quits a region without sending a proper logout but then
3885 // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport
3886 // flag when no teleport had taken place (and hence no close was going to come).
3887// if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle))
3888// {
3889// m_log.DebugFormat(
3890// "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
3891// sp.Name, Name);
3892//
3893// sp.DoNotCloseAfterTeleport = true;
3894// }
3895// else if (EntityTransferModule.IsInTransit(sp.UUID))
3896
3897 sp.LifecycleState = ScenePresenceState.Running;
3898
3899 if (EntityTransferModule.IsInTransit(sp.UUID))
3861 { 3900 {
3862 CapsModule.SetAgentCapsSeeds(agent); 3901 sp.DoNotCloseAfterTeleport = true;
3863 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); 3902
3903 m_log.DebugFormat(
3904 "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.",
3905 sp.Name, Name);
3864 } 3906 }
3865 } 3907 }
3866 } 3908 }
3867 3909
3910 // Need to poll here in case we are currently deleting an sp. Letting threads run over each other will
3911 // allow unpredictable things to happen.
3868 if (sp != null) 3912 if (sp != null)
3869 { 3913 {
3870 if (!sp.IsChildAgent) 3914 const int polls = 10;
3915 const int pollInterval = 1000;
3916 int pollsLeft = polls;
3917
3918 while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0)
3919 Thread.Sleep(pollInterval);
3920
3921 if (sp.LifecycleState == ScenePresenceState.Removing)
3871 { 3922 {
3872 // We have a zombie from a crashed session.
3873 // Or the same user is trying to be root twice here, won't work.
3874 // Kill it.
3875 m_log.WarnFormat( 3923 m_log.WarnFormat(
3876 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3924 "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.",
3877 sp.Name, sp.UUID, RegionInfo.RegionName); 3925 sp.Name, Name, polls * pollInterval / 1000);
3878 3926
3879 sp.ControllingClient.Close(true, true); 3927 return false;
3880 sp = null; 3928 }
3929 else if (polls != pollsLeft)
3930 {
3931 m_log.DebugFormat(
3932 "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.",
3933 sp.Name, Name, polls * pollInterval / 1000);
3881 } 3934 }
3882 } 3935 }
3883 3936
3884 lock (agent) 3937 // TODO: can we remove this lock?
3938 lock (acd)
3885 { 3939 {
3886 //On login test land permisions 3940 if (sp != null && !sp.IsChildAgent)
3941 {
3942 // We have a root agent. Is it in transit?
3943 if (!EntityTransferModule.IsInTransit(sp.UUID))
3944 {
3945 // We have a zombie from a crashed session.
3946 // Or the same user is trying to be root twice here, won't work.
3947 // Kill it.
3948 m_log.WarnFormat(
3949 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3950 sp.Name, sp.UUID, RegionInfo.RegionName);
3951
3952 if (sp.ControllingClient != null)
3953 CloseAgent(sp.UUID, true);
3954
3955 sp = null;
3956 }
3957 //else
3958 // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
3959 }
3960
3961 // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
3962 // We need the circuit data here for some of the subsequent checks. (groups, for example)
3963 // If the checks fail, we remove the circuit.
3964 acd.teleportFlags = teleportFlags;
3965 m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd);
3966
3967 land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y);
3968
3969 // On login test land permisions
3887 if (vialogin) 3970 if (vialogin)
3888 { 3971 {
3889 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3972 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3890 if (cache != null) 3973 if (cache != null)
3891 cache.Remove(agent.firstname + " " + agent.lastname); 3974 cache.Remove(acd.firstname + " " + acd.lastname);
3892 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) 3975 if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y))
3893 { 3976 {
3894 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3977 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3895 return false; 3978 return false;
3896 } 3979 }
3897 } 3980 }
@@ -3902,84 +3985,97 @@ namespace OpenSim.Region.Framework.Scenes
3902 { 3985 {
3903 try 3986 try
3904 { 3987 {
3905 if (!VerifyUserPresence(agent, out reason)) 3988 if (!VerifyUserPresence(acd, out reason))
3989 {
3990 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3906 return false; 3991 return false;
3907 } catch (Exception e) 3992 }
3993 }
3994 catch (Exception e)
3908 { 3995 {
3909 m_log.ErrorFormat( 3996 m_log.ErrorFormat(
3910 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3997 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3998
3999 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3911 return false; 4000 return false;
3912 } 4001 }
3913 } 4002 }
3914 4003
3915 try 4004 try
3916 { 4005 {
3917 // Always check estate if this is a login. Always 4006 if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason))
3918 // check if banned regions are to be blacked out.
3919 if (vialogin || (!m_seeIntoBannedRegion))
3920 { 4007 {
3921 if (!AuthorizeUser(agent, out reason)) 4008 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3922 { 4009 return false;
3923 return false;
3924 }
3925 } 4010 }
3926 } 4011 }
3927 catch (Exception e) 4012 catch (Exception e)
3928 { 4013 {
3929 m_log.ErrorFormat( 4014 m_log.ErrorFormat(
3930 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 4015 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
4016
4017 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3931 return false; 4018 return false;
3932 } 4019 }
3933 4020
3934 m_log.InfoFormat( 4021 m_log.InfoFormat(
3935 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", 4022 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})",
3936 RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, 4023 Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname,
3937 agent.AgentID, agent.circuitcode); 4024 acd.AgentID, acd.circuitcode);
3938 4025
4026 if (CapsModule != null)
4027 {
4028 CapsModule.SetAgentCapsSeeds(acd);
4029 CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4030 }
3939 } 4031 }
3940 else 4032 else
3941 { 4033 {
3942 // Let the SP know how we got here. This has a lot of interesting 4034 // Let the SP know how we got here. This has a lot of interesting
3943 // uses down the line. 4035 // uses down the line.
3944 sp.TeleportFlags = (TPFlags)teleportFlags; 4036 sp.TeleportFlags = (TPFlags)teleportFlags;
3945 4037
3946 if (sp.IsChildAgent) 4038 if (sp.IsChildAgent)
3947 { 4039 {
3948 m_log.DebugFormat( 4040 m_log.DebugFormat(
3949 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", 4041 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3950 agent.AgentID, RegionInfo.RegionName); 4042 acd.AgentID, RegionInfo.RegionName);
3951 4043
3952 sp.AdjustKnownSeeds(); 4044 sp.AdjustKnownSeeds();
3953 4045
3954 if (CapsModule != null) 4046 if (CapsModule != null)
3955 CapsModule.SetAgentCapsSeeds(agent); 4047 {
4048 CapsModule.SetAgentCapsSeeds(acd);
4049 CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4050 }
3956 } 4051 }
3957 } 4052 }
3958 }
3959 4053
3960 // In all cases, add or update the circuit data with the new agent circuit data and teleport flags 4054 // Try caching an incoming user name much earlier on to see if this helps with an issue
3961 agent.teleportFlags = teleportFlags; 4055 // where HG users are occasionally seen by others as "Unknown User" because their UUIDName
3962 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 4056 // request for the HG avatar appears to trigger before the user name is cached.
4057 CacheUserName(null, acd);
4058 }
3963 4059
3964 if (CapsModule != null) 4060 if (CapsModule != null)
3965 { 4061 {
3966 CapsModule.ActivateCaps(agent.circuitcode); 4062 CapsModule.ActivateCaps(acd.circuitcode);
3967 } 4063 }
3968 4064
3969 if (vialogin) 4065 if (vialogin)
3970 { 4066 {
3971// CleanDroppedAttachments(); 4067// CleanDroppedAttachments();
3972 4068
3973 if (TestBorderCross(agent.startpos, Cardinals.E)) 4069 if (TestBorderCross(acd.startpos, Cardinals.E))
3974 { 4070 {
3975 Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); 4071 Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E);
3976 agent.startpos.X = crossedBorder.BorderLine.Z - 1; 4072 acd.startpos.X = crossedBorder.BorderLine.Z - 1;
3977 } 4073 }
3978 4074
3979 if (TestBorderCross(agent.startpos, Cardinals.N)) 4075 if (TestBorderCross(acd.startpos, Cardinals.N))
3980 { 4076 {
3981 Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N); 4077 Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N);
3982 agent.startpos.Y = crossedBorder.BorderLine.Z - 1; 4078 acd.startpos.Y = crossedBorder.BorderLine.Z - 1;
3983 } 4079 }
3984 4080
3985 //Mitigate http://opensimulator.org/mantis/view.php?id=3522 4081 //Mitigate http://opensimulator.org/mantis/view.php?id=3522
@@ -3989,68 +4085,88 @@ namespace OpenSim.Region.Framework.Scenes
3989 { 4085 {
3990 lock (EastBorders) 4086 lock (EastBorders)
3991 { 4087 {
3992 if (agent.startpos.X > EastBorders[0].BorderLine.Z) 4088 if (acd.startpos.X > EastBorders[0].BorderLine.Z)
3993 { 4089 {
3994 m_log.Warn("FIX AGENT POSITION"); 4090 m_log.Warn("FIX AGENT POSITION");
3995 agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; 4091 acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
3996 if (agent.startpos.Z > 720) 4092 if (acd.startpos.Z > 720)
3997 agent.startpos.Z = 720; 4093 acd.startpos.Z = 720;
3998 } 4094 }
3999 } 4095 }
4000 lock (NorthBorders) 4096 lock (NorthBorders)
4001 { 4097 {
4002 if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) 4098 if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
4003 { 4099 {
4004 m_log.Warn("FIX Agent POSITION"); 4100 m_log.Warn("FIX Agent POSITION");
4005 agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; 4101 acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
4006 if (agent.startpos.Z > 720) 4102 if (acd.startpos.Z > 720)
4007 agent.startpos.Z = 720; 4103 acd.startpos.Z = 720;
4008 } 4104 }
4009 } 4105 }
4010 } else 4106 } else
4011 { 4107 {
4012 if (agent.startpos.X > EastBorders[0].BorderLine.Z) 4108 if (acd.startpos.X > EastBorders[0].BorderLine.Z)
4013 { 4109 {
4014 m_log.Warn("FIX AGENT POSITION"); 4110 m_log.Warn("FIX AGENT POSITION");
4015 agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; 4111 acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
4016 if (agent.startpos.Z > 720) 4112 if (acd.startpos.Z > 720)
4017 agent.startpos.Z = 720; 4113 acd.startpos.Z = 720;
4018 } 4114 }
4019 if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) 4115 if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
4020 { 4116 {
4021 m_log.Warn("FIX Agent POSITION"); 4117 m_log.Warn("FIX Agent POSITION");
4022 agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; 4118 acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
4023 if (agent.startpos.Z > 720) 4119 if (acd.startpos.Z > 720)
4024 agent.startpos.Z = 720; 4120 acd.startpos.Z = 720;
4025 } 4121 }
4026 } 4122 }
4027 4123
4124// m_log.DebugFormat(
4125// "[SCENE]: Found telehub object {0} for new user connection {1} to {2}",
4126// RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
4127
4028 // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags 4128 // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags
4029 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && 4129 if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero &&
4030 RegionInfo.EstateSettings.AllowDirectTeleport == false && 4130 RegionInfo.EstateSettings.AllowDirectTeleport == false &&
4031 !viahome && !godlike) 4131 !viahome && !godlike)
4032 { 4132 {
4033 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); 4133 SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject);
4034 // Can have multiple SpawnPoints 4134
4035 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); 4135 if (telehub != null)
4036 if (spawnpoints.Count > 1)
4037 { 4136 {
4038 // We have multiple SpawnPoints, Route the agent to a random or sequential one 4137 // Can have multiple SpawnPoints
4039 if (SpawnPointRouting == "random") 4138 List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints();
4040 agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( 4139 if (spawnpoints.Count > 1)
4041 telehub.AbsolutePosition, 4140 {
4042 telehub.GroupRotation 4141 // We have multiple SpawnPoints, Route the agent to a random or sequential one
4043 ); 4142 if (SpawnPointRouting == "random")
4143 acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
4144 telehub.AbsolutePosition,
4145 telehub.GroupRotation
4146 );
4147 else
4148 acd.startpos = spawnpoints[SpawnPoint()].GetLocation(
4149 telehub.AbsolutePosition,
4150 telehub.GroupRotation
4151 );
4152 }
4153 else if (spawnpoints.Count == 1)
4154 {
4155 // We have a single SpawnPoint and will route the agent to it
4156 acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4157 }
4044 else 4158 else
4045 agent.startpos = spawnpoints[SpawnPoint()].GetLocation( 4159 {
4046 telehub.AbsolutePosition, 4160 m_log.DebugFormat(
4047 telehub.GroupRotation 4161 "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.",
4048 ); 4162 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
4163 }
4049 } 4164 }
4050 else 4165 else
4051 { 4166 {
4052 // We have a single SpawnPoint and will route the agent to it 4167 m_log.DebugFormat(
4053 agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4168 "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.",
4169 RegionInfo.RegionSettings.TelehubObject, acd.Name, Name);
4054 } 4170 }
4055 4171
4056 return true; 4172 return true;
@@ -4063,7 +4179,7 @@ namespace OpenSim.Region.Framework.Scenes
4063 { 4179 {
4064 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 4180 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
4065 { 4181 {
4066 agent.startpos = land.LandData.UserLocation; 4182 acd.startpos = land.LandData.UserLocation;
4067 } 4183 }
4068 } 4184 }
4069 */// This is now handled properly in ScenePresence.MakeRootAgent 4185 */// This is now handled properly in ScenePresence.MakeRootAgent
@@ -4158,7 +4274,7 @@ namespace OpenSim.Region.Framework.Scenes
4158 /// <param name="reason">outputs the reason to this string</param> 4274 /// <param name="reason">outputs the reason to this string</param>
4159 /// <returns>True if the region accepts this agent. False if it does not. False will 4275 /// <returns>True if the region accepts this agent. False if it does not. False will
4160 /// also return a reason.</returns> 4276 /// also return a reason.</returns>
4161 protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason) 4277 protected virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason)
4162 { 4278 {
4163 reason = String.Empty; 4279 reason = String.Empty;
4164 4280
@@ -4177,67 +4293,75 @@ namespace OpenSim.Region.Framework.Scenes
4177 } 4293 }
4178 } 4294 }
4179 4295
4180 if (RegionInfo.EstateSettings != null) 4296 // We only test the things below when we want to cut off
4297 // child agents from being present in the scene for which their root
4298 // agent isn't allowed. Otherwise, we allow child agents. The test for
4299 // the root is done elsewhere (QueryAccess)
4300 if (!bypassAccessControl)
4181 { 4301 {
4182 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, 0)) 4302 if (RegionInfo.EstateSettings != null)
4183 { 4303 {
4184 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 4304 int flags = GetUserFlags(agent.AgentID);
4185 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4305 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags))
4186 reason = String.Format("Denied access to region {0}: You have been banned from that region.", 4306 {
4187 RegionInfo.RegionName); 4307 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
4188 return false; 4308 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4309 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
4310 RegionInfo.RegionName);
4311 return false;
4312 }
4189 } 4313 }
4190 } 4314 else
4191 else
4192 {
4193 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4194 }
4195
4196 List<UUID> agentGroups = new List<UUID>();
4197
4198 if (m_groupsModule != null)
4199 {
4200 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID);
4201
4202 if (GroupMembership != null)
4203 { 4315 {
4204 for (int i = 0; i < GroupMembership.Length; i++) 4316 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4205 agentGroups.Add(GroupMembership[i].GroupID);
4206 } 4317 }
4207 else 4318
4319 List<UUID> agentGroups = new List<UUID>();
4320
4321 if (m_groupsModule != null)
4208 { 4322 {
4209 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!"); 4323 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID);
4324
4325 if (GroupMembership != null)
4326 {
4327 for (int i = 0; i < GroupMembership.Length; i++)
4328 agentGroups.Add(GroupMembership[i].GroupID);
4329 }
4330 else
4331 {
4332 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!");
4333 }
4210 } 4334 }
4211 }
4212 4335
4213 bool groupAccess = false; 4336 bool groupAccess = false;
4214 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; 4337 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
4215 4338
4216 if (estateGroups != null) 4339 if (estateGroups != null)
4217 {
4218 foreach (UUID group in estateGroups)
4219 { 4340 {
4220 if (agentGroups.Contains(group)) 4341 foreach (UUID group in estateGroups)
4221 { 4342 {
4222 groupAccess = true; 4343 if (agentGroups.Contains(group))
4223 break; 4344 {
4345 groupAccess = true;
4346 break;
4347 }
4224 } 4348 }
4225 } 4349 }
4226 } 4350 else
4227 else 4351 {
4228 { 4352 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
4229 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 4353 }
4230 }
4231 4354
4232 if (!RegionInfo.EstateSettings.PublicAccess && 4355 if (!RegionInfo.EstateSettings.PublicAccess &&
4233 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && 4356 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
4234 !groupAccess) 4357 !groupAccess)
4235 { 4358 {
4236 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4359 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate",
4237 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4360 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4238 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", 4361 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4239 RegionInfo.RegionName); 4362 RegionInfo.RegionName);
4240 return false; 4363 return false;
4364 }
4241 } 4365 }
4242 4366
4243 // TODO: estate/region settings are not properly hooked up 4367 // TODO: estate/region settings are not properly hooked up
@@ -4362,13 +4486,11 @@ namespace OpenSim.Region.Framework.Scenes
4362 /// <param name="cAgentData">Agent that contains all of the relevant things about an agent. 4486 /// <param name="cAgentData">Agent that contains all of the relevant things about an agent.
4363 /// Appearance, animations, position, etc.</param> 4487 /// Appearance, animations, position, etc.</param>
4364 /// <returns>true if we handled it.</returns> 4488 /// <returns>true if we handled it.</returns>
4365 public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData) 4489 public virtual bool IncomingUpdateChildAgent(AgentData cAgentData)
4366 { 4490 {
4367 m_log.DebugFormat( 4491 m_log.DebugFormat(
4368 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4492 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4369 4493
4370 // XPTO: if this agent is not allowed here as root, always return false
4371
4372 // We have to wait until the viewer contacts this region after receiving EAC. 4494 // We have to wait until the viewer contacts this region after receiving EAC.
4373 // That calls AddNewClient, which finally creates the ScenePresence 4495 // That calls AddNewClient, which finally creates the ScenePresence
4374 int flags = GetUserFlags(cAgentData.AgentID); 4496 int flags = GetUserFlags(cAgentData.AgentID);
@@ -4382,7 +4504,7 @@ namespace OpenSim.Region.Framework.Scenes
4382 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); 4504 ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2);
4383 if (nearestParcel == null) 4505 if (nearestParcel == null)
4384 { 4506 {
4385 m_log.DebugFormat( 4507 m_log.InfoFormat(
4386 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", 4508 "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel",
4387 cAgentData.AgentID, RegionInfo.RegionName); 4509 cAgentData.AgentID, RegionInfo.RegionName);
4388 4510
@@ -4390,13 +4512,44 @@ namespace OpenSim.Region.Framework.Scenes
4390 } 4512 }
4391 4513
4392 // We have to wait until the viewer contacts this region 4514 // We have to wait until the viewer contacts this region
4393 // after receiving the EnableSimulator HTTP Event Queue message. This triggers the viewer to send 4515 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
4394 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. 4516 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
4395 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4517 // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence.
4518 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4396 4519
4397 if (childAgentUpdate != null) 4520 if (sp != null)
4398 { 4521 {
4399 childAgentUpdate.ChildAgentDataUpdate(cAgentData); 4522 if (cAgentData.SessionID != sp.ControllingClient.SessionId)
4523 {
4524 m_log.WarnFormat(
4525 "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).",
4526 sp.UUID, cAgentData.SessionID);
4527
4528 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
4529 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4530 }
4531
4532 sp.UpdateChildAgent(cAgentData);
4533
4534 int ntimes = 20;
4535 if (cAgentData.SenderWantsToWaitForRoot)
4536 {
4537 while (sp.IsChildAgent && ntimes-- > 0)
4538 Thread.Sleep(1000);
4539
4540 if (sp.IsChildAgent)
4541 m_log.WarnFormat(
4542 "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}",
4543 sp.Name, sp.UUID, Name);
4544 else
4545 m_log.InfoFormat(
4546 "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits",
4547 sp.Name, sp.UUID, Name, 20 - ntimes);
4548
4549 if (sp.IsChildAgent)
4550 return false;
4551 }
4552
4400 return true; 4553 return true;
4401 } 4554 }
4402 4555
@@ -4409,12 +4562,17 @@ namespace OpenSim.Region.Framework.Scenes
4409 /// </summary> 4562 /// </summary>
4410 /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param> 4563 /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param>
4411 /// <returns>true if we handled it.</returns> 4564 /// <returns>true if we handled it.</returns>
4412 public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData) 4565 public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData)
4413 { 4566 {
4414 //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); 4567 //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName);
4415 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); 4568 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
4416 if (childAgentUpdate != null) 4569 if (childAgentUpdate != null)
4417 { 4570 {
4571// if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID)
4572// // Only warn for now
4573// m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?",
4574// childAgentUpdate.UUID, cAgentData.SessionID);
4575
4418 // I can't imagine *yet* why we would get an update if the agent is a root agent.. 4576 // I can't imagine *yet* why we would get an update if the agent is a root agent..
4419 // however to avoid a race condition crossing borders.. 4577 // however to avoid a race condition crossing borders..
4420 if (childAgentUpdate.IsChildAgent) 4578 if (childAgentUpdate.IsChildAgent)
@@ -4424,7 +4582,7 @@ namespace OpenSim.Region.Framework.Scenes
4424 uint tRegionX = RegionInfo.RegionLocX; 4582 uint tRegionX = RegionInfo.RegionLocX;
4425 uint tRegionY = RegionInfo.RegionLocY; 4583 uint tRegionY = RegionInfo.RegionLocY;
4426 //Send Data to ScenePresence 4584 //Send Data to ScenePresence
4427 childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); 4585 childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY);
4428 // Not Implemented: 4586 // Not Implemented:
4429 //TODO: Do we need to pass the message on to one of our neighbors? 4587 //TODO: Do we need to pass the message on to one of our neighbors?
4430 } 4588 }
@@ -4451,35 +4609,99 @@ namespace OpenSim.Region.Framework.Scenes
4451 m_log.WarnFormat( 4609 m_log.WarnFormat(
4452 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", 4610 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4453 agentID, RegionInfo.RegionName); 4611 agentID, RegionInfo.RegionName);
4454// else
4455// m_log.DebugFormat(
4456// "[SCENE PRESENCE]: Found presence {0} {1} {2} in {3} after {4} waits",
4457// sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", RegionInfo.RegionName, 10 - ntimes);
4458 4612
4459 return sp; 4613 return sp;
4460 } 4614 }
4461 4615
4462 public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) 4616 /// <summary>
4617 /// Authenticated close (via network)
4618 /// </summary>
4619 /// <param name="agentID"></param>
4620 /// <param name="force"></param>
4621 /// <param name="auth_token"></param>
4622 /// <returns></returns>
4623 public bool CloseAgent(UUID agentID, bool force, string auth_token)
4463 { 4624 {
4464 agent = null; 4625 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
4465 ScenePresence sp = GetScenePresence(id); 4626
4466 if ((sp != null) && (!sp.IsChildAgent)) 4627 // Check that the auth_token is valid
4628 AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID);
4629
4630 if (acd == null)
4467 { 4631 {
4468 sp.IsChildAgent = true; 4632 m_log.DebugFormat(
4469 return sp.CopyAgent(out agent); 4633 "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.",
4634 agentID, Name);
4635
4636 return false;
4637 }
4638
4639 if (acd.SessionID.ToString() == auth_token)
4640 {
4641 return CloseAgent(agentID, force);
4642 }
4643 else
4644 {
4645 m_log.WarnFormat(
4646 "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}",
4647 agentID, auth_token, Name);
4470 } 4648 }
4471 4649
4472 return false; 4650 return false;
4473 } 4651 }
4474 4652
4475 public bool IncomingCloseAgent(UUID agentID) 4653// public bool IncomingCloseAgent(UUID agentID)
4476 { 4654// {
4477 return IncomingCloseAgent(agentID, false); 4655// return IncomingCloseAgent(agentID, false);
4478 } 4656// }
4479 4657
4480 public bool IncomingCloseChildAgent(UUID agentID) 4658// public bool IncomingCloseChildAgent(UUID agentID)
4659// {
4660// return IncomingCloseAgent(agentID, true);
4661// }
4662
4663 /// <summary>
4664 /// Tell a single client to prepare to close.
4665 /// </summary>
4666 /// <remarks>
4667 /// This should only be called if we may close the client but there will be some delay in so doing. Meant for
4668 /// internal use - other callers should almost certainly called CloseClient().
4669 /// </remarks>
4670 /// <param name="sp"></param>
4671 /// <returns>true if pre-close state notification was successful. false if the agent
4672 /// was not in a state where it could transition to pre-close.</returns>
4673 public bool IncomingPreCloseClient(ScenePresence sp)
4481 { 4674 {
4482 return IncomingCloseAgent(agentID, true); 4675 lock (m_removeClientLock)
4676 {
4677 // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4678 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4679 // want to obey this close since C may have renewed the child agent lease on B.
4680 if (sp.DoNotCloseAfterTeleport)
4681 {
4682 m_log.DebugFormat(
4683 "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4684 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4685
4686 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4687 sp.DoNotCloseAfterTeleport = false;
4688
4689 return false;
4690 }
4691
4692 if (sp.LifecycleState != ScenePresenceState.Running)
4693 {
4694 m_log.DebugFormat(
4695 "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}",
4696 sp.Name, Name, sp.LifecycleState);
4697
4698 return false;
4699 }
4700
4701 sp.LifecycleState = ScenePresenceState.PreRemove;
4702
4703 return true;
4704 }
4483 } 4705 }
4484 4706
4485 /// <summary> 4707 /// <summary>
@@ -4490,18 +4712,57 @@ namespace OpenSim.Region.Framework.Scenes
4490 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to 4712 /// Force the agent to close even if it might be in the middle of some other operation. You do not want to
4491 /// force unless you are absolutely sure that the agent is dead and a normal close is not working. 4713 /// force unless you are absolutely sure that the agent is dead and a normal close is not working.
4492 /// </param> 4714 /// </param>
4493 public bool IncomingCloseAgent(UUID agentID, bool force) 4715 public override bool CloseAgent(UUID agentID, bool force)
4494 { 4716 {
4495 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4717 ScenePresence sp;
4496 4718
4497 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4719 lock (m_removeClientLock)
4498 if (presence != null) 4720 {
4721 sp = GetScenePresence(agentID);
4722
4723 if (sp == null)
4724 {
4725 m_log.DebugFormat(
4726 "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}",
4727 agentID, Name);
4728
4729 return false;
4730 }
4731
4732 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4733 {
4734 m_log.DebugFormat(
4735 "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}",
4736 sp.Name, Name, sp.LifecycleState);
4737
4738 return false;
4739 }
4740
4741 // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4742 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4743 // want to obey this close since C may have renewed the child agent lease on B.
4744 if (sp.DoNotCloseAfterTeleport)
4745 {
4746 m_log.DebugFormat(
4747 "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4748 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4749
4750 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4751 sp.DoNotCloseAfterTeleport = false;
4752
4753 return false;
4754 }
4755
4756 sp.LifecycleState = ScenePresenceState.Removing;
4757 }
4758
4759 if (sp != null)
4499 { 4760 {
4500 presence.ControllingClient.Close(force, force); 4761 sp.ControllingClient.Close(force, force);
4501 return true; 4762 return true;
4502 } 4763 }
4503 4764
4504 // Agent not here 4765 // Agent not here
4505 return false; 4766 return false;
4506 } 4767 }
4507 4768
@@ -5091,21 +5352,6 @@ namespace OpenSim.Region.Framework.Scenes
5091 5352
5092 #endregion 5353 #endregion
5093 5354
5094 public void RegionHandleRequest(IClientAPI client, UUID regionID)
5095 {
5096 ulong handle = 0;
5097 if (regionID == RegionInfo.RegionID)
5098 handle = RegionInfo.RegionHandle;
5099 else
5100 {
5101 GridRegion r = GridService.GetRegionByUUID(UUID.Zero, regionID);
5102 if (r != null)
5103 handle = r.RegionHandle;
5104 }
5105
5106 if (handle != 0)
5107 client.SendRegionHandle(regionID, handle);
5108 }
5109 5355
5110// Commented pending deletion since this method no longer appears to do anything at all 5356// Commented pending deletion since this method no longer appears to do anything at all
5111// public bool NeedSceneCacheClear(UUID agentID) 5357// public bool NeedSceneCacheClear(UUID agentID)
@@ -5657,12 +5903,12 @@ Environment.Exit(1);
5657 List<SceneObjectGroup> objects, 5903 List<SceneObjectGroup> objects,
5658 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) 5904 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
5659 { 5905 {
5660 minX = 256; 5906 minX = float.MaxValue;
5661 maxX = -256; 5907 maxX = float.MinValue;
5662 minY = 256; 5908 minY = float.MaxValue;
5663 maxY = -256; 5909 maxY = float.MinValue;
5664 minZ = 8192; 5910 minZ = float.MaxValue;
5665 maxZ = -256; 5911 maxZ = float.MinValue;
5666 5912
5667 List<Vector3> offsets = new List<Vector3>(); 5913 List<Vector3> offsets = new List<Vector3>();
5668 5914
@@ -5802,17 +6048,6 @@ Environment.Exit(1);
5802 { 6048 {
5803 reason = "You are banned from the region"; 6049 reason = "You are banned from the region";
5804 6050
5805 if (EntityTransferModule.IsInTransit(agentID))
5806 {
5807 reason = "Agent is still in transit from this region";
5808
5809 m_log.WarnFormat(
5810 "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit",
5811 agentID, RegionInfo.RegionName);
5812
5813 return false;
5814 }
5815
5816 if (Permissions.IsGod(agentID)) 6051 if (Permissions.IsGod(agentID))
5817 { 6052 {
5818 reason = String.Empty; 6053 reason = String.Empty;
@@ -5862,9 +6097,9 @@ Environment.Exit(1);
5862 6097
5863 try 6098 try
5864 { 6099 {
5865 if (!AuthorizeUser(aCircuit, out reason)) 6100 if (!AuthorizeUser(aCircuit, false, out reason))
5866 { 6101 {
5867 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); 6102 //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5868 return false; 6103 return false;
5869 } 6104 }
5870 } 6105 }