diff options
author | Melanie Thielker | 2014-06-21 00:39:55 +0200 |
---|---|---|
committer | Melanie Thielker | 2014-06-21 00:39:55 +0200 |
commit | 159fcbf150b7da0e229b29aa7b94793484543d12 (patch) | |
tree | b8c0ff3b4c758a3fba8315b556c923ef4c02a185 /OpenSim/Region/Framework/Scenes/Scene.cs | |
parent | Merge commit '68c8633ba18f0a11cfc0ed04d1d0c7c59e6cec76' (diff) | |
parent | Merge branch 'master' into careminster (diff) | |
download | opensim-SC_OLD-159fcbf150b7da0e229b29aa7b94793484543d12.zip opensim-SC_OLD-159fcbf150b7da0e229b29aa7b94793484543d12.tar.gz opensim-SC_OLD-159fcbf150b7da0e229b29aa7b94793484543d12.tar.bz2 opensim-SC_OLD-159fcbf150b7da0e229b29aa7b94793484543d12.tar.xz |
Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
Conflicts:
OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 823 |
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 | } |