diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 88 |
1 files changed, 55 insertions, 33 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d2c7c76..b4274ba 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -110,6 +110,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | 112 | ||
113 | /// <summary> | ||
114 | /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and | ||
115 | /// the viewer fires these in quick succession. | ||
116 | /// </summary> | ||
117 | /// <remarks> | ||
118 | /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement | ||
119 | /// regulation done there. | ||
120 | /// </remarks> | ||
121 | private object m_completeMovementLock = new object(); | ||
122 | |||
113 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 123 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
114 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 124 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
115 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 125 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -980,6 +990,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
980 | /// <summary> | 990 | /// <summary> |
981 | /// Turns a child agent into a root agent. | 991 | /// Turns a child agent into a root agent. |
982 | /// </summary> | 992 | /// </summary> |
993 | /// <remarks> | ||
983 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the | 994 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the |
984 | /// avatar is actual in the sim. They can perform all actions. | 995 | /// avatar is actual in the sim. They can perform all actions. |
985 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, | 996 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, |
@@ -987,49 +998,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
987 | /// | 998 | /// |
988 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here | 999 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here |
989 | /// delays that crossing. | 1000 | /// delays that crossing. |
990 | /// </summary> | 1001 | /// </remarks> |
991 | private void MakeRootAgent(Vector3 pos, bool isFlying) | 1002 | private bool MakeRootAgent(Vector3 pos, bool isFlying) |
992 | { | 1003 | { |
993 | // m_log.InfoFormat( | 1004 | lock (m_completeMovementLock) |
994 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | ||
995 | // Name, m_scene.RegionInfo.RegionName); | ||
996 | |||
997 | if (ParentUUID != UUID.Zero) | ||
998 | { | 1005 | { |
999 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); | 1006 | if (!IsChildAgent) |
1000 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | 1007 | return false; |
1001 | if (part == null) | 1008 | |
1009 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | ||
1010 | |||
1011 | // m_log.InfoFormat( | ||
1012 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | ||
1013 | // Name, m_scene.RegionInfo.RegionName); | ||
1014 | |||
1015 | if (ParentUUID != UUID.Zero) | ||
1002 | { | 1016 | { |
1003 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | 1017 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); |
1018 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | ||
1019 | if (part == null) | ||
1020 | { | ||
1021 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | ||
1022 | } | ||
1023 | else | ||
1024 | { | ||
1025 | part.ParentGroup.AddAvatar(UUID); | ||
1026 | if (part.SitTargetPosition != Vector3.Zero) | ||
1027 | part.SitTargetAvatar = UUID; | ||
1028 | // ParentPosition = part.GetWorldPosition(); | ||
1029 | ParentID = part.LocalId; | ||
1030 | ParentPart = part; | ||
1031 | m_pos = PrevSitOffset; | ||
1032 | // pos = ParentPosition; | ||
1033 | pos = part.GetWorldPosition(); | ||
1034 | } | ||
1035 | ParentUUID = UUID.Zero; | ||
1036 | |||
1037 | // Animator.TrySetMovementAnimation("SIT"); | ||
1004 | } | 1038 | } |
1005 | else | 1039 | else |
1006 | { | 1040 | { |
1007 | part.ParentGroup.AddAvatar(UUID); | 1041 | IsLoggingIn = false; |
1008 | if (part.SitTargetPosition != Vector3.Zero) | ||
1009 | part.SitTargetAvatar = UUID; | ||
1010 | // ParentPosition = part.GetWorldPosition(); | ||
1011 | ParentID = part.LocalId; | ||
1012 | ParentPart = part; | ||
1013 | m_pos = PrevSitOffset; | ||
1014 | // pos = ParentPosition; | ||
1015 | pos = part.GetWorldPosition(); | ||
1016 | } | 1042 | } |
1017 | ParentUUID = UUID.Zero; | ||
1018 | |||
1019 | IsChildAgent = false; | ||
1020 | 1043 | ||
1021 | // Animator.TrySetMovementAnimation("SIT"); | ||
1022 | } | ||
1023 | else | ||
1024 | { | ||
1025 | IsChildAgent = false; | 1044 | IsChildAgent = false; |
1026 | IsLoggingIn = false; | ||
1027 | } | 1045 | } |
1028 | 1046 | ||
1029 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | ||
1030 | |||
1031 | IsChildAgent = false; | ||
1032 | |||
1033 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag | 1047 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag |
1034 | // set and prevent the close of the connection on a subsequent re-teleport. | 1048 | // set and prevent the close of the connection on a subsequent re-teleport. |
1035 | // Should not be needed if we are not trying to tell this region to close | 1049 | // Should not be needed if we are not trying to tell this region to close |
@@ -1216,6 +1230,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1216 | 1230 | ||
1217 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1231 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1218 | 1232 | ||
1233 | return true; | ||
1219 | } | 1234 | } |
1220 | 1235 | ||
1221 | public int GetStateSource() | 1236 | public int GetStateSource() |
@@ -1639,7 +1654,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1639 | } | 1654 | } |
1640 | 1655 | ||
1641 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1656 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1642 | MakeRootAgent(AbsolutePosition, flying); | 1657 | if (!MakeRootAgent(AbsolutePosition, flying)) |
1658 | { | ||
1659 | m_log.DebugFormat( | ||
1660 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", | ||
1661 | Name, Scene.Name); | ||
1662 | |||
1663 | return; | ||
1664 | } | ||
1643 | 1665 | ||
1644 | // Tell the client that we're totally ready | 1666 | // Tell the client that we're totally ready |
1645 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | 1667 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |