diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 362 |
1 files changed, 232 insertions, 130 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index aa09092..6323a88 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 | ||
@@ -1338,7 +1338,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1338 | Thread.Sleep(500); | 1338 | Thread.Sleep(500); |
1339 | 1339 | ||
1340 | // Stop all client threads. | 1340 | // Stop all client threads. |
1341 | ForEachScenePresence(delegate(ScenePresence avatar) { avatar.ControllingClient.Close(); }); | 1341 | ForEachScenePresence(delegate(ScenePresence avatar) { IncomingCloseAgent(avatar.UUID, false); }); |
1342 | 1342 | ||
1343 | m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); | 1343 | m_log.Debug("[SCENE]: TriggerSceneShuttingDown"); |
1344 | EventManager.TriggerSceneShuttingDown(this); | 1344 | EventManager.TriggerSceneShuttingDown(this); |
@@ -3127,7 +3127,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3127 | if (sp != null) | 3127 | if (sp != null) |
3128 | { | 3128 | { |
3129 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); | 3129 | PresenceService.LogoutAgent(sp.ControllingClient.SessionId); |
3130 | sp.ControllingClient.Close(); | 3130 | |
3131 | IncomingCloseAgent(sp.UUID, false); | ||
3131 | } | 3132 | } |
3132 | 3133 | ||
3133 | // BANG! SLASH! | 3134 | // BANG! SLASH! |
@@ -3541,47 +3542,48 @@ namespace OpenSim.Region.Framework.Scenes | |||
3541 | 3542 | ||
3542 | public override void RemoveClient(UUID agentID, bool closeChildAgents) | 3543 | public override void RemoveClient(UUID agentID, bool closeChildAgents) |
3543 | { | 3544 | { |
3544 | // CheckHeartbeat(); | 3545 | AgentCircuitData acd = m_authenticateHandler.GetAgentCircuitData(agentID); |
3545 | bool isChildAgent = false; | ||
3546 | AgentCircuitData acd; | ||
3547 | 3546 | ||
3548 | lock (m_removeClientLock) | 3547 | // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which |
3548 | // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not | ||
3549 | // However, will keep for now just in case. | ||
3550 | if (acd == null) | ||
3549 | { | 3551 | { |
3550 | acd = m_authenticateHandler.GetAgentCircuitData(agentID); | 3552 | m_log.ErrorFormat( |
3553 | "[SCENE]: No agent circuit found for {0} in {1}, aborting Scene.RemoveClient", agentID, Name); | ||
3551 | 3554 | ||
3552 | if (acd == null) | 3555 | return; |
3553 | { | 3556 | } |
3554 | m_log.ErrorFormat("[SCENE]: No agent circuit found for {0}, aborting Scene.RemoveClient", agentID); | 3557 | else |
3555 | return; | 3558 | { |
3556 | } | 3559 | m_authenticateHandler.RemoveCircuit(agentID); |
3557 | else | ||
3558 | { | ||
3559 | // We remove the acd up here to avoid later race conditions if two RemoveClient() calls occurred | ||
3560 | // simultaneously. | ||
3561 | // We also need to remove by agent ID since NPCs will have no circuit code. | ||
3562 | m_authenticateHandler.RemoveCircuit(agentID); | ||
3563 | } | ||
3564 | } | 3560 | } |
3565 | 3561 | ||
3562 | // TODO: Can we now remove this lock? | ||
3566 | lock (acd) | 3563 | lock (acd) |
3567 | { | 3564 | { |
3565 | bool isChildAgent = false; | ||
3566 | |||
3568 | ScenePresence avatar = GetScenePresence(agentID); | 3567 | ScenePresence avatar = GetScenePresence(agentID); |
3569 | 3568 | ||
3569 | // Shouldn't be necessary since RemoveClient() is currently only called by IClientAPI.Close() which | ||
3570 | // in turn is only called by Scene.IncomingCloseAgent() which checks whether the presence exists or not | ||
3571 | // However, will keep for now just in case. | ||
3570 | if (avatar == null) | 3572 | if (avatar == null) |
3571 | { | 3573 | { |
3572 | m_log.WarnFormat( | 3574 | m_log.ErrorFormat( |
3573 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); | 3575 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in the scene.", agentID); |
3574 | 3576 | ||
3575 | return; | 3577 | return; |
3576 | } | 3578 | } |
3577 | 3579 | ||
3578 | try | 3580 | try |
3579 | { | 3581 | { |
3580 | isChildAgent = avatar.IsChildAgent; | 3582 | isChildAgent = avatar.IsChildAgent; |
3581 | 3583 | ||
3582 | m_log.DebugFormat( | 3584 | m_log.DebugFormat( |
3583 | "[SCENE]: Removing {0} agent {1} {2} from {3}", | 3585 | "[SCENE]: Removing {0} agent {1} {2} from {3}", |
3584 | (isChildAgent ? "child" : "root"), avatar.Name, agentID, RegionInfo.RegionName); | 3586 | isChildAgent ? "child" : "root", avatar.Name, agentID, Name); |
3585 | 3587 | ||
3586 | // Don't do this to root agents, it's not nice for the viewer | 3588 | // Don't do this to root agents, it's not nice for the viewer |
3587 | if (closeChildAgents && isChildAgent) | 3589 | if (closeChildAgents && isChildAgent) |
@@ -3745,13 +3747,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3745 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of | 3747 | /// is activated later when the viewer sends the initial UseCircuitCodePacket UDP packet (in the case of |
3746 | /// the LLUDP stack). | 3748 | /// the LLUDP stack). |
3747 | /// </remarks> | 3749 | /// </remarks> |
3748 | /// <param name="agent">CircuitData of the agent who is connecting</param> | 3750 | /// <param name="acd">CircuitData of the agent who is connecting</param> |
3749 | /// <param name="reason">Outputs the reason for the false response on this string</param> | 3751 | /// <param name="reason">Outputs the reason for the false response on this string</param> |
3750 | /// <param name="requirePresenceLookup">True for normal presence. False for NPC | 3752 | /// <param name="requirePresenceLookup">True for normal presence. False for NPC |
3751 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> | 3753 | /// or other applications where a full grid/Hypergrid presence may not be required.</param> |
3752 | /// <returns>True if the region accepts this agent. False if it does not. False will | 3754 | /// <returns>True if the region accepts this agent. False if it does not. False will |
3753 | /// also return a reason.</returns> | 3755 | /// also return a reason.</returns> |
3754 | public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason, bool requirePresenceLookup) | 3756 | public bool NewUserConnection(AgentCircuitData acd, uint teleportFlags, out string reason, bool requirePresenceLookup) |
3755 | { | 3757 | { |
3756 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || | 3758 | bool vialogin = ((teleportFlags & (uint)TPFlags.ViaLogin) != 0 || |
3757 | (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); | 3759 | (teleportFlags & (uint)TPFlags.ViaHGLogin) != 0); |
@@ -3771,15 +3773,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3771 | m_log.DebugFormat( | 3773 | m_log.DebugFormat( |
3772 | "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", | 3774 | "[SCENE]: Region {0} told of incoming {1} agent {2} {3} {4} (circuit code {5}, IP {6}, viewer {7}, teleportflags ({8}), position {9})", |
3773 | RegionInfo.RegionName, | 3775 | RegionInfo.RegionName, |
3774 | (agent.child ? "child" : "root"), | 3776 | (acd.child ? "child" : "root"), |
3775 | agent.firstname, | 3777 | acd.firstname, |
3776 | agent.lastname, | 3778 | acd.lastname, |
3777 | agent.AgentID, | 3779 | acd.AgentID, |
3778 | agent.circuitcode, | 3780 | acd.circuitcode, |
3779 | agent.IPAddress, | 3781 | acd.IPAddress, |
3780 | agent.Viewer, | 3782 | acd.Viewer, |
3781 | ((TPFlags)teleportFlags).ToString(), | 3783 | ((TPFlags)teleportFlags).ToString(), |
3782 | agent.startpos | 3784 | acd.startpos |
3783 | ); | 3785 | ); |
3784 | 3786 | ||
3785 | if (!LoginsEnabled) | 3787 | if (!LoginsEnabled) |
@@ -3797,7 +3799,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3797 | { | 3799 | { |
3798 | foreach (string viewer in m_AllowedViewers) | 3800 | foreach (string viewer in m_AllowedViewers) |
3799 | { | 3801 | { |
3800 | if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) | 3802 | if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower()) |
3801 | { | 3803 | { |
3802 | ViewerDenied = false; | 3804 | ViewerDenied = false; |
3803 | break; | 3805 | break; |
@@ -3814,7 +3816,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3814 | { | 3816 | { |
3815 | foreach (string viewer in m_BannedViewers) | 3817 | foreach (string viewer in m_BannedViewers) |
3816 | { | 3818 | { |
3817 | if (viewer == agent.Viewer.Substring(0, viewer.Length).Trim().ToLower()) | 3819 | if (viewer == acd.Viewer.Substring(0, viewer.Length).Trim().ToLower()) |
3818 | { | 3820 | { |
3819 | ViewerDenied = true; | 3821 | ViewerDenied = true; |
3820 | break; | 3822 | break; |
@@ -3826,61 +3828,115 @@ namespace OpenSim.Region.Framework.Scenes | |||
3826 | { | 3828 | { |
3827 | m_log.DebugFormat( | 3829 | m_log.DebugFormat( |
3828 | "[SCENE]: Access denied for {0} {1} using {2}", | 3830 | "[SCENE]: Access denied for {0} {1} using {2}", |
3829 | agent.firstname, agent.lastname, agent.Viewer); | 3831 | acd.firstname, acd.lastname, acd.Viewer); |
3830 | reason = "Access denied, your viewer is banned by the region owner"; | 3832 | reason = "Access denied, your viewer is banned by the region owner"; |
3831 | return false; | 3833 | return false; |
3832 | } | 3834 | } |
3835 | |||
3836 | ILandObject land; | ||
3837 | ScenePresence sp; | ||
3833 | 3838 | ||
3834 | lock (agent) | 3839 | lock (m_removeClientLock) |
3835 | { | 3840 | { |
3836 | ScenePresence sp = GetScenePresence(agent.AgentID); | 3841 | sp = GetScenePresence(acd.AgentID); |
3837 | 3842 | ||
3838 | if (sp != null) | 3843 | // We need to ensure that we are not already removing the scene presence before we ask it not to be |
3844 | // closed. | ||
3845 | if (sp != null && sp.IsChildAgent && sp.LifecycleState == ScenePresenceState.Running) | ||
3839 | { | 3846 | { |
3840 | if (!sp.IsChildAgent) | 3847 | m_log.DebugFormat( |
3841 | { | 3848 | "[SCENE]: Reusing existing child scene presence for {0} in {1}", sp.Name, Name); |
3842 | // We have a root agent. Is it in transit? | ||
3843 | if (!EntityTransferModule.IsInTransit(sp.UUID)) | ||
3844 | { | ||
3845 | // We have a zombie from a crashed session. | ||
3846 | // Or the same user is trying to be root twice here, won't work. | ||
3847 | // Kill it. | ||
3848 | m_log.WarnFormat( | ||
3849 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | ||
3850 | sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3851 | 3849 | ||
3852 | if (sp.ControllingClient != null) | 3850 | // In the case where, for example, an A B C D region layout, an avatar may |
3853 | sp.ControllingClient.Close(true, true); | 3851 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. When C |
3852 | // renews the lease on the child agent at B, we must make sure that the close from A does not succeed. | ||
3853 | if (!acd.ChildrenCapSeeds.ContainsKey(RegionInfo.RegionHandle)) | ||
3854 | { | ||
3855 | m_log.DebugFormat( | ||
3856 | "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because source will attempt close.", | ||
3857 | sp.Name, Name); | ||
3854 | 3858 | ||
3855 | sp = null; | 3859 | sp.DoNotCloseAfterTeleport = true; |
3856 | } | ||
3857 | //else | ||
3858 | // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3859 | } | 3860 | } |
3860 | else | 3861 | else if (EntityTransferModule.IsInTransit(sp.UUID)) |
3861 | { | 3862 | { |
3862 | // We have a child agent here | 3863 | m_log.DebugFormat( |
3864 | "[SCENE]: Setting DoNotCloseAfterTeleport for child scene presence {0} in {1} because this region will attempt previous end-of-teleport close.", | ||
3865 | sp.Name, Name); | ||
3866 | |||
3863 | sp.DoNotCloseAfterTeleport = true; | 3867 | sp.DoNotCloseAfterTeleport = true; |
3864 | //m_log.WarnFormat("[SCENE]: Existing child scene presence for {0} {1} in {2}", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3865 | } | 3868 | } |
3866 | } | 3869 | } |
3870 | } | ||
3871 | |||
3872 | // Need to poll here in case we are currently deleting an sp. Letting threads run over each other will | ||
3873 | // allow unpredictable things to happen. | ||
3874 | if (sp != null) | ||
3875 | { | ||
3876 | const int polls = 10; | ||
3877 | const int pollInterval = 1000; | ||
3878 | int pollsLeft = polls; | ||
3879 | |||
3880 | while (sp.LifecycleState == ScenePresenceState.Removing && pollsLeft-- > 0) | ||
3881 | Thread.Sleep(pollInterval); | ||
3882 | |||
3883 | if (sp.LifecycleState == ScenePresenceState.Removing) | ||
3884 | { | ||
3885 | m_log.WarnFormat( | ||
3886 | "[SCENE]: Agent {0} in {1} was still being removed after {2}s. Aborting NewUserConnection.", | ||
3887 | sp.Name, Name, polls * pollInterval / 1000); | ||
3888 | |||
3889 | return false; | ||
3890 | } | ||
3891 | else if (polls != pollsLeft) | ||
3892 | { | ||
3893 | m_log.DebugFormat( | ||
3894 | "[SCENE]: NewUserConnection for agent {0} in {1} had to wait {2}s for in-progress removal to complete on an old presence.", | ||
3895 | sp.Name, Name, polls * pollInterval / 1000); | ||
3896 | } | ||
3897 | } | ||
3898 | |||
3899 | // TODO: can we remove this lock? | ||
3900 | lock (acd) | ||
3901 | { | ||
3902 | if (sp != null && !sp.IsChildAgent) | ||
3903 | { | ||
3904 | // We have a root agent. Is it in transit? | ||
3905 | if (!EntityTransferModule.IsInTransit(sp.UUID)) | ||
3906 | { | ||
3907 | // We have a zombie from a crashed session. | ||
3908 | // Or the same user is trying to be root twice here, won't work. | ||
3909 | // Kill it. | ||
3910 | m_log.WarnFormat( | ||
3911 | "[SCENE]: Existing root scene presence detected for {0} {1} in {2} when connecting. Removing existing presence.", | ||
3912 | sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3913 | |||
3914 | if (sp.ControllingClient != null) | ||
3915 | IncomingCloseAgent(sp.UUID, true); | ||
3916 | |||
3917 | sp = null; | ||
3918 | } | ||
3919 | //else | ||
3920 | // m_log.WarnFormat("[SCENE]: Existing root scene presence for {0} {1} in {2}, but agent is in trasit", sp.Name, sp.UUID, RegionInfo.RegionName); | ||
3921 | } | ||
3867 | 3922 | ||
3868 | // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. | 3923 | // Optimistic: add or update the circuit data with the new agent circuit data and teleport flags. |
3869 | // We need the circuit data here for some of the subsequent checks. (groups, for example) | 3924 | // We need the circuit data here for some of the subsequent checks. (groups, for example) |
3870 | // If the checks fail, we remove the circuit. | 3925 | // If the checks fail, we remove the circuit. |
3871 | agent.teleportFlags = teleportFlags; | 3926 | acd.teleportFlags = teleportFlags; |
3872 | m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); | 3927 | m_authenticateHandler.AddNewCircuit(acd.circuitcode, acd); |
3873 | 3928 | ||
3929 | land = LandChannel.GetLandObject(acd.startpos.X, acd.startpos.Y); | ||
3930 | |||
3874 | // On login test land permisions | 3931 | // On login test land permisions |
3875 | if (vialogin) | 3932 | if (vialogin) |
3876 | { | 3933 | { |
3877 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); | 3934 | IUserAccountCacheModule cache = RequestModuleInterface<IUserAccountCacheModule>(); |
3878 | if (cache != null) | 3935 | if (cache != null) |
3879 | cache.Remove(agent.firstname + " " + agent.lastname); | 3936 | cache.Remove(acd.firstname + " " + acd.lastname); |
3880 | if (!TestLandRestrictions(agent.AgentID, out reason, ref agent.startpos.X, ref agent.startpos.Y)) | 3937 | if (land != null && !TestLandRestrictions(acd.AgentID, out reason, ref acd.startpos.X, ref acd.startpos.Y)) |
3881 | { | 3938 | { |
3882 | m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); | 3939 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3883 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | ||
3884 | return false; | 3940 | return false; |
3885 | } | 3941 | } |
3886 | } | 3942 | } |
@@ -3891,9 +3947,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3891 | { | 3947 | { |
3892 | try | 3948 | try |
3893 | { | 3949 | { |
3894 | if (!VerifyUserPresence(agent, out reason)) | 3950 | if (!VerifyUserPresence(acd, out reason)) |
3895 | { | 3951 | { |
3896 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3952 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3897 | return false; | 3953 | return false; |
3898 | } | 3954 | } |
3899 | } | 3955 | } |
@@ -3902,16 +3958,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3902 | m_log.ErrorFormat( | 3958 | m_log.ErrorFormat( |
3903 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); | 3959 | "[SCENE]: Exception verifying presence {0}{1}", e.Message, e.StackTrace); |
3904 | 3960 | ||
3905 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3961 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3906 | return false; | 3962 | return false; |
3907 | } | 3963 | } |
3908 | } | 3964 | } |
3909 | 3965 | ||
3910 | try | 3966 | try |
3911 | { | 3967 | { |
3912 | if (!AuthorizeUser(agent, SeeIntoRegion, out reason)) | 3968 | if (!AuthorizeUser(acd, SeeIntoRegion, out reason)) |
3913 | { | 3969 | { |
3914 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3970 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3915 | return false; | 3971 | return false; |
3916 | } | 3972 | } |
3917 | } | 3973 | } |
@@ -3920,15 +3976,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
3920 | m_log.ErrorFormat( | 3976 | m_log.ErrorFormat( |
3921 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); | 3977 | "[SCENE]: Exception authorizing user {0}{1}", e.Message, e.StackTrace); |
3922 | 3978 | ||
3923 | m_authenticateHandler.RemoveCircuit(agent.circuitcode); | 3979 | m_authenticateHandler.RemoveCircuit(acd.circuitcode); |
3924 | return false; | 3980 | return false; |
3925 | } | 3981 | } |
3926 | 3982 | ||
3927 | m_log.InfoFormat( | 3983 | m_log.InfoFormat( |
3928 | "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", | 3984 | "[SCENE]: Region {0} authenticated and authorized incoming {1} agent {2} {3} {4} (circuit code {5})", |
3929 | RegionInfo.RegionName, (agent.child ? "child" : "root"), agent.firstname, agent.lastname, | 3985 | Name, (acd.child ? "child" : "root"), acd.firstname, acd.lastname, |
3930 | agent.AgentID, agent.circuitcode); | 3986 | acd.AgentID, acd.circuitcode); |
3931 | 3987 | ||
3988 | if (CapsModule != null) | ||
3989 | { | ||
3990 | CapsModule.SetAgentCapsSeeds(acd); | ||
3991 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); | ||
3992 | } | ||
3932 | } | 3993 | } |
3933 | else | 3994 | else |
3934 | { | 3995 | { |
@@ -3940,14 +4001,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3940 | { | 4001 | { |
3941 | m_log.DebugFormat( | 4002 | m_log.DebugFormat( |
3942 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", | 4003 | "[SCENE]: Adjusting known seeds for existing agent {0} in {1}", |
3943 | agent.AgentID, RegionInfo.RegionName); | 4004 | acd.AgentID, RegionInfo.RegionName); |
3944 | 4005 | ||
3945 | sp.AdjustKnownSeeds(); | 4006 | sp.AdjustKnownSeeds(); |
3946 | 4007 | ||
3947 | if (CapsModule != null) | 4008 | if (CapsModule != null) |
3948 | { | 4009 | { |
3949 | CapsModule.SetAgentCapsSeeds(agent); | 4010 | CapsModule.SetAgentCapsSeeds(acd); |
3950 | CapsModule.CreateCaps(agent.AgentID, agent.circuitcode); | 4011 | CapsModule.CreateCaps(acd.AgentID, acd.circuitcode); |
3951 | } | 4012 | } |
3952 | } | 4013 | } |
3953 | } | 4014 | } |
@@ -3955,28 +4016,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3955 | // Try caching an incoming user name much earlier on to see if this helps with an issue | 4016 | // Try caching an incoming user name much earlier on to see if this helps with an issue |
3956 | // where HG users are occasionally seen by others as "Unknown User" because their UUIDName | 4017 | // where HG users are occasionally seen by others as "Unknown User" because their UUIDName |
3957 | // request for the HG avatar appears to trigger before the user name is cached. | 4018 | // request for the HG avatar appears to trigger before the user name is cached. |
3958 | CacheUserName(null, agent); | 4019 | CacheUserName(null, acd); |
3959 | } | 4020 | } |
3960 | 4021 | ||
3961 | if (CapsModule != null) | 4022 | if (CapsModule != null) |
3962 | { | 4023 | { |
3963 | CapsModule.ActivateCaps(agent.circuitcode); | 4024 | CapsModule.ActivateCaps(acd.circuitcode); |
3964 | } | 4025 | } |
3965 | 4026 | ||
3966 | if (vialogin) | 4027 | if (vialogin) |
3967 | { | 4028 | { |
3968 | // CleanDroppedAttachments(); | 4029 | // CleanDroppedAttachments(); |
3969 | 4030 | ||
3970 | if (TestBorderCross(agent.startpos, Cardinals.E)) | 4031 | if (TestBorderCross(acd.startpos, Cardinals.E)) |
3971 | { | 4032 | { |
3972 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); | 4033 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.E); |
3973 | agent.startpos.X = crossedBorder.BorderLine.Z - 1; | 4034 | acd.startpos.X = crossedBorder.BorderLine.Z - 1; |
3974 | } | 4035 | } |
3975 | 4036 | ||
3976 | if (TestBorderCross(agent.startpos, Cardinals.N)) | 4037 | if (TestBorderCross(acd.startpos, Cardinals.N)) |
3977 | { | 4038 | { |
3978 | Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.N); | 4039 | Border crossedBorder = GetCrossedBorder(acd.startpos, Cardinals.N); |
3979 | agent.startpos.Y = crossedBorder.BorderLine.Z - 1; | 4040 | acd.startpos.Y = crossedBorder.BorderLine.Z - 1; |
3980 | } | 4041 | } |
3981 | 4042 | ||
3982 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 | 4043 | //Mitigate http://opensimulator.org/mantis/view.php?id=3522 |
@@ -3986,39 +4047,39 @@ namespace OpenSim.Region.Framework.Scenes | |||
3986 | { | 4047 | { |
3987 | lock (EastBorders) | 4048 | lock (EastBorders) |
3988 | { | 4049 | { |
3989 | if (agent.startpos.X > EastBorders[0].BorderLine.Z) | 4050 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) |
3990 | { | 4051 | { |
3991 | m_log.Warn("FIX AGENT POSITION"); | 4052 | m_log.Warn("FIX AGENT POSITION"); |
3992 | agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | 4053 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; |
3993 | if (agent.startpos.Z > 720) | 4054 | if (acd.startpos.Z > 720) |
3994 | agent.startpos.Z = 720; | 4055 | acd.startpos.Z = 720; |
3995 | } | 4056 | } |
3996 | } | 4057 | } |
3997 | lock (NorthBorders) | 4058 | lock (NorthBorders) |
3998 | { | 4059 | { |
3999 | if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) | 4060 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) |
4000 | { | 4061 | { |
4001 | m_log.Warn("FIX Agent POSITION"); | 4062 | m_log.Warn("FIX Agent POSITION"); |
4002 | agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | 4063 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; |
4003 | if (agent.startpos.Z > 720) | 4064 | if (acd.startpos.Z > 720) |
4004 | agent.startpos.Z = 720; | 4065 | acd.startpos.Z = 720; |
4005 | } | 4066 | } |
4006 | } | 4067 | } |
4007 | } else | 4068 | } else |
4008 | { | 4069 | { |
4009 | if (agent.startpos.X > EastBorders[0].BorderLine.Z) | 4070 | if (acd.startpos.X > EastBorders[0].BorderLine.Z) |
4010 | { | 4071 | { |
4011 | m_log.Warn("FIX AGENT POSITION"); | 4072 | m_log.Warn("FIX AGENT POSITION"); |
4012 | agent.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; | 4073 | acd.startpos.X = EastBorders[0].BorderLine.Z * 0.5f; |
4013 | if (agent.startpos.Z > 720) | 4074 | if (acd.startpos.Z > 720) |
4014 | agent.startpos.Z = 720; | 4075 | acd.startpos.Z = 720; |
4015 | } | 4076 | } |
4016 | if (agent.startpos.Y > NorthBorders[0].BorderLine.Z) | 4077 | if (acd.startpos.Y > NorthBorders[0].BorderLine.Z) |
4017 | { | 4078 | { |
4018 | m_log.Warn("FIX Agent POSITION"); | 4079 | m_log.Warn("FIX Agent POSITION"); |
4019 | agent.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; | 4080 | acd.startpos.Y = NorthBorders[0].BorderLine.Z * 0.5f; |
4020 | if (agent.startpos.Z > 720) | 4081 | if (acd.startpos.Z > 720) |
4021 | agent.startpos.Z = 720; | 4082 | acd.startpos.Z = 720; |
4022 | } | 4083 | } |
4023 | } | 4084 | } |
4024 | 4085 | ||
@@ -4034,12 +4095,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
4034 | { | 4095 | { |
4035 | // We have multiple SpawnPoints, Route the agent to a random or sequential one | 4096 | // We have multiple SpawnPoints, Route the agent to a random or sequential one |
4036 | if (SpawnPointRouting == "random") | 4097 | if (SpawnPointRouting == "random") |
4037 | agent.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( | 4098 | acd.startpos = spawnpoints[Util.RandomClass.Next(spawnpoints.Count) - 1].GetLocation( |
4038 | telehub.AbsolutePosition, | 4099 | telehub.AbsolutePosition, |
4039 | telehub.GroupRotation | 4100 | telehub.GroupRotation |
4040 | ); | 4101 | ); |
4041 | else | 4102 | else |
4042 | agent.startpos = spawnpoints[SpawnPoint()].GetLocation( | 4103 | acd.startpos = spawnpoints[SpawnPoint()].GetLocation( |
4043 | telehub.AbsolutePosition, | 4104 | telehub.AbsolutePosition, |
4044 | telehub.GroupRotation | 4105 | telehub.GroupRotation |
4045 | ); | 4106 | ); |
@@ -4047,7 +4108,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4047 | else | 4108 | else |
4048 | { | 4109 | { |
4049 | // We have a single SpawnPoint and will route the agent to it | 4110 | // We have a single SpawnPoint and will route the agent to it |
4050 | agent.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | 4111 | acd.startpos = spawnpoints[0].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); |
4051 | } | 4112 | } |
4052 | 4113 | ||
4053 | return true; | 4114 | return true; |
@@ -4060,7 +4121,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4060 | { | 4121 | { |
4061 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) | 4122 | if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero) |
4062 | { | 4123 | { |
4063 | agent.startpos = land.LandData.UserLocation; | 4124 | acd.startpos = land.LandData.UserLocation; |
4064 | } | 4125 | } |
4065 | } | 4126 | } |
4066 | */// This is now handled properly in ScenePresence.MakeRootAgent | 4127 | */// This is now handled properly in ScenePresence.MakeRootAgent |
@@ -4444,24 +4505,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
4444 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); | 4505 | ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); |
4445 | if (childAgentUpdate != null) | 4506 | if (childAgentUpdate != null) |
4446 | { | 4507 | { |
4447 | if (childAgentUpdate.ControllingClient.SessionId == cAgentData.SessionID) | 4508 | if (childAgentUpdate.ControllingClient.SessionId != cAgentData.SessionID) |
4509 | // Only warn for now | ||
4510 | m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}. Neighbor running older version?", | ||
4511 | childAgentUpdate.UUID, cAgentData.SessionID); | ||
4512 | |||
4513 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. | ||
4514 | // however to avoid a race condition crossing borders.. | ||
4515 | if (childAgentUpdate.IsChildAgent) | ||
4448 | { | 4516 | { |
4449 | // I can't imagine *yet* why we would get an update if the agent is a root agent.. | 4517 | uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); |
4450 | // however to avoid a race condition crossing borders.. | 4518 | uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); |
4451 | if (childAgentUpdate.IsChildAgent) | 4519 | uint tRegionX = RegionInfo.RegionLocX; |
4452 | { | 4520 | uint tRegionY = RegionInfo.RegionLocY; |
4453 | uint rRegionX = (uint)(cAgentData.RegionHandle >> 40); | 4521 | //Send Data to ScenePresence |
4454 | uint rRegionY = (((uint)(cAgentData.RegionHandle)) >> 8); | 4522 | childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); |
4455 | uint tRegionX = RegionInfo.RegionLocX; | 4523 | // Not Implemented: |
4456 | uint tRegionY = RegionInfo.RegionLocY; | 4524 | //TODO: Do we need to pass the message on to one of our neighbors? |
4457 | //Send Data to ScenePresence | ||
4458 | childAgentUpdate.ChildAgentDataUpdate(cAgentData, tRegionX, tRegionY, rRegionX, rRegionY); | ||
4459 | // Not Implemented: | ||
4460 | //TODO: Do we need to pass the message on to one of our neighbors? | ||
4461 | } | ||
4462 | } | 4525 | } |
4463 | else | 4526 | |
4464 | m_log.WarnFormat("[SCENE]: Attempt at updating position of agent {0} with invalid session id {1}", childAgentUpdate.UUID, cAgentData.SessionID); | ||
4465 | return true; | 4527 | return true; |
4466 | } | 4528 | } |
4467 | 4529 | ||
@@ -4540,11 +4602,51 @@ namespace OpenSim.Region.Framework.Scenes | |||
4540 | /// </param> | 4602 | /// </param> |
4541 | public bool IncomingCloseAgent(UUID agentID, bool force) | 4603 | public bool IncomingCloseAgent(UUID agentID, bool force) |
4542 | { | 4604 | { |
4543 | //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); | 4605 | ScenePresence sp; |
4544 | ScenePresence presence = m_sceneGraph.GetScenePresence(agentID); | 4606 | |
4545 | if (presence != null) | 4607 | lock (m_removeClientLock) |
4608 | { | ||
4609 | sp = GetScenePresence(agentID); | ||
4610 | |||
4611 | if (sp == null) | ||
4612 | { | ||
4613 | m_log.DebugFormat( | ||
4614 | "[SCENE]: Called RemoveClient() with agent ID {0} but no such presence is in {1}", | ||
4615 | agentID, Name); | ||
4616 | |||
4617 | return false; | ||
4618 | } | ||
4619 | |||
4620 | if (sp.LifecycleState != ScenePresenceState.Running) | ||
4621 | { | ||
4622 | m_log.DebugFormat( | ||
4623 | "[SCENE]: Called RemoveClient() for {0} in {1} but presence is already in state {2}", | ||
4624 | sp.Name, Name, sp.LifecycleState); | ||
4625 | |||
4626 | return false; | ||
4627 | } | ||
4628 | |||
4629 | // We need to avoid a race condition where in, for example, an A B C D region layout, an avatar may | ||
4630 | // teleport from A -> D, but then -> C before A has asked B to close its old child agent. We do not | ||
4631 | // want to obey this close since C may have renewed the child agent lease on B. | ||
4632 | if (sp.DoNotCloseAfterTeleport) | ||
4633 | { | ||
4634 | m_log.DebugFormat( | ||
4635 | "[SCENE]: Not closing {0} agent {1} in {2} since another simulator has re-established the child connection", | ||
4636 | sp.IsChildAgent ? "child" : "root", sp.Name, Name); | ||
4637 | |||
4638 | // Need to reset the flag so that a subsequent close after another teleport can succeed. | ||
4639 | sp.DoNotCloseAfterTeleport = false; | ||
4640 | |||
4641 | return false; | ||
4642 | } | ||
4643 | |||
4644 | sp.LifecycleState = ScenePresenceState.Removing; | ||
4645 | } | ||
4646 | |||
4647 | if (sp != null) | ||
4546 | { | 4648 | { |
4547 | presence.ControllingClient.Close(force, force); | 4649 | sp.ControllingClient.Close(force, force); |
4548 | return true; | 4650 | return true; |
4549 | } | 4651 | } |
4550 | 4652 | ||