aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityInventory.cs15
-rw-r--r--OpenSim/Region/Framework/Interfaces/INPCModule.cs8
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs75
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs10
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs129
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs59
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs74
-rw-r--r--OpenSim/Region/Framework/Scenes/Tests/ScenePresenceSitTests.cs24
10 files changed, 346 insertions, 96 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 4f0e100..4274cbe 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces
92 void ResumeScripts(); 92 void ResumeScripts();
93 93
94 /// <summary> 94 /// <summary>
95 /// Stop all the scripts in this entity. 95 /// Stop and remove all the scripts in this entity from the scene.
96 /// </summary> 96 /// </summary>
97 /// <param name="sceneObjectBeingDeleted"> 97 /// <param name="sceneObjectBeingDeleted">
98 /// Should be true if these scripts are being removed because the scene 98 /// Should be true if these scripts are being removed because the scene
@@ -101,6 +101,11 @@ namespace OpenSim.Region.Framework.Interfaces
101 void RemoveScriptInstances(bool sceneObjectBeingDeleted); 101 void RemoveScriptInstances(bool sceneObjectBeingDeleted);
102 102
103 /// <summary> 103 /// <summary>
104 /// Stop all the scripts in this entity.
105 /// </summary>
106 void StopScriptInstances();
107
108 /// <summary>
104 /// Start a script which is in this entity's inventory. 109 /// Start a script which is in this entity's inventory.
105 /// </summary> 110 /// </summary>
106 /// <param name="item"></param> 111 /// <param name="item"></param>
@@ -131,7 +136,7 @@ namespace OpenSim.Region.Framework.Interfaces
131 ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); 136 ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
132 137
133 /// <summary> 138 /// <summary>
134 /// Stop a script which is in this prim's inventory. 139 /// Stop and remove a script which is in this prim's inventory from the scene.
135 /// </summary> 140 /// </summary>
136 /// <param name="itemId"></param> 141 /// <param name="itemId"></param>
137 /// <param name="sceneObjectBeingDeleted"> 142 /// <param name="sceneObjectBeingDeleted">
@@ -141,6 +146,12 @@ namespace OpenSim.Region.Framework.Interfaces
141 void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted); 146 void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
142 147
143 /// <summary> 148 /// <summary>
149 /// Stop a script which is in this prim's inventory.
150 /// </summary>
151 /// <param name="itemId"></param>
152 void StopScriptInstance(UUID itemId);
153
154 /// <summary>
144 /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative 155 /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative
145 /// name is chosen. 156 /// name is chosen.
146 /// </summary> 157 /// </summary>
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index 860483d..d582149 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -184,6 +184,14 @@ namespace OpenSim.Region.Framework.Interfaces
184 bool Stand(UUID agentID, Scene scene); 184 bool Stand(UUID agentID, Scene scene);
185 185
186 /// <summary> 186 /// <summary>
187 /// Get the NPC to touch an object.
188 /// </summary>
189 /// <param name="agentID"></param>
190 /// <param name="partID"></param>
191 /// <returns>true if the touch is actually attempted, false if not</returns>
192 bool Touch(UUID agentID, UUID partID);
193
194 /// <summary>
187 /// Delete an NPC. 195 /// Delete an NPC.
188 /// </summary> 196 /// </summary>
189 /// <param name="agentID">The UUID of the NPC</param> 197 /// <param name="agentID">The UUID of the NPC</param>
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
28using System; 28using System;
29using System.Collections.Generic;
29using System.Reflection; 30using System.Reflection;
30using Nini.Config; 31using Nini.Config;
31using NUnit.Framework; 32using 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]