From 843112340e3220e6bef5a05d8607efb478e19013 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 6 Jul 2012 00:37:45 +0100
Subject: Log MONO_THREADS_PER_CPU value on simulator startup, or "unset" if it
 is not set

---
 OpenSim/Region/Application/Application.cs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs
index c130038..ebfebc4 100644
--- a/OpenSim/Region/Application/Application.cs
+++ b/OpenSim/Region/Application/Application.cs
@@ -92,9 +92,14 @@ namespace OpenSim
                 m_log.Info("[OPENSIM MAIN]: configured log4net using default OpenSim.exe.config");
             }
 
-            m_log.DebugFormat(
+            m_log.InfoFormat(
                 "[OPENSIM MAIN]: System Locale is {0}", System.Threading.Thread.CurrentThread.CurrentCulture);
 
+            string monoThreadsPerCpu = System.Environment.GetEnvironmentVariable("MONO_THREADS_PER_CPU");
+
+            m_log.InfoFormat(
+                "[OPENSIM MAIN]: Environment variable MONO_THREADS_PER_CPU is {0}", monoThreadsPerCpu ?? "unset");
+
             // Increase the number of IOCP threads available. Mono defaults to a tragically low number
             int workerThreads, iocpThreads;
             System.Threading.ThreadPool.GetMaxThreads(out workerThreads, out iocpThreads);
@@ -109,7 +114,6 @@ namespace OpenSim
 
             // Check if the system is compatible with OpenSimulator.
             // Ensures that the minimum system requirements are met
-            m_log.Info("Performing compatibility checks... \n");
             string supported = String.Empty;
             if (Util.IsEnvironmentSupported(ref supported))
             {
-- 
cgit v1.1


From f6e5791ecd0b75ae4a6a85c66874af7047f6f55b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 6 Jul 2012 22:07:19 +0100
Subject: refactor: extract method UpdateUserInventoryWithAttachment() from
 AttachObject() for better code comprehension

---
 .../Avatar/Attachments/AttachmentsModule.cs        | 67 ++++++++++++----------
 1 file changed, 38 insertions(+), 29 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index af30a8e..9eb0e38 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -292,31 +292,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
     
                 group.AttachmentPoint = attachmentPt;
                 group.AbsolutePosition = attachPos;
-    
-                // We also don't want to do any of the inventory operations for an NPC.
+
                 if (sp.PresenceType != PresenceType.Npc)
-                {
-                    // Remove any previous attachments
-                    List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
-    
-                    // At the moment we can only deal with a single attachment
-                    if (attachments.Count != 0)
-                    {
-                        if (attachments[0].FromItemID != UUID.Zero)
-                            DetachSingleAttachmentToInvInternal(sp, attachments[0]);
-                        else
-                            m_log.WarnFormat(
-                                "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
-                                attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
-                    }
-    
-                    // Add the new attachment to inventory if we don't already have it.
-                    UUID newAttachmentItemID = group.FromItemID;
-                    if (newAttachmentItemID == UUID.Zero)
-                        newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
-        
-                    ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
-                }
+                    UpdateUserInventoryWithAttachment(sp, group, attachmentPt);
     
                 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
             }
@@ -324,6 +302,30 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
             return true;
         }
 
+        private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt)
+        {
+            // Remove any previous attachments
+            List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
+
+            // At the moment we can only deal with a single attachment
+            if (attachments.Count != 0)
+            {
+                if (attachments[0].FromItemID != UUID.Zero)
+                    DetachSingleAttachmentToInvInternal(sp, attachments[0]);
+                else
+                    m_log.WarnFormat(
+                        "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!",
+                        attachments[0].Name, attachments[0].LocalId, attachmentPt, group.Name, group.LocalId, sp.Name);
+            }
+
+            // Add the new attachment to inventory if we don't already have it.
+            UUID newAttachmentItemID = group.FromItemID;
+            if (newAttachmentItemID == UUID.Zero)
+                newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
+
+            ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group);
+        }
+
         public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt)
         {
             if (!Enabled)
@@ -652,11 +654,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
             //                "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}",
             //                grp.Name, grp.LocalId, remoteClient.Name);
 
-            InventoryItemBase newItem =  m_invAccessModule.CopyToInventory(
-                DeRezAction.TakeCopy,
-                m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
-                new List<SceneObjectGroup> { grp },
-                sp.ControllingClient, true)[0];
+            InventoryItemBase newItem
+                = m_invAccessModule.CopyToInventory(
+                    DeRezAction.TakeCopy,
+                    m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID,
+                    new List<SceneObjectGroup> { grp },
+                    sp.ControllingClient, true)[0];
 
             // sets itemID so client can show item as 'attached' in inventory
             grp.FromItemID = newItem.ID;
@@ -782,7 +785,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
             item = m_scene.InventoryService.GetItem(item);
             bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID);
             if (changed && m_scene.AvatarFactory != null)
+            {
+//                m_log.DebugFormat(
+//                    "[ATTACHMENTS MODULE]: Queueing appearance save for {0}, attachment {1} point {2} in ShowAttachInUserInventory()",
+//                    sp.Name, att.Name, AttachmentPt);
+
                 m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID);
+            }
         }
 
         #endregion
-- 
cgit v1.1


From 43a2da9edb9a234ee10735a234d2ad253a33cb7a Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 6 Jul 2012 22:33:16 +0100
Subject: Pull prim crossing/teleport checks up into
 Scene.IncomingCreateObject() from Scene.AddObject()

Only IncomingCreateObject() needs these checks.  General object adding does not need to perform crossing perm checks
---
 OpenSim/Region/Framework/Scenes/Scene.cs | 41 +++++++++++++++++++++-----------
 1 file changed, 27 insertions(+), 14 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 36d39ea..6239d51 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2495,7 +2495,16 @@ namespace OpenSim.Region.Framework.Scenes
             }
             catch (Exception e)
             {
-                m_log.WarnFormat("[SCENE]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace);
+                m_log.WarnFormat("[INTERREGION]: Problem casting object, exception {0}{1}", e.Message, e.StackTrace);
+                return false;
+            }
+
+            // If the user is banned, we won't let any of their objects
+            // enter. Period.
+            //
+            if (RegionInfo.EstateSettings.IsBanned(newObject.OwnerID))
+            {
+                m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", newObject.OwnerID);
                 return false;
             }
 
@@ -2504,14 +2513,28 @@ namespace OpenSim.Region.Framework.Scenes
 
             if (!AddSceneObject(newObject))
             {
-                m_log.DebugFormat("[SCENE]: Problem adding scene object {0} in {1} ", sog.UUID, RegionInfo.RegionName);
+                m_log.DebugFormat(
+                    "[INTERREGION]: Problem adding scene object {0} in {1} ", newObject.UUID, RegionInfo.RegionName);
                 return false;
             }
 
-            // For attachments, we need to wait until the agent is root
-            // before we restart the scripts, or else some functions won't work.
             if (!newObject.IsAttachment)
             {
+                // FIXME: It would be better to never add the scene object at all rather than add it and then delete
+                // it
+                if (!Permissions.CanObjectEntry(newObject.UUID, true, newObject.AbsolutePosition))
+                {
+                    // Deny non attachments based on parcel settings
+                    //
+                    m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
+
+                    DeleteSceneObject(newObject, false);
+
+                    return false;
+                }
+
+                // For attachments, we need to wait until the agent is root
+                // before we restart the scripts, or else some functions won't work.
                 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
                 newObject.ResumeScripts();
             }
@@ -2531,16 +2554,6 @@ namespace OpenSim.Region.Framework.Scenes
         /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
         public bool AddSceneObject(SceneObjectGroup sceneObject)
         {
-            // If the user is banned, we won't let any of their objects
-            // enter. Period.
-            //
-            if (RegionInfo.EstateSettings.IsBanned(sceneObject.OwnerID))
-            {
-                m_log.InfoFormat("[INTERREGION]: Denied prim crossing for banned avatar {0}", sceneObject.OwnerID);
-
-                return false;
-            }
-
             sceneObject.SetScene(this);
 
             // Force allocation of new LocalId
-- 
cgit v1.1


From 1b1f841c6aaf2453b3aca0eade84855ae658e655 Mon Sep 17 00:00:00 2001
From: Talun
Date: Tue, 3 Jul 2012 11:10:09 +0100
Subject: Mantis 6063 osNpcTouch.

Allow NPCS to touch obects.
---
 OpenSim/Region/Framework/Interfaces/INPCModule.cs  |  8 +++++
 .../Region/OptionalModules/World/NPC/NPCAvatar.cs  | 39 ++++++++++++++++++++++
 .../Region/OptionalModules/World/NPC/NPCModule.cs  | 10 ++++++
 .../Shared/Api/Implementation/OSSL_Api.cs          | 35 +++++++++++++++++++
 .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs |  1 +
 .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs   |  5 +++
 6 files changed, 98 insertions(+)

(limited to 'OpenSim/Region')

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
         bool Stand(UUID agentID, Scene scene);
 
         /// <summary>
+        /// Get the NPC to touch an object.
+        /// </summary>
+        /// <param name="agentID"></param>
+        /// <param name="partID"></param>
+        /// <returns>true if the touch is actually attempted, false if not</returns>
+        bool Touch(UUID agentID, UUID partID);
+
+        /// <summary>
         /// Delete an NPC.
         /// </summary>
         /// <param name="agentID">The UUID of the NPC</param>
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index b3e1069..43a09ec 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -104,6 +104,45 @@ namespace OpenSim.Region.OptionalModules.World.NPC
             OnMoneyTransferRequest(m_uuid, target, amount, 1, "Payment");
         }
 
+        public bool Touch(UUID target)
+        {
+            SceneObjectPart part = m_scene.GetSceneObjectPart(target);
+            if (part == null)
+                return false;
+            bool objectTouchable = hasTouchEvents(part); // Only touch an object that is scripted to respond
+            if (!objectTouchable && !part.IsRoot)
+                objectTouchable = hasTouchEvents(part.ParentGroup.RootPart);
+            if (!objectTouchable)
+                return false;
+            // Set up the surface args as if the touch is from a client that does not support this
+            SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
+            surfaceArgs.FaceIndex = -1; // TOUCH_INVALID_FACE
+            surfaceArgs.Binormal =  Vector3.Zero; // TOUCH_INVALID_VECTOR
+            surfaceArgs.Normal =  Vector3.Zero; // TOUCH_INVALID_VECTOR
+            surfaceArgs.STCoord = new Vector3(-1.0f, -1.0f, 0.0f); // TOUCH_INVALID_TEXCOORD
+            surfaceArgs.UVCoord = surfaceArgs.STCoord; // TOUCH_INVALID_TEXCOORD
+            List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
+            touchArgs.Add(surfaceArgs);
+            Vector3 offset = part.OffsetPosition * -1.0f;
+            if (OnGrabObject == null)
+                return false;
+            OnGrabObject(part.LocalId, offset, this, touchArgs);
+            if (OnGrabUpdate != null)
+                OnGrabUpdate(part.UUID, offset, part.ParentGroup.RootPart.GroupPosition, this, touchArgs);
+            if (OnDeGrabObject != null)
+                OnDeGrabObject(part.LocalId, this, touchArgs);
+            return true;
+        }
+
+        private bool hasTouchEvents(SceneObjectPart part)
+        {
+            if ((part.ScriptEvents & scriptEvents.touch) != 0 ||
+                (part.ScriptEvents & scriptEvents.touch_start) != 0 ||
+                (part.ScriptEvents & scriptEvents.touch_end) != 0)
+                return true;
+            return false;
+        }
+
         public void InstantMessage(UUID target, string message)
         {
             OnInstantMessage(this, new GridInstantMessage(m_scene,
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index d3456ab..1e85fb4 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -305,6 +305,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC
             return false;
         }
 
+        public bool Touch(UUID agentID, UUID objectID)
+        {
+            lock (m_avatars)
+            {
+                if (m_avatars.ContainsKey(agentID))
+                    return m_avatars[agentID].Touch(objectID);
+                return false;
+            }
+        }
+
         public UUID GetOwner(UUID agentID)
         {
             lock (m_avatars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7385dd9..61394af 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2677,6 +2677,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             }
         }
 
+        public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
+        {
+            CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
+            m_host.AddScriptLPS(1);
+            INPCModule module = World.RequestModuleInterface<INPCModule>();
+            int linkNum = link_num.value;
+            if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
+            {
+                UUID npcId;
+                if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
+                    return;
+                SceneObjectPart part = null;
+                UUID objectId;
+                if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
+                    part = World.GetSceneObjectPart(objectId);
+                if (part == null)
+                    return;
+                if (linkNum != ScriptBaseClass.LINK_THIS)
+                {
+                    if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
+                    { // 0 and 1 are treated as root, find the root if the current part isnt it
+                        if (!part.IsRoot)
+                            part = part.ParentGroup.RootPart;
+                    }
+                    else
+                    { // Find the prim with the given link number if not found then fail silently
+                        part = part.ParentGroup.GetLinkNumPart(linkNum);
+                        if (part == null)
+                            return;
+                    }
+                }
+                module.Touch(npcId, part.UUID);
+            }
+        }
+
         /// <summary>
         /// Save the current appearance of the script owner permanently to the named notecard.
         /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index a8335aa..d38709e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -231,6 +231,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
         void        osNpcRemove(key npc);
         void        osNpcPlayAnimation(LSL_Key npc, string animation);
         void        osNpcStopAnimation(LSL_Key npc, string animation);
+        void        osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num);
         void        osNpcWhisper(key npc, int channel, string message);
 
         LSL_Key     osOwnerSaveAppearance(string notecard);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 500ed96..692bb0a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -626,6 +626,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
             m_OSSL_Functions.osNpcWhisper(npc, channel, message);
         }
 
+        public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
+        {
+            m_OSSL_Functions.osNpcTouch(npcLSL_Key, object_key, link_num);
+        }
+
         public LSL_Key osOwnerSaveAppearance(string notecard)
         {
             return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
-- 
cgit v1.1


From ae1f2114f5ccb0422536ec73feb2dbf16c2645fd Mon Sep 17 00:00:00 2001
From: Talun
Date: Thu, 5 Jul 2012 23:34:23 +0100
Subject: Mantis 6077 trim NPC chat on channel zero.

This patch trims leading and trailing spaces from NPC chat and
suppresses the sending of empty chat strings on open chat channel 0.
---
 OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 43a09ec..9b3400d 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -192,6 +192,14 @@ namespace OpenSim.Region.OptionalModules.World.NPC
 
         private void SendOnChatFromClient(int channel, string message, ChatTypeEnum chatType)
         {
+            if (channel == 0)
+            {
+                message = message.Trim();
+                if (string.IsNullOrEmpty(message))
+                {
+                    return;
+                }
+            }
             OSChatMessage chatFromClient = new OSChatMessage();
             chatFromClient.Channel = channel;
             chatFromClient.From = Name;
-- 
cgit v1.1


From 056c9a59b2fee1e459915bd1ca908107c7c9695d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 6 Jul 2012 23:07:50 +0100
Subject: Add assert to attachment regression tests to check that number of
 objects in the scene graph

---
 .../Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 14 ++++++++++++++
 OpenSim/Region/Framework/Scenes/Scene.cs               | 11 +++++++++++
 OpenSim/Region/Framework/Scenes/SceneGraph.cs          | 18 +++++++++++++-----
 3 files changed, 38 insertions(+), 5 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 7856953..c1ba8a8 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -149,6 +149,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object);
             Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID));
 
