aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs362
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