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.cs739
1 files changed, 482 insertions, 257 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index b189599..d6d2df4 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 }
@@ -859,9 +863,11 @@ namespace OpenSim.Region.Framework.Scenes
859 //Animation states 863 //Animation states
860 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); 864 m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false);
861 865
866
867 MaxUndoCount = startupConfig.GetInt("MaxPrimUndos", 20);
868
862 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true); 869 PhysicalPrims = startupConfig.GetBoolean("physical_prim", true);
863 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true); 870 CollidablePrims = startupConfig.GetBoolean("collidable_prim", true);
864
865 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys); 871 m_minNonphys = startupConfig.GetFloat("NonPhysicalPrimMin", m_minNonphys);
866 if (RegionInfo.NonphysPrimMin > 0) 872 if (RegionInfo.NonphysPrimMin > 0)
867 { 873 {
@@ -1332,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes
1332 Thread.Sleep(500); 1338 Thread.Sleep(500);
1333 1339
1334 // Stop all client threads. 1340 // Stop all client threads.
1335 ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); 1341 ForEachScenePresence(delegate(ScenePresence avatar) { IncomingCloseAgent(avatar.UUID, false); });
1336 1342
1337 m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); 1343 m_log.Debug("[SCENE]: TriggerSceneShuttingDown");
1338 EventManager.TriggerSceneShuttingDown(this); 1344 EventManager.TriggerSceneShuttingDown(this);
@@ -1361,10 +1367,18 @@ namespace OpenSim.Region.Framework.Scenes
1361 } 1367 }
1362 } 1368 }
1363 1369
1370 public override void Start()
1371 {
1372 Start(true);
1373 }
1374
1364 /// <summary> 1375 /// <summary>
1365 /// Start the scene 1376 /// Start the scene
1366 /// </summary> 1377 /// </summary>
1367 public void Start() 1378 /// <param name='startScripts'>
1379 /// Start the scripts within the scene.
1380 /// </param>
1381 public void Start(bool startScripts)
1368 { 1382 {
1369 m_active = true; 1383 m_active = true;
1370 1384
@@ -1401,6 +1415,8 @@ namespace OpenSim.Region.Framework.Scenes
1401 m_heartbeatThread 1415 m_heartbeatThread
1402 = Watchdog.StartThread( 1416 = Watchdog.StartThread(
1403 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false); 1417 Heartbeat, string.Format("Heartbeat ({0})", RegionInfo.RegionName), ThreadPriority.Normal, false, false);
1418
1419 StartScripts();
1404 } 1420 }
1405 1421
1406 /// <summary> 1422 /// <summary>
@@ -1557,6 +1573,8 @@ namespace OpenSim.Region.Framework.Scenes
1557 1573
1558 try 1574 try
1559 { 1575 {
1576 EventManager.TriggerRegionHeartbeatStart(this);
1577
1560 // Apply taints in terrain module to terrain in physics scene 1578 // Apply taints in terrain module to terrain in physics scene
1561 if (Frame % m_update_terrain == 0) 1579 if (Frame % m_update_terrain == 0)
1562 { 1580 {
@@ -2939,6 +2957,7 @@ namespace OpenSim.Region.Framework.Scenes
2939 { 2957 {
2940 ScenePresence sp; 2958 ScenePresence sp;
2941 bool vialogin; 2959 bool vialogin;
2960 bool reallyNew = true;
2942 2961
2943 // Validation occurs in LLUDPServer 2962 // Validation occurs in LLUDPServer
2944 // 2963 //
@@ -2997,16 +3016,21 @@ namespace OpenSim.Region.Framework.Scenes
2997 m_log.WarnFormat( 3016 m_log.WarnFormat(
2998 "[SCENE]: Already found {0} scene presence for {1} in {2} when asked to add new scene presence", 3017 "[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); 3018 sp.IsChildAgent ? "child" : "root", sp.Name, RegionInfo.RegionName);
3019 reallyNew = false;
3000 } 3020 }
3001 3021
3002 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the 3022 // We must set this here so that TriggerOnNewClient and TriggerOnClientLogin can determine whether the
3003 // client is for a root or child agent. 3023 // client is for a root or child agent.
3004 client.SceneAgent = sp; 3024 client.SceneAgent = sp;
3005 3025
3006 // Cache the user's name 3026 // This is currently also being done earlier in NewUserConnection for real users to see if this
3027 // resolves problems where HG agents are occasionally seen by others as "Unknown user" in chat and other
3028 // places. However, we still need to do it here for NPCs.
3007 CacheUserName(sp, aCircuit); 3029 CacheUserName(sp, aCircuit);
3008 3030
3009 EventManager.TriggerOnNewClient(client); 3031 if (reallyNew)
3032 EventManager.TriggerOnNewClient(client);
3033
3010 if (vialogin) 3034 if (vialogin)
3011 EventManager.TriggerOnClientLogin(client); 3035 EventManager.TriggerOnClientLogin(client);
3012 } 3036 }
@@ -3027,7 +3051,7 @@ namespace OpenSim.Region.Framework.Scenes
3027 { 3051 {
3028 string first = aCircuit.firstname, last = aCircuit.lastname; 3052 string first = aCircuit.firstname, last = aCircuit.lastname;
3029 3053
3030 if (sp.PresenceType == PresenceType.Npc) 3054 if (sp != null && sp.PresenceType == PresenceType.Npc)
3031 { 3055 {
3032 UserManagementModule.AddUser(aCircuit.AgentID, first, last); 3056 UserManagementModule.AddUser(aCircuit.AgentID, first, last);
3033 } 3057 }
@@ -3105,7 +3129,8 @@ namespace OpenSim.Region.Framework.Scenes
3105 if (sp != null) 3129 if (sp != null)
3106 { 3130 {
3107 PresenceService.LogoutAgent(sp.ControllingClient.SessionId); 3131 PresenceService.LogoutAgent(sp.ControllingClient.SessionId);
3108 sp.ControllingClient.Close(); 3132
3133 IncomingCloseAgent(sp.UUID, false);
3109 } 3134 }
3110 3135
3111 // BANG! SLASH! 3136 // BANG! SLASH!
@@ -3244,8 +3269,6 @@ namespace OpenSim.Region.Framework.Scenes
3244 { 3269 {
3245 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest; 3270 //client.OnNameFromUUIDRequest += HandleUUIDNameRequest;
3246 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest; 3271 client.OnMoneyTransferRequest += ProcessMoneyTransferRequest;
3247 client.OnSetStartLocationRequest += SetHomeRezPoint;
3248 client.OnRegionHandleRequest += RegionHandleRequest;
3249 } 3272 }
3250 3273
3251 public virtual void SubscribeToClientNetworkEvents(IClientAPI client) 3274 public virtual void SubscribeToClientNetworkEvents(IClientAPI client)
@@ -3371,8 +3394,6 @@ namespace OpenSim.Region.Framework.Scenes
3371 { 3394 {
3372 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest; 3395 //client.OnNameFromUUIDRequest -= HandleUUIDNameRequest;
3373 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest; 3396 client.OnMoneyTransferRequest -= ProcessMoneyTransferRequest;
3374 client.OnSetStartLocationRequest -= SetHomeRezPoint;
3375 client.OnRegionHandleRequest -= RegionHandleRequest;
3376 } 3397 }
3377 3398
3378 public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client) 3399 public virtual void UnSubscribeToClientNetworkEvents(IClientAPI client)
@@ -3498,33 +3519,6 @@ namespace OpenSim.Region.Framework.Scenes
3498 } 3519 }
3499 3520
3500 /// <summary> 3521 /// <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. 3522 /// Get the avatar apperance for the given client.
3529 /// </summary> 3523 /// </summary>
3530 /// <param name="client"></param> 3524 /// <param name="client"></param>
@@ -3548,63 +3542,69 @@ namespace OpenSim.Region.Framework.Scenes
3548 } 3542 }
3549 } 3543 }
3550 3544
3545 /// <summary>
3546 /// Remove the given client from the scene.
3547 /// </summary>
3548 /// <remarks>
3549 /// Only clientstack code should call this directly. All other code should call IncomingCloseAgent() instead
3550 /// to properly operate the state machine and avoid race conditions with other close requests (such as directly
3551 /// from viewers).
3552 /// </remarks>
3553 /// <param name='agentID'>ID of agent to close</param>
3554 /// <param name='closeChildAgents'>
3555 /// Close the neighbour child agents associated with this client.
3556 /// </param>
3551 public override void RemoveClient(UUID agentID, bool closeChildAgents) 3557 public override void RemoveClient(UUID agentID, bool closeChildAgents)
3552 { 3558 {
3553// CheckHeartbeat(); 3559 AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID);
3554 bool isChildAgent = false;
3555 AgentCircuitData acd;
3556 3560
3557 lock (m_removeClientLock) 3561 // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3562 // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3563 // However, will keep for now just in case.
3564 if (acd == null)
3558 { 3565 {
3559 acd = m_authenticateHandler.GetAgentCircuitData(agentID); 3566 m_log.ErrorFormat(
3567 "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name);
3560 3568
3561 if (acd == null) 3569 return;
3562 { 3570 }
3563 m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID); 3571 else
3564 return; 3572 {
3565 } 3573 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 } 3574 }
3574 3575
3576 // TODO: Can we now remove this lock?
3575 lock (acd) 3577 lock (acd)
3576 { 3578 {
3579 bool isChildAgent = false;
3580
3577 ScenePresence avatar = GetScenePresence(agentID); 3581 ScenePresence avatar = GetScenePresence(agentID);
3578 3582
3583 // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which
3584 // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not
3585 // However, will keep for now just in case.
3579 if (avatar == null) 3586 if (avatar == null)
3580 { 3587 {
3581 m_log.WarnFormat( 3588 m_log.ErrorFormat(
3582 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); 3589 "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID);
3583 3590
3584 return; 3591 return;
3585 } 3592 }
3586 3593
3587 try 3594 try
3588 { 3595 {
3589 isChildAgent = avatar.IsChildAgent; 3596 isChildAgent = avatar.IsChildAgent;
3590 3597
3591 m_log.DebugFormat( 3598 m_log.DebugFormat(
3592 "[SCENE]: Removing {0} agent {1} {2} from {3}", 3599 "[SCENE]: Removing {0} agent {1} {2} from {3}",
3593 (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); 3600 isChildAgent ? "child" : "root", avatar.Name, agentID, Name);
3594 3601
3595 // Don't do this to root agents, it's not nice for the viewer 3602 // Don't do this to root agents, it's not nice for the viewer
3596 if (closeChildAgents && isChildAgent) 3603 if (closeChildAgents && isChildAgent)
3597 { 3604 {
3598 // Tell a single agent to disconnect from the region. 3605 // Tell a single agent to disconnect from the region.
3599 IEventQueue eq = RequestModuleInterface<IEventQueue>(); 3606 // Let's do this via UDP
3600 if (eq != null) 3607 avatar.ControllingClient.SendShutdownConnectionNotice();
3601 {
3602 eq.DisableSimulator(RegionInfo.RegionHandle, avatar.UUID);
3603 }
3604 else
3605 {
3606 avatar.ControllingClient.SendShutdownConnectionNotice();
3607 }
3608 } 3608 }
3609 3609
3610 // Only applies to root agents. 3610 // Only applies to root agents.
@@ -3620,16 +3620,13 @@ namespace OpenSim.Region.Framework.Scenes
3620 if (closeChildAgents && CapsModule != null) 3620 if (closeChildAgents && CapsModule != null)
3621 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode); 3621 CapsModule.RemoveCaps(agentID, avatar.ControllingClient.CircuitCode);
3622 3622
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) 3623 if (closeChildAgents && !isChildAgent)
3629 { 3624 {
3630 List<ulong> regions = avatar.KnownRegionHandles; 3625 List<ulong> regions = avatar.KnownRegionHandles;
3631 regions.Remove(RegionInfo.RegionHandle); 3626 regions.Remove(RegionInfo.RegionHandle);
3632 m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); 3627
3628 // This ends up being done asynchronously so that a logout isn't held up where there are many present but unresponsive neighbours.
3629 m_sceneGridService.SendCloseChildAgentConnections(agentID, acd.SessionID.ToString(), regions);
3633 } 3630 }
3634 3631
3635 m_eventManager.TriggerClientClosed(agentID, this); 3632 m_eventManager.TriggerClientClosed(agentID, this);
@@ -3646,7 +3643,7 @@ namespace OpenSim.Region.Framework.Scenes
3646 delegate(IClientAPI client) 3643 delegate(IClientAPI client)
3647 { 3644 {
3648 //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway 3645 //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 }); } 3646 try { client.SendKillObject(new List<uint> { avatar.LocalId }); }
3650 catch (NullReferenceException) { } 3647 catch (NullReferenceException) { }
3651 }); 3648 });
3652 } 3649 }
@@ -3727,7 +3724,8 @@ namespace OpenSim.Region.Framework.Scenes
3727 } 3724 }
3728 deleteIDs.Add(localID); 3725 deleteIDs.Add(localID);
3729 } 3726 }
3730 ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); }); 3727
3728 ForEachClient(c => c.SendKillObject(deleteIDs));
3731 } 3729 }
3732 3730
3733 #endregion 3731 #endregion
@@ -3763,13 +3761,13 @@ namespace OpenSim.Region.Framework.Scenes
3763 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of 3761 /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of
3764 /// the LLUDP stack). 3762 /// the LLUDP stack).
3765 /// </remarks> 3763 /// </remarks>
3766 /// <param name="agent">CircuitData of the agent who is connecting</param> 3764 /// <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> 3765 /// <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 3766 /// <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> 3767 /// 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 3768 /// <returns>True if the region accepts this agent. False if it does not. False will
3771 /// also return a reason.</returns> 3769 /// also return a reason.</returns>
3772 public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) 3770 public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, out string reason, bool requirePresenceLookup)
3773 { 3771 {
3774 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || 3772 bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 ||
3775 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); 3773 (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0);
@@ -3789,15 +3787,15 @@ namespace OpenSim.Region.Framework.Scenes
3789 m_log.DebugFormat( 3787 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})", 3788 "[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, 3789 RegionInfo.RegionName,
3792 (agent.child ? "child" : "root"), 3790 (acd.child ? "child" : "root"),
3793 agent.firstname, 3791 acd.firstname,
3794 agent.lastname, 3792 acd.lastname,
3795 agent.AgentID, 3793 acd.AgentID,
3796 agent.circuitcode, 3794 acd.circuitcode,
3797 agent.IPAddress, 3795 acd.IPAddress,
3798 agent.Viewer, 3796 acd.Viewer,
3799 ((TPFlags)teleportFlags).ToString(), 3797 ((TPFlags)teleportFlags).ToString(),
3800 agent.startpos 3798 acd.startpos
3801 ); 3799 );
3802 3800
3803 if (!LoginsEnabled) 3801 if (!LoginsEnabled)
@@ -3815,7 +3813,7 @@ namespace OpenSim.Region.Framework.Scenes
3815 { 3813 {
3816 foreach (string viewer in m_AllowedViewers) 3814 foreach (string viewer in m_AllowedViewers)
3817 { 3815 {
3818 if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) 3816 if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower())
3819 { 3817 {
3820 ViewerDenied = false; 3818 ViewerDenied = false;
3821 break; 3819 break;
@@ -3832,7 +3830,7 @@ namespace OpenSim.Region.Framework.Scenes
3832 { 3830 {
3833 foreach (string viewer in m_BannedViewers) 3831 foreach (string viewer in m_BannedViewers)
3834 { 3832 {
3835 if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) 3833 if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower())
3836 { 3834 {
3837 ViewerDenied = true; 3835 ViewerDenied = true;
3838 break; 3836 break;
@@ -3844,54 +3842,129 @@ namespace OpenSim.Region.Framework.Scenes
3844 { 3842 {
3845 m_log.DebugFormat( 3843 m_log.DebugFormat(
3846 "[SCENE]: Access denied for {0} {1} using {2}", 3844 "[SCENE]: Access denied for {0} {1} using {2}",
3847 agent.firstname, agent.lastname, agent.Viewer); 3845 acd.firstname, acd.lastname, acd.Viewer);
3848 reason = "Access denied, your viewer is banned by the region owner"; 3846 reason = "Access denied, your viewer is banned by the region owner";
3849 return false; 3847 return false;
3850 } 3848 }
3851 3849
3852 ScenePresence sp = GetScenePresence(agent.AgentID); 3850 ILandObject land;
3851 ScenePresence sp;
3853 3852
3854 // If we have noo presence here or if that presence is a zombie root 3853 lock (m_removeClientLock)
3855 // presence that will be kicled, we need a new CAPS object.
3856 if (sp == null || (sp != null && !sp.IsChildAgent))
3857 { 3854 {
3858 if (CapsModule != null) 3855 sp = GetScenePresence(acd.AgentID);
3856
3857 // We need to ensure that we are not already removing the scene presence before we ask it not to be
3858 // closed.
3859 if (sp != null && sp.IsChildAgent
3860 && (sp.LifecycleState == ScenePresenceState.Running
3861 || sp.LifecycleState == ScenePresenceState.PreRemove))
3859 { 3862 {
3860 lock (agent) 3863 m_log.DebugFormat(
3864 "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}",
3865 sp.Name, sp.LifecycleState, Name);
3866
3867 // In the case where, for example, an A B C D region layout, an avatar may
3868 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C
3869 // renews the lease on the child agent at B, we must make sure that the close from A does not succeed.
3870 //
3871 // XXX: In the end, this should not be necessary if child agents are closed without delay on
3872 // teleport, since realistically, the close request should always be processed before any other
3873 // region tried to re-establish a child agent. This is much simpler since the logic below is
3874 // vulnerable to an issue when a viewer quits a region without sending a proper logout but then
3875 // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport
3876 // flag when no teleport had taken place (and hence no close was going to come).
3877// if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle))
3878// {
3879// m_log.DebugFormat(
3880// "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.",
3881// sp.Name, Name);
3882//
3883// sp.DoNotCloseAfterTeleport = true;
3884// }
3885// else if (EntityTransferModule.IsInTransit(sp.UUID))
3886
3887 sp.LifecycleState = ScenePresenceState.Running;
3888
3889 if (EntityTransferModule.IsInTransit(sp.UUID))
3861 { 3890 {
3862 CapsModule.SetAgentCapsSeeds(agent); 3891 sp.DoNotCloseAfterTeleport = true;
3863 CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); 3892
3893 m_log.DebugFormat(
3894 "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.",
3895 sp.Name, Name);
3864 } 3896 }
3865 } 3897 }
3866 } 3898 }
3867 3899
3900 // Need to poll here in case we are currently deleting an sp. Letting threads run over each other will
3901 // allow unpredictable things to happen.
3868 if (sp != null) 3902 if (sp != null)
3869 { 3903 {
3870 if (!sp.IsChildAgent) 3904 const int polls = 10;
3905 const int pollInterval = 1000;
3906 int pollsLeft = polls;
3907
3908 while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0)
3909 Thread.Sleep(pollInterval);
3910
3911 if (sp.LifecycleState == ScenePresenceState.Removing)
3871 { 3912 {
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( 3913 m_log.WarnFormat(
3876 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", 3914 "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.",
3877 sp.Name, sp.UUID, RegionInfo.RegionName); 3915 sp.Name, Name, polls * pollInterval / 1000);
3878 3916
3879 sp.ControllingClient.Close(true, true); 3917 return false;
3880 sp = null; 3918 }
3919 else if (polls != pollsLeft)
3920 {
3921 m_log.DebugFormat(
3922 "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.",
3923 sp.Name, Name, polls * pollInterval / 1000);
3881 } 3924 }
3882 } 3925 }
3883 3926
3884 lock (agent) 3927 // TODO: can we remove this lock?
3928 lock (acd)
3885 { 3929 {
3886 //On login test land permisions 3930 if (sp != null && !sp.IsChildAgent)
3931 {
3932 // We have a root agent. Is it in transit?
3933 if (!EntityTransferModule.IsInTransit(sp.UUID))
3934 {
3935 // We have a zombie from a crashed session.
3936 // Or the same user is trying to be root twice here, won't work.
3937 // Kill it.
3938 m_log.WarnFormat(
3939 "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.",
3940 sp.Name, sp.UUID, RegionInfo.RegionName);
3941
3942 if (sp.ControllingClient != null)
3943 IncomingCloseAgent(sp.UUID, true);
3944
3945 sp = null;
3946 }
3947 //else
3948 // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName);
3949 }
3950
3951 // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags.
3952 // We need the circuit data here for some of the subsequent checks. (groups, for example)
3953 // If the checks fail, we remove the circuit.
3954 acd.teleportFlags = teleportFlags;
3955 m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd);
3956
3957 land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y);
3958
3959 // On login test land permisions
3887 if (vialogin) 3960 if (vialogin)
3888 { 3961 {
3889 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); 3962 IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>();
3890 if (cache != null) 3963 if (cache != null)
3891 cache.Remove(agent.firstname + " " + agent.lastname); 3964 cache.Remove(acd.firstname + " " + acd.lastname);
3892 if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) 3965 if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y))
3893 { 3966 {
3894 m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); 3967 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3895 return false; 3968 return false;
3896 } 3969 }
3897 } 3970 }
@@ -3902,40 +3975,49 @@ namespace OpenSim.Region.Framework.Scenes
3902 { 3975 {
3903 try 3976 try
3904 { 3977 {
3905 if (!VerifyUserPresence(agent, out reason)) 3978 if (!VerifyUserPresence(acd, out reason))
3979 {
3980 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3906 return false; 3981 return false;
3907 } catch (Exception e) 3982 }
3983 }
3984 catch (Exception e)
3908 { 3985 {
3909 m_log.ErrorFormat( 3986 m_log.ErrorFormat(
3910 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); 3987 "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace);
3988
3989 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3911 return false; 3990 return false;
3912 } 3991 }
3913 } 3992 }
3914 3993
3915 try 3994 try
3916 { 3995 {
3917 // Always check estate if this is a login. Always 3996 if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason))
3918 // check if banned regions are to be blacked out.
3919 if (vialogin || (!m_seeIntoBannedRegion))
3920 { 3997 {
3921 if (!AuthorizeUser(agent, out reason)) 3998 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3922 { 3999 return false;
3923 return false;
3924 }
3925 } 4000 }
3926 } 4001 }
3927 catch (Exception e) 4002 catch (Exception e)
3928 { 4003 {
3929 m_log.ErrorFormat( 4004 m_log.ErrorFormat(
3930 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); 4005 "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace);
4006
4007 m_authenticateHandler.RemoveCircuit(acd.circuitcode);
3931 return false; 4008 return false;
3932 } 4009 }
3933 4010
3934 m_log.InfoFormat( 4011 m_log.InfoFormat(
3935 "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", 4012 "[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, 4013 Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname,
3937 agent.AgentID, agent.circuitcode); 4014 acd.AgentID, acd.circuitcode);
3938 4015
4016 if (CapsModule != null)
4017 {
4018 CapsModule.SetAgentCapsSeeds(acd);
4019 CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4020 }
3939 } 4021 }
3940 else 4022 else
3941 { 4023 {
@@ -3943,43 +4025,60 @@ namespace OpenSim.Region.Framework.Scenes
3943 // uses down the line. 4025 // uses down the line.
3944 sp.TeleportFlags = (TPFlags)teleportFlags; 4026 sp.TeleportFlags = (TPFlags)teleportFlags;
3945 4027
4028 // We must carry out a further authorization check if there's an
4029 // attempt to make a child agent into a root agent, since SeeIntoRegion may have allowed a child
4030 // agent to login to a region where a full avatar would not be allowed.
4031 //
4032 // We determine whether this is a CreateAgent for a future non-child agent by inspecting
4033 // TeleportFlags, which will be default for a child connection. This relies on input from the source
4034 // region.
4035 if (sp.TeleportFlags != TPFlags.Default)
4036 {
4037 if (!AuthorizeUser(acd, false, out reason))
4038 return false;
4039 }
4040
3946 if (sp.IsChildAgent) 4041 if (sp.IsChildAgent)
3947 { 4042 {
3948 m_log.DebugFormat( 4043 m_log.DebugFormat(
3949 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", 4044 "[SCENE]: Adjusting known seeds for existing agent {0} in {1}",
3950 agent.AgentID, RegionInfo.RegionName); 4045 acd.AgentID, RegionInfo.RegionName);
3951 4046
3952 sp.AdjustKnownSeeds(); 4047 sp.AdjustKnownSeeds();
3953 4048
3954 if (CapsModule != null) 4049 if (CapsModule != null)
3955 CapsModule.SetAgentCapsSeeds(agent); 4050 {
4051 CapsModule.SetAgentCapsSeeds(acd);
4052 CapsModule.CreateCaps(acd.AgentID, acd.circuitcode);
4053 }
3956 } 4054 }
3957 } 4055 }
3958 }
3959 4056
3960 // In all cases, add or update the circuit data with the new agent circuit data and teleport flags 4057 // Try caching an incoming user name much earlier on to see if this helps with an issue
3961 agent.teleportFlags = teleportFlags; 4058 // where HG users are occasionally seen by others as "Unknown User" because their UUIDName
3962 m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); 4059 // request for the HG avatar appears to trigger before the user name is cached.
4060 CacheUserName(null, acd);
4061 }
3963 4062
3964 if (CapsModule != null) 4063 if (CapsModule != null)
3965 { 4064 {
3966 CapsModule.ActivateCaps(agent.circuitcode); 4065 CapsModule.ActivateCaps(acd.circuitcode);
3967 } 4066 }
3968 4067
3969 if (vialogin) 4068 if (vialogin)
3970 { 4069 {
3971// CleanDroppedAttachments(); 4070// CleanDroppedAttachments();
3972 4071
3973 if (TestBorderCross(agent.startpos, Cardinals.E)) 4072 if (TestBorderCross(acd.startpos, Cardinals.E))
3974 { 4073 {
3975 Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); 4074 Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E);
3976 agent.startpos.X = crossedBorder.BorderLine.Z - 1; 4075 acd.startpos.X = crossedBorder.BorderLine.Z - 1;
3977 } 4076 }
3978 4077
3979 if (TestBorderCross(agent.startpos, Cardinals.N)) 4078 if (TestBorderCross(acd.startpos, Cardinals.N))
3980 { 4079 {
3981 Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N); 4080 Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N);
3982 agent.startpos.Y = crossedBorder.BorderLine.Z - 1; 4081 acd.startpos.Y = crossedBorder.BorderLine.Z - 1;
3983 } 4082 }
3984 4083
3985 //Mitigate http://opensimulator.org/mantis/view.php?id=3522 4084 //Mitigate http://opensimulator.org/mantis/view.php?id=3522
@@ -3989,39 +4088,39 @@ namespace OpenSim.Region.Framework.Scenes
3989 { 4088 {
3990 lock (EastBorders) 4089 lock (EastBorders)
3991 { 4090 {
3992 if (agent.startpos.X > EastBorders[0].BorderLine.Z) 4091 if (acd.startpos.X > EastBorders[0].BorderLine.Z)
3993 { 4092 {
3994 m_log.Warn("FIX AGENT POSITION"); 4093 m_log.Warn("FIX AGENT POSITION");
3995 agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; 4094 acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
3996 if (agent.startpos.Z > 720) 4095 if (acd.startpos.Z > 720)
3997 agent.startpos.Z = 720; 4096 acd.startpos.Z = 720;
3998 } 4097 }
3999 } 4098 }
4000 lock (NorthBorders) 4099 lock (NorthBorders)
4001 { 4100 {
4002 if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) 4101 if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
4003 { 4102 {
4004 m_log.Warn("FIX Agent POSITION"); 4103 m_log.Warn("FIX Agent POSITION");
4005 agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; 4104 acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
4006 if (agent.startpos.Z > 720) 4105 if (acd.startpos.Z > 720)
4007 agent.startpos.Z = 720; 4106 acd.startpos.Z = 720;
4008 } 4107 }
4009 } 4108 }
4010 } else 4109 } else
4011 { 4110 {
4012 if (agent.startpos.X > EastBorders[0].BorderLine.Z) 4111 if (acd.startpos.X > EastBorders[0].BorderLine.Z)
4013 { 4112 {
4014 m_log.Warn("FIX AGENT POSITION"); 4113 m_log.Warn("FIX AGENT POSITION");
4015 agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; 4114 acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f;
4016 if (agent.startpos.Z > 720) 4115 if (acd.startpos.Z > 720)
4017 agent.startpos.Z = 720; 4116 acd.startpos.Z = 720;
4018 } 4117 }
4019 if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) 4118 if (acd.startpos.Y > NorthBorders[0].BorderLine.Z)
4020 { 4119 {
4021 m_log.Warn("FIX Agent POSITION"); 4120 m_log.Warn("FIX Agent POSITION");
4022 agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; 4121 acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f;
4023 if (agent.startpos.Z > 720) 4122 if (acd.startpos.Z > 720)
4024 agent.startpos.Z = 720; 4123 acd.startpos.Z = 720;
4025 } 4124 }
4026 } 4125 }
4027 4126
@@ -4037,12 +4136,12 @@ namespace OpenSim.Region.Framework.Scenes
4037 { 4136 {
4038 // We have multiple SpawnPoints, Route the agent to a random or sequential one 4137 // We have multiple SpawnPoints, Route the agent to a random or sequential one
4039 if (SpawnPointRouting == "random") 4138 if (SpawnPointRouting == "random")
4040 agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( 4139 acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation(
4041 telehub.AbsolutePosition, 4140 telehub.AbsolutePosition,
4042 telehub.GroupRotation 4141 telehub.GroupRotation
4043 ); 4142 );
4044 else 4143 else
4045 agent.startpos = spawnpoints[SpawnPoint()].GetLocation( 4144 acd.startpos = spawnpoints[SpawnPoint()].GetLocation(
4046 telehub.AbsolutePosition, 4145 telehub.AbsolutePosition,
4047 telehub.GroupRotation 4146 telehub.GroupRotation
4048 ); 4147 );
@@ -4050,7 +4149,7 @@ namespace OpenSim.Region.Framework.Scenes
4050 else 4149 else
4051 { 4150 {
4052 // We have a single SpawnPoint and will route the agent to it 4151 // We have a single SpawnPoint and will route the agent to it
4053 agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4152 acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4054 } 4153 }
4055 4154
4056 return true; 4155 return true;
@@ -4063,7 +4162,7 @@ namespace OpenSim.Region.Framework.Scenes
4063 { 4162 {
4064 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) 4163 if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero)
4065 { 4164 {
4066 agent.startpos = land.LandData.UserLocation; 4165 acd.startpos = land.LandData.UserLocation;
4067 } 4166 }
4068 } 4167 }
4069 */// This is now handled properly in ScenePresence.MakeRootAgent 4168 */// This is now handled properly in ScenePresence.MakeRootAgent
@@ -4158,7 +4257,7 @@ namespace OpenSim.Region.Framework.Scenes
4158 /// <param name="reason">outputs the reason to this string</param> 4257 /// <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 4258 /// <returns>True if the region accepts this agent. False if it does not. False will
4160 /// also return a reason.</returns> 4259 /// also return a reason.</returns>
4161 protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason) 4260 protected virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason)
4162 { 4261 {
4163 reason = String.Empty; 4262 reason = String.Empty;
4164 4263
@@ -4177,67 +4276,75 @@ namespace OpenSim.Region.Framework.Scenes
4177 } 4276 }
4178 } 4277 }
4179 4278
4180 if (RegionInfo.EstateSettings != null) 4279 // We only test the things below when we want to cut off
4280 // child agents from being present in the scene for which their root
4281 // agent isn't allowed. Otherwise, we allow child agents. The test for
4282 // the root is done elsewhere (QueryAccess)
4283 if (!bypassAccessControl)
4181 { 4284 {
4182 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, 0)) 4285 if (RegionInfo.EstateSettings != null)
4183 { 4286 {
4184 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", 4287 int flags = GetUserFlags(agent.AgentID);
4185 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); 4288 if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags))
4186 reason = String.Format("Denied access to region {0}: You have been banned from that region.", 4289 {
4187 RegionInfo.RegionName); 4290 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist",
4188 return false; 4291 agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName);
4292 reason = String.Format("Denied access to region {0}: You have been banned from that region.",
4293 RegionInfo.RegionName);
4294 return false;
4295 }
4189 } 4296 }
4190 } 4297 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 { 4298 {
4204 for (int i = 0; i < GroupMembership.Length; i++) 4299 m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!");
4205 agentGroups.Add(GroupMembership[i].GroupID);
4206 } 4300 }
4207 else 4301
4302 List<UUID> agentGroups = new List<UUID>();
4303
4304 if (m_groupsModule != null)
4208 { 4305 {
4209 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!"); 4306 GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID);
4307
4308 if (GroupMembership != null)
4309 {
4310 for (int i = 0; i < GroupMembership.Length; i++)
4311 agentGroups.Add(GroupMembership[i].GroupID);
4312 }
4313 else
4314 {
4315 m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!");
4316 }
4210 } 4317 }
4211 }
4212 4318
4213 bool groupAccess = false; 4319 bool groupAccess = false;
4214 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; 4320 UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups;
4215 4321
4216 if (estateGroups != null) 4322 if (estateGroups != null)
4217 {
4218 foreach (UUID group in estateGroups)
4219 { 4323 {
4220 if (agentGroups.Contains(group)) 4324 foreach (UUID group in estateGroups)
4221 { 4325 {
4222 groupAccess = true; 4326 if (agentGroups.Contains(group))
4223 break; 4327 {
4328 groupAccess = true;
4329 break;
4330 }
4224 } 4331 }
4225 } 4332 }
4226 } 4333 else
4227 else 4334 {
4228 { 4335 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!");
4229 m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); 4336 }
4230 }
4231 4337
4232 if (!RegionInfo.EstateSettings.PublicAccess && 4338 if (!RegionInfo.EstateSettings.PublicAccess &&
4233 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && 4339 !RegionInfo.EstateSettings.HasAccess(agent.AgentID) &&
4234 !groupAccess) 4340 !groupAccess)
4235 { 4341 {
4236 m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", 4342 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); 4343 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.", 4344 reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.",
4239 RegionInfo.RegionName); 4345 RegionInfo.RegionName);
4240 return false; 4346 return false;
4347 }
4241 } 4348 }
4242 4349
4243 // TODO: estate/region settings are not properly hooked up 4350 // TODO: estate/region settings are not properly hooked up
@@ -4367,8 +4474,6 @@ namespace OpenSim.Region.Framework.Scenes
4367 m_log.DebugFormat( 4474 m_log.DebugFormat(
4368 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); 4475 "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName);
4369 4476
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. 4477 // We have to wait until the viewer contacts this region after receiving EAC.
4373 // That calls AddNewClient, which finally creates the ScenePresence 4478 // That calls AddNewClient, which finally creates the ScenePresence
4374 int flags = GetUserFlags(cAgentData.AgentID); 4479 int flags = GetUserFlags(cAgentData.AgentID);
@@ -4390,13 +4495,39 @@ namespace OpenSim.Region.Framework.Scenes
4390 } 4495 }
4391 4496
4392 // We have to wait until the viewer contacts this region 4497 // 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 4498 // after receiving the EnableSimulator HTTP Event Queue message (for the v1 teleport protocol)
4499 // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send
4394 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence. 4500 // a UseCircuitCode packet which in turn calls AddNewClient which finally creates the ScenePresence.
4395 ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); 4501 ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID);
4396 4502
4397 if (childAgentUpdate != null) 4503 if (sp != null)
4398 { 4504 {
4399 childAgentUpdate.ChildAgentDataUpdate(cAgentData); 4505 if (cAgentData.SessionID != sp.ControllingClient.SessionId)
4506 {
4507 m_log.WarnFormat(
4508 "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).",
4509 sp.UUID, cAgentData.SessionID);
4510
4511 Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}",
4512 sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID));
4513 }
4514
4515 sp.ChildAgentDataUpdate(cAgentData);
4516
4517 int ntimes = 20;
4518 if (cAgentData.SenderWantsToWaitForRoot)
4519 {
4520 while (sp.IsChildAgent && ntimes-- > 0)
4521 Thread.Sleep(1000);
4522
4523 m_log.DebugFormat(
4524 "[SCENE]: Found presence {0} {1} {2} in {3} after {4} waits",
4525 sp.Name, sp.UUID, sp.IsChildAgent ? "child" : "root", Name, 20 - ntimes);
4526
4527 if (sp.IsChildAgent)
4528 return false;
4529 }
4530
4400 return true; 4531 return true;
4401 } 4532 }
4402 4533
@@ -4415,6 +4546,11 @@ namespace OpenSim.Region.Framework.Scenes
4415 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); 4546 ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
4416 if (childAgentUpdate != null) 4547 if (childAgentUpdate != null)
4417 { 4548 {
4549// if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID)
4550// // Only warn for now
4551// m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?",
4552// childAgentUpdate.UUID, cAgentData.SessionID);
4553
4418 // I can't imagine *yet* why we would get an update if the agent is a root agent.. 4554 // 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.. 4555 // however to avoid a race condition crossing borders..
4420 if (childAgentUpdate.IsChildAgent) 4556 if (childAgentUpdate.IsChildAgent)
@@ -4451,10 +4587,6 @@ namespace OpenSim.Region.Framework.Scenes
4451 m_log.WarnFormat( 4587 m_log.WarnFormat(
4452 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", 4588 "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout",
4453 agentID, RegionInfo.RegionName); 4589 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 4590
4459 return sp; 4591 return sp;
4460 } 4592 }
@@ -4471,6 +4603,42 @@ namespace OpenSim.Region.Framework.Scenes
4471 4603
4472 return false; 4604 return false;
4473 } 4605 }
4606 /// <summary>
4607 /// Authenticated close (via network)
4608 /// </summary>
4609 /// <param name="agentID"></param>
4610 /// <param name="force"></param>
4611 /// <param name="auth_token"></param>
4612 /// <returns></returns>
4613 public bool IncomingCloseAgent(UUID agentID, bool force, string auth_token)
4614 {
4615 //m_log.DebugFormat("[SCENE]: Processing incoming close agent {0} in region {1} with auth_token {2}", agentID, RegionInfo.RegionName, auth_token);
4616
4617 // Check that the auth_token is valid
4618 AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID);
4619
4620 if (acd == null)
4621 {
4622 m_log.DebugFormat(
4623 "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.",
4624 agentID, Name);
4625
4626 return false;
4627 }
4628
4629 if (acd.SessionID.ToString() == auth_token)
4630 {
4631 return IncomingCloseAgent(agentID, force);
4632 }
4633 else
4634 {
4635 m_log.WarnFormat(
4636 "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}",
4637 agentID, auth_token, Name);
4638 }
4639
4640 return false;
4641 }
4474 4642
4475 public bool IncomingCloseAgent(UUID agentID) 4643 public bool IncomingCloseAgent(UUID agentID)
4476 { 4644 {
@@ -4483,6 +4651,50 @@ namespace OpenSim.Region.Framework.Scenes
4483 } 4651 }
4484 4652
4485 /// <summary> 4653 /// <summary>
4654 /// Tell a single agent to prepare to close.
4655 /// </summary>
4656 /// <remarks>
4657 /// This should only be called if we may close the agent but there will be some delay in so doing. Meant for
4658 /// internal use - other callers should almost certainly called IncomingCloseAgent().
4659 /// </remarks>
4660 /// <param name="sp"></param>
4661 /// <returns>true if pre-close state notification was successful. false if the agent
4662 /// was not in a state where it could transition to pre-close.</returns>
4663 public bool IncomingPreCloseAgent(ScenePresence sp)
4664 {
4665 lock (m_removeClientLock)
4666 {
4667 // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4668 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4669 // want to obey this close since C may have renewed the child agent lease on B.
4670 if (sp.DoNotCloseAfterTeleport)
4671 {
4672 m_log.DebugFormat(
4673 "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4674 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4675
4676 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4677 sp.DoNotCloseAfterTeleport = false;
4678
4679 return false;
4680 }
4681
4682 if (sp.LifecycleState != ScenePresenceState.Running)
4683 {
4684 m_log.DebugFormat(
4685 "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}",
4686 sp.Name, Name, sp.LifecycleState);
4687
4688 return false;
4689 }
4690
4691 sp.LifecycleState = ScenePresenceState.PreRemove;
4692
4693 return true;
4694 }
4695 }
4696
4697 /// <summary>
4486 /// Tell a single agent to disconnect from the region. 4698 /// Tell a single agent to disconnect from the region.
4487 /// </summary> 4699 /// </summary>
4488 /// <param name="agentID"></param> 4700 /// <param name="agentID"></param>
@@ -4492,16 +4704,55 @@ namespace OpenSim.Region.Framework.Scenes
4492 /// </param> 4704 /// </param>
4493 public bool IncomingCloseAgent(UUID agentID, bool force) 4705 public bool IncomingCloseAgent(UUID agentID, bool force)
4494 { 4706 {
4495 //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); 4707 ScenePresence sp;
4496 4708
4497 ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); 4709 lock (m_removeClientLock)
4498 if (presence != null) 4710 {
4711 sp = GetScenePresence(agentID);
4712
4713 if (sp == null)
4714 {
4715 m_log.DebugFormat(
4716 "[SCENE]: Called IncomingCloseAgent() with agent ID {0} but no such presence is in {1}",
4717 agentID, Name);
4718
4719 return false;
4720 }
4721
4722 if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove)
4723 {
4724 m_log.DebugFormat(
4725 "[SCENE]: Called IncomingCloseAgent() for {0} in {1} but presence is already in state {2}",
4726 sp.Name, Name, sp.LifecycleState);
4727
4728 return false;
4729 }
4730
4731 // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may
4732 // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not
4733 // want to obey this close since C may have renewed the child agent lease on B.
4734 if (sp.DoNotCloseAfterTeleport)
4735 {
4736 m_log.DebugFormat(
4737 "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection",
4738 sp.IsChildAgent ? "child" : "root", sp.Name, Name);
4739
4740 // Need to reset the flag so that a subsequent close after another teleport can succeed.
4741 sp.DoNotCloseAfterTeleport = false;
4742
4743 return false;
4744 }
4745
4746 sp.LifecycleState = ScenePresenceState.Removing;
4747 }
4748
4749 if (sp != null)
4499 { 4750 {
4500 presence.ControllingClient.Close(force, force); 4751 sp.ControllingClient.Close(force, force);
4501 return true; 4752 return true;
4502 } 4753 }
4503 4754
4504 // Agent not here 4755 // Agent not here
4505 return false; 4756 return false;
4506 } 4757 }
4507 4758
@@ -5091,21 +5342,6 @@ namespace OpenSim.Region.Framework.Scenes
5091 5342
5092 #endregion 5343 #endregion
5093 5344
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 5345
5110// Commented pending deletion since this method no longer appears to do anything at all 5346// Commented pending deletion since this method no longer appears to do anything at all
5111// public bool NeedSceneCacheClear(UUID agentID) 5347// public bool NeedSceneCacheClear(UUID agentID)
@@ -5657,12 +5893,12 @@ Environment.Exit(1);
5657 List<SceneObjectGroup> objects, 5893 List<SceneObjectGroup> objects,
5658 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) 5894 out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
5659 { 5895 {
5660 minX = 256; 5896 minX = float.MaxValue;
5661 maxX = -256; 5897 maxX = float.MinValue;
5662 minY = 256; 5898 minY = float.MaxValue;
5663 maxY = -256; 5899 maxY = float.MinValue;
5664 minZ = 8192; 5900 minZ = float.MaxValue;
5665 maxZ = -256; 5901 maxZ = float.MinValue;
5666 5902
5667 List<Vector3> offsets = new List<Vector3>(); 5903 List<Vector3> offsets = new List<Vector3>();
5668 5904
@@ -5802,17 +6038,6 @@ Environment.Exit(1);
5802 { 6038 {
5803 reason = "You are banned from the region"; 6039 reason = "You are banned from the region";
5804 6040
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)) 6041 if (Permissions.IsGod(agentID))
5817 { 6042 {
5818 reason = String.Empty; 6043 reason = String.Empty;
@@ -5862,9 +6087,9 @@ Environment.Exit(1);
5862 6087
5863 try 6088 try
5864 { 6089 {
5865 if (!AuthorizeUser(aCircuit, out reason)) 6090 if (!AuthorizeUser(aCircuit, false, out reason))
5866 { 6091 {
5867 // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); 6092 //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID);
5868 return false; 6093 return false;
5869 } 6094 }
5870 } 6095 }