+            Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
+
 //            TestHelpers.DisableLogging();
         }
 
@@ -181,6 +183,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             // Check appearance status
             Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1));
             Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
+
+            Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
         }
 
         [Test]
@@ -239,6 +243,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
 
             // Check item status
             Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo(0));
+
+            Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(0));
         }
 
         /// <summary>
@@ -300,6 +306,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             Assert.That(retreivedAttachments[0].ItemID, Is.EqualTo(attItem.ID));
             Assert.That(retreivedAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
             Assert.That(presence.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
+
+            Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
         }
 
         [Test]
@@ -399,6 +407,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
             Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
 
+            // Teleporting attachments should not end up in the scene graph
+            Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
+
             // Check attachments have been removed from sceneA
             ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
 
@@ -410,6 +421,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             // This is the actual attachment, which should no longer exist
             List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
             Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
+
+            // Teleporting attachments should not end up in the scene graph
+            Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
         }
 
         // I'm commenting this test because scene setup NEEDS InventoryService to 
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 6239d51..d98c01d 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -4474,6 +4474,17 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
+        /// Get all the scene object groups.
+        /// </summary>
+        /// <returns>
+        /// The scene object groups.  If the scene is empty then an empty list is returned.
+        /// </returns>
+        public List<SceneObjectGroup> GetSceneObjectGroups()
+        {
+            return m_sceneGraph.GetSceneObjectGroups();
+        }
+
+        /// <summary>
         /// Get a group via its UUID
         /// </summary>
         /// <param name="fullID"></param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index a59758f..bc9a585 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -958,6 +958,18 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
+        /// Get all the scene object groups.
+        /// </summary>
+        /// <returns>
+        /// The scene object groups.  If the scene is empty then an empty list is returned.
+        /// </returns>
+        protected internal List<SceneObjectGroup> GetSceneObjectGroups()
+        {
+            lock (SceneObjectGroupsByFullID)
+                return new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
+        }
+
+        /// <summary>
         /// Get a group in the scene
         /// </summary>
         /// <param name="fullID">UUID of the group</param>
@@ -1100,11 +1112,7 @@ namespace OpenSim.Region.Framework.Scenes
         /// <param name="action"></param>
         protected internal void ForEachSOG(Action<SceneObjectGroup> action)
         {
-            List<SceneObjectGroup> objlist;
-            lock (SceneObjectGroupsByFullID)
-                objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values);
-
-            foreach (SceneObjectGroup obj in objlist)
+            foreach (SceneObjectGroup obj in GetSceneObjectGroups())
             {
                 try
                 {
-- 
cgit v1.1


From e4a6611865848ffcfa6adedd813534e0a0e4abf3 Mon Sep 17 00:00:00 2001
From: Robert Adams
Date: Fri, 6 Jul 2012 10:01:47 -0700
Subject: Clean up collision reporting code so they are properly passed to    
 the simulator in batches. More comments.

---
 .../Region/Physics/BulletSPlugin/BSCharacter.cs    | 102 ++++++++++++---------
 OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs   |  11 +++
 OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs     |  29 +++---
 OpenSim/Region/Physics/BulletSPlugin/BSScene.cs    |  23 ++++-
 4 files changed, 107 insertions(+), 58 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
index b08d5db..dc0c008 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs
@@ -74,7 +74,7 @@ public class BSCharacter : PhysicsActor
     private float _buoyancy;
 
     private int _subscribedEventsMs = 0;
-    private int _lastCollisionTime = 0;
+    private int _nextCollisionOkTime = 0;
 
     private Vector3 _PIDTarget;
     private bool _usePID;
@@ -360,17 +360,22 @@ public class BSCharacter : PhysicsActor
         }
         //m_lastUpdateSent = false;
     }
+
     public override void AddAngularForce(Vector3 force, bool pushforce) { 
     }
     public override void SetMomentum(Vector3 momentum) { 
     }
+
+    // Turn on collision events at a rate no faster than one every the given milliseconds
     public override void SubscribeEvents(int ms) {
         _subscribedEventsMs = ms;
-        _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
+        _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
     }
+    // Stop collision events
     public override void UnSubscribeEvents() { 
         _subscribedEventsMs = 0;
     }
+    // Return 'true' if someone has subscribed to events
     public override bool SubscribedEvents() {
         return (_subscribedEventsMs > 0);
     }
@@ -386,47 +391,57 @@ public class BSCharacter : PhysicsActor
         _mass = _density * _avatarVolume;
     }
 
