diff options
author | Melanie | 2014-01-28 21:02:20 +0000 |
---|---|---|
committer | Melanie | 2014-01-28 21:02:20 +0000 |
commit | c6e9db58669d773c85041db99b19b942f70324f7 (patch) | |
tree | 99f69fb669332cff69a45ce6f7473aed6d965a0d /OpenSim/Region/Framework/Scenes/ScenePresence.cs | |
parent | Merge branch 'master' into careminster (diff) | |
parent | Merge branch 'justincc-master' (diff) | |
download | opensim-SC_OLD-c6e9db58669d773c85041db99b19b942f70324f7.zip opensim-SC_OLD-c6e9db58669d773c85041db99b19b942f70324f7.tar.gz opensim-SC_OLD-c6e9db58669d773c85041db99b19b942f70324f7.tar.bz2 opensim-SC_OLD-c6e9db58669d773c85041db99b19b942f70324f7.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Framework/RegionSettings.cs
OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
OpenSim/Region/Framework/Interfaces/IInterregionComms.cs
OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 135 |
1 files changed, 86 insertions, 49 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 252c72f..f57d4fe 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -109,6 +109,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | /// <summary> | ||
113 | /// This exists to prevent race conditions between two CompleteMovement threads if the simulator is slow and | ||
114 | /// the viewer fires these in quick succession. | ||
115 | /// </summary> | ||
116 | /// <remarks> | ||
117 | /// TODO: The child -> agent transition should be folded into LifecycleState and the CompleteMovement | ||
118 | /// regulation done there. | ||
119 | /// </remarks> | ||
120 | private object m_completeMovementLock = new object(); | ||
121 | |||
112 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); | 122 | // private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); |
113 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); | 123 | private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); |
114 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); | 124 | private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); |
@@ -984,6 +994,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
984 | /// <summary> | 994 | /// <summary> |
985 | /// Turns a child agent into a root agent. | 995 | /// Turns a child agent into a root agent. |
986 | /// </summary> | 996 | /// </summary> |
997 | /// <remarks> | ||
987 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the | 998 | /// Child agents are logged into neighbouring sims largely to observe changes. Root agents exist when the |
988 | /// avatar is actual in the sim. They can perform all actions. | 999 | /// avatar is actual in the sim. They can perform all actions. |
989 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, | 1000 | /// This change is made whenever an avatar enters a region, whether by crossing over from a neighbouring sim, |
@@ -991,49 +1002,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
991 | /// | 1002 | /// |
992 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here | 1003 | /// This method is on the critical path for transferring an avatar from one region to another. Delay here |
993 | /// delays that crossing. | 1004 | /// delays that crossing. |
994 | /// </summary> | 1005 | /// </remarks> |
995 | private void MakeRootAgent(Vector3 pos, bool isFlying) | 1006 | private bool MakeRootAgent(Vector3 pos, bool isFlying) |
996 | { | 1007 | { |
997 | // m_log.InfoFormat( | 1008 | lock (m_completeMovementLock) |
998 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | ||
999 | // Name, m_scene.RegionInfo.RegionName); | ||
1000 | |||
1001 | if (ParentUUID != UUID.Zero) | ||
1002 | { | 1009 | { |
1003 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); | 1010 | if (!IsChildAgent) |
1004 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | 1011 | return false; |
1005 | if (part == null) | 1012 | |
1013 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | ||
1014 | |||
1015 | // m_log.InfoFormat( | ||
1016 | // "[SCENE]: Upgrading child to root agent for {0} in {1}", | ||
1017 | // Name, m_scene.RegionInfo.RegionName); | ||
1018 | |||
1019 | if (ParentUUID != UUID.Zero) | ||
1006 | { | 1020 | { |
1007 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | 1021 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); |
1022 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | ||
1023 | if (part == null) | ||
1024 | { | ||
1025 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | part.ParentGroup.AddAvatar(UUID); | ||
1030 | if (part.SitTargetPosition != Vector3.Zero) | ||
1031 | part.SitTargetAvatar = UUID; | ||
1032 | // ParentPosition = part.GetWorldPosition(); | ||
1033 | ParentID = part.LocalId; | ||
1034 | ParentPart = part; | ||
1035 | m_pos = PrevSitOffset; | ||
1036 | // pos = ParentPosition; | ||
1037 | pos = part.GetWorldPosition(); | ||
1038 | } | ||
1039 | ParentUUID = UUID.Zero; | ||
1040 | |||
1041 | // Animator.TrySetMovementAnimation("SIT"); | ||
1008 | } | 1042 | } |
1009 | else | 1043 | else |
1010 | { | 1044 | { |
1011 | part.ParentGroup.AddAvatar(UUID); | 1045 | IsLoggingIn = false; |
1012 | if (part.SitTargetPosition != Vector3.Zero) | ||
1013 | part.SitTargetAvatar = UUID; | ||
1014 | // ParentPosition = part.GetWorldPosition(); | ||
1015 | ParentID = part.LocalId; | ||
1016 | ParentPart = part; | ||
1017 | m_pos = PrevSitOffset; | ||
1018 | // pos = ParentPosition; | ||
1019 | pos = part.GetWorldPosition(); | ||
1020 | } | 1046 | } |
1021 | ParentUUID = UUID.Zero; | ||
1022 | |||
1023 | IsChildAgent = false; | ||
1024 | 1047 | ||
1025 | // Animator.TrySetMovementAnimation("SIT"); | ||
1026 | } | ||
1027 | else | ||
1028 | { | ||
1029 | IsChildAgent = false; | 1048 | IsChildAgent = false; |
1030 | IsLoggingIn = false; | ||
1031 | } | 1049 | } |
1032 | 1050 | ||
1033 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | ||
1034 | |||
1035 | IsChildAgent = false; | ||
1036 | |||
1037 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag | 1051 | // Must reset this here so that a teleport to a region next to an existing region does not keep the flag |
1038 | // set and prevent the close of the connection on a subsequent re-teleport. | 1052 | // set and prevent the close of the connection on a subsequent re-teleport. |
1039 | // Should not be needed if we are not trying to tell this region to close | 1053 | // Should not be needed if we are not trying to tell this region to close |
@@ -1178,22 +1192,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
1178 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | 1192 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently |
1179 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | 1193 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are |
1180 | // not transporting the required data. | 1194 | // not transporting the required data. |
1181 | lock (m_attachments) | 1195 | // |
1196 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1197 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1198 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1199 | // not transporting the required data. | ||
1200 | // | ||
1201 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
1202 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
1203 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
1204 | // | ||
1205 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
1206 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
1207 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
1208 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
1209 | // | ||
1210 | // One cannot simply iterate over attachments in a fire and forget thread because this would no longer | ||
1211 | // be locked, allowing race conditions if other code changes the attachments list. | ||
1212 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
1213 | |||
1214 | if (attachments.Count > 0) | ||
1182 | { | 1215 | { |
1183 | if (HasAttachments()) | 1216 | m_log.DebugFormat( |
1184 | { | 1217 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); |
1185 | m_log.DebugFormat( | ||
1186 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1187 | 1218 | ||
1188 | // Resume scripts | 1219 | // Resume scripts |
1189 | Util.FireAndForget(delegate(object x) { | 1220 | foreach (SceneObjectGroup sog in attachments) |
1190 | foreach (SceneObjectGroup sog in m_attachments) | 1221 | { |
1191 | { | 1222 | sog.ScheduleGroupForFullUpdate(); |
1192 | sog.ScheduleGroupForFullUpdate(); | 1223 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); |
1193 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | 1224 | sog.ResumeScripts(); |
1194 | sog.ResumeScripts(); | ||
1195 | } | ||
1196 | }); | ||
1197 | } | 1225 | } |
1198 | } | 1226 | } |
1199 | } | 1227 | } |
@@ -1215,6 +1243,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1215 | 1243 | ||
1216 | m_scene.EventManager.TriggerOnMakeRootAgent(this); | 1244 | m_scene.EventManager.TriggerOnMakeRootAgent(this); |
1217 | 1245 | ||
1246 | return true; | ||
1218 | } | 1247 | } |
1219 | 1248 | ||
1220 | public int GetStateSource() | 1249 | public int GetStateSource() |
@@ -1637,7 +1666,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1637 | } | 1666 | } |
1638 | 1667 | ||
1639 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1668 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1640 | MakeRootAgent(AbsolutePosition, flying); | 1669 | if (!MakeRootAgent(AbsolutePosition, flying)) |
1670 | { | ||
1671 | m_log.DebugFormat( | ||
1672 | "[SCENE PRESENCE]: Aborting CompleteMovement call for {0} in {1} as they are already root", | ||
1673 | Name, Scene.Name); | ||
1674 | |||
1675 | return; | ||
1676 | } | ||
1641 | 1677 | ||
1642 | // Tell the client that we're totally ready | 1678 | // Tell the client that we're totally ready |
1643 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | 1679 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); |
@@ -2884,7 +2920,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2884 | Rotation = newRot; | 2920 | Rotation = newRot; |
2885 | 2921 | ||
2886 | // ParentPosition = part.AbsolutePosition; | 2922 | // ParentPosition = part.AbsolutePosition; |
2887 | part.ParentGroup.AddAvatar(UUID); | ||
2888 | } | 2923 | } |
2889 | else | 2924 | else |
2890 | { | 2925 | { |
@@ -2893,13 +2928,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2893 | m_pos -= part.GroupPosition; | 2928 | m_pos -= part.GroupPosition; |
2894 | 2929 | ||
2895 | // ParentPosition = part.AbsolutePosition; | 2930 | // ParentPosition = part.AbsolutePosition; |
2896 | part.ParentGroup.AddAvatar(UUID); | ||
2897 | 2931 | ||
2898 | // m_log.DebugFormat( | 2932 | // m_log.DebugFormat( |
2899 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", | 2933 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", |
2900 | // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); | 2934 | // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); |
2901 | } | 2935 | } |
2902 | 2936 | ||
2937 | part.ParentGroup.AddAvatar(UUID); | ||
2903 | ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 2938 | ParentPart = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
2904 | ParentID = m_requestedSitTargetID; | 2939 | ParentID = m_requestedSitTargetID; |
2905 | m_AngularVelocity = Vector3.Zero; | 2940 | m_AngularVelocity = Vector3.Zero; |
@@ -3210,6 +3245,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3210 | // again here... this comes after the cached appearance check because the avatars | 3245 | // again here... this comes after the cached appearance check because the avatars |
3211 | // appearance goes into the avatar update packet | 3246 | // appearance goes into the avatar update packet |
3212 | SendAvatarDataToAllAgents(); | 3247 | SendAvatarDataToAllAgents(); |
3248 | |||
3249 | // This invocation always shows up in the viewer logs as an error. Is it needed? | ||
3213 | SendAppearanceToAgent(this); | 3250 | SendAppearanceToAgent(this); |
3214 | 3251 | ||
3215 | // If we are using the the cached appearance then send it out to everyone | 3252 | // If we are using the the cached appearance then send it out to everyone |