diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 834 |
1 files changed, 538 insertions, 296 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b189599..0266faf 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 | } |
@@ -2444,7 +2469,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2444 | foreach (UUID av in avatars) | 2469 | foreach (UUID av in avatars) |
2445 | { | 2470 | { |
2446 | ScenePresence p = GetScenePresence(av); | 2471 | ScenePresence p = GetScenePresence(av); |
2447 | if (p != null) | 2472 | if (p != null && p.ParentUUID == UUID.Zero) |
2448 | p.StandUp(); | 2473 | p.StandUp(); |
2449 | } | 2474 | } |
2450 | 2475 | ||
@@ -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 | } |
@@ -3100,12 +3134,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3100 | // and the scene presence and the client, if they exist | 3134 | // and the scene presence and the client, if they exist |
3101 | try | 3135 | try |
3102 | { | 3136 | { |
3103 | ScenePresence sp = GetScenePresence(agentID); | 3137 | ScenePresence sp = WaitGetScenePresence(agentID); |
3104 | 3138 | ||
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,40 +3630,44 @@ 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); |
3643 | // m_log.Debug("[Scene]TriggerClientClosed done"); | ||
3636 | m_eventManager.TriggerOnRemovePresence(agentID); | 3644 | m_eventManager.TriggerOnRemovePresence(agentID); |
3645 | // m_log.Debug("[Scene]TriggerOnRemovePresence done"); | ||
3637 | 3646 | ||
3638 | if (!isChildAgent) | 3647 | if (!isChildAgent) |
3639 | { | 3648 | { |
3640 | if (AttachmentsModule != null) | 3649 | if (AttachmentsModule != null) |
3641 | { | 3650 | { |
3651 | // m_log.Debug("[Scene]DeRezAttachments"); | ||
3642 | AttachmentsModule.DeRezAttachments(avatar); | 3652 | AttachmentsModule.DeRezAttachments(avatar); |
3653 | // m_log.Debug("[Scene]DeRezAttachments done"); | ||
3643 | } | 3654 | } |
3644 | 3655 | ||
3645 | ForEachClient( | 3656 | ForEachClient( |
3646 | delegate(IClientAPI client) | 3657 | delegate(IClientAPI client) |
3647 | { | 3658 | { |
3648 | //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway | 3659 | //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 }); } | 3660 | try { client.SendKillObject(new List<uint> { avatar.LocalId }); } |
3650 | catch (NullReferenceException) { } | 3661 | catch (NullReferenceException) { } |
3651 | }); | 3662 | }); |
3652 | } | 3663 | } |
3653 | 3664 | ||
3654 | // It's possible for child agents to have transactions if changes are being made cross-border. | 3665 | // It's possible for child agents to have transactions if changes are being made cross-border. |
3655 | if (AgentTransactionsModule != null) | 3666 | if (AgentTransactionsModule != null) |
3667 | { | ||
3668 | // m_log.Debug("[Scene]RemoveAgentAssetTransactions"); | ||
3656 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); | 3669 | AgentTransactionsModule.RemoveAgentAssetTransactions(agentID); |
3670 | } | ||
3657 | m_log.Debug("[Scene] The avatar has left the building"); | 3671 | m_log.Debug("[Scene] The avatar has left the building"); |
3658 | } | 3672 | } |
3659 | catch (Exception e) | 3673 | catch (Exception e) |
@@ -3727,7 +3741,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3727 | } | 3741 | } |
3728 | deleteIDs.Add(localID); | 3742 | deleteIDs.Add(localID); |
3729 | } | 3743 | } |
3730 | ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); }); | 3744 | |
3745 | ForEachClient(c => c.SendKillObject(deleteIDs)); | ||
3731 | } | 3746 | } |
3732 | 3747 | ||
3733 | #endregion | 3748 | #endregion |
@@ -3763,13 +3778,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3763 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of | 3778 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of |
3764 | /// the LLUDP stack). | 3779 | /// the LLUDP stack). |
3765 | /// </remarks> | 3780 | /// </remarks> |
3766 | /// <param name="agent">CircuitData of the agent who is connecting</param> | 3781 | /// <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> | 3782 | /// <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 | 3783 | /// <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> | 3784 | /// 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 | 3785 | /// <returns>True if the region accepts this agent. False if it does not. False will |
3771 | /// also return a reason.</returns> | 3786 | /// also return a reason.</returns> |
3772 | public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) | 3787 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, out string reason, bool requirePresenceLookup) |
3773 | { | 3788 | { |
3774 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || | 3789 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || |
3775 | (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); | 3790 | (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); |
@@ -3789,15 +3804,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3789 | m_log.DebugFormat( | 3804 | 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})", | 3805 | "[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, | 3806 | RegionInfo.RegionName, |
3792 | (agent.child ? "child" : "root"), | 3807 | (acd.child ? "child" : "root"), |
3793 | agent.firstname, | 3808 | acd.firstname, |
3794 | agent.lastname, | 3809 | acd.lastname, |
3795 | agent.AgentID, | 3810 | acd.AgentID, |
3796 | agent.circuitcode, | 3811 | acd.circuitcode, |
3797 | agent.IPAddress, | 3812 | acd.IPAddress, |
3798 | agent.Viewer, | 3813 | acd.Viewer, |
3799 | ((TPFlags)teleportFlags).ToString(), | 3814 | ((TPFlags)teleportFlags).ToString(), |
3800 | agent.startpos | 3815 | acd.startpos |
3801 | ); | 3816 | ); |
3802 | 3817 | ||
3803 | if (!LoginsEnabled) | 3818 | if (!LoginsEnabled) |
@@ -3815,7 +3830,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3815 | { | 3830 | { |
3816 | foreach (string viewer in m_AllowedViewers) | 3831 | foreach (string viewer in m_AllowedViewers) |
3817 | { | 3832 | { |
3818 | if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) | 3833 | if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower()) |
3819 | { | 3834 | { |
3820 | ViewerDenied = false; | 3835 | ViewerDenied = false; |
3821 | break; | 3836 | break; |
@@ -3832,7 +3847,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3832 | { | 3847 | { |
3833 | foreach (string viewer in m_BannedViewers) | 3848 | foreach (string viewer in m_BannedViewers) |
3834 | { | 3849 | { |
3835 | if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) | 3850 | if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower()) |
3836 | { | 3851 | { |
3837 | ViewerDenied = true; | 3852 | ViewerDenied = true; |
3838 | break; | 3853 | break; |
@@ -3844,54 +3859,129 @@ namespace OpenSim.Region.Framework.Scenes | |||
3844 | { | 3859 | { |
3845 | m_log.DebugFormat( | 3860 | m_log.DebugFormat( |
3846 | "[SCENE]: Access denied for {0} {1} using {2}", | 3861 | "[SCENE]: Access denied for {0} {1} using {2}", |
3847 | agent.firstname, agent.lastname, agent.Viewer); | 3862 | acd.firstname, acd.lastname, acd.Viewer); |
3848 | reason = "Access denied, your viewer is banned by the region owner"; | 3863 | reason = "Access denied, your viewer is banned by the region owner"; |
3849 | return false; | 3864 | return false; |
3850 | } | 3865 | } |
3851 | 3866 | ||
3852 | ScenePresence sp = GetScenePresence(agent.AgentID); | 3867 | ILandObject land; |
3868 | ScenePresence sp; | ||
3853 | 3869 | ||
3854 | // If we have noo presence here or if that presence is a zombie root | 3870 | lock (m_removeClientLock) |
3855 | // presence that will be kicled, we need a new CAPS object. | ||
3856 | if (sp == null || (sp != null && !sp.IsChildAgent)) | ||
3857 | { | 3871 | { |
3858 | if (CapsModule != null) | 3872 | sp = GetScenePresence(acd.AgentID); |
3873 | |||
3874 | // We need to ensure that we are not already removing the scene presence before we ask it not to be | ||
3875 | // closed. | ||
3876 | if (sp != null && sp.IsChildAgent | ||
3877 | && (sp.LifecycleState == ScenePresenceState.Running | ||
3878 | || sp.LifecycleState == ScenePresenceState.PreRemove)) | ||
3859 | { | 3879 | { |
3860 | lock (agent) | 3880 | m_log.DebugFormat( |
3881 | "[SCENE]: Reusing existing child scene presence for {0}, state {1} in {2}", | ||
3882 | sp.Name, sp.LifecycleState, Name); | ||
3883 | |||
3884 | // In the case where, for example, an A B C D region layout, an avatar may | ||
3885 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C | ||
3886 | // renews the lease on the child agent at B, we must make sure that the close from A does not succeed. | ||
3887 | // | ||
3888 | // XXX: In the end, this should not be necessary if child agents are closed without delay on | ||
3889 | // teleport, since realistically, the close request should always be processed before any other | ||
3890 | // region tried to re-establish a child agent. This is much simpler since the logic below is | ||
3891 | // vulnerable to an issue when a viewer quits a region without sending a proper logout but then | ||
3892 | // re-establishes the connection on a relogin. This could wrongly set the DoNotCloseAfterTeleport | ||
3893 | // flag when no teleport had taken place (and hence no close was going to come). | ||
3894 | // if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) | ||
3895 | // { | ||
3896 | // m_log.DebugFormat( | ||
3897 | // "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", | ||
3898 | // sp.Name, Name); | ||
3899 | // | ||
3900 | // sp.DoNotCloseAfterTeleport = true; | ||
3901 | // } | ||
3902 | // else if (EntityTransferModule.IsInTransit(sp.UUID)) | ||
3903 | |||
3904 | sp.LifecycleState = ScenePresenceState.Running; | ||
3905 | |||
3906 | if (EntityTransferModule.IsInTransit(sp.UUID)) | ||
3861 | { | 3907 | { |
3862 | CapsModule.SetAgentCapsSeeds(agent); | 3908 | sp.DoNotCloseAfterTeleport = true; |
3863 | CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); | 3909 | |
3910 | m_log.DebugFormat( | ||
3911 | "[SCENE]: Set DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt end-of-teleport close from a previous close.", | ||
3912 | sp.Name, Name); | ||
3864 | } | 3913 | } |
3865 | } | 3914 | } |
3866 | } | 3915 | } |
3867 | 3916 | ||
3917 | // Need to poll here in case we are currently deleting an sp. Letting threads run over each other will | ||
3918 | // allow unpredictable things to happen. | ||
3868 | if (sp != null) | 3919 | if (sp != null) |
3869 | { | 3920 | { |
3870 | if (!sp.IsChildAgent) | 3921 | const int polls = 10; |
3922 | const int pollInterval = 1000; | ||
3923 | int pollsLeft = polls; | ||
3924 | |||
3925 | while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0) | ||
3926 | Thread.Sleep(pollInterval); | ||
3927 | |||
3928 | if (sp.LifecycleState == ScenePresenceState.Removing) | ||
3871 | { | 3929 | { |
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( | 3930 | m_log.WarnFormat( |
3876 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | 3931 | "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.", |
3877 | sp.Name, sp.UUID, RegionInfo.RegionName); | 3932 | sp.Name, Name, polls * pollInterval / 1000); |
3878 | 3933 | ||
3879 | sp.ControllingClient.Close(true, true); | 3934 | return false; |
3880 | sp = null; | 3935 | } |
3936 | else if (polls != pollsLeft) | ||
3937 | { | ||
3938 | m_log.DebugFormat( | ||
3939 | "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.", | ||
3940 | sp.Name, Name, polls * pollInterval / 1000); | ||
3881 | } | 3941 | } |
3882 | } | 3942 | } |
3883 | 3943 | ||
3884 | lock (agent) | 3944 | // TODO: can we remove this lock? |
3945 | lock (acd) | ||
3885 | { | 3946 | { |
3886 | //On login test land permisions | 3947 | if (sp != null && !sp.IsChildAgent) |
3948 | { | ||
3949 | // We have a root agent. Is it in transit? | ||
3950 | if (!EntityTransferModule.IsInTransit(sp.UUID)) | ||
3951 | { | ||
3952 | // We have a zombie from a crashed session. | ||
3953 | // Or the same user is trying to be root twice here, won't work. | ||
3954 | // Kill it. | ||
3955 | m_log.WarnFormat( | ||
3956 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | ||
3957 | sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3958 | |||
3959 | if (sp.ControllingClient != null) | ||
3960 | CloseAgent(sp.UUID, true); | ||
3961 | |||
3962 | sp = null; | ||
3963 | } | ||
3964 | //else | ||
3965 | // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3966 | } | ||
3967 | |||
3968 | // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. | ||
3969 | // We need the circuit data here for some of the subsequent checks. (groups, for example) | ||
3970 | // If the checks fail, we remove the circuit. | ||
3971 | acd.teleportFlags = teleportFlags; | ||
3972 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); | ||
3973 | |||
3974 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); | ||
3975 | |||
3976 | // On login test land permisions | ||
3887 | if (vialogin) | 3977 | if (vialogin) |
3888 | { | 3978 | { |
3889 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); | 3979 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); |
3890 | if (cache != null) | 3980 | if (cache != null) |
3891 | cache.Remove(agent.firstname + " " + agent.lastname); | 3981 | cache.Remove(acd.firstname + " " + acd.lastname); |
3892 | if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) | 3982 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) |
3893 | { | 3983 | { |
3894 | m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); | 3984 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3895 | return false; | 3985 | return false; |
3896 | } | 3986 | } |
3897 | } | 3987 | } |
@@ -3902,84 +3992,97 @@ namespace OpenSim.Region.Framework.Scenes | |||
3902 | { | 3992 | { |
3903 | try | 3993 | try |
3904 | { | 3994 | { |
3905 | if (!VerifyUserPresence(agent, out reason)) | 3995 | if (!VerifyUserPresence(acd, out reason)) |
3996 | { | ||
3997 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); | ||
3906 | return false; | 3998 | return false; |
3907 | } catch (Exception e) | 3999 | } |
4000 | } | ||
4001 | catch (Exception e) | ||
3908 | { | 4002 | { |
3909 | m_log.ErrorFormat( | 4003 | m_log.ErrorFormat( |
3910 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); | 4004 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); |
4005 | |||
4006 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); | ||
3911 | return false; | 4007 | return false; |
3912 | } | 4008 | } |
3913 | } | 4009 | } |
3914 | 4010 | ||
3915 | try | 4011 | try |
3916 | { | 4012 | { |
3917 | // Always check estate if this is a login. Always | 4013 | if (!AuthorizeUser(acd, (vialogin ? false : SeeIntoRegion), out reason)) |
3918 | // check if banned regions are to be blacked out. | ||
3919 | if (vialogin || (!m_seeIntoBannedRegion)) | ||
3920 | { | 4014 | { |
3921 | if (!AuthorizeUser(agent, out reason)) | 4015 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3922 | { | 4016 | return false; |
3923 | return false; | ||
3924 | } | ||
3925 | } | 4017 | } |
3926 | } | 4018 | } |
3927 | catch (Exception e) | 4019 | catch (Exception e) |
3928 | { | 4020 | { |
3929 | m_log.ErrorFormat( | 4021 | m_log.ErrorFormat( |
3930 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); | 4022 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); |
4023 | |||
4024 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); | ||
3931 | return false; | 4025 | return false; |
3932 | } | 4026 | } |
3933 | 4027 | ||
3934 | m_log.InfoFormat( | 4028 | m_log.InfoFormat( |
3935 | "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", | 4029 | "[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, | 4030 | Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname, |
3937 | agent.AgentID, agent.circuitcode); | 4031 | acd.AgentID, acd.circuitcode); |
3938 | 4032 | ||
4033 | if (CapsModule != null) | ||
4034 | { | ||
4035 | CapsModule.SetAgentCapsSeeds(acd); | ||
4036 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); | ||
4037 | } | ||
3939 | } | 4038 | } |
3940 | else | 4039 | else |
3941 | { | 4040 | { |
3942 | // Let the SP know how we got here. This has a lot of interesting | 4041 | // Let the SP know how we got here. This has a lot of interesting |
3943 | // uses down the line. | 4042 | // uses down the line. |
3944 | sp.TeleportFlags = (TPFlags)teleportFlags; | 4043 | sp.TeleportFlags = (TPFlags)teleportFlags; |
3945 | 4044 | ||
3946 | if (sp.IsChildAgent) | 4045 | if (sp.IsChildAgent) |
3947 | { | 4046 | { |
3948 | m_log.DebugFormat( | 4047 | m_log.DebugFormat( |
3949 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", | 4048 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", |
3950 | agent.AgentID, RegionInfo.RegionName); | 4049 | acd.AgentID, RegionInfo.RegionName); |
3951 | 4050 | ||
3952 | sp.AdjustKnownSeeds(); | 4051 | sp.AdjustKnownSeeds(); |
3953 | 4052 | ||
3954 | if (CapsModule != null) | 4053 | if (CapsModule != null) |
3955 | CapsModule.SetAgentCapsSeeds(agent); | 4054 | { |
4055 | CapsModule.SetAgentCapsSeeds(acd); | ||
4056 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); | ||
4057 | } | ||
3956 | } | 4058 | } |
3957 | } | 4059 | } |
3958 | } | ||
3959 | 4060 | ||
3960 | // In all cases, add or update the circuit data with the new agent circuit data and teleport flags | 4061 | // Try caching an incoming user name much earlier on to see if this helps with an issue |
3961 | agent.teleportFlags = teleportFlags; | 4062 | // where HG users are occasionally seen by others as "Unknown User" because their UUIDName |
3962 | m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); | 4063 | // request for the HG avatar appears to trigger before the user name is cached. |
4064 | CacheUserName(null, acd); | ||
4065 | } | ||
3963 | 4066 | ||
3964 | if (CapsModule != null) | 4067 | if (CapsModule != null) |
3965 | { | 4068 | { |
3966 | CapsModule.ActivateCaps(agent.circuitcode); | 4069 | CapsModule.ActivateCaps(acd.circuitcode); |
3967 | } | 4070 | } |
3968 | 4071 | ||
3969 | if (vialogin) | 4072 | if (vialogin) |
3970 | { | 4073 | { |
3971 | // CleanDroppedAttachments(); | 4074 | // CleanDroppedAttachments(); |
3972 | 4075 | ||
3973 | if (TestBorderCross(agent.startpos, Cardinals.E)) | 4076 | if (TestBorderCross(acd.startpos, Cardinals.E)) |
3974 | { | 4077 | { |
3975 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); | 4078 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); |
3976 | agent.startpos.X = crossedBorder.BorderLine.Z - 1; | 4079 | acd.startpos.X = crossedBorder.BorderLine.Z - 1; |
3977 | } | 4080 | } |
3978 | 4081 | ||
3979 | if (TestBorderCross(agent.startpos, Cardinals.N)) | 4082 | if (TestBorderCross(acd.startpos, Cardinals.N)) |
3980 | { | 4083 | { |
3981 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N); | 4084 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); |
3982 | agent.startpos.Y = crossedBorder.BorderLine.Z - 1; | 4085 | acd.startpos.Y = crossedBorder.BorderLine.Z - 1; |
3983 | } | 4086 | } |
3984 | 4087 | ||
3985 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 | 4088 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 |
@@ -3989,68 +4092,88 @@ namespace OpenSim.Region.Framework.Scenes | |||
3989 | { | 4092 | { |
3990 | lock (EastBorders) | 4093 | lock (EastBorders) |
3991 | { | 4094 | { |
3992 | if (agent.startpos.X > EastBorders[0].BorderLine.Z) | 4095 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) |
3993 | { | 4096 | { |
3994 | m_log.Warn("FIX AGENT POSITION"); | 4097 | m_log.Warn("FIX AGENT POSITION"); |
3995 | agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | 4098 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; |
3996 | if (agent.startpos.Z > 720) | 4099 | if (acd.startpos.Z > 720) |
3997 | agent.startpos.Z = 720; | 4100 | acd.startpos.Z = 720; |
3998 | } | 4101 | } |
3999 | } | 4102 | } |
4000 | lock (NorthBorders) | 4103 | lock (NorthBorders) |
4001 | { | 4104 | { |
4002 | if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) | 4105 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) |
4003 | { | 4106 | { |
4004 | m_log.Warn("FIX Agent POSITION"); | 4107 | m_log.Warn("FIX Agent POSITION"); |
4005 | agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | 4108 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; |
4006 | if (agent.startpos.Z > 720) | 4109 | if (acd.startpos.Z > 720) |
4007 | agent.startpos.Z = 720; | 4110 | acd.startpos.Z = 720; |
4008 | } | 4111 | } |
4009 | } | 4112 | } |
4010 | } else | 4113 | } else |
4011 | { | 4114 | { |
4012 | if (agent.startpos.X > EastBorders[0].BorderLine.Z) | 4115 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) |
4013 | { | 4116 | { |
4014 | m_log.Warn("FIX AGENT POSITION"); | 4117 | m_log.Warn("FIX AGENT POSITION"); |
4015 | agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | 4118 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; |
4016 | if (agent.startpos.Z > 720) | 4119 | if (acd.startpos.Z > 720) |
4017 | agent.startpos.Z = 720; | 4120 | acd.startpos.Z = 720; |
4018 | } | 4121 | } |
4019 | if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) | 4122 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) |
4020 | { | 4123 | { |
4021 | m_log.Warn("FIX Agent POSITION"); | 4124 | m_log.Warn("FIX Agent POSITION"); |
4022 | agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | 4125 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; |
4023 | if (agent.startpos.Z > 720) | 4126 | if (acd.startpos.Z > 720) |
4024 | agent.startpos.Z = 720; | 4127 | acd.startpos.Z = 720; |
4025 | } | 4128 | } |
4026 | } | 4129 | } |
4027 | 4130 | ||
4131 | // m_log.DebugFormat( | ||
4132 | // "[SCENE]: Found telehub object {0} for new user connection {1} to {2}", | ||
4133 | // RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); | ||
4134 | |||
4028 | // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags | 4135 | // Honor Estate teleport routing via Telehubs excluding ViaHome and GodLike TeleportFlags |
4029 | if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && | 4136 | if (RegionInfo.RegionSettings.TelehubObject != UUID.Zero && |
4030 | RegionInfo.EstateSettings.AllowDirectTeleport == false && | 4137 | RegionInfo.EstateSettings.AllowDirectTeleport == false && |
4031 | !viahome && !godlike) | 4138 | !viahome && !godlike) |
4032 | { | 4139 | { |
4033 | SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); | 4140 | SceneObjectGroup telehub = GetSceneObjectGroup(RegionInfo.RegionSettings.TelehubObject); |
4034 | // Can have multiple SpawnPoints | 4141 | |
4035 | List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); | 4142 | if (telehub != null) |
4036 | if (spawnpoints.Count > 1) | ||
4037 | { | 4143 | { |
4038 | // We have multiple SpawnPoints, Route the agent to a random or sequential one | 4144 | // Can have multiple SpawnPoints |
4039 | if (SpawnPointRouting == "random") | 4145 | List<SpawnPoint> spawnpoints = RegionInfo.RegionSettings.SpawnPoints(); |
4040 | agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( | 4146 | if (spawnpoints.Count > 1) |
4041 | telehub.AbsolutePosition, | 4147 | { |
4042 | telehub.GroupRotation | 4148 | // We have multiple SpawnPoints, Route the agent to a random or sequential one |
4043 | ); | 4149 | if (SpawnPointRouting == "random") |
4150 | acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( | ||
4151 | telehub.AbsolutePosition, | ||
4152 | telehub.GroupRotation | ||
4153 | ); | ||
4154 | else | ||
4155 | acd.startpos = spawnpoints[SpawnPoint()].GetLocation( | ||
4156 | telehub.AbsolutePosition, | ||
4157 | telehub.GroupRotation | ||
4158 | ); | ||
4159 | } | ||
4160 | else if (spawnpoints.Count == 1) | ||
4161 | { | ||
4162 | // We have a single SpawnPoint and will route the agent to it | ||
4163 | acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | ||
4164 | } | ||
4044 | else | 4165 | else |
4045 | agent.startpos = spawnpoints[SpawnPoint()].GetLocation( | 4166 | { |
4046 | telehub.AbsolutePosition, | 4167 | m_log.DebugFormat( |
4047 | telehub.GroupRotation | 4168 | "[SCENE]: No spawnpoints defined for telehub {0} for {1} in {2}. Continuing.", |
4048 | ); | 4169 | RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); |
4170 | } | ||
4049 | } | 4171 | } |
4050 | else | 4172 | else |
4051 | { | 4173 | { |
4052 | // We have a single SpawnPoint and will route the agent to it | 4174 | m_log.DebugFormat( |
4053 | agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | 4175 | "[SCENE]: No telehub {0} found to direct {1} in {2}. Continuing.", |
4176 | RegionInfo.RegionSettings.TelehubObject, acd.Name, Name); | ||
4054 | } | 4177 | } |
4055 | 4178 | ||
4056 | return true; | 4179 | return true; |
@@ -4063,7 +4186,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4063 | { | 4186 | { |
4064 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) | 4187 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) |
4065 | { | 4188 | { |
4066 | agent.startpos = land.LandData.UserLocation; | 4189 | acd.startpos = land.LandData.UserLocation; |
4067 | } | 4190 | } |
4068 | } | 4191 | } |
4069 | */// This is now handled properly in ScenePresence.MakeRootAgent | 4192 | */// This is now handled properly in ScenePresence.MakeRootAgent |
@@ -4158,7 +4281,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4158 | /// <param name="reason">outputs the reason to this string</param> | 4281 | /// <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 | 4282 | /// <returns>True if the region accepts this agent. False if it does not. False will |
4160 | /// also return a reason.</returns> | 4283 | /// also return a reason.</returns> |
4161 | protected virtual bool AuthorizeUser(AgentCircuitData agent, out string reason) | 4284 | protected virtual bool AuthorizeUser(AgentCircuitData agent, bool bypassAccessControl, out string reason) |
4162 | { | 4285 | { |
4163 | reason = String.Empty; | 4286 | reason = String.Empty; |
4164 | 4287 | ||
@@ -4177,67 +4300,75 @@ namespace OpenSim.Region.Framework.Scenes | |||
4177 | } | 4300 | } |
4178 | } | 4301 | } |
4179 | 4302 | ||
4180 | if (RegionInfo.EstateSettings != null) | 4303 | // We only test the things below when we want to cut off |
4304 | // child agents from being present in the scene for which their root | ||
4305 | // agent isn't allowed. Otherwise, we allow child agents. The test for | ||
4306 | // the root is done elsewhere (QueryAccess) | ||
4307 | if (!bypassAccessControl) | ||
4181 | { | 4308 | { |
4182 | if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, 0)) | 4309 | if (RegionInfo.EstateSettings != null) |
4183 | { | 4310 | { |
4184 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", | 4311 | int flags = GetUserFlags(agent.AgentID); |
4185 | agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); | 4312 | if (RegionInfo.EstateSettings.IsBanned(agent.AgentID, flags)) |
4186 | reason = String.Format("Denied access to region {0}: You have been banned from that region.", | 4313 | { |
4187 | RegionInfo.RegionName); | 4314 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", |
4188 | return false; | 4315 | agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); |
4316 | reason = String.Format("Denied access to region {0}: You have been banned from that region.", | ||
4317 | RegionInfo.RegionName); | ||
4318 | return false; | ||
4319 | } | ||
4189 | } | 4320 | } |
4190 | } | 4321 | 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 | { | 4322 | { |
4204 | for (int i = 0; i < GroupMembership.Length; i++) | 4323 | m_log.ErrorFormat("[CONNECTION BEGIN]: Estate Settings is null!"); |
4205 | agentGroups.Add(GroupMembership[i].GroupID); | ||
4206 | } | 4324 | } |
4207 | else | 4325 | |
4326 | List<UUID> agentGroups = new List<UUID>(); | ||
4327 | |||
4328 | if (m_groupsModule != null) | ||
4208 | { | 4329 | { |
4209 | m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!"); | 4330 | GroupMembershipData[] GroupMembership = m_groupsModule.GetMembershipData(agent.AgentID); |
4331 | |||
4332 | if (GroupMembership != null) | ||
4333 | { | ||
4334 | for (int i = 0; i < GroupMembership.Length; i++) | ||
4335 | agentGroups.Add(GroupMembership[i].GroupID); | ||
4336 | } | ||
4337 | else | ||
4338 | { | ||
4339 | m_log.ErrorFormat("[CONNECTION BEGIN]: GroupMembership is null!"); | ||
4340 | } | ||
4210 | } | 4341 | } |
4211 | } | ||
4212 | 4342 | ||
4213 | bool groupAccess = false; | 4343 | bool groupAccess = false; |
4214 | UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; | 4344 | UUID[] estateGroups = RegionInfo.EstateSettings.EstateGroups; |
4215 | 4345 | ||
4216 | if (estateGroups != null) | 4346 | if (estateGroups != null) |
4217 | { | ||
4218 | foreach (UUID group in estateGroups) | ||
4219 | { | 4347 | { |
4220 | if (agentGroups.Contains(group)) | 4348 | foreach (UUID group in estateGroups) |
4221 | { | 4349 | { |
4222 | groupAccess = true; | 4350 | if (agentGroups.Contains(group)) |
4223 | break; | 4351 | { |
4352 | groupAccess = true; | ||
4353 | break; | ||
4354 | } | ||
4224 | } | 4355 | } |
4225 | } | 4356 | } |
4226 | } | 4357 | else |
4227 | else | 4358 | { |
4228 | { | 4359 | m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); |
4229 | m_log.ErrorFormat("[CONNECTION BEGIN]: EstateGroups is null!"); | 4360 | } |
4230 | } | ||
4231 | 4361 | ||
4232 | if (!RegionInfo.EstateSettings.PublicAccess && | 4362 | if (!RegionInfo.EstateSettings.PublicAccess && |
4233 | !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && | 4363 | !RegionInfo.EstateSettings.HasAccess(agent.AgentID) && |
4234 | !groupAccess) | 4364 | !groupAccess) |
4235 | { | 4365 | { |
4236 | m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user does not have access to the estate", | 4366 | 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); | 4367 | 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.", | 4368 | reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", |
4239 | RegionInfo.RegionName); | 4369 | RegionInfo.RegionName); |
4240 | return false; | 4370 | return false; |
4371 | } | ||
4241 | } | 4372 | } |
4242 | 4373 | ||
4243 | // TODO: estate/region settings are not properly hooked up | 4374 | // TODO: estate/region settings are not properly hooked up |
@@ -4362,13 +4493,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
4362 | /// <param name="cAgentData">Agent that contains all of the relevant things about an agent. | 4493 | /// <param name="cAgentData">Agent that contains all of the relevant things about an agent. |
4363 | /// Appearance, animations, position, etc.</param> | 4494 | /// Appearance, animations, position, etc.</param> |
4364 | /// <returns>true if we handled it.</returns> | 4495 | /// <returns>true if we handled it.</returns> |
4365 | public virtual bool IncomingChildAgentDataUpdate(AgentData cAgentData) | 4496 | public virtual bool IncomingUpdateChildAgent(AgentData cAgentData) |
4366 | { | 4497 | { |
4367 | m_log.DebugFormat( | 4498 | m_log.DebugFormat( |
4368 | "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); | 4499 | "[SCENE]: Incoming child agent update for {0} in {1}", cAgentData.AgentID, RegionInfo.RegionName); |
4369 | 4500 | ||
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. | 4501 | // We have to wait until the viewer contacts this region after receiving EAC. |
4373 | // That calls AddNewClient, which finally creates the ScenePresence | 4502 | // That calls AddNewClient, which finally creates the ScenePresence |
4374 | int flags = GetUserFlags(cAgentData.AgentID); | 4503 | int flags = GetUserFlags(cAgentData.AgentID); |
@@ -4382,7 +4511,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4382 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); | 4511 | ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); |
4383 | if (nearestParcel == null) | 4512 | if (nearestParcel == null) |
4384 | { | 4513 | { |
4385 | m_log.DebugFormat( | 4514 | m_log.InfoFormat( |
4386 | "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", | 4515 | "[SCENE]: Denying root agent entry to {0} in {1}: no allowed parcel", |
4387 | cAgentData.AgentID, RegionInfo.RegionName); | 4516 | cAgentData.AgentID, RegionInfo.RegionName); |
4388 | 4517 | ||
@@ -4390,13 +4519,44 @@ namespace OpenSim.Region.Framework.Scenes | |||
4390 | } | 4519 | } |
4391 | 4520 | ||
4392 | // We have to wait until the viewer contacts this region | 4521 | // 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 | 4522 | // 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. | 4523 | // or TeleportFinish (for the v2 teleport protocol). This triggers the viewer to send |
4395 | ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); | 4524 | // a UseCircuitCode packet which in turn calls AddNewAgent which finally creates the ScenePresence. |
4525 | ScenePresence sp = WaitGetScenePresence(cAgentData.AgentID); | ||
4396 | 4526 | ||
4397 | if (childAgentUpdate != null) | 4527 | if (sp != null) |
4398 | { | 4528 | { |
4399 | childAgentUpdate.ChildAgentDataUpdate(cAgentData); | 4529 | if (cAgentData.SessionID != sp.ControllingClient.SessionId) |
4530 | { | ||
4531 | m_log.WarnFormat( | ||
4532 | "[SCENE]: Attempt to update agent {0} with invalid session id {1} (possibly from simulator in older version; tell them to update).", | ||
4533 | sp.UUID, cAgentData.SessionID); | ||
4534 | |||
4535 | Console.WriteLine(String.Format("[SCENE]: Attempt to update agent {0} ({1}) with invalid session id {2}", | ||
4536 | sp.UUID, sp.ControllingClient.SessionId, cAgentData.SessionID)); | ||
4537 | } | ||
4538 | |||
4539 | sp.UpdateChildAgent(cAgentData); | ||
4540 | |||
4541 | int ntimes = 20; | ||
4542 | if (cAgentData.SenderWantsToWaitForRoot) | ||
4543 | { | ||
4544 | while (sp.IsChildAgent && ntimes-- > 0) | ||
4545 | Thread.Sleep(1000); | ||
4546 | |||
4547 | if (sp.IsChildAgent) | ||
4548 | m_log.WarnFormat( | ||
4549 | "[SCENE]: Found presence {0} {1} unexpectedly still child in {2}", | ||
4550 | sp.Name, sp.UUID, Name); | ||
4551 | else | ||
4552 | m_log.InfoFormat( | ||
4553 | "[SCENE]: Found presence {0} {1} as root in {2} after {3} waits", | ||
4554 | sp.Name, sp.UUID, Name, 20 - ntimes); | ||
4555 | |||
4556 | if (sp.IsChildAgent) | ||
4557 | return false; | ||
4558 | } | ||
4559 | |||
4400 | return true; | 4560 | return true; |
4401 | } | 4561 | } |
4402 | 4562 | ||
@@ -4409,12 +4569,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
4409 | /// </summary> | 4569 | /// </summary> |
4410 | /// <param name="cAgentData">AgentPosition that contains agent positional data so we can know what to send</param> | 4570 | /// <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> | 4571 | /// <returns>true if we handled it.</returns> |
4412 | public virtual bool IncomingChildAgentDataUpdate(AgentPosition cAgentData) | 4572 | public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData) |
4413 | { | 4573 | { |
4414 | //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); | 4574 | //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); |
4415 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); | 4575 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); |
4416 | if (childAgentUpdate != null) | 4576 | if (childAgentUpdate != null) |
4417 | { | 4577 | { |
4578 | // if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) | ||
4579 | // // Only warn for now | ||
4580 | // m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", | ||
4581 | // childAgentUpdate.UUID, cAgentData.SessionID); | ||
4582 | |||
4418 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. | 4583 | // 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.. | 4584 | // however to avoid a race condition crossing borders.. |
4420 | if (childAgentUpdate.IsChildAgent) | 4585 | if (childAgentUpdate.IsChildAgent) |
@@ -4424,7 +4589,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4424 | uint tRegionX = RegionInfo.RegionLocX; | 4589 | uint tRegionX = RegionInfo.RegionLocX; |
4425 | uint tRegionY = RegionInfo.RegionLocY; | 4590 | uint tRegionY = RegionInfo.RegionLocY; |
4426 | //Send Data to ScenePresence | 4591 | //Send Data to ScenePresence |
4427 | childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); | 4592 | childAgentUpdate.UpdateChildAgent(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); |
4428 | // Not Implemented: | 4593 | // Not Implemented: |
4429 | //TODO: Do we need to pass the message on to one of our neighbors? | 4594 | //TODO: Do we need to pass the message on to one of our neighbors? |
4430 | } | 4595 | } |
@@ -4451,35 +4616,99 @@ namespace OpenSim.Region.Framework.Scenes | |||
4451 | m_log.WarnFormat( | 4616 | m_log.WarnFormat( |
4452 | "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", | 4617 | "[SCENE PRESENCE]: Did not find presence with id {0} in {1} before timeout", |
4453 | agentID, RegionInfo.RegionName); | 4618 | 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 | 4619 | ||
4459 | return sp; | 4620 | return sp; |
4460 | } | 4621 | } |
4461 | 4622 | ||
4462 | public virtual bool IncomingRetrieveRootAgent(UUID id, out IAgentData agent) | 4623 | /// <summary> |
4624 | /// Authenticated close (via network) | ||
4625 | /// </summary> | ||
4626 | /// <param name="agentID"></param> | ||
4627 | /// <param name="force"></param> | ||
4628 | /// <param name="auth_token"></param> | ||
4629 | /// <returns></returns> | ||
4630 | public bool CloseAgent(UUID agentID, bool force, string auth_token) | ||
4463 | { | 4631 | { |
4464 | agent = null; | 4632 | //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); | 4633 | |
4466 | if ((sp != null) && (!sp.IsChildAgent)) | 4634 | // Check that the auth_token is valid |
4635 | AgentCircuitData acd = AuthenticateHandler.GetAgentCircuitData(agentID); | ||
4636 | |||
4637 | if (acd == null) | ||
4467 | { | 4638 | { |
4468 | sp.IsChildAgent = true; | 4639 | m_log.DebugFormat( |
4469 | return sp.CopyAgent(out agent); | 4640 | "[SCENE]: Request to close agent {0} but no such agent in scene {1}. May have been closed previously.", |
4641 | agentID, Name); | ||
4642 | |||
4643 | return false; | ||
4644 | } | ||
4645 | |||
4646 | if (acd.SessionID.ToString() == auth_token) | ||
4647 | { | ||
4648 | return CloseAgent(agentID, force); | ||
4649 | } | ||
4650 | else | ||
4651 | { | ||
4652 | m_log.WarnFormat( | ||
4653 | "[SCENE]: Request to close agent {0} with invalid authorization token {1} in {2}", | ||
4654 | agentID, auth_token, Name); | ||
4470 | } | 4655 | } |
4471 | 4656 | ||
4472 | return false; | 4657 | return false; |
4473 | } | 4658 | } |
4474 | 4659 | ||
4475 | public bool IncomingCloseAgent(UUID agentID) | 4660 | // public bool IncomingCloseAgent(UUID agentID) |
4476 | { | 4661 | // { |
4477 | return IncomingCloseAgent(agentID, false); | 4662 | // return IncomingCloseAgent(agentID, false); |
4478 | } | 4663 | // } |
4479 | 4664 | ||
4480 | public bool IncomingCloseChildAgent(UUID agentID) | 4665 | // public bool IncomingCloseChildAgent(UUID agentID) |
4666 | // { | ||
4667 | // return IncomingCloseAgent(agentID, true); | ||
4668 | // } | ||
4669 | |||
4670 | /// <summary> | ||
4671 | /// Tell a single client to prepare to close. | ||
4672 | /// </summary> | ||
4673 | /// <remarks> | ||
4674 | /// This should only be called if we may close the client but there will be some delay in so doing. Meant for | ||
4675 | /// internal use - other callers should almost certainly called CloseClient(). | ||
4676 | /// </remarks> | ||
4677 | /// <param name="sp"></param> | ||
4678 | /// <returns>true if pre-close state notification was successful. false if the agent | ||
4679 | /// was not in a state where it could transition to pre-close.</returns> | ||
4680 | public bool IncomingPreCloseClient(ScenePresence sp) | ||
4481 | { | 4681 | { |
4482 | return IncomingCloseAgent(agentID, true); | 4682 | lock (m_removeClientLock) |
4683 | { | ||
4684 | // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may | ||
4685 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not | ||
4686 | // want to obey this close since C may have renewed the child agent lease on B. | ||
4687 | if (sp.DoNotCloseAfterTeleport) | ||
4688 | { | ||
4689 | m_log.DebugFormat( | ||
4690 | "[SCENE]: Not pre-closing {0} agent {1} in {2} since another simulator has re-established the child connection", | ||
4691 | sp.IsChildAgent ? "child" : "root", sp.Name, Name); | ||
4692 | |||
4693 | // Need to reset the flag so that a subsequent close after another teleport can succeed. | ||
4694 | sp.DoNotCloseAfterTeleport = false; | ||
4695 | |||
4696 | return false; | ||
4697 | } | ||
4698 | |||
4699 | if (sp.LifecycleState != ScenePresenceState.Running) | ||
4700 | { | ||
4701 | m_log.DebugFormat( | ||
4702 | "[SCENE]: Called IncomingPreCloseAgent() for {0} in {1} but presence is already in state {2}", | ||
4703 | sp.Name, Name, sp.LifecycleState); | ||
4704 | |||
4705 | return false; | ||
4706 | } | ||
4707 | |||
4708 | sp.LifecycleState = ScenePresenceState.PreRemove; | ||
4709 | |||
4710 | return true; | ||
4711 | } | ||
4483 | } | 4712 | } |
4484 | 4713 | ||
4485 | /// <summary> | 4714 | /// <summary> |
@@ -4490,18 +4719,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 | 4719 | /// 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. | 4720 | /// force unless you are absolutely sure that the agent is dead and a normal close is not working. |
4492 | /// </param> | 4721 | /// </param> |
4493 | public bool IncomingCloseAgent(UUID agentID, bool force) | 4722 | public override bool CloseAgent(UUID agentID, bool force) |
4494 | { | 4723 | { |
4495 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | 4724 | ScenePresence sp; |
4496 | 4725 | ||
4497 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | 4726 | lock (m_removeClientLock) |
4498 | if (presence != null) | ||
4499 | { | 4727 | { |
4500 | presence.ControllingClient.Close(force, force); | 4728 | sp = GetScenePresence(agentID); |
4729 | |||
4730 | if (sp == null) | ||
4731 | { | ||
4732 | m_log.DebugFormat( | ||
4733 | "[SCENE]: Called CloseClient() with agent ID {0} but no such presence is in {1}", | ||
4734 | agentID, Name); | ||
4735 | |||
4736 | return false; | ||
4737 | } | ||
4738 | |||
4739 | if (sp.LifecycleState != ScenePresenceState.Running && sp.LifecycleState != ScenePresenceState.PreRemove) | ||
4740 | { | ||
4741 | m_log.DebugFormat( | ||
4742 | "[SCENE]: Called CloseClient() for {0} in {1} but presence is already in state {2}", | ||
4743 | sp.Name, Name, sp.LifecycleState); | ||
4744 | |||
4745 | return false; | ||
4746 | } | ||
4747 | |||
4748 | // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may | ||
4749 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not | ||
4750 | // want to obey this close since C may have renewed the child agent lease on B. | ||
4751 | if (sp.DoNotCloseAfterTeleport) | ||
4752 | { | ||
4753 | m_log.DebugFormat( | ||
4754 | "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection", | ||
4755 | sp.IsChildAgent ? "child" : "root", sp.Name, Name); | ||
4756 | |||
4757 | // Need to reset the flag so that a subsequent close after another teleport can succeed. | ||
4758 | sp.DoNotCloseAfterTeleport = false; | ||
4759 | |||
4760 | return false; | ||
4761 | } | ||
4762 | |||
4763 | sp.LifecycleState = ScenePresenceState.Removing; | ||
4764 | } | ||
4765 | |||
4766 | if (sp != null) | ||
4767 | { | ||
4768 | sp.ControllingClient.Close(force, force); | ||
4501 | return true; | 4769 | return true; |
4502 | } | 4770 | } |
4503 | 4771 | ||
4504 | // Agent not here | 4772 | // Agent not here |
4505 | return false; | 4773 | return false; |
4506 | } | 4774 | } |
4507 | 4775 | ||
@@ -5091,21 +5359,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
5091 | 5359 | ||
5092 | #endregion | 5360 | #endregion |
5093 | 5361 | ||
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 | 5362 | ||
5110 | // Commented pending deletion since this method no longer appears to do anything at all | 5363 | // Commented pending deletion since this method no longer appears to do anything at all |
5111 | // public bool NeedSceneCacheClear(UUID agentID) | 5364 | // public bool NeedSceneCacheClear(UUID agentID) |
@@ -5657,12 +5910,12 @@ Environment.Exit(1); | |||
5657 | List<SceneObjectGroup> objects, | 5910 | List<SceneObjectGroup> objects, |
5658 | out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) | 5911 | out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) |
5659 | { | 5912 | { |
5660 | minX = 256; | 5913 | minX = float.MaxValue; |
5661 | maxX = -256; | 5914 | maxX = float.MinValue; |
5662 | minY = 256; | 5915 | minY = float.MaxValue; |
5663 | maxY = -256; | 5916 | maxY = float.MinValue; |
5664 | minZ = 8192; | 5917 | minZ = float.MaxValue; |
5665 | maxZ = -256; | 5918 | maxZ = float.MinValue; |
5666 | 5919 | ||
5667 | List<Vector3> offsets = new List<Vector3>(); | 5920 | List<Vector3> offsets = new List<Vector3>(); |
5668 | 5921 | ||
@@ -5802,17 +6055,6 @@ Environment.Exit(1); | |||
5802 | { | 6055 | { |
5803 | reason = "You are banned from the region"; | 6056 | reason = "You are banned from the region"; |
5804 | 6057 | ||
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)) | 6058 | if (Permissions.IsGod(agentID)) |
5817 | { | 6059 | { |
5818 | reason = String.Empty; | 6060 | reason = String.Empty; |
@@ -5862,9 +6104,9 @@ Environment.Exit(1); | |||
5862 | 6104 | ||
5863 | try | 6105 | try |
5864 | { | 6106 | { |
5865 | if (!AuthorizeUser(aCircuit, out reason)) | 6107 | if (!AuthorizeUser(aCircuit, false, out reason)) |
5866 | { | 6108 | { |
5867 | // m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); | 6109 | //m_log.DebugFormat("[SCENE]: Denying access for {0}", agentID); |
5868 | return false; | 6110 | return false; |
5869 | } | 6111 | } |
5870 | } | 6112 | } |