+    // Set to 'true' if the individual changed items should be checked
+    //   (someday RequestPhysicsTerseUpdate() will take a bitmap of changed properties)
+    const bool SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES = false;
+
     // The physics engine says that properties have updated. Update same and inform
     // the world that things have changed.
     public void UpdateProperties(EntityProperties entprop)
     {
         bool changed = false;
-        // we assign to the local variables so the normal set action does not happen
-        if (_position != entprop.Position)
-        {
-            _position = entprop.Position;
-            changed = true;
+        if (SHOULD_CHECK_FOR_INDIVIDUAL_CHANGES) {
+            // we assign to the local variables so the normal set action does not happen
+            if (_position != entprop.Position) {
+                _position = entprop.Position;
+                changed = true;
+            }
+            if (_orientation != entprop.Rotation) {
+                _orientation = entprop.Rotation;
+                changed = true;
+            }
+            if (_velocity != entprop.Velocity) {
+                _velocity = entprop.Velocity;
+                changed = true;
+            }
+            if (_acceleration != entprop.Acceleration) {
+                _acceleration = entprop.Acceleration;
+                changed = true;
+            }
+            if (_rotationalVelocity != entprop.RotationalVelocity) {
+                _rotationalVelocity = entprop.RotationalVelocity;
+                changed = true;
+            }
+            if (changed) {
+                // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
+                // Avatar movement is not done by generating this event. There is code in the heartbeat
+                //   loop that updates avatars.
+                // base.RequestPhysicsterseUpdate();
+            }
         }
-        if (_orientation != entprop.Rotation)
-        {
+        else {
+            _position = entprop.Position;
             _orientation = entprop.Rotation;
-            changed = true;
-        }
-        if (_velocity != entprop.Velocity)
-        {
             _velocity = entprop.Velocity;
-            changed = true;
-        }
-        if (_acceleration != entprop.Acceleration)
-        {
             _acceleration = entprop.Acceleration;
-            changed = true;
-        }
-        if (_rotationalVelocity != entprop.RotationalVelocity)
-        {
             _rotationalVelocity = entprop.RotationalVelocity;
-            changed = true;
-        }
-        if (changed)
-        {
-            // m_log.DebugFormat("{0}: UpdateProperties: id={1}, c={2}, pos={3}, rot={4}", LogHeader, LocalID, changed, _position, _orientation);
-            // Avatar movement is not done by generating this event. There is a system that
-            //  checks for avatar updates each heartbeat loop.
             // base.RequestPhysicsterseUpdate();
         }
     }
 
     // Called by the scene when a collision with this object is reported
+    // The collision, if it should be reported to the character, is placed in a collection
+    //   that will later be sent to the simulator when SendCollisions() is called.
     CollisionEventUpdate collisionCollection = null;
     public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
     {
@@ -440,29 +455,34 @@ public class BSCharacter : PhysicsActor
         }
 
         // throttle collisions to the rate specified in the subscription
-        if (_subscribedEventsMs == 0) return;   // don't want collisions
-        int nowTime = _scene.SimulationNowTime;
-        if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
-        _lastCollisionTime = nowTime;
+        if (_subscribedEventsMs != 0) {
+            int nowTime = _scene.SimulationNowTime;
+            if (nowTime >= _nextCollisionOkTime) {
+                _nextCollisionOkTime = nowTime + _subscribedEventsMs;
 
-        if (collisionCollection == null)
-            collisionCollection = new CollisionEventUpdate();
-        collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
+                if (collisionCollection == null)
+                    collisionCollection = new CollisionEventUpdate();
+                collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
+            }
+        }
     }
 
     public void SendCollisions()
     {
-        // if (collisionCollection != null)
-        // {
-        //     base.SendCollisionUpdate(collisionCollection);
-        //     collisionCollection = null;
-        // }
+        /*
+        if (collisionCollection != null && collisionCollection.Count > 0)
+        {
+            base.SendCollisionUpdate(collisionCollection);
+            collisionCollection = null;
+        }
+         */
         // Kludge to make a collision call even if there are no collisions.
         // This causes the avatar animation to get updated.
         if (collisionCollection == null)
             collisionCollection = new CollisionEventUpdate();
         base.SendCollisionUpdate(collisionCollection);
-        collisionCollection = null;
+        collisionCollection.Clear();
+        // End kludge
     }
 
 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs
index 0730824..0f027b8 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPlugin.cs
@@ -32,6 +32,14 @@ using OpenMetaverse;
 
 namespace OpenSim.Region.Physics.BulletSPlugin
 {
+    /// <summary>
+    /// Entry for a port of Bullet (http://bulletphysics.org/) to OpenSim. 
+    /// This module interfaces to an unmanaged C++ library which makes the
+    /// actual calls into the Bullet physics engine.
+    /// The unmanaged library is found in opensim-libs::trunk/unmanaged/BulletSim/.
+    /// The unmanaged library is compiled and linked statically with Bullet
+    /// to create BulletSim.dll and libBulletSim.so (for both 32 and 64 bit).
+    /// </summary>
 public class BSPlugin : IPhysicsPlugin
 {
     //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
@@ -53,6 +61,9 @@ public class BSPlugin : IPhysicsPlugin
         {
             if (Util.IsWindows())
                 Util.LoadArchSpecificWindowsDll("BulletSim.dll");
+            // If not Windows, loading is performed by the
+            // Mono loader as specified in 
+            // "bin/Physics/OpenSim.Region.Physics.BulletSPlugin.dll.config".
 
             _mScene = new BSScene(sceneIdentifier);
         }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
index 248d1f2..130f1ca 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs
@@ -90,7 +90,7 @@ public sealed class BSPrim : PhysicsActor
     private BSPrim _parentPrim;
 
     private int _subscribedEventsMs = 0;
-    private int _lastCollisionTime = 0;
+    private int _nextCollisionOkTime = 0;
     long _collidingStep;
     long _collidingGroundStep;
 
@@ -597,7 +597,8 @@ public sealed class BSPrim : PhysicsActor
     }
     public override void SubscribeEvents(int ms) { 
         _subscribedEventsMs = ms;
-        _lastCollisionTime = Util.EnvironmentTickCount() - _subscribedEventsMs; // make first collision happen
+        // make sure first collision happens
+        _nextCollisionOkTime = Util.EnvironmentTickCount() - _subscribedEventsMs;
     }
     public override void UnSubscribeEvents() { 
         _subscribedEventsMs = 0;
@@ -1338,23 +1339,27 @@ public sealed class BSPrim : PhysicsActor
             _collidingGroundStep = _scene.SimulationStep;
         }
 
-        if (_subscribedEventsMs == 0) return;   // nothing in the object is waiting for collision events
-        // throttle the collisions to the number of milliseconds specified in the subscription
-        int nowTime = _scene.SimulationNowTime;
-        if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
-        _lastCollisionTime = nowTime;
+        // if someone is subscribed to collision events....
+        if (_subscribedEventsMs != 0) {
+            // throttle the collisions to the number of milliseconds specified in the subscription
+            int nowTime = _scene.SimulationNowTime;
+            if (nowTime >= _nextCollisionOkTime) {
+                _nextCollisionOkTime = nowTime + _subscribedEventsMs;
 
-        if (collisionCollection == null)
-            collisionCollection = new CollisionEventUpdate();
-        collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
+                if (collisionCollection == null)
+                    collisionCollection = new CollisionEventUpdate();
+                collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
+            }
+        }
     }
 
+    // The scene is telling us it's time to pass our collected collisions into the simulator
     public void SendCollisions()
     {
-        if (collisionCollection != null)
+        if (collisionCollection != null && collisionCollection.Count > 0)
         {
             base.SendCollisionUpdate(collisionCollection);
-            collisionCollection = null;
+            collisionCollection.Clear();
         }
     }
 }
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
index 94a0ccf..417cb5f 100644
--- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
+++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs
@@ -52,6 +52,7 @@ using OpenSim.Region.Framework;
 // Should prim.link() and prim.delink() membership checking happen at taint time?
 // Mesh sharing. Use meshHash to tell if we already have a hull of that shape and only create once
 // Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
+// Use collision masks for collision with terrain and phantom objects 
 // Implement the genCollisions feature in BulletSim::SetObjectProperties (don't pass up unneeded collisions)
 // Implement LockAngularMotion
 // Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
@@ -62,9 +63,6 @@ using OpenSim.Region.Framework;
 // Multiple contact points on collision?
 //    See code in ode::near... calls to collision_accounting_events()
 //    (This might not be a problem. ODE collects all the collisions with one object in one tick.)
-// Use collision masks for collision with terrain and phantom objects 
-// Figure out how to not allocate a new Dictionary and List for every collision
-//    in BSPrim.Collide() and BSCharacter.Collide(). Can the same ones be reused?
 // Raycast
 // 
 namespace OpenSim.Region.Physics.BulletSPlugin
@@ -405,6 +403,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
         // prevent simulation until we've been initialized
         if (!m_initialized) return 10.0f;
 
+        long simulateStartTime = Util.EnvironmentTickCount();
+
         // update the prim states while we know the physics engine is not busy
         ProcessTaints();
 
@@ -437,13 +437,18 @@ public class BSScene : PhysicsScene, IPhysicsParameters
             }
         }
 
-        // The SendCollision's batch up the collisions on the objects. Now push the collisions into the simulator.
+        // The above SendCollision's batch up the collisions on the objects.
+        //      Now push the collisions into the simulator.
         foreach (BSPrim bsp in m_primsWithCollisions)
             bsp.SendCollisions();
         m_primsWithCollisions.Clear();
+
+        // This is a kludge to get avatar movement updated. 
+        //   Don't send collisions only if there were collisions -- send everytime.
+        //   ODE sends collisions even if there are none and this is used to update
+        //   avatar animations and stuff.
         // foreach (BSCharacter bsc in m_avatarsWithCollisions)
         //     bsc.SendCollisions();
-        // This is a kludge to get avatar movement updated. ODE sends collisions even if there isn't any
         foreach (KeyValuePair<uint, BSCharacter> kvp in m_avatars)
             kvp.Value.SendCollisions();
         m_avatarsWithCollisions.Clear();
@@ -465,10 +470,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
                 if (m_avatars.TryGetValue(entprop.ID, out actor))
                 {
                     actor.UpdateProperties(entprop);
+                    continue;
                 }
             }
         }
 
+        // If enabled, call into the physics engine to dump statistics
         if (m_detailedStatsStep > 0)
         {
             if ((m_simulationStep % m_detailedStatsStep) == 0)
@@ -477,6 +484,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
             }
         }
 
+        // this is a waste since the outside routine also calcuates the physics simulation
+        //   period. TODO: There should be a way of computing physics frames from simulator computation.
+        // long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
+        // return (timeStep * (float)simulateTotalTime);
+
         // TODO: FIX THIS: fps calculation wrong. This calculation always returns about 1 in normal operation.
         return timeStep / (numSubSteps * m_fixedTimeStep) * 1000f;
     }
@@ -528,6 +540,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
     public override void SetWaterLevel(float baseheight) 
     {
         m_waterLevel = baseheight;
+        // TODO: pass to physics engine so things will float?
     }
     public float GetWaterLevel()
     {
-- 
cgit v1.1


From 74014a38548b831ab56fa552f20d26fa29a83332 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 6 Jul 2012 23:13:00 +0100
Subject: minor: Remove some wrong comments in attachments regression tests

---
 .../CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs      | 2 --
 1 file changed, 2 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index c1ba8a8..5dcbd28 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -407,7 +407,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
             Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
 
-            // Teleporting attachments should not end up in the scene graph
             Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
 
             // Check attachments have been removed from sceneA
@@ -422,7 +421,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
             List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
             Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
 
-            // Teleporting attachments should not end up in the scene graph
             Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
         }
 
-- 
cgit v1.1


From f1f390cfdfa7485d771e65449889b12b64ad7f56 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 6 Jul 2012 23:22:40 +0100
Subject: Remove now duplicate interregion object check that should have been
 removed a few commits ago in 43a2da9

