diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 75 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 24 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | 10 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 24 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 129 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 59 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 74 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs | 24 |
8 files changed, 325 insertions, 94 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a63ed13..eae8b8e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2281,13 +2281,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
2281 | /// <summary> | 2281 | /// <summary> |
2282 | /// Synchronously delete the given object from the scene. | 2282 | /// Synchronously delete the given object from the scene. |
2283 | /// </summary> | 2283 | /// </summary> |
2284 | /// <remarks> | ||
2285 | /// Scripts are also removed. | ||
2286 | /// </remarks> | ||
2284 | /// <param name="group">Object Id</param> | 2287 | /// <param name="group">Object Id</param> |
2285 | /// <param name="silent">Suppress broadcasting changes to other clients.</param> | 2288 | /// <param name="silent">Suppress broadcasting changes to other clients.</param> |
2286 | public void DeleteSceneObject(SceneObjectGroup group, bool silent) | 2289 | public void DeleteSceneObject(SceneObjectGroup group, bool silent) |
2290 | { | ||
2291 | DeleteSceneObject(group, silent, true); | ||
2292 | } | ||
2293 | |||
2294 | /// <summary> | ||
2295 | /// Synchronously delete the given object from the scene. | ||
2296 | /// </summary> | ||
2297 | /// <param name="group">Object Id</param> | ||
2298 | /// <param name="silent">Suppress broadcasting changes to other clients.</param> | ||
2299 | /// <param name="removeScripts">If true, then scripts are removed. If false, then they are only stopped.</para> | ||
2300 | public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts) | ||
2287 | { | 2301 | { |
2288 | // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); | 2302 | // m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID); |
2289 | 2303 | ||
2290 | group.RemoveScriptInstances(true); | 2304 | if (removeScripts) |
2305 | group.RemoveScriptInstances(true); | ||
2306 | else | ||
2307 | group.StopScriptInstances(); | ||
2291 | 2308 | ||
2292 | SceneObjectPart[] partList = group.Parts; | 2309 | SceneObjectPart[] partList = group.Parts; |
2293 | 2310 | ||
@@ -2595,7 +2612,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2595 | } | 2612 | } |
2596 | catch (Exception e) | 2613 | catch (Exception e) |
2597 | { | 2614 | { |
2598 | m_log.WarnFormat("[SCENE]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace); | 2615 | m_log.WarnFormat("[INTERREGION]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace); |
2616 | return false; | ||
2617 | } | ||
2618 | |||
2619 | // If the user is banned, we won't let any of their objects | ||
2620 | // enter. Period. | ||
2621 | // | ||
2622 | if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID, 36)) | ||
2623 | { | ||
2624 | m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID); | ||
2599 | return false; | 2625 | return false; |
2600 | } | 2626 | } |
2601 | 2627 | ||
@@ -2606,14 +2632,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
2606 | 2632 | ||
2607 | if (!AddSceneObject(newObject)) | 2633 | if (!AddSceneObject(newObject)) |
2608 | { | 2634 | { |
2609 | m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName); | 2635 | m_log.DebugFormat( |
2636 | "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName); | ||
2610 | return false; | 2637 | return false; |
2611 | } | 2638 | } |
2612 | 2639 | ||
2613 | // For attachments, we need to wait until the agent is root | ||
2614 | // before we restart the scripts, or else some functions won't work. | ||
2615 | if (!newObject.IsAttachment) | 2640 | if (!newObject.IsAttachment) |
2616 | { | 2641 | { |
2642 | // FIXME: It would be better to never add the scene object at all rather than add it and then delete | ||
2643 | // it | ||
2644 | if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition)) | ||
2645 | { | ||
2646 | // Deny non attachments based on parcel settings | ||
2647 | // | ||
2648 | m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); | ||
2649 | |||
2650 | DeleteSceneObject(newObject, false); | ||
2651 | |||
2652 | return false; | ||
2653 | } | ||
2654 | |||
2655 | // For attachments, we need to wait until the agent is root | ||
2656 | // before we restart the scripts, or else some functions won't work. | ||
2617 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); | 2657 | newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); |
2618 | newObject.ResumeScripts(); | 2658 | newObject.ResumeScripts(); |
2619 | } | 2659 | } |
@@ -2650,8 +2690,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2650 | return false; | 2690 | return false; |
2651 | } | 2691 | } |
2652 | 2692 | ||
2653 | sceneObject.SetScene(this); | ||
2654 | |||
2655 | // Force allocation of new LocalId | 2693 | // Force allocation of new LocalId |
2656 | // | 2694 | // |
2657 | SceneObjectPart[] parts = sceneObject.Parts; | 2695 | SceneObjectPart[] parts = sceneObject.Parts; |
@@ -2707,18 +2745,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2707 | return false; | 2745 | return false; |
2708 | } | 2746 | } |
2709 | AddRestoredSceneObject(sceneObject, true, false); | 2747 | AddRestoredSceneObject(sceneObject, true, false); |
2710 | |||
2711 | if (!Permissions.CanObjectEntry(sceneObject.UUID, | ||
2712 | true, sceneObject.AbsolutePosition)) | ||
2713 | { | ||
2714 | // Deny non attachments based on parcel settings | ||
2715 | // | ||
2716 | m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings"); | ||
2717 | |||
2718 | DeleteSceneObject(sceneObject, false); | ||
2719 | |||
2720 | return false; | ||
2721 | } | ||
2722 | } | 2748 | } |
2723 | 2749 | ||
2724 | return true; | 2750 | return true; |
@@ -4654,6 +4680,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
4654 | } | 4680 | } |
4655 | 4681 | ||
4656 | /// <summary> | 4682 | /// <summary> |
4683 | /// Get all the scene object groups. | ||
4684 | /// </summary> | ||
4685 | /// <returns> | ||
4686 | /// The scene object groups. If the scene is empty then an empty list is returned. | ||
4687 | /// </returns> | ||
4688 | public List<SceneObjectGroup> GetSceneObjectGroups() | ||
4689 | { | ||
4690 | return m_sceneGraph.GetSceneObjectGroups(); | ||
4691 | } | ||
4692 | |||
4693 | /// <summary> | ||
4657 | /// Get a group via its UUID | 4694 | /// Get a group via its UUID |
4658 | /// </summary> | 4695 | /// </summary> |
4659 | /// <param name="fullID"></param> | 4696 | /// <param name="fullID"></param> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 3390aba..b23d2e5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -401,9 +401,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
401 | 401 | ||
402 | if (Entities.ContainsKey(sceneObject.UUID)) | 402 | if (Entities.ContainsKey(sceneObject.UUID)) |
403 | { | 403 | { |
404 | // m_log.DebugFormat( | 404 | m_log.DebugFormat( |
405 | // "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", | 405 | "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", |
406 | // m_parentScene.RegionInfo.RegionName, sceneObject.UUID); | 406 | m_parentScene.RegionInfo.RegionName, sceneObject.UUID); |
407 | 407 | ||
408 | return false; | 408 | return false; |
409 | } | 409 | } |
@@ -1038,6 +1038,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | /// <summary> | 1040 | /// <summary> |
1041 | /// Get all the scene object groups. | ||
1042 | /// </summary> | ||
1043 | /// <returns> | ||
1044 | /// The scene object groups. If the scene is empty then an empty list is returned. | ||
1045 | /// </returns> | ||
1046 | protected internal List<SceneObjectGroup> GetSceneObjectGroups() | ||
1047 | { | ||
1048 | lock (SceneObjectGroupsByFullID) | ||
1049 | return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | ||
1050 | } | ||
1051 | |||
1052 | /// <summary> | ||
1041 | /// Get a group in the scene | 1053 | /// Get a group in the scene |
1042 | /// </summary> | 1054 | /// </summary> |
1043 | /// <param name="fullID">UUID of the group</param> | 1055 | /// <param name="fullID">UUID of the group</param> |
@@ -1180,11 +1192,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1180 | /// <param name="action"></param> | 1192 | /// <param name="action"></param> |
1181 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) | 1193 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1182 | { | 1194 | { |
1183 | List<SceneObjectGroup> objlist; | 1195 | foreach (SceneObjectGroup obj in GetSceneObjectGroups()) |
1184 | lock (SceneObjectGroupsByFullID) | ||
1185 | objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | ||
1186 | |||
1187 | foreach (SceneObjectGroup obj in objlist) | ||
1188 | { | 1196 | { |
1189 | try | 1197 | try |
1190 | { | 1198 | { |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 1038111..26524fb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
79 | } | 79 | } |
80 | 80 | ||
81 | /// <summary> | 81 | /// <summary> |
82 | /// Stop the scripts contained in all the prims in this group | 82 | /// Stop and remove the scripts contained in all the prims in this group |
83 | /// </summary> | 83 | /// </summary> |
84 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 84 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
85 | { | 85 | { |
@@ -89,6 +89,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
89 | } | 89 | } |
90 | 90 | ||
91 | /// <summary> | 91 | /// <summary> |
92 | /// Stop the scripts contained in all the prims in this group | ||
93 | /// </summary> | ||
94 | public void StopScriptInstances() | ||
95 | { | ||
96 | Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => p.Inventory.StopScriptInstances()); | ||
97 | } | ||
98 | |||
99 | /// <summary> | ||
92 | /// Add an inventory item from a user's inventory to a prim in this scene object. | 100 | /// Add an inventory item from a user's inventory to a prim in this scene object. |
93 | /// </summary> | 101 | /// </summary> |
94 | /// <param name="agentID">The agent adding the item.</param> | 102 | /// <param name="agentID">The agent adding the item.</param> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f68a5b3..cc7d0fb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1674,16 +1674,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1674 | { | 1674 | { |
1675 | return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | 1675 | return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); |
1676 | } | 1676 | } |
1677 | |||
1678 | /// <summary> | ||
1679 | /// Added as a way for the storage provider to reset the scene, | ||
1680 | /// most likely a better way to do this sort of thing but for now... | ||
1681 | /// </summary> | ||
1682 | /// <param name="scene"></param> | ||
1683 | public void SetScene(Scene scene) | ||
1684 | { | ||
1685 | m_scene = scene; | ||
1686 | } | ||
1687 | 1677 | ||
1688 | /// <summary> | 1678 | /// <summary> |
1689 | /// Set a part to act as the root part for this scene object | 1679 | /// Set a part to act as the root part for this scene object |
@@ -4324,6 +4314,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
4324 | return count; | 4314 | return count; |
4325 | } | 4315 | } |
4326 | 4316 | ||
4317 | /// <summary> | ||
4318 | /// Gets the number of sitting avatars. | ||
4319 | /// </summary> | ||
4320 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
4321 | /// <returns></returns> | ||
4322 | public int GetSittingAvatarsCount() | ||
4323 | { | ||
4324 | int count = 0; | ||
4325 | |||
4326 | Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount()); | ||
4327 | |||
4328 | return count; | ||
4329 | } | ||
4330 | |||
4327 | public override string ToString() | 4331 | public override string ToString() |
4328 | { | 4332 | { |
4329 | return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); | 4333 | return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7b1f5d2..1f1caca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -147,6 +147,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
147 | get { return ParentGroup.RootPart == this; } | 147 | get { return ParentGroup.RootPart == this; } |
148 | } | 148 | } |
149 | 149 | ||
150 | /// <summary> | ||
151 | /// Is an explicit sit target set for this part? | ||
152 | /// </summary> | ||
153 | public bool IsSitTargetSet | ||
154 | { | ||
155 | get | ||
156 | { | ||
157 | return | ||
158 | !(SitTargetPosition == Vector3.Zero | ||
159 | && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion | ||
160 | || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 1f && SitTargetOrientation.W == 0f // W-Z Mapping was invalid at one point | ||
161 | || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f && SitTargetOrientation.W == 0f)); // Invalid Quaternion | ||
162 | } | ||
163 | } | ||
164 | |||
150 | #region Fields | 165 | #region Fields |
151 | 166 | ||
152 | public bool AllowedDrop; | 167 | public bool AllowedDrop; |
@@ -426,7 +441,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
426 | private uint _category; | 441 | private uint _category; |
427 | private Int32 _creationDate; | 442 | private Int32 _creationDate; |
428 | private uint _parentID = 0; | 443 | private uint _parentID = 0; |
429 | private UUID m_sitTargetAvatar = UUID.Zero; | ||
430 | private uint _baseMask = (uint)PermissionMask.All; | 444 | private uint _baseMask = (uint)PermissionMask.All; |
431 | private uint _ownerMask = (uint)PermissionMask.All; | 445 | private uint _ownerMask = (uint)PermissionMask.All; |
432 | private uint _groupMask = (uint)PermissionMask.None; | 446 | private uint _groupMask = (uint)PermissionMask.None; |
@@ -1312,13 +1326,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1312 | } | 1326 | } |
1313 | 1327 | ||
1314 | /// <summary> | 1328 | /// <summary> |
1315 | /// ID of the avatar that is sat on us. If there is no such avatar then is UUID.Zero | 1329 | /// ID of the avatar that is sat on us if we have a sit target. If there is no such avatar then is UUID.Zero |
1316 | /// </summary> | 1330 | /// </summary> |
1317 | public UUID SitTargetAvatar | 1331 | public UUID SitTargetAvatar { get; set; } |
1318 | { | 1332 | |
1319 | get { return m_sitTargetAvatar; } | 1333 | /// <summary> |
1320 | set { m_sitTargetAvatar = value; } | 1334 | /// IDs of all avatars start on this object part. |
1321 | } | 1335 | /// </summary> |
1336 | /// <remarks> | ||
1337 | /// We need to track this so that we can stop sat upon prims from being attached. | ||
1338 | /// </remarks> | ||
1339 | /// <value> | ||
1340 | /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. | ||
1341 | /// </value> | ||
1342 | private HashSet<UUID> m_sittingAvatars; | ||
1322 | 1343 | ||
1323 | public virtual UUID RegionID | 1344 | public virtual UUID RegionID |
1324 | { | 1345 | { |
@@ -5128,5 +5149,99 @@ namespace OpenSim.Region.Framework.Scenes | |||
5128 | Inventory.UpdateInventoryItem(item, false, false); | 5149 | Inventory.UpdateInventoryItem(item, false, false); |
5129 | } | 5150 | } |
5130 | } | 5151 | } |
5152 | |||
5153 | /// <summary> | ||
5154 | /// Record an avatar sitting on this part. | ||
5155 | /// </summary> | ||
5156 | /// <remarks>This is called for all the sitting avatars whether there is a sit target set or not.</remarks> | ||
5157 | /// <returns> | ||
5158 | /// true if the avatar was not already recorded, false otherwise. | ||
5159 | /// </returns> | ||
5160 | /// <param name='avatarId'></param> | ||
5161 | protected internal bool AddSittingAvatar(UUID avatarId) | ||
5162 | { | ||
5163 | if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) | ||
5164 | SitTargetAvatar = avatarId; | ||
5165 | |||
5166 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5167 | |||
5168 | if (sittingAvatars == null) | ||
5169 | sittingAvatars = new HashSet<UUID>(); | ||
5170 | |||
5171 | lock (sittingAvatars) | ||
5172 | { | ||
5173 | m_sittingAvatars = sittingAvatars; | ||
5174 | return m_sittingAvatars.Add(avatarId); | ||
5175 | } | ||
5176 | } | ||
5177 | |||
5178 | /// <summary> | ||
5179 | /// Remove an avatar recorded as sitting on this part. | ||
5180 | /// </summary> | ||
5181 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
5182 | /// <returns> | ||
5183 | /// true if the avatar was present and removed, false if it was not present. | ||
5184 | /// </returns> | ||
5185 | /// <param name='avatarId'></param> | ||
5186 | protected internal bool RemoveSittingAvatar(UUID avatarId) | ||
5187 | { | ||
5188 | if (SitTargetAvatar == avatarId) | ||
5189 | SitTargetAvatar = UUID.Zero; | ||
5190 | |||
5191 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5192 | |||
5193 | // This can occur under a race condition where another thread | ||
5194 | if (sittingAvatars == null) | ||
5195 | return false; | ||
5196 | |||
5197 | lock (sittingAvatars) | ||
5198 | { | ||
5199 | if (sittingAvatars.Remove(avatarId)) | ||
5200 | { | ||
5201 | if (sittingAvatars.Count == 0) | ||
5202 | m_sittingAvatars = null; | ||
5203 | |||
5204 | return true; | ||
5205 | } | ||
5206 | } | ||
5207 | |||
5208 | return false; | ||
5209 | } | ||
5210 | |||
5211 | /// <summary> | ||
5212 | /// Get a copy of the list of sitting avatars. | ||
5213 | /// </summary> | ||
5214 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
5215 | /// <returns>A hashset of the sitting avatars. Returns null if there are no sitting avatars.</returns> | ||
5216 | public HashSet<UUID> GetSittingAvatars() | ||
5217 | { | ||
5218 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5219 | |||
5220 | if (sittingAvatars == null) | ||
5221 | { | ||
5222 | return null; | ||
5223 | } | ||
5224 | else | ||
5225 | { | ||
5226 | lock (sittingAvatars) | ||
5227 | return new HashSet<UUID>(sittingAvatars); | ||
5228 | } | ||
5229 | } | ||
5230 | |||
5231 | /// <summary> | ||
5232 | /// Gets the number of sitting avatars. | ||
5233 | /// </summary> | ||
5234 | /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks> | ||
5235 | /// <returns></returns> | ||
5236 | public int GetSittingAvatarsCount() | ||
5237 | { | ||
5238 | HashSet<UUID> sittingAvatars = m_sittingAvatars; | ||
5239 | |||
5240 | if (sittingAvatars == null) | ||
5241 | return 0; | ||
5242 | |||
5243 | lock (sittingAvatars) | ||
5244 | return sittingAvatars.Count; | ||
5245 | } | ||
5131 | } | 5246 | } |
5132 | } | 5247 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 1dff088..e5e29d0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -292,7 +292,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
292 | } | 292 | } |
293 | 293 | ||
294 | /// <summary> | 294 | /// <summary> |
295 | /// Stop all the scripts in this prim. | 295 | /// Stop and remove all the scripts in this prim. |
296 | /// </summary> | 296 | /// </summary> |
297 | /// <param name="sceneObjectBeingDeleted"> | 297 | /// <param name="sceneObjectBeingDeleted"> |
298 | /// Should be true if these scripts are being removed because the scene | 298 | /// Should be true if these scripts are being removed because the scene |
@@ -309,6 +309,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
309 | } | 309 | } |
310 | 310 | ||
311 | /// <summary> | 311 | /// <summary> |
312 | /// Stop all the scripts in this prim. | ||
313 | /// </summary> | ||
314 | public void StopScriptInstances() | ||
315 | { | ||
316 | GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i)); | ||
317 | } | ||
318 | |||
319 | /// <summary> | ||
312 | /// Start a script which is in this prim's inventory. | 320 | /// Start a script which is in this prim's inventory. |
313 | /// </summary> | 321 | /// </summary> |
314 | /// <param name="item"></param> | 322 | /// <param name="item"></param> |
@@ -596,7 +604,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
596 | } | 604 | } |
597 | 605 | ||
598 | /// <summary> | 606 | /// <summary> |
599 | /// Stop a script which is in this prim's inventory. | 607 | /// Stop and remove a script which is in this prim's inventory. |
600 | /// </summary> | 608 | /// </summary> |
601 | /// <param name="itemId"></param> | 609 | /// <param name="itemId"></param> |
602 | /// <param name="sceneObjectBeingDeleted"> | 610 | /// <param name="sceneObjectBeingDeleted"> |
@@ -615,7 +623,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
615 | } | 623 | } |
616 | else | 624 | else |
617 | { | 625 | { |
618 | m_log.ErrorFormat( | 626 | m_log.WarnFormat( |
619 | "[PRIM INVENTORY]: " + | 627 | "[PRIM INVENTORY]: " + |
620 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 628 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
621 | itemId, m_part.Name, m_part.UUID, | 629 | itemId, m_part.Name, m_part.UUID, |
@@ -624,6 +632,51 @@ namespace OpenSim.Region.Framework.Scenes | |||
624 | } | 632 | } |
625 | 633 | ||
626 | /// <summary> | 634 | /// <summary> |
635 | /// Stop a script which is in this prim's inventory. | ||
636 | /// </summary> | ||
637 | /// <param name="itemId"></param> | ||
638 | /// <param name="sceneObjectBeingDeleted"> | ||
639 | /// Should be true if this script is being removed because the scene | ||
640 | /// object is being deleted. This will prevent spurious updates to the client. | ||
641 | /// </param> | ||
642 | public void StopScriptInstance(UUID itemId) | ||
643 | { | ||
644 | TaskInventoryItem scriptItem; | ||
645 | |||
646 | lock (m_items) | ||
647 | m_items.TryGetValue(itemId, out scriptItem); | ||
648 | |||
649 | if (scriptItem != null) | ||
650 | { | ||
651 | StopScriptInstance(scriptItem); | ||
652 | } | ||
653 | else | ||
654 | { | ||
655 | m_log.WarnFormat( | ||
656 | "[PRIM INVENTORY]: " + | ||
657 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | ||
658 | itemId, m_part.Name, m_part.UUID, | ||
659 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | /// <summary> | ||
664 | /// Stop a script which is in this prim's inventory. | ||
665 | /// </summary> | ||
666 | /// <param name="itemId"></param> | ||
667 | /// <param name="sceneObjectBeingDeleted"> | ||
668 | /// Should be true if this script is being removed because the scene | ||
669 | /// object is being deleted. This will prevent spurious updates to the client. | ||
670 | /// </param> | ||
671 | public void StopScriptInstance(TaskInventoryItem item) | ||
672 | { | ||
673 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID); | ||
674 | |||
675 | // At the moment, even stopped scripts are counted as active, which is probably wrong. | ||
676 | // m_part.ParentGroup.AddActiveScriptCount(-1); | ||
677 | } | ||
678 | |||
679 | /// <summary> | ||
627 | /// Check if the inventory holds an item with a given name. | 680 | /// Check if the inventory holds an item with a given name. |
628 | /// </summary> | 681 | /// </summary> |
629 | /// <param name="name"></param> | 682 | /// <param name="name"></param> |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f0ceff6..e27d309 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -594,6 +594,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
594 | private UUID m_parentUUID = UUID.Zero; | 594 | private UUID m_parentUUID = UUID.Zero; |
595 | 595 | ||
596 | /// <summary> | 596 | /// <summary> |
597 | /// Are we sitting on an object? | ||
598 | /// </summary> | ||
599 | /// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks> | ||
600 | public bool IsSatOnObject { get { return ParentID != 0; } } | ||
601 | |||
602 | /// <summary> | ||
597 | /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. | 603 | /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. |
598 | /// </summary> | 604 | /// </summary> |
599 | /// <remarks> | 605 | /// <remarks> |
@@ -1940,10 +1946,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1940 | } | 1946 | } |
1941 | } | 1947 | } |
1942 | 1948 | ||
1943 | // Reset sit target. | ||
1944 | if (part.SitTargetAvatar == UUID) | ||
1945 | part.SitTargetAvatar = UUID.Zero; | ||
1946 | |||
1947 | part.ParentGroup.DeleteAvatar(UUID); | 1949 | part.ParentGroup.DeleteAvatar(UUID); |
1948 | // ParentPosition = part.GetWorldPosition(); | 1950 | // ParentPosition = part.GetWorldPosition(); |
1949 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); | 1951 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); |
@@ -1961,6 +1963,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1961 | SendAvatarDataToAllAgents(); | 1963 | SendAvatarDataToAllAgents(); |
1962 | m_requestedSitTargetID = 0; | 1964 | m_requestedSitTargetID = 0; |
1963 | 1965 | ||
1966 | part.RemoveSittingAvatar(UUID); | ||
1967 | |||
1964 | if (part != null) | 1968 | if (part != null) |
1965 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); | 1969 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); |
1966 | } | 1970 | } |
@@ -1994,15 +1998,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1994 | //look for prims with explicit sit targets that are available | 1998 | //look for prims with explicit sit targets that are available |
1995 | foreach (SceneObjectPart part in partArray) | 1999 | foreach (SceneObjectPart part in partArray) |
1996 | { | 2000 | { |
1997 | // Is a sit target available? | 2001 | if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) |
1998 | Vector3 avSitOffset = part.SitTargetPosition; | ||
1999 | Quaternion avSitOrientation = part.SitTargetOrientation; | ||
2000 | UUID avOnTargetAlready = part.SitTargetAvatar; | ||
2001 | |||
2002 | bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero; | ||
2003 | bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity; | ||
2004 | |||
2005 | if (SitTargetisSet && SitTargetUnOccupied) | ||
2006 | { | 2002 | { |
2007 | //switch the target to this prim | 2003 | //switch the target to this prim |
2008 | return part; | 2004 | return part; |
@@ -2013,10 +2009,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2013 | return targetPart; | 2009 | return targetPart; |
2014 | } | 2010 | } |
2015 | 2011 | ||
2016 | private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation) | 2012 | private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation) |
2017 | { | 2013 | { |
2018 | Vector3 pos = new Vector3(); | ||
2019 | Quaternion sitOrientation = pSitOrientation; | ||
2020 | Vector3 cameraEyeOffset = Vector3.Zero; | 2014 | Vector3 cameraEyeOffset = Vector3.Zero; |
2021 | Vector3 cameraAtOffset = Vector3.Zero; | 2015 | Vector3 cameraAtOffset = Vector3.Zero; |
2022 | bool forceMouselook = false; | 2016 | bool forceMouselook = false; |
@@ -2028,42 +2022,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
2028 | // TODO: determine position to sit at based on scene geometry; don't trust offset from client | 2022 | // TODO: determine position to sit at based on scene geometry; don't trust offset from client |
2029 | // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it | 2023 | // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it |
2030 | 2024 | ||
2031 | // Is a sit target available? | ||
2032 | Vector3 avSitOffSet = part.SitTargetPosition; | ||
2033 | Quaternion avSitOrientation = part.SitTargetOrientation; | ||
2034 | UUID avOnTargetAlready = part.SitTargetAvatar; | ||
2035 | |||
2036 | bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); | ||
2037 | bool SitTargetisSet = | ||
2038 | (!(avSitOffSet == Vector3.Zero && | ||
2039 | ( | ||
2040 | avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion | ||
2041 | || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point | ||
2042 | || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion | ||
2043 | ) | ||
2044 | )); | ||
2045 | |||
2046 | // m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); | ||
2047 | |||
2048 | if (PhysicsActor != null) | 2025 | if (PhysicsActor != null) |
2049 | m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; | 2026 | m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; |
2050 | 2027 | ||
2051 | bool canSit = false; | 2028 | bool canSit = false; |
2052 | pos = part.AbsolutePosition + offset; | 2029 | Vector3 pos = part.AbsolutePosition + offset; |
2053 | 2030 | ||
2054 | if (SitTargetisSet) | 2031 | if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero) |
2055 | { | 2032 | { |
2056 | if (SitTargetUnOccupied) | ||
2057 | { | ||
2058 | // m_log.DebugFormat( | 2033 | // m_log.DebugFormat( |
2059 | // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", | 2034 | // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", |
2060 | // Name, part.Name, part.LocalId); | 2035 | // Name, part.Name, part.LocalId); |
2061 | 2036 | ||
2062 | part.SitTargetAvatar = UUID; | 2037 | offset = part.SitTargetPosition; |
2063 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); | 2038 | sitOrientation = part.SitTargetOrientation; |
2064 | sitOrientation = avSitOrientation; | 2039 | canSit = true; |
2065 | canSit = true; | ||
2066 | } | ||
2067 | } | 2040 | } |
2068 | else | 2041 | else |
2069 | { | 2042 | { |
@@ -2076,6 +2049,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2076 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); | 2049 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); |
2077 | canSit = true; | 2050 | canSit = true; |
2078 | } | 2051 | } |
2052 | // else | ||
2053 | // { | ||
2054 | // m_log.DebugFormat( | ||
2055 | // "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m", | ||
2056 | // Name, part.Name, part.LocalId); | ||
2057 | // } | ||
2079 | } | 2058 | } |
2080 | 2059 | ||
2081 | if (canSit) | 2060 | if (canSit) |
@@ -2086,6 +2065,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2086 | RemoveFromPhysicalScene(); | 2065 | RemoveFromPhysicalScene(); |
2087 | } | 2066 | } |
2088 | 2067 | ||
2068 | part.AddSittingAvatar(UUID); | ||
2069 | |||
2089 | cameraAtOffset = part.GetCameraAtOffset(); | 2070 | cameraAtOffset = part.GetCameraAtOffset(); |
2090 | cameraEyeOffset = part.GetCameraEyeOffset(); | 2071 | cameraEyeOffset = part.GetCameraEyeOffset(); |
2091 | forceMouselook = part.GetForceMouselook(); | 2072 | forceMouselook = part.GetForceMouselook(); |
@@ -2362,6 +2343,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2362 | 2343 | ||
2363 | if (part != null) | 2344 | if (part != null) |
2364 | { | 2345 | { |
2346 | if (part.ParentGroup.IsAttachment) | ||
2347 | { | ||
2348 | m_log.WarnFormat( | ||
2349 | "[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}", | ||
2350 | Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar); | ||
2351 | |||
2352 | return; | ||
2353 | } | ||
2354 | |||
2365 | if (part.SitTargetAvatar == UUID) | 2355 | if (part.SitTargetAvatar == UUID) |
2366 | { | 2356 | { |
2367 | Vector3 sitTargetPos = part.SitTargetPosition; | 2357 | Vector3 sitTargetPos = part.SitTargetPosition; |
diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs index ed39be1..493ab70 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | ||
29 | using System.Reflection; | 30 | using System.Reflection; |
30 | using Nini.Config; | 31 | using Nini.Config; |
31 | using NUnit.Framework; | 32 | using NUnit.Framework; |
@@ -69,6 +70,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
69 | m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); | 70 | m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); |
70 | 71 | ||
71 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | 72 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); |
73 | Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); | ||
74 | Assert.That(part.GetSittingAvatars(), Is.Null); | ||
72 | Assert.That(m_sp.ParentID, Is.EqualTo(0)); | 75 | Assert.That(m_sp.ParentID, Is.EqualTo(0)); |
73 | } | 76 | } |
74 | 77 | ||
@@ -86,7 +89,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
86 | 89 | ||
87 | m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); | 90 | m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); |
88 | 91 | ||
92 | Assert.That(m_sp.PhysicsActor, Is.Null); | ||
93 | |||
89 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | 94 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); |
95 | Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); | ||
96 | HashSet<UUID> sittingAvatars = part.GetSittingAvatars(); | ||
97 | Assert.That(sittingAvatars.Count, Is.EqualTo(1)); | ||
98 | Assert.That(sittingAvatars.Contains(m_sp.UUID)); | ||
90 | Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); | 99 | Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); |
91 | } | 100 | } |
92 | 101 | ||
@@ -104,10 +113,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
104 | 113 | ||
105 | m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); | 114 | m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero); |
106 | 115 | ||
107 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | ||
108 | Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId)); | ||
109 | Assert.That(m_sp.PhysicsActor, Is.Null); | ||
110 | |||
111 | // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the | 116 | // FIXME: This is different for live avatars - z position is adjusted. This is half the height of the |
112 | // default avatar. | 117 | // default avatar. |
113 | // Curiously, Vector3.ToString() will not display the last two places of the float. For example, | 118 | // Curiously, Vector3.ToString() will not display the last two places of the float. For example, |
@@ -119,6 +124,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
119 | m_sp.StandUp(); | 124 | m_sp.StandUp(); |
120 | 125 | ||
121 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | 126 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); |
127 | Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); | ||
128 | Assert.That(part.GetSittingAvatars(), Is.Null); | ||
122 | Assert.That(m_sp.ParentID, Is.EqualTo(0)); | 129 | Assert.That(m_sp.ParentID, Is.EqualTo(0)); |
123 | Assert.That(m_sp.PhysicsActor, Is.Not.Null); | 130 | Assert.That(m_sp.PhysicsActor, Is.Not.Null); |
124 | } | 131 | } |
@@ -145,11 +152,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests | |||
145 | Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); | 152 | Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT)); |
146 | Assert.That(m_sp.PhysicsActor, Is.Null); | 153 | Assert.That(m_sp.PhysicsActor, Is.Null); |
147 | 154 | ||
155 | Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1)); | ||
156 | HashSet<UUID> sittingAvatars = part.GetSittingAvatars(); | ||
157 | Assert.That(sittingAvatars.Count, Is.EqualTo(1)); | ||
158 | Assert.That(sittingAvatars.Contains(m_sp.UUID)); | ||
159 | |||
148 | m_sp.StandUp(); | 160 | m_sp.StandUp(); |
149 | 161 | ||
150 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | 162 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); |
151 | Assert.That(m_sp.ParentID, Is.EqualTo(0)); | 163 | Assert.That(m_sp.ParentID, Is.EqualTo(0)); |
152 | Assert.That(m_sp.PhysicsActor, Is.Not.Null); | 164 | Assert.That(m_sp.PhysicsActor, Is.Not.Null); |
165 | |||
166 | Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero)); | ||
167 | Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0)); | ||
168 | Assert.That(part.GetSittingAvatars(), Is.Null); | ||
153 | } | 169 | } |
154 | 170 | ||
155 | [Test] | 171 | [Test] |