From 7e73f609e5f61040358ec247d371306165945ca1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 5 Jul 2012 23:15:59 +0100 Subject: Log warning if time between invocations of the watchdog thread is twice the timer setting. This is to help detect situations where thread timeout warnings are being generated because of general machine issues rather than deadlock, network or other problems. --- OpenSim/Framework/Watchdog.cs | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 2b3a719..8a74f53 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -101,12 +101,24 @@ namespace OpenSim.Framework private static Dictionary m_threads; private static System.Timers.Timer m_watchdogTimer; + /// + /// Last time the watchdog thread ran. + /// + /// + /// Should run every WATCHDOG_INTERVAL_MS + /// + public static int LastWatchdogThreadTick { get; private set; } + static Watchdog() { m_threads = new Dictionary(); m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS); m_watchdogTimer.AutoReset = false; m_watchdogTimer.Elapsed += WatchdogTimerElapsed; + + // Set now so we don't get alerted on the first run + LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; + m_watchdogTimer.Start(); } @@ -264,6 +276,16 @@ namespace OpenSim.Framework /// private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e) { + int now = Environment.TickCount & Int32.MaxValue; + int msElapsed = now - LastWatchdogThreadTick; + + if (msElapsed > WATCHDOG_INTERVAL_MS * 2) + m_log.WarnFormat( + "[WATCHDOG]: {0} ms since Watchdog last ran. Interval should be approximately {1} ms", + msElapsed, WATCHDOG_INTERVAL_MS); + + LastWatchdogThreadTick = Environment.TickCount & Int32.MaxValue; + Action callback = OnWatchdogTimeout; if (callback != null) @@ -272,8 +294,6 @@ namespace OpenSim.Framework lock (m_threads) { - int now = Environment.TickCount & Int32.MaxValue; - foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) { if (threadInfo.Thread.ThreadState == ThreadState.Stopped) -- cgit v1.1 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(-) 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(-) 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 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 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 { grp }, - sp.ControllingClient, true)[0]; + InventoryItemBase newItem + = m_invAccessModule.CopyToInventory( + DeRezAction.TakeCopy, + m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, + new List { 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(-) 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 /// True if the SceneObjectGroup was added, False if it was not 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(+) 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); /// + /// Get the NPC to touch an object. + /// + /// + /// + /// true if the touch is actually attempted, false if not + bool Touch(UUID agentID, UUID partID); + + /// /// Delete an NPC. /// /// The UUID of the NPC 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 touchArgs = new List(); + 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(); + 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); + } + } + /// /// Save the current appearance of the script owner permanently to the named notecard. /// 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(+) 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(-) 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)); } /// @@ -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 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 } /// + /// Get all the scene object groups. + /// + /// + /// The scene object groups. If the scene is empty then an empty list is returned. + /// + public List GetSceneObjectGroups() + { + return m_sceneGraph.GetSceneObjectGroups(); + } + + /// /// Get a group via its UUID /// /// 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 } /// + /// Get all the scene object groups. + /// + /// + /// The scene object groups. If the scene is empty then an empty list is returned. + /// + protected internal List GetSceneObjectGroups() + { + lock (SceneObjectGroupsByFullID) + return new List(SceneObjectGroupsByFullID.Values); + } + + /// /// Get a group in the scene /// /// UUID of the group @@ -1100,11 +1112,7 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void ForEachSOG(Action action) { - List objlist; - lock (SceneObjectGroupsByFullID) - objlist = new List(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(-) 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 { + /// + /// 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). + /// 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 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(-) 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 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(-) 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 af9d8de515ff0043d2c19b67a2ce9040b462d12e Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Fri, 6 Jul 2012 15:56:35 -0700 Subject: BulletSim: update the binaries to the current sources --- bin/lib32/BulletSim.dll | Bin 533504 -> 538112 bytes bin/lib32/libBulletSim.so | Bin 2333901 -> 2334329 bytes bin/lib64/BulletSim.dll | Bin 686080 -> 690688 bytes bin/lib64/libBulletSim.so | Bin 2528521 -> 2529000 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/lib32/BulletSim.dll b/bin/lib32/BulletSim.dll index 2c28063..a3ccb98 100755 Binary files a/bin/lib32/BulletSim.dll and b/bin/lib32/BulletSim.dll differ diff --git a/bin/lib32/libBulletSim.so b/bin/lib32/libBulletSim.so index f40f446..0b286aa 100755 Binary files a/bin/lib32/libBulletSim.so and b/bin/lib32/libBulletSim.so differ diff --git a/bin/lib64/BulletSim.dll b/bin/lib64/BulletSim.dll index d9e5e89..d91dac1 100755 Binary files a/bin/lib64/BulletSim.dll and b/bin/lib64/BulletSim.dll differ diff --git a/bin/lib64/libBulletSim.so b/bin/lib64/libBulletSim.so index 06770a4..891c956 100755 Binary files a/bin/lib64/libBulletSim.so and b/bin/lib64/libBulletSim.so differ -- 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/Data/Tests/RegionTests.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2 -- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 +++--- .../Region/Framework/Scenes/SceneObjectGroup.cs | 10 ---------- .../Shared/Tests/OSSL_ApiAppearanceTest.cs | 14 ++++++------- .../ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs | 6 +++--- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 23 +++++++++++++++++++--- 7 files changed, 34 insertions(+), 29 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 474609b..55b9b4d 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -1081,7 +1081,7 @@ namespace OpenSim.Data.Tests sop.Shape = PrimitiveBaseShape.Default; SceneObjectGroup sog = new SceneObjectGroup(sop); - sog.SetScene(scene); +// sog.SetScene(scene); return sog; } 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 /// True if the SceneObjectGroup was added, False if it was not 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); } - - /// - /// 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... - /// - /// - public void SetScene(Scene scene) - { - m_scene = scene; - } /// /// 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 /// [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. /// [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); diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 3a2e420..d5354cb 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -601,19 +601,36 @@ namespace OpenSim.Tests.Common ownerId, PrimitiveBaseShape.Default, Vector3.Zero, Quaternion.Identity, Vector3.Zero) { Name = name, UUID = id, Scale = new Vector3(1, 1, 1) }; } - + /// /// Create a scene object but do not add it to the scene. /// /// - /// UUID always starts at 00000000-0000-0000-0000-000000000001 + /// UUID always starts at 00000000-0000-0000-0000-000000000001. For some purposes, (e.g. serializing direct + /// to another object's inventory) we do not need a scene unique ID. So it would be better to add the + /// UUID when we actually add an object to a scene rather than on creation. /// /// The number of parts that should be in the scene object /// /// public static SceneObjectGroup CreateSceneObject(int parts, UUID ownerId) { - return CreateSceneObject(parts, ownerId, "", 0x1); + return CreateSceneObject(parts, ownerId, 0x1); + } + + /// + /// Create a scene object but do not add it to the scene. + /// + /// The number of parts that should be in the scene object + /// + /// + /// The hexadecimal last part of the UUID for parts created. A UUID of the form "00000000-0000-0000-0000-{0:XD12}" + /// will be given to the root part, and incremented for each part thereafter. + /// + /// + public static SceneObjectGroup CreateSceneObject(int parts, UUID ownerId, int uuidTail) + { + return CreateSceneObject(parts, ownerId, "", uuidTail); } /// -- 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(-) 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(-) 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(-) 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 @@ \ \ - \ -- 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/Data/Tests/RegionTests.cs | 2 -- OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiAttachmentTests.cs | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 55b9b4d..dbed8f6 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -1069,8 +1069,6 @@ namespace OpenSim.Data.Tests regionInfo.RegionLocX = 0; regionInfo.RegionLocY = 0; - Scene scene = new Scene(regionInfo); - SceneObjectPart sop = new SceneObjectPart(); sop.Name = name; sop.Description = name; 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(-) 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 57094bd0177e656ce1ed08df87b19657a6043c68 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 8 Jul 2012 13:02:02 -0400 Subject: Add more automation keys to OpenSim.ini.example --- bin/OpenSim.ini.example | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index c07e1ab..ce571ee 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -61,17 +61,20 @@ ;; Place to create a PID file ; PIDFile = "/tmp/my.pid" + ;# {region_info_source} {} {Where to load region from?} {filesystem web} filesystem ;; Determine where OpenSimulator looks for the files which tell it ;; which regions to server ;; Default is "filesystem" ; region_info_source = "filesystem" ; region_info_source = "web" - + + ;# {regionload_regionsdir} {region_info_source} {Location of file?} {} Regions ;; Determines where the region XML files are stored if you are loading ;; these from the filesystem. ;; Defaults to bin/Regions in your OpenSimulator installation directory ; regionload_regionsdir="C:\somewhere\xmlfiles\" + ;# {regionload_webserver_url} {region_info_source} {URL to load region from?} {} ;; Determines the page from which regions xml is retrieved if you are ;; loading these from the web. ;; The XML here has the same format as it does on the filesystem @@ -92,6 +95,7 @@ ;; Maximum size where a prim can be physical. Affects resizing of existing prims. This can be overriden in the region config file. ; PhysicalPrimMax = 10 + ;# {ClampPrimSize} {} {Clamp viewer rezzed prims to max sizes?} {true false} false ;; If a viewer attempts to rez a prim larger than the non-physical or physical prim max, clamp the dimensions to the appropriate maximum ;; This can be overriden in the region config file. ; ClampPrimSize = false @@ -117,6 +121,7 @@ ;; This will likely break them ; CombineContiguousRegions = false + ;# {InworldRestartShutsDown} {} {Shutdown instance on region restart?} {true false} false ;; If you have only one region in an instance, or to avoid the many bugs ;; that you can trigger in modules by restarting a region, set this to ;; true to make the entire instance exit instead of restarting the region. @@ -131,14 +136,17 @@ ;; If both of these values are set to zero then persistence of all changed ;; objects will happen on every sweep. + ;# {MinimumTimeBeforePersistenceConsidered} {} {Time before un-changed object may be persisted} {} 60 ;; Objects will be considered for persistance in the next sweep when they ;; have not changed for this number of seconds. ; MinimumTimeBeforePersistenceConsidered = 60 + ;# {MaximumTimeBeforePersistenceConsidered} {} {Time before changed objects may be persisted?} {} 600 ;; Objects will always be considered for persistance in the next sweep ;; if the first change occurred this number of seconds ago. ; MaximumTimeBeforePersistenceConsidered = 600 + ;# {see_into_this_sim_from_neighbor} {} {Should avatars in neighbor sims see objects in this sim?} {true false} true ;; Should avatars in neighbor sims see objects in this sim? ; see_into_this_sim_from_neighbor = true @@ -153,6 +161,7 @@ ;; Note that only the ODE physics engine currently deals with meshed ;; prims in a satisfactory way. + ;# {meshing} {} {Select mesher} {Meshmerizer ZeroMesher} Meshmerizer ;; ZeroMesher is faster but leaves the physics engine to model the mesh ;; using the basic shapes that it supports. ;; Usually this is only a box. @@ -161,6 +170,7 @@ ; meshing = ZeroMesher ;; Choose one of the physics engines below + ;# {physics} {} {Select physics engine} {OpenDynamicsEngine BulletSim basicphysics POS} OpenDynamicsEngine ;; OpenDynamicsEngine is by some distance the most developed physics engine ;; BulletSim is incomplete and experimental but in active development ;; basicphysics effectively does not model physics at all, making all objects phantom @@ -184,38 +194,52 @@ ;; If set to true, then all permissions checks are carried out ; serverside_object_permissions = true + ;# {allow_grid_gods} {} {Allow grid gods?} {true false} false ;; This allows users with a UserLevel of 200 or more to assume god ;; powers in the regions in this simulator. ; allow_grid_gods = false ;; This allows some control over permissions ;; please note that this still doesn't duplicate SL, and is not intended to + ;# {region_owner_is_god} {} {Allow region owner gods} {true false} true + ;; Allow region owners to assume god powers in their regions ; region_owner_is_god = true + + ;# {region_manager_is_god} {} {Allow region manager gods} {true false} false + ;; Allow region managers to assume god powers in regions they manage ; region_manager_is_god = false + + ;# {parcel_owner_is_god} {} {Allow parcel owner gods} {true false} true + ;; Allow parcel owners to assume god powers in their parcels ; parcel_owner_is_god = true + ;# {simple_build_permissions} {} {Allow building in parcel by access list (no groups)} {true false} false ;; More control over permissions ;; This is definitely not SL! - ; Provides a simple control for land owners to give build rights to specific avatars - ; in publicly accessible parcels that disallow object creation in general. - ; Owners specific avatars by adding them to the Access List of the parcel - ; without having to use the Groups feature + ;; Provides a simple control for land owners to give build rights to specific avatars + ;; in publicly accessible parcels that disallow object creation in general. + ;; Owners specific avatars by adding them to the Access List of the parcel + ;; without having to use the Groups feature ; simple_build_permissions = false + ;# {DefaultScriptEngine} {} {Default script engine} {XEngine} XEngine ;; Default script engine to use. Currently, we only have XEngine ; DefaultScriptEngine = "XEngine" + ;# {GenerateMaptiles} {} {Generate map tiles?} {true false} true ;; Map tile options. You can choose to generate no map tiles at all, ;; generate normal maptiles, or nominate an uploaded texture to ;; be the map tile ; GenerateMaptiles = true + ;# {MaptileRefresh} {GenerateMaptiles} {Maptile refresh period?} {} 0 ;; If desired, a running region can update the map tiles periodically ;; to reflect building activity. This names no sense of you don't have ;; prims on maptiles. Value is in seconds. ; MaptileRefresh = 0 + ;# {MaptileStaticUUID} {} {Asset ID for static map texture} {} 00000000-0000-0000-0000-000000000000 ;; If not generating maptiles, use this static texture asset ID ; MaptileStaticUUID = "00000000-0000-0000-0000-000000000000" @@ -228,9 +252,11 @@ ;; got a large number of objects, so you can turn it off here if you'd like. ; DrawPrimOnMapTile = true + ;# {HttpProxy} {} {Proxy URL for llHTTPRequest and dynamic texture loading} {} http://proxy.com:8080 ;; Http proxy setting for llHTTPRequest and dynamic texture loading, if required ; HttpProxy = "http://proxy.com:8080" + ;# {HttpProxyExceptions} {HttpProxy} {Set of regular expressions defining URL that should not be proxied} {} ;; If you're using HttpProxy, then you can set HttpProxyExceptions to a list of regular expressions for URLs that you don't want to go through the proxy ;; For example, servers inside your firewall. ;; Separate patterns with a ';' @@ -254,7 +280,8 @@ ;; default is false ; TelehubAllowLandmark = false - ;# Comma separated list of viewers which may gain access to the regions. + ;# {AllowedViewerList} {} {Comma separated list of allowed viewers} {} + ;; Comma separated list of viewers which may gain access to the regions. ;; One can use a Substring of the viewer name to enable only certain subversions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" ;; - "Imprudence" has access @@ -262,6 +289,7 @@ ;; - "Imprudence 1.3.1" has no access ;; AllowedViewerList = + ;# {BannedViewerList} {} {Comma separated list of banned viewers} {} ;# Comma separated list of viewers which may not gain access to the regions. ;; One can use a Substring of the viewer name to disable only certain subversions ;; Example: Agent uses the viewer "Imprudence 1.3.2.0" -- cgit v1.1 From a96ac7330291c3041729fac08b06d0098469f4d7 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 8 Jul 2012 13:44:04 -0400 Subject: Add more keys for OpenSim.ini.defaults automation --- bin/OpenSim.ini.example | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index ce571ee..661abc0 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -304,16 +304,30 @@ ; If these values are uncommented then they will be used to create a default estate as necessary. ; New regions will be automatically assigned to that default estate. + ;# {DefaultEstateName} {} {Default name for estate?} {} My Estate + ;; Name for the default estate ; DefaultEstateName = My Estate + + ;# {DefaultEstateOwnerName} {} {Default estate owner name?} {} FirstName LastName + ;; Name for default estate owner ; DefaultEstateOwnerName = FirstName LastName - - ; The following parameters will only be used on a standalone system to create an estate owner that does not already exist - ; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random UUID will be assigned. - ; This is normally what you want + + ; ** Standalone Estate Settings ** + ; The following parameters will only be used on a standalone system to + ; create an estate owner that does not already exist + + ;# {DefaultEstateOwnerUUID} {} {Default estate owner UUID?} {} 00000000-0000-0000-0000-000000000000 + ;; If DefaultEstateOwnerUUID is left at UUID.Zero (as below) then a random + ;; UUID will be assigned. This is normally what you want ; DefaultEstateOwnerUUID = 00000000-0000-0000-0000-000000000000 + ;# {DefaultEstateOwnerEMail} {} {Default estate owner email?} {} + ;; Email address for the default estate owner ; DefaultEstateOwnerEMail = owner@domain.com + + ;# {DefaultEstateOwnerPassword} {} {Default estate owner password} {} + ;; Password for the default estate owner ; DefaultEstateOwnerPassword = password -- cgit v1.1 From 1a2ab7bc691192f4a263d3d57e2d83bb05f8c69c Mon Sep 17 00:00:00 2001 From: BlueWall Date: Sun, 8 Jul 2012 22:49:36 -0400 Subject: More keys for automated ini processing --- bin/OpenSim.ini.example | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/bin/OpenSim.ini.example b/bin/OpenSim.ini.example index 661abc0..33eaccb 100644 --- a/bin/OpenSim.ini.example +++ b/bin/OpenSim.ini.example @@ -364,10 +364,14 @@ ; SMTP_SERVER_PASSWORD = "" [Network] + + ;# {ConsoleUser} {} {User name for console account} {} ;; Configure the remote console user here. This will not actually be used ;; unless you use -console=rest at startup. ; ConsoleUser = "Test" + ;# {ConsolePass} {} {Password for console account} {} ; ConsolePass = "secret" + ;# {console_port} {} {Port for console connections} {} 0 ; console_port = 0 ;# {http_listener_port} {} {TCP Port for this simulator to listen on? (This must be unique to the simulator!)} {} 9000 @@ -431,11 +435,14 @@ [SimulatorFeatures] + + ;# {MapImageServerURI} {} {URL for the map server} {} ; Experimental new information sent in SimulatorFeatures cap for Kokua viewers ; meant to override the MapImage and search server url given at login, and varying ; on a sim-basis. ; Viewers that don't understand it, will ignore it ;MapImageServerURI = "http://127.0.0.1:9000/" + ;# {SearchServerURI} {} {URL of the search server} {} ;SearchServerURI = "http://127.0.0.1:9000/" @@ -629,6 +636,7 @@ [Economy] + ;# {SellEnabled} {} {Enable selling for 0?} {true false} true ; The default economy module only implements just enough to allow free actions (transfer of objects, etc). ; There is no intention to implement anything further in core OpenSimulator. ; This functionality has to be provided by third party modules. @@ -636,9 +644,11 @@ ;; Enables selling things for $0. Default is true. ; SellEnabled = true + ;# {PriceUpload} {} {Price for uploading?} {} 0 ;; Money Unit fee to upload textures, animations etc. Default is 0. ; PriceUpload = 0 + ;# {PriceGroupCreate} {} {Fee for group creation} {} 0 ;; Money Unit fee to create groups. Default is 0. ; PriceGroupCreate = 0 @@ -748,32 +758,41 @@ ; If both Allow_ and Creators_ are given, effective permissions ; are the union of the two. + ;# {EventLimit} {} {Amount of time a script can spend in an event handler} {} 30 ;; Time a script can spend in an event handler before it is interrupted ; EventLimit = 30 + ;# {KillTimedOutScripts} {} {Kill script in case of event time overruns?} {true false} false ;; If a script overruns it's event limit, kill the script? ; KillTimedOutScripts = false + ;# {ScriptDelayFactor} {} {Multiplier for scripting delays} {} 1.0 ;; Sets the multiplier for the scripting delays ; ScriptDelayFactor = 1.0 + ;# {ScriptDistanceLimitFactor} {} {Multiplier for 10.0m distance limits?} {} ;; The factor the 10 m distances limits are multiplied by ; ScriptDistanceLimitFactor = 1.0 + ;# {NotecardLineReadCharsMax} {} {Maximum length of notecard line?} {} 255 ;; Maximum length of notecard line read ;; Increasing this to large values potentially opens ;; up the system to malicious scripters ; NotecardLineReadCharsMax = 255 + ;# {SensorMaxRange} {} {Sensor range} {} 96.0 ;; Sensor settings ; SensorMaxRange = 96.0 + ;# {SensorMaxResults} {} {Max sensor results returned?} {} ; SensorMaxResults = 16 + ;# {DisableUndergroundMovement} {} {Disable underground movement of prims} {true false} true ;; Disable underground movement of prims (default true); set to ;; false to allow script controlled underground positioning of ;; prims ; DisableUndergroundMovement = true + ;# {ScriptEnginesPath} {} {Path to script assemblies} {} ScriptEngines ;; Path to script engine assemblies ;; Default is ./bin/ScriptEngines ; ScriptEnginesPath = "ScriptEngines" -- 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 +++- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 75 +++++++++++++---- OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs | 9 ++ 7 files changed, 229 insertions(+), 26 deletions(-) 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(); } + /// + /// Test that we do not attempt to attach an in-world object that someone else is sitting on. + /// + [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; } + /// + /// Gets the number of sitting avatars. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + public int GetSittingAvatarsCount() + { + int count = 0; + + Array.ForEach(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 } /// - /// 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 /// - public UUID SitTargetAvatar - { - get { return m_sitTargetAvatar; } - set { m_sitTargetAvatar = value; } - } + public UUID SitTargetAvatar { get; set; } + + /// + /// IDs of all avatars start on this object part. + /// + /// + /// We need to track this so that we can stop sat upon prims from being attached. + /// + /// + /// null if there are no sitting avatars. This is to save us create a hashset for every prim in a scene. + /// + private HashSet 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)); } + + /// + /// Record an avatar sitting on this part. + /// + /// This is called for all the sitting avatars whether there is a sit target set or not. + /// + /// true if the avatar was not already recorded, false otherwise. + /// + /// + protected internal bool AddSittingAvatar(UUID avatarId) + { + HashSet sittingAvatars = m_sittingAvatars; + + if (sittingAvatars == null) + sittingAvatars = new HashSet(); + + lock (sittingAvatars) + { + m_sittingAvatars = sittingAvatars; + return m_sittingAvatars.Add(avatarId); + } + } + + /// + /// Remove an avatar recorded as sitting on this part. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + /// true if the avatar was present and removed, false if it was not present. + /// + /// + protected internal bool RemoveSittingAvatar(UUID avatarId) + { + HashSet 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; + } + + /// + /// Get a copy of the list of sitting avatars. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + public HashSet GetSittingAvatars() + { + return new HashSet(m_sittingAvatars); + } + + /// + /// Gets the number of sitting avatars. + /// + /// This applies to all sitting avatars whether there is a sit target set or not. + /// + public int GetSittingAvatarsCount() + { + HashSet 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; } /// + /// Are we sitting on an object? + /// + /// A more readable way of testing presence sit status than ParentID == 0 + public bool IsSatOnObject { get { return ParentID != 0; } } + + /// /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. /// /// @@ -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(); diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index d5354cb..769de83 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -412,26 +412,49 @@ namespace OpenSim.Tests.Common /// public static AgentCircuitData GenerateAgentData(UUID agentId) { - string firstName = "testfirstname"; + AgentCircuitData acd = GenerateCommonAgentData(); - AgentCircuitData agentData = new AgentCircuitData(); - agentData.AgentID = agentId; - agentData.firstname = firstName; - agentData.lastname = "testlastname"; + acd.AgentID = agentId; + acd.firstname = "testfirstname"; + acd.lastname = "testlastname"; + acd.ServiceURLs = new Dictionary(); + + return acd; + } + + /// + /// Generate some standard agent connection data. + /// + /// + /// + public static AgentCircuitData GenerateAgentData(UserAccount ua) + { + AgentCircuitData acd = GenerateCommonAgentData(); + + acd.AgentID = ua.PrincipalID; + acd.firstname = ua.FirstName; + acd.lastname = ua.LastName; + acd.ServiceURLs = ua.ServiceURLs; + + return acd; + } + + private static AgentCircuitData GenerateCommonAgentData() + { + AgentCircuitData acd = new AgentCircuitData(); // XXX: Sessions must be unique, otherwise one presence can overwrite another in NullPresenceData. - agentData.SessionID = UUID.Random(); - agentData.SecureSessionID = UUID.Random(); - - agentData.circuitcode = 123; - agentData.BaseFolder = UUID.Zero; - agentData.InventoryFolder = UUID.Zero; - agentData.startpos = Vector3.Zero; - agentData.CapsPath = "http://wibble.com"; - agentData.ServiceURLs = new Dictionary(); - agentData.Appearance = new AvatarAppearance(); - - return agentData; + acd.SessionID = UUID.Random(); + acd.SecureSessionID = UUID.Random(); + + acd.circuitcode = 123; + acd.BaseFolder = UUID.Zero; + acd.InventoryFolder = UUID.Zero; + acd.startpos = Vector3.Zero; + acd.CapsPath = "http://wibble.com"; + acd.Appearance = new AvatarAppearance(); + + return acd; } /// @@ -440,6 +463,9 @@ namespace OpenSim.Tests.Common /// /// This can be used for tests where there is only one region or where there are multiple non-neighbour regions /// and teleport doesn't take place. + /// + /// XXX: Use the version of this method that takes the UserAccount structure wherever possible - this will + /// make the agent circuit data (e.g. first, lastname) consistent with the user account data. /// /// /// @@ -452,6 +478,10 @@ namespace OpenSim.Tests.Common /// /// Add a root agent where the details of the agent connection (apart from the id) are unimportant for the test /// + /// + /// XXX: Use the version of this method that takes the UserAccount structure wherever possible - this will + /// make the agent circuit data (e.g. first, lastname) consistent with the user account data. + /// /// /// /// @@ -464,6 +494,17 @@ namespace OpenSim.Tests.Common /// /// Add a root agent. /// + /// + /// + /// + public static ScenePresence AddScenePresence(Scene scene, UserAccount ua) + { + return AddScenePresence(scene, GenerateAgentData(ua)); + } + + /// + /// Add a root agent. + /// /// /// This function /// diff --git a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs index 3d3e65c..2fbebc4 100644 --- a/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserAccountHelpers.cs @@ -138,6 +138,15 @@ namespace OpenSim.Tests.Common CreateUserWithInventory(scene, ua, pw); return ua; } + + public static UserAccount CreateUserWithInventory( + Scene scene, string firstName, string lastName, int userId, string pw) + { + UserAccount ua + = new UserAccount(TestHelpers.ParseTail(userId)) { FirstName = firstName, LastName = lastName }; + CreateUserWithInventory(scene, ua, pw); + return ua; + } public static void CreateUserWithInventory(Scene scene, UserAccount ua, string pw) { -- 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(+) 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(-) 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 /// - /// 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 /// /// The attachment point. For example, ATTACH_CHEST void osForceAttachToAvatar(int attachment); /// - /// 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 /// + /// + /// Nothing happens if the owner is not in the region. + /// /// Tha name of the item. If this is not found then a warning is said to the owner /// The attachment point. For example, ATTACH_CHEST void osForceAttachToAvatarFromInventory(string itemName, int attachment); /// + /// Attach an inventory item in the object containing this script to any avatar in the region without asking for PERMISSION_ATTACH + /// + /// + /// Nothing happens if the avatar is not in the region. + /// + /// The UUID of the avatar to which to attach. Nothing happens if this is not a UUID + /// The name of the item. If this is not found then a warning is said to the owner + /// The attachment point. For example, ATTACH_CHEST + void osForceAttachToOtherAvatarFromInventory(string rawAvatarId, string itemName, int attachmentPoint); + + /// /// Detach the object containing this script from the avatar it is attached to without checking for PERMISSION_ATTACH /// /// Nothing happens if the object is not attached. 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 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 attachments = sp.GetAttachments(); + Assert.That(attachments.Count, Is.EqualTo(0)); + + Assert.That(sp2.HasAttachments(), Is.True); + List 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 attachmentsInAppearance = sp.Appearance.GetAttachments(); + Assert.That(attachmentsInAppearance.Count, Is.EqualTo(0)); + + List 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(-) 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(-) 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(); /// - /// Stop all the scripts in this entity. + /// Stop and remove all the scripts in this entity from the scene. /// /// /// 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); /// + /// Stop all the scripts in this entity. + /// + void StopScriptInstances(); + + /// /// Start a script which is in this entity's inventory. /// /// @@ -129,7 +134,7 @@ namespace OpenSim.Region.Framework.Interfaces bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); /// - /// 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. /// /// /// @@ -139,6 +144,12 @@ namespace OpenSim.Region.Framework.Interfaces void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted); /// + /// Stop a script which is in this prim's inventory. + /// + /// + void StopScriptInstance(UUID itemId); + + /// /// Add an item to this entity's inventory. If an item with the same name already exists, then an alternative /// name is chosen. /// 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 /// /// Synchronously delete the given object from the scene. /// + /// + /// Scripts are also removed. + /// /// Object Id /// Suppress broadcasting changes to other clients. public void DeleteSceneObject(SceneObjectGroup group, bool silent) + { + DeleteSceneObject(group, silent, true); + } + + /// + /// Synchronously delete the given object from the scene. + /// + /// Object Id + /// Suppress broadcasting changes to other clients. + /// If true, then scripts are removed. If false, then they are only stopped. + 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 } /// - /// Stop the scripts contained in all the prims in this group + /// Stop and remove the scripts contained in all the prims in this group /// /// /// Should be true if these scripts are being removed because the scene @@ -93,6 +93,14 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Stop the scripts contained in all the prims in this group + /// + public void StopScriptInstances() + { + Array.ForEach(m_parts.GetArray(), p => p.Inventory.StopScriptInstances()); + } + + /// /// Add an inventory item from a user's inventory to a prim in this scene object. /// /// The agent adding the item. 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 } /// - /// Stop all the scripts in this prim. + /// Stop and remove all the scripts in this prim. /// /// /// Should be true if these scripts are being removed because the scene @@ -294,6 +294,14 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Stop all the scripts in this prim. + /// + public void StopScriptInstances() + { + GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i)); + } + + /// /// Start a script which is in this prim's inventory. /// /// @@ -443,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Stop a script which is in this prim's inventory. + /// Stop and remove a script which is in this prim's inventory. /// /// /// @@ -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); + } + } + + /// + /// Stop a script which is in this prim's inventory. + /// + /// + /// + /// Should be true if this script is being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + 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 } /// + /// Stop a script which is in this prim's inventory. + /// + /// + /// + /// Should be true if this script is being removed because the scene + /// object is being deleted. This will prevent spurious updates to the client. + /// + 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); + } + + /// /// Check if the inventory holds an item with a given name. /// /// -- 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 ++++++++++++++++++---- prebuild.xml | 1 + 3 files changed, 33 insertions(+), 6 deletions(-) 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. /// /// This applies to all sitting avatars whether there is a sit target set or not. - /// + /// A hashset of the sitting avatars. Returns null if there are no sitting avatars. public HashSet GetSittingAvatars() { - return new HashSet(m_sittingAvatars); + HashSet sittingAvatars = m_sittingAvatars; + + if (sittingAvatars == null) + { + return null; + } + else + { + lock (sittingAvatars) + return new HashSet(sittingAvatars); + } } /// 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 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 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] diff --git a/prebuild.xml b/prebuild.xml index 45f58c7..3419119 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3042,6 +3042,7 @@ ../../../bin/ + -- 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(-) 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(-) 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(-) 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; } } + /// + /// Is an explicit sit target set for this part? + /// + 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(-) 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(-) 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 } /// + /// Is the sit target of this part occupied? + /// + public bool IsSitTargetOccupied { get { return SitTargetAvatar != UUID.Zero; } } + + /// /// Is an explicit sit target set for this part? /// 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(-) 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 } /// - /// Is the sit target of this part occupied? - /// - public bool IsSitTargetOccupied { get { return SitTargetAvatar != UUID.Zero; } } - - /// /// Is an explicit sit target set for this part? /// 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(-) 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 /// protected internal bool AddSittingAvatar(UUID avatarId) { + if (IsSitTargetSet && SitTargetAvatar == UUID.Zero) + SitTargetAvatar = avatarId; + HashSet sittingAvatars = m_sittingAvatars; if (sittingAvatars == null) @@ -4547,6 +4550,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal bool RemoveSittingAvatar(UUID avatarId) { + if (SitTargetAvatar == avatarId) + SitTargetAvatar = UUID.Zero; + HashSet 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(-) 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