---
 OpenSim/Region/Framework/Scenes/Scene.cs | 12 ------------
 1 file changed, 12 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index d98c01d..5c7bca0 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2600,18 +2600,6 @@ namespace OpenSim.Region.Framework.Scenes
             else
             {
                 AddRestoredSceneObject(sceneObject, true, false);
-
-                if (!Permissions.CanObjectEntry(sceneObject.UUID,
-                        true, sceneObject.AbsolutePosition))
-                {
-                    // Deny non attachments based on parcel settings
-                    //
-                    m_log.Info("[INTERREGION]: Denied prim crossing because of parcel settings");
-
-                    DeleteSceneObject(sceneObject, false);
-
-                    return false;
-                }
             }
 
             return true;
-- 
cgit v1.1


From 7ff4eec79cf16886439604a23126abd195ae8b2e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 7 Jul 2012 00:02:45 +0100
Subject: Remove redundant SetScene() function in Scene.AddSceneObject()

This is always done later on in SceneGraph.AddSceneObject() if the call hasn't failed due to sanity checks.
There's no other purpose for this method to exist and it's dangerous/pointless to call in other conditions.
---
 OpenSim/Region/Framework/Scenes/Scene.cs                   |  2 --
 OpenSim/Region/Framework/Scenes/SceneGraph.cs              |  6 +++---
 OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs        | 10 ----------
 .../ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs    | 14 +++++++-------
 .../Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs   |  6 +++---
 5 files changed, 13 insertions(+), 25 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 5c7bca0..ec911a5 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2554,8 +2554,6 @@ namespace OpenSim.Region.Framework.Scenes
         /// <returns>True if the SceneObjectGroup was added, False if it was not</returns>
         public bool AddSceneObject(SceneObjectGroup sceneObject)
         {
-            sceneObject.SetScene(this);
-
             // Force allocation of new LocalId
             //
             SceneObjectPart[] parts = sceneObject.Parts;
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index bc9a585..2be5364 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -355,9 +355,9 @@ namespace OpenSim.Region.Framework.Scenes
 
             if (Entities.ContainsKey(sceneObject.UUID))
             {
-//                m_log.DebugFormat(
-//                    "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
-//                    m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
+                m_log.DebugFormat(
+                    "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()",
+                    m_parentScene.RegionInfo.RegionName, sceneObject.UUID);
 
                 return false;
             }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 96cc376..4e0e183 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -1055,16 +1055,6 @@ namespace OpenSim.Region.Framework.Scenes
         {
             return Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
         }
-
-        /// <summary>
-        /// Added as a way for the storage provider to reset the scene,
-        /// most likely a better way to do this sort of thing but for now...
-        /// </summary>
-        /// <param name="scene"></param>
-        public void SetScene(Scene scene)
-        {
-            m_scene = scene;
-        }
         
         /// <summary>
         /// Set a part to act as the root part for this scene object
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
index 3965734..c8718d9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAppearanceTest.cs
@@ -79,7 +79,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
         /// Test creation of an NPC where the appearance data comes from a notecard
         /// </summary>
         [Test]
-        public void TestOsNpcCreateFromNotecard()
+        public void TestOsNpcCreateUsingAppearanceFromNotecard()
         {
             TestHelpers.InMethod();
 //            log4net.Config.XmlConfigurator.Configure();
@@ -90,7 +90,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
 
             ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
             sp.Appearance.AvatarHeight = newHeight;
-            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
             SceneObjectPart part = so.RootPart;
             m_scene.AddSceneObject(so);
 
@@ -114,10 +114,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
         /// Test creation of an NPC where the appearance data comes from an avatar already in the region.
         /// </summary>
         [Test]
-        public void TestOsNpcCreateFromAvatar()
+        public void TestOsNpcCreateUsingAppearanceFromAvatar()
         {
             TestHelpers.InMethod();
-//            log4net.Config.XmlConfigurator.Configure();
+//            TestHelpers.EnableLogging();
 
             // Store an avatar with a different height from default in a notecard.
             UUID userId = TestHelpers.ParseTail(0x1);
@@ -125,7 +125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
 
             ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
             sp.Appearance.AvatarHeight = newHeight;
-            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
             SceneObjectPart part = so.RootPart;
             m_scene.AddSceneObject(so);
 
@@ -156,7 +156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
 
             ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
             sp.Appearance.AvatarHeight = newHeight;
-            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
             SceneObjectPart part = so.RootPart;
             m_scene.AddSceneObject(so);
 
@@ -197,7 +197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
 
             ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, nonOwnerId);
             sp.Appearance.AvatarHeight = newHeight;
-            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId);
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, ownerId, 0x10);
             SceneObjectPart part = so.RootPart;
             m_scene.AddSceneObject(so);
 
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
index 813e53b..25679a6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -97,11 +97,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
             ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
             sp.Appearance.AvatarHeight = newHeight;
 
-            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
             SceneObjectPart part = so.RootPart;
             m_scene.AddSceneObject(so);
 
-            SceneObjectGroup otherSo = SceneHelpers.CreateSceneObject(1, otherUserId);
+            SceneObjectGroup otherSo = SceneHelpers.CreateSceneObject(1, otherUserId, 0x20);
             SceneObjectPart otherPart = otherSo.RootPart;
             m_scene.AddSceneObject(otherSo);
 
@@ -148,7 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
 
             ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
             sp.Appearance.AvatarHeight = newHeight;
-            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
+            SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, 0x10);
             SceneObjectPart part = so.RootPart;
             m_scene.AddSceneObject(so);
 
-- 
cgit v1.1


From 3bd134474bead7c211b84413275a6bdcc7dc7dea Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 7 Jul 2012 00:09:12 +0100
Subject: minor: Get RegionReady module to shout initialization complete status
 to draw the eye

---
 .../OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs  | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index 0b9f875..db2cbeb 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -228,7 +228,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
                     // m_log.InfoFormat("[RegionReady]: Logins enabled for {0}, Oar {1}",
                     //                 m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
 
-                    m_log.InfoFormat("[RegionReady]: Initialization complete - logins enabled for {0}", m_scene.RegionInfo.RegionName);
+                    m_log.InfoFormat(
+                        "[RegionReady]: INITIALIZATION COMPLETE - LOGINS ENABLED FOR {0}",
+                        m_scene.RegionInfo.RegionName);
 
                     if ( m_uri != string.Empty )
                     {
-- 
cgit v1.1


From a85741ac37ef04e5c33e8aa30113cccd0291962f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 7 Jul 2012 00:14:16 +0100
Subject: minor: Make WORLD MAP category log lines consistent

---
 OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index c1c6b49..724533b 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -730,7 +730,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
                 {
                     if (Environment.TickCount > (m_blacklistedregions[regionhandle] + blacklistTimeout))
                     {
-                        m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted region {0}", regionhandle);
+                        m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted region {0}", regionhandle);
 
                         m_blacklistedregions.Remove(regionhandle);
                     }
@@ -781,7 +781,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
                 {
                     if (Environment.TickCount > (m_blacklistedurls[httpserver] + blacklistTimeout))
                     {
-                        m_log.DebugFormat("[WORLDMAP]: Unblock blacklisted URL {0}", httpserver);
+                        m_log.DebugFormat("[WORLD MAP]: Unblock blacklisted URL {0}", httpserver);
 
                         m_blacklistedurls.Remove(httpserver);
                     }
@@ -1343,7 +1343,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
             if (terrain == null)
                 return;
 
-            m_log.DebugFormat("[WORLDMAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName);
+            m_log.DebugFormat("[WORLD MAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName);
 
             byte[] data = terrain.WriteJpeg2000Image();
             if (data == null)
@@ -1365,7 +1365,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
             asset.Flags = AssetFlags.Maptile;
 
             // Store the new one
-            m_log.DebugFormat("[WORLDMAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName);
+            m_log.DebugFormat("[WORLD MAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName);
             
             m_scene.AssetService.Store(asset);
 
-- 
cgit v1.1


From 1201307c73da77f6f3f0725ce8c985af179f54bd Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 7 Jul 2012 00:26:25 +0100
Subject: Remove duplicate Warp3DImageModule entry in
 CoreModulePlugin.addin.xml

This was causing 2 copies of the module to be created for each scene.
Probably no bad consequences other than a small waste of memory (both for the module and for the warp3D renderer it loaded)
---
 OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml | 1 -
 1 file changed, 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
index dc6efed..424e0ab 100644
--- a/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
+++ b/OpenSim/Region/CoreModules/Resources/CoreModulePlugin.addin.xml
@@ -79,7 +79,6 @@
         <RegionModule id="AuthenticationServiceInConnectorModule" type="OpenSim.Region.CoreModules.ServiceConnectorsIn.Authentication.AuthenticationServiceInConnectorModule" />
         <RegionModule id="AccessModule" type="OpenSim.Region.CoreModules.World.AccessModule" />    \
         <RegionModule id="MapImageModule" type="OpenSim.Region.CoreModules.World.LegacyMap.MapImageModule" />    \
-        <RegionModule id="Warp3DImageModule" type="OpenSim.Region.CoreModules.World.Warp3DMap.Warp3DImageModule" />    \
 
     </Extension>
 
-- 
cgit v1.1


From 16d5b79d57602b6c28e958c98de18e18927fa7a3 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 7 Jul 2012 00:36:01 +0100
Subject: minor: remove some recent mono compiler warnings

---
 OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
index 537b8aa..78db2c6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
@@ -158,7 +158,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
             {
                 osslApi.osForceAttachToAvatarFromInventory(taskInvObjItemName, (int)attachPoint);
             }
-            catch (Exception e)
+            catch (Exception)
             {
                 exceptionCaught = true;
             }
-- 
cgit v1.1


From 112cddc9ca839579cc2710df5e2ea0906110dd8e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 7 Jul 2012 00:53:17 +0100
Subject: minor: rearrange INITIALIZATION COMPLETE log message so that it's
 clear init is only complete for a particular region at a time

---
 .../OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
index db2cbeb..600cafb 100644
--- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
+++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs
@@ -229,10 +229,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady
                     //                 m_scene.RegionInfo.RegionName, m_oarFileLoading.ToString());
 
                     m_log.InfoFormat(
-                        "[RegionReady]: INITIALIZATION COMPLETE - LOGINS ENABLED FOR {0}",
-                        m_scene.RegionInfo.RegionName);
+                        "[RegionReady]: INITIALIZATION COMPLETE FOR {0} - LOGINS ENABLED", m_scene.Name);
 
-                    if ( m_uri != string.Empty )
+                    if (m_uri != string.Empty)
                     {
                         RRAlert("enabled");
                     }
-- 
cgit v1.1


From 2eaa6d5ace738cf1848f82ce7a0b435928b6846f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 9 Jul 2012 21:24:32 +0100
Subject: Do not allow a script to attach a prim if its being sat upon.

This prevents a stack overflow where a get position on the avatar will refer to the attachment which will in turn refer back to the avatar.
This required recording of all sitting avatars on a prim which is done separately from recording the sit target avatar.
Recording HashSet is null if there are no sitting avatars in order to save memory.
---
 .../Avatar/Attachments/AttachmentsModule.cs        |  9 ++
 .../Attachments/Tests/AttachmentsModuleTests.cs    | 32 ++++++-
 .../Region/Framework/Scenes/SceneObjectGroup.cs    | 14 ++++
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 98 ++++++++++++++++++++--
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   | 18 +++-
 5 files changed, 162 insertions(+), 9 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 9eb0e38..eccf7a6 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -251,6 +251,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
 //                m_log.DebugFormat(
 //                    "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
 //                    group.Name, group.LocalId, sp.Name, attachmentPt, silent);
+
+                if (group.GetSittingAvatarsCount() != 0)
+                {
+//                    m_log.WarnFormat(
+//                        "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since {4} avatars are still sitting on it",
+//                        group.Name, group.LocalId, sp.Name, attachmentPt, group.GetSittingAvatarsCount());
+    
+                    return false;
+                }
     
                 if (sp.GetAttachments(attachmentPt).Contains(group))
                 {
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
index 5dcbd28..3e06900 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs
@@ -118,7 +118,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
 
             Scene scene = CreateDefaultTestScene();
             UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
-            ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID);
+            ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
 
             string attName = "att";
 
@@ -154,6 +154,36 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
 //            TestHelpers.DisableLogging();
         }
 
+        /// <summary>
+        /// Test that we do not attempt to attach an in-world object that someone else is sitting on.
+        /// </summary>
+        [Test]
+        public void TestAddSatOnAttachmentFromGround()
+        {
+            TestHelpers.InMethod();
+//            TestHelpers.EnableLogging();
+
+            Scene scene = CreateDefaultTestScene();
+            UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1);
+            ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1);
+
+            string attName = "att";
+
+            SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, sp.UUID);
+
+            UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(scene, 0x2);
+            ScenePresence sp2 = SceneHelpers.AddScenePresence(scene, ua2);
+
+            // Put avatar within 10m of the prim so that sit doesn't fail.
+            sp2.AbsolutePosition = new Vector3(0, 0, 0);
+            sp2.HandleAgentRequestSit(sp2.ControllingClient, sp2.UUID, so.UUID, Vector3.Zero);
+
+            scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Chest, false);
+
+            Assert.That(sp.HasAttachments(), Is.False);
+            Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1));
+        }
+
         [Test]
         public void TestAddAttachmentFromInventory()
         {
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 4e0e183..fc04761 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -3401,6 +3401,20 @@ namespace OpenSim.Region.Framework.Scenes
             return count;
         }
 
+        /// <summary>
+        /// Gets the number of sitting avatars.
+        /// </summary>
+        /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
+        /// <returns></returns>
+        public int GetSittingAvatarsCount()
+        {
+             int count = 0;
+
+             Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => count += p.GetSittingAvatarsCount());
+
+             return count;
+        }
+
         public override string ToString()
         {
             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 3d81358..6518b84 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -374,7 +374,6 @@ namespace OpenSim.Region.Framework.Scenes
         private uint _category;
         private Int32 _creationDate;
         private uint _parentID = 0;
-        private UUID m_sitTargetAvatar = UUID.Zero;
         private uint _baseMask = (uint)PermissionMask.All;
         private uint _ownerMask = (uint)PermissionMask.All;
         private uint _groupMask = (uint)PermissionMask.None;
@@ -1233,13 +1232,20 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
-        /// ID of the avatar that is sat on us.  If there is no such avatar then is UUID.Zero
+        /// 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
         /// </summary>
-        public UUID SitTargetAvatar
-        {
-            get { return m_sitTargetAvatar; }
-            set { m_sitTargetAvatar = value; }
-        }
+        public UUID SitTargetAvatar { get; set; }
+
+        /// <summary>
+        /// IDs of all avatars start on this object part.
+        /// </summary>
+        /// <remarks>
+        /// We need to track this so that we can stop sat upon prims from being attached.
+        /// </remarks>
+        /// <value>
+        /// null if there are no sitting avatars.  This is to save us create a hashset for every prim in a scene.
+        /// </value>
+        private HashSet<UUID> m_sittingAvatars;
 
         public virtual UUID RegionID
         {
@@ -4493,5 +4499,83 @@ namespace OpenSim.Region.Framework.Scenes
             Color color = Color;
             return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
         }
+
+        /// <summary>
+        /// Record an avatar sitting on this part.
+        /// </summary>
+        /// <remarks>This is called for all the sitting avatars whether there is a sit target set or not.</remarks>
+        /// <returns>
+        /// true if the avatar was not already recorded, false otherwise.
+        /// </returns>
+        /// <param name='avatarId'></param>
+        protected internal bool AddSittingAvatar(UUID avatarId)
+        {
+            HashSet<UUID> sittingAvatars = m_sittingAvatars;
+
+            if (sittingAvatars == null)
+                sittingAvatars = new HashSet<UUID>();
+
+            lock (sittingAvatars)
+            {
+                m_sittingAvatars = sittingAvatars;
+                return m_sittingAvatars.Add(avatarId);
+            }
+        }
+
+        /// <summary>
+        /// Remove an avatar recorded as sitting on this part.
+        /// </summary>
+        /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
+        /// <returns>
+        /// true if the avatar was present and removed, false if it was not present.
+        /// </returns>
+        /// <param name='avatarId'></param>
+        protected internal bool RemoveSittingAvatar(UUID avatarId)
+        {
+            HashSet<UUID> sittingAvatars = m_sittingAvatars;
+
+            // This can occur under a race condition where another thread
+            if (sittingAvatars == null)
+                return false;
+
+            lock (sittingAvatars)
+            {
+                if (sittingAvatars.Remove(avatarId))
+                {
+                    if (sittingAvatars.Count == 0)
+                        m_sittingAvatars = null;
+
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Get a copy of the list of sitting avatars.
+        /// </summary>
+        /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
+        /// <returns></returns>
+        public HashSet<UUID> GetSittingAvatars()
+        {
+            return new HashSet<UUID>(m_sittingAvatars);
+        }
+
+        /// <summary>
+        /// Gets the number of sitting avatars.
+        /// </summary>
+        /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
+        /// <returns></returns>
+        public int GetSittingAvatarsCount()
+        {
+            HashSet<UUID> sittingAvatars = m_sittingAvatars;
+
+            if (sittingAvatars == null)
+                return 0;
+
+            lock (sittingAvatars)
+                return sittingAvatars.Count;
+        }
     }
 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c7a670f..c6a2a03 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -578,6 +578,12 @@ namespace OpenSim.Region.Framework.Scenes
         public uint ParentID { get; set; }
 
         /// <summary>
+        /// Are we sitting on an object?
+        /// </summary>
+        /// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks>
+        public bool IsSatOnObject { get { return ParentID != 0; } }
+
+        /// <summary>
         /// If the avatar is sitting, the prim that it's sitting on.  If not sitting then null.
         /// </summary>
         /// <remarks>
@@ -1808,6 +1814,8 @@ namespace OpenSim.Region.Framework.Scenes
                 SendAvatarDataToAllAgents();
                 m_requestedSitTargetID = 0;
 
+                part.RemoveSittingAvatar(UUID);
+
                 if (part != null)
                     part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
             }
@@ -1887,7 +1895,7 @@ namespace OpenSim.Region.Framework.Scenes
                    )
                    ));
 
-//                m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
+            m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
 
             if (PhysicsActor != null)
                 m_sitAvatarHeight = PhysicsActor.Size.Z;
@@ -1920,6 +1928,12 @@ namespace OpenSim.Region.Framework.Scenes
                     AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
                     canSit = true;
                 }
+//                else
+//                {
+//                    m_log.DebugFormat(
+//                        "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
+//                        Name, part.Name, part.LocalId);
+//                }
             }
 
             if (canSit)
@@ -1930,6 +1944,8 @@ namespace OpenSim.Region.Framework.Scenes
                     RemoveFromPhysicalScene();
                 }
 
+                part.AddSittingAvatar(UUID);
+
                 cameraAtOffset = part.GetCameraAtOffset();
                 cameraEyeOffset = part.GetCameraEyeOffset();
                 forceMouselook = part.GetForceMouselook();
-- 
cgit v1.1


From d6f563794efb857210f4c773ef5218855c9a4ea4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 9 Jul 2012 21:43:44 +0100
Subject: Don't allow a prim to be sat upon if its part of an attachment

---
 OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 +++++++++
 1 file changed, 9 insertions(+)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c6a2a03..51ca9bd 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2219,6 +2219,15 @@ namespace OpenSim.Region.Framework.Scenes
 
             if (part != null)
             {
+                if (part.ParentGroup.IsAttachment)
+                {
+                    m_log.WarnFormat(
+                        "[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}",
+                        Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar);
+
+                    return;
+                }
+
                 if (part.SitTargetAvatar == UUID)
                 {
                     Vector3 sitTargetPos = part.SitTargetPosition;
-- 
cgit v1.1


From c8af20f966e005fb512869299d80be6b83cb70bf Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 9 Jul 2012 23:08:41 +0100
Subject: This script allows an object to be attached directly from prim
 inventory to another avatar in the scene. Very useful in serious
 game/environment scenarios where its only allowed for trusted creators.
 Threat level Severe

---
 .../Shared/Api/Implementation/OSSL_Api.cs          | 25 ++++++++--
 .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 18 +++++++-
 .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs   |  5 ++
 .../Shared/Tests/OSSL_ApiAttachmentTests.cs        | 53 ++++++++++++++++++++++
 4 files changed, 96 insertions(+), 5 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 61394af..e90f577 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -3190,13 +3190,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
         {
             CheckThreatLevel(ThreatLevel.High, "osForceAttachToAvatarFromInventory");
 
+            m_host.AddScriptLPS(1);
+
+            ForceAttachToAvatarFromInventory(m_host.OwnerID, itemName, attachmentPoint);
+        }
+
+        public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint)
+        {
+            CheckThreatLevel(ThreatLevel.Severe, "osForceAttachToOtherAvatarFromInventory");
+
+            m_host.AddScriptLPS(1);
+
+            UUID avatarId;
+
+            if (!UUID.TryParse(rawAvatarId, out avatarId))
+                return;
+
+            ForceAttachToAvatarFromInventory(avatarId, itemName, attachmentPoint);
+        }
+
+        public void ForceAttachToAvatarFromInventory(UUID avatarId, string itemName, int attachmentPoint)
+        {
             IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
 
             if (attachmentsModule == null)
                 return;
 
-            m_host.AddScriptLPS(1);
-
             InitLSL();
 
             TaskInventoryItem item = m_host.Inventory.GetInventoryItem(itemName);
@@ -3219,7 +3238,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
                 return;
             }
 
-            ScenePresence sp = World.GetScenePresence(m_host.OwnerID);
+            ScenePresence sp = World.GetScenePresence(avatarId);
 
             if (sp == null)
                 return;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index d38709e..b5416c8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -101,19 +101,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
         // Attachment commands
 
         /// <summary>
-        /// Attach the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH
+        /// Attach the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH
         /// </summary>
         /// <param name='attachment'>The attachment point.  For example, ATTACH_CHEST</param>
         void osForceAttachToAvatar(int attachment);
 
         /// <summary>
-        /// Attach the inventory item in the object containing this script to the avatar that owns it without checking for PERMISSION_ATTACH
+        /// Attach an inventory item in the object containing this script to the avatar that owns it without asking for PERMISSION_ATTACH
         /// </summary>
+        /// <remarks>
+        /// Nothing happens if the owner is not in the region.
+        /// </remarks>
         /// <param name='itemName'>Tha name of the item.  If this is not found then a warning is said to the owner</param>
         /// <param name='attachment'>The attachment point.  For example, ATTACH_CHEST</param>
         void osForceAttachToAvatarFromInventory(string itemName, int attachment);
 
         /// <summary>
+        /// Attach an inventory item in the object containing this script to any avatar in the region without asking for PERMISSION_ATTACH
+        /// </summary>
+        /// <remarks>
+        /// Nothing happens if the avatar is not in the region.
+        /// </remarks>
+        /// <param name='rawAvatarId'>The UUID of the avatar to which to attach.  Nothing happens if this is not a UUID</para>
+        /// <param name='itemName'>The name of the item.  If this is not found then a warning is said to the owner</param>
+        /// <param name='attachment'>The attachment point.  For example, ATTACH_CHEST</param>
+        void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint);
+
+        /// <summary>
         /// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH
         /// </summary>
         /// <remarks>Nothing happens if the object is not attached.</remarks>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 692bb0a..b40bdf0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -301,6 +301,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
             m_OSSL_Functions.osForceAttachToAvatarFromInventory(itemName, attachmentPoint);
         }
 
+        public void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint)
+        {
+            m_OSSL_Functions.osForceAttachToOtherAvatarFromInventory(rawAvatarId, itemName, attachmentPoint);
+        }
+
         public void osForceDetachFromAvatar()
         {
             m_OSSL_Functions.osForceDetachFromAvatar();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
index 78db2c6..f5aa518 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
@@ -174,5 +174,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
             List<AvatarAttachment> attachmentsInAppearance = sp.Appearance.GetAttachments();
             Assert.That(attachmentsInAppearance.Count, Is.EqualTo(0));
         }
+
+        [Test]
+        public void TestOsForceAttachToOtherAvatarFromInventory()
+        {
+            TestHelpers.InMethod();
+            TestHelpers.EnableLogging();
+
+            string taskInvObjItemName = "sphere";
+            UUID taskInvObjItemId = UUID.Parse("00000000-0000-0000-0000-100000000000");
+            AttachmentPoint attachPoint = AttachmentPoint.Chin;
+
+            UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(m_scene, "user", "one", 0x1, "pass");
+            UserAccount ua2 = UserAccountHelpers.CreateUserWithInventory(m_scene, "user", "two", 0x2, "pass");
+
+            ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, ua1);
+            SceneObjectGroup inWorldObj = SceneHelpers.AddSceneObject(m_scene, "inWorldObj", ua1.PrincipalID);
+            TaskInventoryItem scriptItem = TaskInventoryHelpers.AddScript(m_scene, inWorldObj.RootPart);
+
+            new LSL_Api().Initialize(m_engine, inWorldObj.RootPart, scriptItem);
+            OSSL_Api osslApi = new OSSL_Api();
+            osslApi.Initialize(m_engine, inWorldObj.RootPart, scriptItem);
+
+            // Create an object embedded inside the first
+            TaskInventoryHelpers.AddSceneObject(m_scene, inWorldObj.RootPart, taskInvObjItemName, taskInvObjItemId, ua1.PrincipalID);
+
+            ScenePresence sp2 = SceneHelpers.AddScenePresence(m_scene, ua2);
+
+            osslApi.osForceAttachToOtherAvatarFromInventory(sp2.UUID.ToString(), taskInvObjItemName, (int)attachPoint);
+
+            // Check scene presence status
+            Assert.That(sp.HasAttachments(), Is.False);
+            List<SceneObjectGroup> attachments = sp.GetAttachments();
+            Assert.That(attachments.Count, Is.EqualTo(0));
+
+            Assert.That(sp2.HasAttachments(), Is.True);
+            List<SceneObjectGroup> attachments2 = sp2.GetAttachments();
+            Assert.That(attachments2.Count, Is.EqualTo(1));
+            SceneObjectGroup attSo = attachments2[0];
+            Assert.That(attSo.Name, Is.EqualTo(taskInvObjItemName));
+            Assert.That(attSo.OwnerID, Is.EqualTo(ua2.PrincipalID));
+            Assert.That(attSo.AttachmentPoint, Is.EqualTo((uint)attachPoint));
+            Assert.That(attSo.IsAttachment);
+            Assert.That(attSo.UsesPhysics, Is.False);
+            Assert.That(attSo.IsTemporary, Is.False);
+
+            // Check appearance status
+            List<AvatarAttachment> attachmentsInAppearance = sp.Appearance.GetAttachments();
+            Assert.That(attachmentsInAppearance.Count, Is.EqualTo(0));
+
+            List<AvatarAttachment> attachmentsInAppearance2 = sp2.Appearance.GetAttachments();
+            Assert.That(attachmentsInAppearance2.Count, Is.EqualTo(1));
+            Assert.That(sp2.Appearance.GetAttachpoint(attachmentsInAppearance2[0].ItemID), Is.EqualTo((uint)attachPoint));
+        }
     }
 }
\ No newline at end of file
-- 
cgit v1.1


From eb5ec4a78698a3b1fd6d581c800ac985d5d946fa Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 21:42:51 +0100
Subject: If a script is being stopped manually, then give the scriptpool
 thread 1 second to finish normally before forcibly aborting.

This is to avoid the worst of the problems in mono 2.6, 2.10 where an aborted thread does not always release all its locks.
This very short grace period is identical to the existing behaviour when a script is removed from the scene.
---
 OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 7f3bd76..efcae94 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -1574,7 +1574,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine
         {
             IScriptInstance instance = GetInstance(itemID);
             if (instance != null)
-                instance.Stop(0);
+            {
+                // Give the script some time to finish processing its last event.  Simply aborting the script thread can
+                // cause issues on mono 2.6, 2.10 and possibly later where locks are not released properly on abort.
+                instance.Stop(1000);
+            }
         }
 
         public DetectParams GetDetectParams(UUID itemID, int idx)
-- 
cgit v1.1


From f3134b5cf688af9b824880e0221072b24d22f33e Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 22:41:11 +0100
Subject: When an attachment is detached to inv or derezzed, stop the scripts,
 update the known item with script state still in the script engine and then
 remove the scripts.

This is to fix a regression starting from 5301648 where attachments had to start being deleted before persistence in order to avoid race conditions with hud update threads.
---
 .../Avatar/Attachments/AttachmentsModule.cs        | 20 +++++---
 .../Framework/Interfaces/IEntityInventory.cs       | 15 +++++-
 OpenSim/Region/Framework/Scenes/Scene.cs           | 19 ++++++-
 .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 10 +++-
 .../Framework/Scenes/SceneObjectPartInventory.cs   | 59 ++++++++++++++++++++--
 5 files changed, 110 insertions(+), 13 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index eccf7a6..efab6ed 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -211,16 +211,20 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
 
             lock (sp.AttachmentsSyncLock)
             {
-                foreach (SceneObjectGroup grp in sp.GetAttachments())
+                foreach (SceneObjectGroup so in sp.GetAttachments())
                 {
-                    grp.Scene.DeleteSceneObject(grp, false);
+                    // We can only remove the script instances from the script engine after we've retrieved their xml state
+                    // when we update the attachment item.
+                    m_scene.DeleteSceneObject(so, false, false);
     
                     if (saveChanged || saveAllScripted)
                     {
-                        grp.IsAttachment = false;
-                        grp.AbsolutePosition = grp.RootPart.AttachedPos;
-                        UpdateKnownItem(sp, grp, saveAllScripted);
+                        so.IsAttachment = false;
+                        so.AbsolutePosition = so.RootPart.AttachedPos;
+                        UpdateKnownItem(sp, so, saveAllScripted);
                     }
+
+                    so.RemoveScriptInstances(true);
                 }
     
                 sp.ClearAttachments();
@@ -682,7 +686,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
 
             m_scene.EventManager.TriggerOnAttach(so.LocalId, so.FromItemID, UUID.Zero);
             sp.RemoveAttachment(so);
-            m_scene.DeleteSceneObject(so, false);
+
+            // We can only remove the script instances from the script engine after we've retrieved their xml state
+            // when we update the attachment item.
+            m_scene.DeleteSceneObject(so, false, false);
 
             // Prepare sog for storage
             so.AttachedAvatar = UUID.Zero;
@@ -691,6 +698,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
             so.AbsolutePosition = so.RootPart.AttachedPos;
 
             UpdateKnownItem(sp, so, true);
+            so.RemoveScriptInstances(true);
         }
 
         private SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
index 1c9bdce..8d62847 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs
@@ -92,7 +92,7 @@ namespace OpenSim.Region.Framework.Interfaces
         void ResumeScripts();
 
         /// <summary>
-        /// Stop all the scripts in this entity.
+        /// Stop and remove all the scripts in this entity from the scene.
         /// </summary>
         /// <param name="sceneObjectBeingDeleted">
         /// Should be true if these scripts are being removed because the scene
@@ -101,6 +101,11 @@ namespace OpenSim.Region.Framework.Interfaces
         void RemoveScriptInstances(bool sceneObjectBeingDeleted);
 
         /// <summary>
+        /// Stop all the scripts in this entity.
+        /// </summary>
+        void StopScriptInstances();
+
+        /// <summary>
         /// Start a script which is in this entity's inventory.
         /// </summary>
         /// <param name="item"></param>
@@ -129,7 +134,7 @@ namespace OpenSim.Region.Framework.Interfaces
         bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource);
 
         /// <summary>
-        /// Stop a script which is in this prim's inventory.
+        /// Stop and remove a script which is in this prim's inventory from the scene.
         /// </summary>
         /// <param name="itemId"></param>
         /// <param name="sceneObjectBeingDeleted">
@@ -139,6 +144,12 @@ namespace OpenSim.Region.Framework.Interfaces
         void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted);
 
         /// <summary>
+        /// Stop a script which is in this prim's inventory.
+        /// </summary>
+        /// <param name="itemId"></param>
+        void StopScriptInstance(UUID itemId);
+
+        /// <summary>
         /// Add an item to this entity's inventory.  If an item with the same name already exists, then an alternative
         /// name is chosen.
         /// </summary>
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index ec911a5..25223b9 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2183,13 +2183,30 @@ namespace OpenSim.Region.Framework.Scenes
         /// <summary>
         /// Synchronously delete the given object from the scene.
         /// </summary>
+        /// <remarks>
+        /// Scripts are also removed.
+        /// </remarks>
         /// <param name="group">Object Id</param>
         /// <param name="silent">Suppress broadcasting changes to other clients.</param>
         public void DeleteSceneObject(SceneObjectGroup group, bool silent)
+        {
+            DeleteSceneObject(group, silent, true);
+        }
+
+        /// <summary>
+        /// Synchronously delete the given object from the scene.
+        /// </summary>
+        /// <param name="group">Object Id</param>
+        /// <param name="silent">Suppress broadcasting changes to other clients.</param>
+        /// <param name="removeScripts">If true, then scripts are removed.  If false, then they are only stopped.</para>
+        public void DeleteSceneObject(SceneObjectGroup group, bool silent, bool removeScripts)
         {            
 //            m_log.DebugFormat("[SCENE]: Deleting scene object {0} {1}", group.Name, group.UUID);
 
-            group.RemoveScriptInstances(true);
+            if (removeScripts)
+                group.RemoveScriptInstances(true);
+            else
+                group.StopScriptInstances();
 
             SceneObjectPart[] partList = group.Parts;
 
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs
index 2866b54..ddf5da0 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
         }
 
         /// <summary>
-        /// Stop the scripts contained in all the prims in this group
+        /// Stop and remove the scripts contained in all the prims in this group
         /// </summary>
         /// <param name="sceneObjectBeingDeleted">
         /// Should be true if these scripts are being removed because the scene
@@ -93,6 +93,14 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
+        /// Stop the scripts contained in all the prims in this group
+        /// </summary>
+        public void StopScriptInstances()
+        {
+            Array.ForEach<SceneObjectPart>(m_parts.GetArray(), p => p.Inventory.StopScriptInstances());
+        }
+
+        /// <summary>
         /// Add an inventory item from a user's inventory to a prim in this scene object.
         /// </summary>
         /// <param name="agentID">The agent adding the item.</param>
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 866311a..cf2ed1a 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -280,7 +280,7 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
-        /// Stop all the scripts in this prim.
+        /// Stop and remove all the scripts in this prim.
         /// </summary>
         /// <param name="sceneObjectBeingDeleted">
         /// Should be true if these scripts are being removed because the scene
@@ -294,6 +294,14 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
+        /// Stop all the scripts in this prim.
+        /// </summary>
+        public void StopScriptInstances()
+        {
+            GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i));
+        }
+
+        /// <summary>
         /// Start a script which is in this prim's inventory.
         /// </summary>
         /// <param name="item"></param>
@@ -443,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
-        /// Stop a script which is in this prim's inventory.
+        /// Stop and remove a script which is in this prim's inventory.
         /// </summary>
         /// <param name="itemId"></param>
         /// <param name="sceneObjectBeingDeleted">
@@ -470,7 +478,36 @@ namespace OpenSim.Region.Framework.Scenes
             }
             else
             {
-                m_log.ErrorFormat(
+                m_log.WarnFormat(
+                    "[PRIM INVENTORY]: " +
+                    "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
+                    itemId, m_part.Name, m_part.UUID, 
+                    m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
+            }
+        }
+
+        /// <summary>
+        /// Stop a script which is in this prim's inventory.
+        /// </summary>
+        /// <param name="itemId"></param>
+        /// <param name="sceneObjectBeingDeleted">
+        /// Should be true if this script is being removed because the scene
+        /// object is being deleted.  This will prevent spurious updates to the client.
+        /// </param>
+        public void StopScriptInstance(UUID itemId)
+        {
+            TaskInventoryItem scriptItem;
+
+            lock (m_items)
+                m_items.TryGetValue(itemId, out scriptItem);
+
+            if (scriptItem != null)
+            {
+                StopScriptInstance(scriptItem);
+            }
+            else
+            {
+                m_log.WarnFormat(
                     "[PRIM INVENTORY]: " +
                     "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
                     itemId, m_part.Name, m_part.UUID, 
@@ -479,6 +516,22 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
+        /// Stop a script which is in this prim's inventory.
+        /// </summary>
+        /// <param name="itemId"></param>
+        /// <param name="sceneObjectBeingDeleted">
+        /// Should be true if this script is being removed because the scene
+        /// object is being deleted.  This will prevent spurious updates to the client.
+        /// </param>
+        public void StopScriptInstance(TaskInventoryItem item)
+        {
+            m_part.ParentGroup.Scene.EventManager.TriggerStopScript(m_part.LocalId, item.ItemID);
+
+            // At the moment, even stopped scripts are counted as active, which is probably wrong.
+//            m_part.ParentGroup.AddActiveScriptCount(-1);
+        }
+
+        /// <summary>
         /// Check if the inventory holds an item with a given name.
         /// </summary>
         /// <param name="name"></param>
-- 
cgit v1.1


From 58869e5aa09a292dc2159c73bada2c487151dda0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:03:52 +0100
Subject: Fix recent SOP.GetSittingAvatars() to return null if there are no
 sitting avatars rather than throwing an exception.

Extends sitting avatar regression tests to test new sitters information
---
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 14 +++++++++++--
 .../Scenes/Tests/ScenePresenceSitTests.cs          | 24 ++++++++++++++++++----
 2 files changed, 32 insertions(+), 6 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6518b84..6677dae 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4556,10 +4556,20 @@ namespace OpenSim.Region.Framework.Scenes
         /// Get a copy of the list of sitting avatars.
         /// </summary>
         /// <remarks>This applies to all sitting avatars whether there is a sit target set or not.</remarks>
-        /// <returns></returns>
+        /// <returns>A hashset of the sitting avatars.  Returns null if there are no sitting avatars.</returns>
         public HashSet<UUID> GetSittingAvatars()
         {
-            return new HashSet<UUID>(m_sittingAvatars);
+            HashSet<UUID> sittingAvatars = m_sittingAvatars;
+
+            if (sittingAvatars == null)
+            {
+                return null;
+            }
+            else
+            {
+                lock (sittingAvatars)
+                    return new HashSet<UUID>(sittingAvatars);
+            }
         }
 
         /// <summary>
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 @@
  */
 
 using System;
+using System.Collections.Generic;
 using System.Reflection;
 using Nini.Config;
 using NUnit.Framework;
@@ -69,6 +70,8 @@ namespace OpenSim.Region.Framework.Scenes.Tests
             m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
 
             Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
+            Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
+            Assert.That(part.GetSittingAvatars(), Is.Null);
             Assert.That(m_sp.ParentID, Is.EqualTo(0));
         }
 
@@ -86,7 +89,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests
 
             m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
 
+            Assert.That(m_sp.PhysicsActor, Is.Null);
+
             Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
+            Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));
+            HashSet<UUID> sittingAvatars = part.GetSittingAvatars();
+            Assert.That(sittingAvatars.Count, Is.EqualTo(1));
+            Assert.That(sittingAvatars.Contains(m_sp.UUID));
             Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
         }
 
@@ -104,10 +113,6 @@ namespace OpenSim.Region.Framework.Scenes.Tests
 
             m_sp.HandleAgentRequestSit(m_sp.ControllingClient, m_sp.UUID, part.UUID, Vector3.Zero);
 
-            Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
-            Assert.That(m_sp.ParentID, Is.EqualTo(part.LocalId));
-            Assert.That(m_sp.PhysicsActor, Is.Null);
-
             // FIXME: This is different for live avatars - z position is adjusted.  This is half the height of the
             // default avatar.
             // 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
             m_sp.StandUp();
 
             Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
+            Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
+            Assert.That(part.GetSittingAvatars(), Is.Null);
             Assert.That(m_sp.ParentID, Is.EqualTo(0));
             Assert.That(m_sp.PhysicsActor, Is.Not.Null);
         }
@@ -145,11 +152,20 @@ namespace OpenSim.Region.Framework.Scenes.Tests
                 Is.EqualTo(part.AbsolutePosition + part.SitTargetPosition + ScenePresence.SIT_TARGET_ADJUSTMENT));
             Assert.That(m_sp.PhysicsActor, Is.Null);
 
+            Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(1));
+            HashSet<UUID> sittingAvatars = part.GetSittingAvatars();
+            Assert.That(sittingAvatars.Count, Is.EqualTo(1));
+            Assert.That(sittingAvatars.Contains(m_sp.UUID));
+
             m_sp.StandUp();
 
             Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
             Assert.That(m_sp.ParentID, Is.EqualTo(0));
             Assert.That(m_sp.PhysicsActor, Is.Not.Null);
+
+            Assert.That(part.SitTargetAvatar, Is.EqualTo(UUID.Zero));
+            Assert.That(part.GetSittingAvatarsCount(), Is.EqualTo(0));
+            Assert.That(part.GetSittingAvatars(), Is.Null);
         }
 
         [Test]
-- 
cgit v1.1


From 9f01c3d4087266a8aa9a372a87ff78cae971d0c5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:04:44 +0100
Subject: Disable logging in regression test in OSSL_ApiAttachmentTests

---
 OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
index f5aa518..5ed1f3d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs
@@ -179,7 +179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
         public void TestOsForceAttachToOtherAvatarFromInventory()
         {
             TestHelpers.InMethod();
-            TestHelpers.EnableLogging();
+//            TestHelpers.EnableLogging();
 
             string taskInvObjItemName = "sphere";
             UUID taskInvObjItemId = UUID.Parse("00000000-0000-0000-0000-100000000000");
-- 
cgit v1.1


From 506437b68449ab521f0ccf467ad642ad5e442d73 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:06:34 +0100
Subject: Remove log line accidentally left in SP.SendSitResponse()

---
 OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 51ca9bd..c71bae9 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1895,7 +1895,7 @@ namespace OpenSim.Region.Framework.Scenes
                    )
                    ));
 
-            m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
+//            m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
 
             if (PhysicsActor != null)
                 m_sitAvatarHeight = PhysicsActor.Size.Z;
-- 
cgit v1.1


From e8347b70957273421ee567577e2d9a6139af0621 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:19:52 +0100
Subject: Move common code to detect whether a part has a valid sit target into
 a SOP property rather than being repeated in SP.

This also makes the detection in SP.FindNextAvailableSitTarget() and SendSitResponse() identical.
Previously they varied slightly (SendSitResponse didn't check for an older type of invalid quaternion) but the practical effect is most probably zero.
---
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 15 ++++++++++
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   | 35 ++++------------------
 2 files changed, 20 insertions(+), 30 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 6677dae..dcec7e9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -135,6 +135,21 @@ namespace OpenSim.Region.Framework.Scenes
             get { return ParentGroup.RootPart == this; } 
         }
 
+        /// <summary>
+        /// Is an explicit sit target set for this part?
+        /// </summary>
+        public bool IsSitTargetSet
+        {
+            get
+            {
+                return
+                    !(SitTargetPosition == Vector3.Zero
+                      && (SitTargetOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
+                       || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 1f && SitTargetOrientation.W == 0f // W-Z Mapping was invalid at one point
+                       || SitTargetOrientation.X == 0f && SitTargetOrientation.Y == 0f && SitTargetOrientation.Z == 0f && SitTargetOrientation.W == 0f)); // Invalid Quaternion
+            }
+        }
+
         #region Fields
 
         public bool AllowedDrop;
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c71bae9..c644ea5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1846,15 +1846,7 @@ namespace OpenSim.Region.Framework.Scenes
             //look for prims with explicit sit targets that are available
             foreach (SceneObjectPart part in partArray)
             {
-                // Is a sit target available?
-                Vector3 avSitOffset = part.SitTargetPosition;
-                Quaternion avSitOrientation = part.SitTargetOrientation;
-                UUID avOnTargetAlready = part.SitTargetAvatar;
-
-                bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero;
-                bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity;
-
-                if (SitTargetisSet && SitTargetUnOccupied)
+                if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
                 {
                     //switch the target to this prim
                     return part;
@@ -1880,40 +1872,23 @@ namespace OpenSim.Region.Framework.Scenes
             // TODO: determine position to sit at based on scene geometry; don't trust offset from client
             // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
 
-            // Is a sit target available?
-            Vector3 avSitOffSet = part.SitTargetPosition;
-            Quaternion avSitOrientation = part.SitTargetOrientation;
-            UUID avOnTargetAlready = part.SitTargetAvatar;
-
-            bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
-            bool SitTargetisSet =
-                (!(avSitOffSet == Vector3.Zero &&
-                   (
-                       avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
-                       || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
-                       || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
-                   )
-                   ));
-
-//            m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
-
             if (PhysicsActor != null)
                 m_sitAvatarHeight = PhysicsActor.Size.Z;
 
             bool canSit = false;
             pos = part.AbsolutePosition + offset;
 
-            if (SitTargetisSet)
+            if (part.IsSitTargetSet)
             {
-                if (SitTargetUnOccupied)
+                if (part.SitTargetAvatar == UUID.Zero)
                 {
 //                    m_log.DebugFormat(
 //                        "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
 //                        Name, part.Name, part.LocalId);
 
                     part.SitTargetAvatar = UUID;
-                    offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z);
-                    sitOrientation = avSitOrientation;
+                    offset = part.SitTargetPosition;
+                    sitOrientation = part.SitTargetOrientation;
                     canSit = true;
                 }
             }
-- 
cgit v1.1


From 69a6f6e3cd5cf1146a2d11d1393df0851c051e67 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:26:40 +0100
Subject: refactor: use sit orientation argument passed in to
 SP.SendSitResponse() rather than creating a new copy

There are no issues with side-effects since this is a struct.
---
 OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c644ea5..a8c98ed 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1857,10 +1857,8 @@ namespace OpenSim.Region.Framework.Scenes
             return targetPart;
         }
 
-        private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation)
+        private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation)
         {
-            Vector3 pos = new Vector3();
-            Quaternion sitOrientation = pSitOrientation;
             Vector3 cameraEyeOffset = Vector3.Zero;
             Vector3 cameraAtOffset = Vector3.Zero;
             bool forceMouselook = false;
@@ -1876,7 +1874,7 @@ namespace OpenSim.Region.Framework.Scenes
                 m_sitAvatarHeight = PhysicsActor.Size.Z;
 
             bool canSit = false;
-            pos = part.AbsolutePosition + offset;
+            Vector3 pos = part.AbsolutePosition + offset;
 
             if (part.IsSitTargetSet)
             {
-- 
cgit v1.1


From c8f0d476d2f775ba4d7afca12eeff527b46bb8e2 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:34:40 +0100
Subject: refactor: Add SOP.IsSitTargetOccupied to improve readability

---
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++++-
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   | 4 ++--
 2 files changed, 8 insertions(+), 3 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index dcec7e9..937f43e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -136,6 +136,11 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
+        /// Is the sit target of this part occupied?
+        /// </summary>
+        public bool IsSitTargetOccupied { get { return SitTargetAvatar != UUID.Zero; } }
+
+        /// <summary>
         /// Is an explicit sit target set for this part?
         /// </summary>
         public bool IsSitTargetSet
@@ -736,7 +741,7 @@ namespace OpenSim.Region.Framework.Scenes
                 }
                 
                 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
-                if (SitTargetAvatar != UUID.Zero)
+                if (IsSitTargetOccupied)
                 {
                     ScenePresence avatar;
                     if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8c98ed..c824e56 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1846,7 +1846,7 @@ namespace OpenSim.Region.Framework.Scenes
             //look for prims with explicit sit targets that are available
             foreach (SceneObjectPart part in partArray)
             {
-                if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
+                if (part.IsSitTargetSet && !part.IsSitTargetOccupied)
                 {
                     //switch the target to this prim
                     return part;
@@ -1878,7 +1878,7 @@ namespace OpenSim.Region.Framework.Scenes
 
             if (part.IsSitTargetSet)
             {
-                if (part.SitTargetAvatar == UUID.Zero)
+                if (!part.IsSitTargetOccupied)
                 {
 //                    m_log.DebugFormat(
 //                        "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
-- 
cgit v1.1


From 11e0ad6dc8663756154652465750c1ebaaf3124f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:39:05 +0100
Subject: Revert "refactor: Add SOP.IsSitTargetOccupied to improve readability"

This reverts commit c8f0d476d2f775ba4d7afca12eeff527b46bb8e2.
On reconsideration, I think this is less readable since immediately following code still sets SitTargetAvatar directly
---
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 +------
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   | 4 ++--
 2 files changed, 3 insertions(+), 8 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 937f43e..dcec7e9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -136,11 +136,6 @@ namespace OpenSim.Region.Framework.Scenes
         }
 
         /// <summary>
-        /// Is the sit target of this part occupied?
-        /// </summary>
-        public bool IsSitTargetOccupied { get { return SitTargetAvatar != UUID.Zero; } }
-
-        /// <summary>
         /// Is an explicit sit target set for this part?
         /// </summary>
         public bool IsSitTargetSet
@@ -741,7 +736,7 @@ namespace OpenSim.Region.Framework.Scenes
                 }
                 
                 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
-                if (IsSitTargetOccupied)
+                if (SitTargetAvatar != UUID.Zero)
                 {
                     ScenePresence avatar;
                     if (ParentGroup.Scene.TryGetScenePresence(SitTargetAvatar, out avatar))
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index c824e56..a8c98ed 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1846,7 +1846,7 @@ namespace OpenSim.Region.Framework.Scenes
             //look for prims with explicit sit targets that are available
             foreach (SceneObjectPart part in partArray)
             {
-                if (part.IsSitTargetSet && !part.IsSitTargetOccupied)
+                if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
                 {
                     //switch the target to this prim
                     return part;
@@ -1878,7 +1878,7 @@ namespace OpenSim.Region.Framework.Scenes
 
             if (part.IsSitTargetSet)
             {
-                if (!part.IsSitTargetOccupied)
+                if (part.SitTargetAvatar == UUID.Zero)
                 {
 //                    m_log.DebugFormat(
 //                        "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
-- 
cgit v1.1


From cdea572d2ea0256423a4cd72f132346d88a93e92 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:50:04 +0100
Subject: refactor: move management of SOP.SitTargetAvatar into
 SOP.AddSittingAvatar() and SOP.RemoveSittingAvatar()

---
 OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 ++++++
 OpenSim/Region/Framework/Scenes/ScenePresence.cs   | 5 -----
 2 files changed, 6 insertions(+), 5 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index dcec7e9..b3f11a7 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -4525,6 +4525,9 @@ namespace OpenSim.Region.Framework.Scenes
         /// <param name='avatarId'></param>
         protected internal bool AddSittingAvatar(UUID avatarId)
         {
+            if (IsSitTargetSet && SitTargetAvatar == UUID.Zero)
+                SitTargetAvatar = avatarId;
+
             HashSet<UUID> sittingAvatars = m_sittingAvatars;
 
             if (sittingAvatars == null)
@@ -4547,6 +4550,9 @@ namespace OpenSim.Region.Framework.Scenes
         /// <param name='avatarId'></param>
         protected internal bool RemoveSittingAvatar(UUID avatarId)
         {
+            if (SitTargetAvatar == avatarId)
+                SitTargetAvatar = UUID.Zero;
+
             HashSet<UUID> sittingAvatars = m_sittingAvatars;
 
             // This can occur under a race condition where another thread
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index a8c98ed..514c314 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1799,10 +1799,6 @@ namespace OpenSim.Region.Framework.Scenes
                     }
                 }
 
-                // Reset sit target.
-                if (part.SitTargetAvatar == UUID)
-                    part.SitTargetAvatar = UUID.Zero;
-
                 ParentPosition = part.GetWorldPosition();
                 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
 
@@ -1884,7 +1880,6 @@ namespace OpenSim.Region.Framework.Scenes
 //                        "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
 //                        Name, part.Name, part.LocalId);
 
-                    part.SitTargetAvatar = UUID;
                     offset = part.SitTargetPosition;
                     sitOrientation = part.SitTargetOrientation;
                     canSit = true;
-- 
cgit v1.1


From 337ea019bd0fa617df00d7bee10b869e73a50075 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 10 Jul 2012 23:55:22 +0100
Subject: If a part has a sit target and an avatar is already sitting, allow
 another avatar to sit in the position given if no sit target was set.

Previous behave was that the second avatar could not sit.
This matches behaviour observed on the LL grid.
---
 OpenSim/Region/Framework/Scenes/ScenePresence.cs | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

(limited to 'OpenSim/Region')

diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 514c314..0e7f2e5 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1872,18 +1872,15 @@ namespace OpenSim.Region.Framework.Scenes
             bool canSit = false;
             Vector3 pos = part.AbsolutePosition + offset;
 
-            if (part.IsSitTargetSet)
+            if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
             {
-                if (part.SitTargetAvatar == UUID.Zero)
-                {
 //                    m_log.DebugFormat(
 //                        "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
 //                        Name, part.Name, part.LocalId);
 
-                    offset = part.SitTargetPosition;
-                    sitOrientation = part.SitTargetOrientation;
-                    canSit = true;
-                }
+                offset = part.SitTargetPosition;
+                sitOrientation = part.SitTargetOrientation;
+                canSit = true;
             }
             else
             {
-- 
cgit v1.1