From e90168c7382f7750faa001542652e2316841c961 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 22:42:40 +0100 Subject: Add VectorRenderModuleTests.TestRepeatDraw() --- .../VectorRender/Tests/VectorRenderModuleTests.cs | 59 ++++++++++++++++++---- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 9787c8c..f9b5a59 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -45,31 +45,68 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests { [TestFixture] - public class VectorRenderModuleTests + public class VectorRenderModuleTests : OpenSimTestCase { + Scene m_scene; + DynamicTextureModule m_dtm; + VectorRenderModule m_vrm; + + [SetUp] + public void SetUp() + { + m_scene = new SceneHelpers().SetupScene(); + m_dtm = new DynamicTextureModule(); + m_vrm = new VectorRenderModule(); + SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm); + } + [Test] public void TestDraw() { TestHelpers.InMethod(); - Scene scene = new SceneHelpers().SetupScene(); - DynamicTextureModule dtm = new DynamicTextureModule(); - VectorRenderModule vrm = new VectorRenderModule(); - SceneHelpers.SetupSceneModules(scene, dtm, vrm); - - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene); + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; - dtm.AddDynamicTextureData( - scene.RegionInfo.RegionID, + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, so.UUID, - vrm.GetContentType(), + m_vrm.GetContentType(), "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", "", 0); - Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } + + [Test] + public void TestRepeatDraw() + { + TestHelpers.InMethod(); + + string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } } } \ No newline at end of file -- cgit v1.1 From 3082fdd0f6d73fa07fe2266170fcd3e5e572f2a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 22:58:20 +0100 Subject: Add VectorRenderModuleTests.TestRepeatDrawContainingImage() --- .../VectorRender/Tests/VectorRenderModuleTests.cs | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index f9b5a59..21e1d54 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -108,5 +108,36 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); } + + [Test] + public void TestRepeatDrawContainingImage() + { + TestHelpers.InMethod(); + + string dtText + = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; + + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } } } \ No newline at end of file -- cgit v1.1 From 4e26d039d6ffe03ae9509120015b39692bad44f9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 23:03:21 +0100 Subject: Add VectorRenderModule.TestRepeatSameDrawDifferentExtraParams() --- .../VectorRender/Tests/VectorRenderModuleTests.cs | 34 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 21e1d54..180ea9f 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests } [Test] - public void TestRepeatDraw() + public void TestRepeatSameDraw() { TestHelpers.InMethod(); @@ -110,7 +110,37 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests } [Test] - public void TestRepeatDrawContainingImage() + public void TestRepeatSameDrawDifferentExtraParams() + { + TestHelpers.InMethod(); + + string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "alpha:250", + 0); + + Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } + + [Test] + public void TestRepeatSameDrawContainingImage() { TestHelpers.InMethod(); -- cgit v1.1 From ab9bfe5156d955ca02b7cfcb0ccb5919f6b0743d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 27 Aug 2012 23:06:37 +0100 Subject: minor: Simplify return of vector render module name and some very minor removal of unncessary syntax clutter --- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index c48a703..f988c0e 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -47,7 +47,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private string m_name = "VectorRenderModule"; private Scene m_scene; private IDynamicTextureManager m_textureManager; private Graphics m_graph; @@ -61,12 +60,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public string GetContentType() { - return ("vector"); + return "vector"; } public string GetName() { - return m_name; + return Name; } public bool SupportsAsynchronous() @@ -152,7 +151,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public string Name { - get { return m_name; } + get { return "VectorRenderModule"; } } public bool IsSharedModule -- cgit v1.1 From a6d689c529e443df58eb218ccb512c516fb7cc81 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sun, 26 Aug 2012 22:52:33 +0100 Subject: refactoring to assign the first argument to a variable --- OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 3f848ed..3546654 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -1176,7 +1176,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain private void InterfaceRunPluginEffect(Object[] args) { - if ((string) args[0] == "list") + string firstArg = (string)args[0]; + if (firstArg == "list") { m_log.Info("List of loaded plugins"); foreach (KeyValuePair kvp in m_plugineffects) @@ -1185,14 +1186,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain } return; } - if ((string) args[0] == "reload") + if (firstArg == "reload") { LoadPlugins(); return; } - if (m_plugineffects.ContainsKey((string) args[0])) + if (m_plugineffects.ContainsKey(firstArg)) { - m_plugineffects[(string) args[0]].RunEffect(m_channel); + m_plugineffects[firstArg].RunEffect(m_channel); CheckForTerrainUpdates(); } else -- cgit v1.1 From 72c2d13ac6e350317b59b04bca9c79f371f0528a Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Sun, 26 Aug 2012 22:53:59 +0100 Subject: refactoring to load from self (fixes ChanneDigger being absent) --- .../Region/CoreModules/World/Terrain/TerrainModule.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 3546654..620d3b5 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -414,6 +414,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain private void LoadPlugins() { m_plugineffects = new Dictionary(); + LoadPlugins(Assembly.GetCallingAssembly()); string plugineffectsPath = "Terrain"; // Load the files in the Terrain/ dir @@ -427,6 +428,16 @@ namespace OpenSim.Region.CoreModules.World.Terrain try { Assembly library = Assembly.LoadFrom(file); + LoadPlugins(library); + } + catch (BadImageFormatException) + { + } + } + } + + private void LoadPlugins(Assembly library) + { foreach (Type pluginType in library.GetTypes()) { try @@ -453,11 +464,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain { } } - } - catch (BadImageFormatException) - { - } - } } public void InstallPlugin(string pluginName, ITerrainEffect effect) -- cgit v1.1 From e916b1399f08e726302f576d1653dc7edc445217 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Mon, 27 Aug 2012 01:50:53 +0100 Subject: formatting --- .../CoreModules/World/Terrain/TerrainModule.cs | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 620d3b5..4694b14 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -438,32 +438,32 @@ namespace OpenSim.Region.CoreModules.World.Terrain private void LoadPlugins(Assembly library) { - foreach (Type pluginType in library.GetTypes()) - { - try - { - if (pluginType.IsAbstract || pluginType.IsNotPublic) - continue; + foreach (Type pluginType in library.GetTypes()) + { + try + { + if (pluginType.IsAbstract || pluginType.IsNotPublic) + continue; - string typeName = pluginType.Name; + string typeName = pluginType.Name; - if (pluginType.GetInterface("ITerrainEffect", false) != null) - { - ITerrainEffect terEffect = (ITerrainEffect) Activator.CreateInstance(library.GetType(pluginType.ToString())); + if (pluginType.GetInterface("ITerrainEffect", false) != null) + { + ITerrainEffect terEffect = (ITerrainEffect)Activator.CreateInstance(library.GetType(pluginType.ToString())); - InstallPlugin(typeName, terEffect); - } - else if (pluginType.GetInterface("ITerrainLoader", false) != null) - { - ITerrainLoader terLoader = (ITerrainLoader) Activator.CreateInstance(library.GetType(pluginType.ToString())); - m_loaders[terLoader.FileExtension] = terLoader; - m_log.Info("L ... " + typeName); - } - } - catch (AmbiguousMatchException) - { - } + InstallPlugin(typeName, terEffect); + } + else if (pluginType.GetInterface("ITerrainLoader", false) != null) + { + ITerrainLoader terLoader = (ITerrainLoader)Activator.CreateInstance(library.GetType(pluginType.ToString())); + m_loaders[terLoader.FileExtension] = terLoader; + m_log.Info("L ... " + typeName); } + } + catch (AmbiguousMatchException) + { + } + } } public void InstallPlugin(string pluginName, ITerrainEffect effect) -- cgit v1.1 From 8a7fbfb06a20fa1c4b8e25809eb42c12a621e0b4 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Mon, 27 Aug 2012 01:37:55 +0100 Subject: adding some files to .gitignore that get generated when debugging in c# express with OpenSim.32BitLaunch as the startup project --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index bf3ac37..1e41243 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,10 @@ bin/*.db-journal bin/addin-db-* bin/*.dll bin/OpenSim.vshost.exe.config +bin/OpenSim.32BitLaunch.vshost.exe.config +bin/OpenSim.32BitLaunch.log +UpgradeLog.XML +_UpgradeReport_Files/ bin/ScriptEngines/*-*-*-*-* bin/ScriptEngines/*.dll bin/ScriptEngines/*/*.dll -- cgit v1.1 From 1e18f0f26aeb45ff9d0097206fec3910fb2291c8 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Thu, 23 Aug 2012 13:59:06 +0100 Subject: copying documentation from http://opensimulator.org/wiki/Threat_level --- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 9ad1c22..ce1845c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -40,16 +40,75 @@ using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { + /// + /// To permit region owners to enable the extended scripting functionality + /// of OSSL, without allowing malicious scripts to access potentially + /// troublesome functions, each OSSL function is assigned a threat level, + /// and access to the functions is granted or denied based on a default + /// threshold set in OpenSim.ini (which can be overridden for individual + /// functions on a case-by-case basis) + /// public enum ThreatLevel { + // Not documented, presumably means permanently disabled ? NoAccess = -1, + + /// + /// Function is no threat at all. It doesn't constitute a threat to + /// either users or the system and has no known side effects. + /// None = 0, + + /// + /// Abuse of this command can cause a nuisance to the region operator, + /// such as log message spew. + /// Nuisance = 1, + + /// + /// Extreme levels of abuse of this function can cause impaired + /// functioning of the region, or very gullible users can be tricked + /// into experiencing harmless effects. + /// VeryLow = 2, + + /// + /// Intentional abuse can cause crashes or malfunction under certain + /// circumstances, which can be easily rectified; or certain users can + /// be tricked into certain situations in an avoidable manner. + /// Low = 3, + + /// + /// Intentional abuse can cause denial of service and crashes with + /// potential of data or state loss; or trusting users can be tricked + /// into embarrassing or uncomfortable situations. + /// Moderate = 4, + + /// + /// Casual abuse can cause impaired functionality or temporary denial + /// of service conditions. Intentional abuse can easily cause crashes + /// with potential data loss, or can be used to trick experienced and + /// cautious users into unwanted situations, or changes global data + /// permanently and without undo ability. + /// High = 5, + + /// + /// Even normal use may, depending on the number of instances, or + /// frequency of use, result in severe service impairment or crash + /// with loss of data, or can be used to cause unwanted or harmful + /// effects on users without giving the user a means to avoid it. + /// VeryHigh = 6, + + /// + /// Even casual use is a danger to region stability, or function allows + /// console or OS command execution, or function allows taking money + /// without consent, or allows deletion or modification of user data, + /// or allows the compromise of sensitive data by design. + /// Severe = 7 }; -- cgit v1.1 From aa44df9c04658cfa0af9a0f203faea5e493c6f25 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 28 Aug 2012 20:35:17 +0100 Subject: Add IDynamicTextureManager.ConvertData() to match AsyncConvertData(). Remove mismatching ConvertStream() where there is no AsyncConvertStream and neither IDynamicTextureManager implementer implements this method. --- .../CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | 2 +- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 11 ++++++----- OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 6f83948..6e38b3f 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL return null; } - public byte[] ConvertStream(Stream data, string extraParams) + public byte[] ConvertData(string bodyData, string extraParams) { return null; } diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index f988c0e..3a758c5 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -78,9 +78,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender return null; } - public byte[] ConvertStream(Stream data, string extraParams) + public byte[] ConvertData(string bodyData, string extraParams) { - return null; + return Draw(bodyData, extraParams); } public bool AsyncConvertUrl(UUID id, string url, string extraParams) @@ -90,7 +90,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public bool AsyncConvertData(UUID id, string bodyData, string extraParams) { - Draw(bodyData, id, extraParams); + // XXX: This isn't actually being done asynchronously! + m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); return true; } @@ -161,7 +162,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - private void Draw(string data, UUID id, string extraParams) + private byte[] Draw(string data, string extraParams) { // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 @@ -358,7 +359,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender e.Message, e.StackTrace); } - m_textureManager.ReturnData(id, imageJ2000); + return imageJ2000; } finally { diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs index 8954513..773ba73 100644 --- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs +++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs @@ -114,7 +114,7 @@ namespace OpenSim.Region.Framework.Interfaces string GetContentType(); bool SupportsAsynchronous(); byte[] ConvertUrl(string url, string extraParams); - byte[] ConvertStream(Stream data, string extraParams); + byte[] ConvertData(string bodyData, string extraParams); bool AsyncConvertUrl(UUID id, string url, string extraParams); bool AsyncConvertData(UUID id, string bodyData, string extraParams); void GetDrawStringSize(string text, string fontName, int fontSize, -- cgit v1.1 From c1cece4b82d24a17a09b66c9ec3975190cc05d95 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Tue, 28 Aug 2012 23:06:53 +0100 Subject: Add experimental DynamicTextureModule.ReuseTextures flag, currently only configurable on compile. Disabled (status quo) by default. This flag makes the dynamic texture module reuse cache previously dynamically generated textures given the same input commands and extra params for 24 hours. This occurs as long as those commands would always generate the same texture (e.g. they do not contain commands to fetch data from the web). This makes texture changing faster as a viewer-cached texture uuid is sent and may reduce simulator load in regions with generation of lots of dynamic textures. A downside is that this stops expiry of old temporary dynamic textures from the cache, Another downside is that a jpeg2000 generation that partially failed is currently not regenerated until restart or after 24 hours. --- .../DynamicTexture/DynamicTextureModule.cs | 169 +++++++++++++++------ .../Scripting/LoadImageURL/LoadImageURLModule.cs | 10 +- .../VectorRender/Tests/VectorRenderModuleTests.cs | 125 ++++++++++++++- .../Scripting/VectorRender/VectorRenderModule.cs | 48 +++++- .../Framework/Interfaces/IDynamicTextureManager.cs | 14 +- 5 files changed, 310 insertions(+), 56 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 18bd018..13b7498 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public const int DISP_EXPIRE = 1; public const int DISP_TEMP = 2; + /// + /// If true then where possible dynamic textures are reused. + /// + public bool ReuseTextures { get; set; } + private Dictionary RegisteredScenes = new Dictionary(); private Dictionary RenderPlugins = @@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture private Dictionary Updaters = new Dictionary(); + /// + /// Record dynamic textures that we can reuse for a given data and parameter combination rather than + /// regenerate. + /// + /// + /// Key is string.Format("{0}{1}", data + /// + private Cache m_reuseableDynamicTextures; + #region IDynamicTextureManager Members public void RegisterRender(string handleType, IDynamicTextureRender render) @@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture /// /// /// - public void ReturnData(UUID id, byte[] data) + /// True if the data generated can be reused for subsequent identical requests + public void ReturnData(UUID id, byte[] data, bool isReuseable) { DynamicTextureUpdater updater = null; @@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture if (RegisteredScenes.ContainsKey(updater.SimUUID)) { Scene scene = RegisteredScenes[updater.SimUUID]; - updater.DataReceived(data, scene); + UUID newTextureID = updater.DataReceived(data, scene); + + if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture) + m_reuseableDynamicTextures.Store( + GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID); } } @@ -169,6 +188,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { if (RenderPlugins.ContainsKey(contentType)) { + // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire + // them. + if (ReuseTextures) + disp = disp & ~DISP_EXPIRE; + DynamicTextureUpdater updater = new DynamicTextureUpdater(); updater.SimUUID = simID; updater.PrimID = primID; @@ -183,21 +207,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture updater.Url = "Local image"; updater.Disp = disp; - lock (Updaters) + object reusableTextureUUID = null; + + if (ReuseTextures) + reusableTextureUUID + = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams)); + + // We cannot reuse a dynamic texture if the data is going to be blended with something already there. + if (reusableTextureUUID == null || updater.BlendWithOldTexture) { - if (!Updaters.ContainsKey(updater.UpdaterID)) + lock (Updaters) { - Updaters.Add(updater.UpdaterID, updater); + if (!Updaters.ContainsKey(updater.UpdaterID)) + { + Updaters.Add(updater.UpdaterID, updater); + } + } + + RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); + } + else + { + // No need to add to updaters as the texture is always the same. Not that this functionality + // apppears to be implemented anyway. + if (RegisteredScenes.ContainsKey(updater.SimUUID)) + { + SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID); + + if (part != null) + updater.UpdatePart(part, (UUID)reusableTextureUUID); } } - RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); return updater.UpdaterID; } return UUID.Zero; } + private string GenerateReusableTextureKey(string data, string extraParams) + { + return string.Format("{0}{1}", data, extraParams); + } + public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, out double xSize, out double ySize) { @@ -224,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public void PostInitialise() { +// ReuseTextures = true; + if (ReuseTextures) + { + m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); + m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0); + } } public void Close() @@ -269,9 +327,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } /// + /// Update the given part with the new texture. + /// + /// + /// The old texture UUID. + /// + public UUID UpdatePart(SceneObjectPart part, UUID textureID) + { + UUID oldID; + + lock (part) + { + // mostly keep the values from before + Primitive.TextureEntry tmptex = part.Shape.Textures; + + // FIXME: Need to return the appropriate ID if only a single face is replaced. + oldID = tmptex.DefaultTexture.TextureID; + + if (Face == ALL_SIDES) + { + oldID = tmptex.DefaultTexture.TextureID; + tmptex.DefaultTexture.TextureID = textureID; + } + else + { + try + { + Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); + texface.TextureID = textureID; + tmptex.FaceTextures[Face] = texface; + } + catch (Exception) + { + tmptex.DefaultTexture.TextureID = textureID; + } + } + + // I'm pretty sure we always want to force this to true + // I'm pretty sure noone whats to set fullbright true if it wasn't true before. + // tmptex.DefaultTexture.Fullbright = true; + + part.UpdateTextureEntry(tmptex.GetBytes()); + } + + return oldID; + } + + /// /// Called once new texture data has been received for this updater. /// - public void DataReceived(byte[] data, Scene scene) + /// + /// + /// True if the data given is reuseable. + /// The asset UUID given to the incoming data. + public UUID DataReceived(byte[] data, Scene scene) { SceneObjectPart part = scene.GetSceneObjectPart(PrimID); @@ -281,7 +390,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); - return; + + return UUID.Zero; } byte[] assetData = null; @@ -323,52 +433,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture cacheLayerDecode = null; } - UUID oldID = UUID.Zero; - - lock (part) - { - // mostly keep the values from before - Primitive.TextureEntry tmptex = part.Shape.Textures; - - // remove the old asset from the cache - oldID = tmptex.DefaultTexture.TextureID; - - if (Face == ALL_SIDES) - { - tmptex.DefaultTexture.TextureID = asset.FullID; - } - else - { - try - { - Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face); - texface.TextureID = asset.FullID; - tmptex.FaceTextures[Face] = texface; - } - catch (Exception) - { - tmptex.DefaultTexture.TextureID = asset.FullID; - } - } - - // I'm pretty sure we always want to force this to true - // I'm pretty sure noone whats to set fullbright true if it wasn't true before. - // tmptex.DefaultTexture.Fullbright = true; - - part.UpdateTextureEntry(tmptex.GetBytes()); - } + UUID oldID = UpdatePart(part, asset.FullID); if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) { - if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); + if (oldAsset == null) + oldAsset = scene.AssetService.Get(oldID.ToString()); + if (oldAsset != null) { - if (oldAsset.Temporary == true) + if (oldAsset.Temporary) { scene.AssetService.Delete(oldID.ToString()); } } } + + return asset.FullID; } private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 6e38b3f..2b3a0f2 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -67,6 +67,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL return true; } +// public bool AlwaysIdenticalConversion(string bodyData, string extraParams) +// { +// // We don't support conversion of body data. +// return false; +// } + public byte[] ConvertUrl(string url, string extraParams) { return null; @@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL stream.Close(); } } + m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", imageJ2000.Length, state.RequestID); - m_textureManager.ReturnData(state.RequestID, imageJ2000); + + m_textureManager.ReturnData(state.RequestID, imageJ2000, false); } #region Nested type: RequestState diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs index 180ea9f..b50c0bd 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs @@ -51,12 +51,15 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests DynamicTextureModule m_dtm; VectorRenderModule m_vrm; - [SetUp] - public void SetUp() + private void SetupScene(bool reuseTextures) { m_scene = new SceneHelpers().SetupScene(); + m_dtm = new DynamicTextureModule(); + m_dtm.ReuseTextures = reuseTextures; + m_vrm = new VectorRenderModule(); + SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm); } @@ -65,6 +68,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests { TestHelpers.InMethod(); + SetupScene(false); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; @@ -86,6 +90,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + SetupScene(false); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); m_dtm.AddDynamicTextureData( @@ -116,6 +121,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + SetupScene(false); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); m_dtm.AddDynamicTextureData( @@ -147,6 +153,121 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; + SetupScene(false); + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } + + [Test] + public void TestDrawReusingTexture() + { + TestHelpers.InMethod(); + + SetupScene(true); + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", + "", + 0); + + Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } + + [Test] + public void TestRepeatSameDrawReusingTexture() + { + TestHelpers.InMethod(); + + string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + + SetupScene(true); + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } + + [Test] + public void TestRepeatSameDrawDifferentExtraParamsReusingTexture() + { + TestHelpers.InMethod(); + + string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;"; + + SetupScene(true); + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "", + 0); + + UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + m_dtm.AddDynamicTextureData( + m_scene.RegionInfo.RegionID, + so.UUID, + m_vrm.GetContentType(), + dtText, + "alpha:250", + 0); + + Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + } + + [Test] + public void TestRepeatSameDrawContainingImageReusingTexture() + { + TestHelpers.InMethod(); + + string dtText + = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png"; + + SetupScene(true); SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene); m_dtm.AddDynamicTextureData( diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 3a758c5..4268f2e 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -30,6 +30,7 @@ using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; +using System.Linq; using System.Net; using Nini.Config; using OpenMetaverse; @@ -73,6 +74,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender return true; } +// public bool AlwaysIdenticalConversion(string bodyData, string extraParams) +// { +// string[] lines = GetLines(bodyData); +// return lines.Any((str, r) => str.StartsWith("Image")); +// } + public byte[] ConvertUrl(string url, string extraParams) { return null; @@ -80,7 +87,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public byte[] ConvertData(string bodyData, string extraParams) { - return Draw(bodyData, extraParams); + bool reuseable; + return Draw(bodyData, extraParams, out reuseable); + } + + private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable) + { + return Draw(bodyData, extraParams, out reuseable); } public bool AsyncConvertUrl(UUID id, string url, string extraParams) @@ -91,7 +104,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender public bool AsyncConvertData(UUID id, string bodyData, string extraParams) { // XXX: This isn't actually being done asynchronously! - m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams)); + bool reuseable; + byte[] data = ConvertData(bodyData, extraParams, out reuseable); + + m_textureManager.ReturnData(id, data, reuseable); + return true; } @@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - private byte[] Draw(string data, string extraParams) + private byte[] Draw(string data, string extraParams, out bool reuseable) { // We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 @@ -343,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } } - GDIDraw(data, graph, altDataDelim); + GDIDraw(data, graph, altDataDelim, out reuseable); } byte[] imageJ2000 = new byte[0]; @@ -434,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } */ - private void GDIDraw(string data, Graphics graph, char dataDelim) + /// + /// Split input data into discrete command lines. + /// + /// + /// + /// + private string[] GetLines(string data, char dataDelim) { + char[] lineDelimiter = { dataDelim }; + return data.Split(lineDelimiter); + } + + private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable) + { + reuseable = true; Point startPoint = new Point(0, 0); Point endPoint = new Point(0, 0); Pen drawPen = null; @@ -450,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender myFont = new Font(fontName, fontSize); myBrush = new SolidBrush(Color.Black); - char[] lineDelimiter = {dataDelim}; char[] partsDelimiter = {','}; - string[] lines = data.Split(lineDelimiter); - foreach (string line in lines) + foreach (string line in GetLines(data, dataDelim)) { string nextLine = line.Trim(); //replace with switch, or even better, do some proper parsing @@ -485,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } else if (nextLine.StartsWith("Image")) { + // We cannot reuse any generated texture involving fetching an image via HTTP since that image + // can change. + reuseable = false; + float x = 0; float y = 0; GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); diff --git a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs index 773ba73..1a3bcbb 100644 --- a/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs +++ b/OpenSim/Region/Framework/Interfaces/IDynamicTextureManager.cs @@ -33,7 +33,7 @@ namespace OpenSim.Region.Framework.Interfaces public interface IDynamicTextureManager { void RegisterRender(string handleType, IDynamicTextureRender render); - void ReturnData(UUID id, byte[] data); + void ReturnData(UUID id, byte[] data, bool isReuseable); UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams, int updateTimer); @@ -113,6 +113,18 @@ namespace OpenSim.Region.Framework.Interfaces string GetName(); string GetContentType(); bool SupportsAsynchronous(); + +// /// +// /// Return true if converting the input body and extra params data will always result in the same byte[] array +// /// +// /// +// /// This method allows the caller to use a previously generated asset if it has one. +// /// +// /// +// /// +// /// +// bool AlwaysIdenticalConversion(string bodyData, string extraParams); + byte[] ConvertUrl(string url, string extraParams); byte[] ConvertData(string bodyData, string extraParams); bool AsyncConvertUrl(UUID id, string url, string extraParams); -- cgit v1.1 From 7ea832d47c827ad9ef8eb0ce24702fbee585b1ee Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 29 Aug 2012 02:01:43 +0100 Subject: Fix regression introduced in a0d178b2 (Sat Aug 25 02:00:17 2012) where folders with asset type of 'Folder' and 'Unknown' were accidentally treated as system folders. This prevented more than one additional ordinary folder from being created in the base "My Inventory" user folder. Added regression test for this case. Switched tests to use XInventoryService with mostly implemented TestXInventoryDataPlugin rather than InventoryService Disabled TestLoadIarV0_1SameNameCreator() since this has not been working for a very long time (ever since XInventoryService) started being used since it doesnt' preserve creator data in the same way as InventoryService did and so effectively lost the OSPAs. However, nobody noticed/complained about this issue and OSPAs have been superseded by HG like creator information via the --home save oar/iar switch. --- OpenSim/Data/IXInventoryData.cs | 10 ++ OpenSim/Framework/InventoryFolderBase.cs | 18 +-- .../Serialization/External/OspResolver.cs | 14 ++- .../Archiver/Tests/InventoryArchiverTests.cs | 64 +++++----- .../Framework/Scenes/Tests/UserInventoryTests.cs | 36 +++++- .../Services/InventoryService/XInventoryService.cs | 3 +- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 2 +- .../Tests/Common/Helpers/UserInventoryHelpers.cs | 4 +- .../Tests/Common/Mock/TestXInventoryDataPlugin.cs | 131 +++++++++++++++++++++ OpenSim/Tests/Common/TestHelpers.cs | 1 + 10 files changed, 231 insertions(+), 52 deletions(-) create mode 100644 OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs index 85a5c08..e64a828 100644 --- a/OpenSim/Data/IXInventoryData.cs +++ b/OpenSim/Data/IXInventoryData.cs @@ -40,6 +40,11 @@ namespace OpenSim.Data public UUID folderID; public UUID agentID; public UUID parentFolderID; + + public XInventoryFolder Clone() + { + return (XInventoryFolder)MemberwiseClone(); + } } public class XInventoryItem @@ -64,6 +69,11 @@ namespace OpenSim.Data public UUID avatarID; public UUID parentFolderID; public int inventoryGroupPermissions; + + public XInventoryItem Clone() + { + return (XInventoryItem)MemberwiseClone(); + } } public interface IXInventoryData diff --git a/OpenSim/Framework/InventoryFolderBase.cs b/OpenSim/Framework/InventoryFolderBase.cs index a12183c..b3457a6 100644 --- a/OpenSim/Framework/InventoryFolderBase.cs +++ b/OpenSim/Framework/InventoryFolderBase.cs @@ -73,33 +73,27 @@ namespace OpenSim.Framework { } - public InventoryFolderBase(UUID id) + public InventoryFolderBase(UUID id) : this() { ID = id; } - public InventoryFolderBase(UUID id, UUID owner) + public InventoryFolderBase(UUID id, UUID owner) : this(id) { - ID = id; Owner = owner; } - public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) + public InventoryFolderBase(UUID id, string name, UUID owner, UUID parent) : this(id, owner) { - ID = id; Name = name; - Owner = owner; ParentID = parent; } - public InventoryFolderBase(UUID id, string name, UUID owner, short type, UUID parent, ushort version) + public InventoryFolderBase( + UUID id, string name, UUID owner, short type, UUID parent, ushort version) : this(id, name, owner, parent) { - ID = id; - Name = name; - Owner = owner; Type = type; - ParentID = parent; Version = version; } } -} +} \ No newline at end of file diff --git a/OpenSim/Framework/Serialization/External/OspResolver.cs b/OpenSim/Framework/Serialization/External/OspResolver.cs index d31d27c..fa7160f 100644 --- a/OpenSim/Framework/Serialization/External/OspResolver.cs +++ b/OpenSim/Framework/Serialization/External/OspResolver.cs @@ -65,9 +65,14 @@ namespace OpenSim.Framework.Serialization UserAccount account = userService.GetUserAccount(UUID.Zero, userId); if (account != null) + { return MakeOspa(account.FirstName, account.LastName); + } // else +// { // m_log.WarnFormat("[OSP RESOLVER]: No user account for {0}", userId); +// System.Console.WriteLine("[OSP RESOLVER]: No user account for {0}", userId); +// } return null; } @@ -79,10 +84,13 @@ namespace OpenSim.Framework.Serialization /// public static string MakeOspa(string firstName, string lastName) { -// m_log.DebugFormat("[OSP RESOLVER]: Making OSPA for {0} {1}", firstName, lastName); + string ospa + = OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; + +// m_log.DebugFormat("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); +// System.Console.WriteLine("[OSP RESOLVER]: Made OSPA {0} for {1} {2}", ospa, firstName, lastName); - return - OSPA_PREFIX + OSPA_NAME_KEY + OSPA_PAIR_SEPARATOR + firstName + OSPA_NAME_VALUE_SEPARATOR + lastName; + return ospa; } /// diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs index b112b6d..12a05b3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/Tests/InventoryArchiverTests.cs @@ -350,38 +350,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver.Tests Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL1.PrincipalID)); } - /// - /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where - /// an account exists with the same name as the creator, though not the same id. - /// - [Test] - public void TestLoadIarV0_1SameNameCreator() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); - UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); - - m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); - InventoryItemBase foundItem1 - = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); - - Assert.That( - foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), - "Loaded item non-uuid creator doesn't match original"); - Assert.That( - foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), - "Loaded item uuid creator doesn't match original"); - Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), - "Loaded item owner doesn't match inventory reciever"); - - AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); - string xmlData = Utils.BytesToString(asset1.Data); - SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); - - Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); - } +// /// +// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where +// /// an account exists with the same name as the creator, though not the same id. +// /// +// [Test] +// public void TestLoadIarV0_1SameNameCreator() +// { +// TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); +// +// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaMT, "meowfood"); +// UserAccountHelpers.CreateUserWithInventory(m_scene, m_uaLL2, "hampshire"); +// +// m_archiverModule.DearchiveInventory(m_uaMT.FirstName, m_uaMT.LastName, "/", "meowfood", m_iarStream); +// InventoryItemBase foundItem1 +// = InventoryArchiveUtils.FindItemByPath(m_scene.InventoryService, m_uaMT.PrincipalID, m_item1Name); +// +// Assert.That( +// foundItem1.CreatorId, Is.EqualTo(m_uaLL2.PrincipalID.ToString()), +// "Loaded item non-uuid creator doesn't match original"); +// Assert.That( +// foundItem1.CreatorIdAsUuid, Is.EqualTo(m_uaLL2.PrincipalID), +// "Loaded item uuid creator doesn't match original"); +// Assert.That(foundItem1.Owner, Is.EqualTo(m_uaMT.PrincipalID), +// "Loaded item owner doesn't match inventory reciever"); +// +// AssetBase asset1 = m_scene.AssetService.Get(foundItem1.AssetID.ToString()); +// string xmlData = Utils.BytesToString(asset1.Data); +// SceneObjectGroup sog1 = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); +// +// Assert.That(sog1.RootPart.CreatorID, Is.EqualTo(m_uaLL2.PrincipalID)); +// } /// /// Test loading a V0.1 OpenSim Inventory Archive (subject to change since there is no fixed format yet) where diff --git a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs index 44d2d45..9457ebb 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/UserInventoryTests.cs @@ -50,9 +50,41 @@ using OpenSim.Tests.Common.Mock; namespace OpenSim.Region.Framework.Tests { [TestFixture] - public class UserInventoryTests + public class UserInventoryTests : OpenSimTestCase { [Test] + public void TestCreateInventoryFolders() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + // For this test both folders will have the same name which is legal in SL user inventories. + string foldersName = "f1"; + + Scene scene = new SceneHelpers().SetupScene(); + UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); + + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName); + + List oneFolder + = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName); + + Assert.That(oneFolder.Count, Is.EqualTo(1)); + InventoryFolderBase firstRetrievedFolder = oneFolder[0]; + Assert.That(firstRetrievedFolder.Name, Is.EqualTo(foldersName)); + + UserInventoryHelpers.CreateInventoryFolder(scene.InventoryService, user1.PrincipalID, foldersName); + + List twoFolders + = UserInventoryHelpers.GetInventoryFolders(scene.InventoryService, user1.PrincipalID, foldersName); + + Assert.That(twoFolders.Count, Is.EqualTo(2)); + Assert.That(twoFolders[0].Name, Is.EqualTo(foldersName)); + Assert.That(twoFolders[1].Name, Is.EqualTo(foldersName)); + Assert.That(twoFolders[0].ID, Is.Not.EqualTo(twoFolders[1].ID)); + } + + [Test] public void TestGiveInventoryItem() { TestHelpers.InMethod(); @@ -83,7 +115,7 @@ namespace OpenSim.Region.Framework.Tests public void TestGiveInventoryFolder() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); Scene scene = new SceneHelpers().SetupScene(); UserAccount user1 = UserAccountHelpers.CreateUserWithInventory(scene, TestHelpers.ParseTail(1001)); diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index deacd5a..309dab4 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -94,6 +94,7 @@ namespace OpenSim.Services.InventoryService m_Database = LoadPlugin(dllName, new Object[] {connString, String.Empty}); + if (m_Database == null) throw new Exception("Could not find a storage interface in the given module"); } @@ -326,7 +327,7 @@ namespace OpenSim.Services.InventoryService if (check != null) return false; - if (folder.Type != (short)AssetType.Folder || folder.Type != (short)AssetType.Unknown) + if (folder.Type != (short)AssetType.Folder && folder.Type != (short)AssetType.Unknown) { InventoryFolderBase rootFolder = GetRootFolder(folder.Owner); diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 7598cc3..fc49169 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -245,7 +245,7 @@ namespace OpenSim.Tests.Common config.AddConfig("Modules"); config.AddConfig("InventoryService"); config.Configs["Modules"].Set("InventoryServices", "LocalInventoryServicesConnector"); - config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:InventoryService"); + config.Configs["InventoryService"].Set("LocalServiceModule", "OpenSim.Services.InventoryService.dll:XInventoryService"); config.Configs["InventoryService"].Set("StorageProvider", "OpenSim.Tests.Common.dll"); LocalInventoryServicesConnector inventoryService = new LocalInventoryServicesConnector(); diff --git a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs index b3a7c9e..87d9410 100644 --- a/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/UserInventoryHelpers.cs @@ -199,7 +199,9 @@ namespace OpenSim.Tests.Common string[] components = path.Split(new string[] { PATH_DELIMITER }, 2, StringSplitOptions.None); InventoryFolderBase newFolder - = new InventoryFolderBase(UUID.Random(), components[0], parentFolder.Owner, parentFolder.ID); + = new InventoryFolderBase( + UUID.Random(), components[0], parentFolder.Owner, (short)AssetType.Unknown, parentFolder.ID, 0); + inventoryService.AddFolder(newFolder); if (components.Length > 1) diff --git a/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs new file mode 100644 index 0000000..bca5979 --- /dev/null +++ b/OpenSim/Tests/Common/Mock/TestXInventoryDataPlugin.cs @@ -0,0 +1,131 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Data; + +namespace OpenSim.Tests.Common.Mock +{ + public class TestXInventoryDataPlugin : IXInventoryData + { + private Dictionary m_allFolders = new Dictionary(); + private Dictionary m_allItems = new Dictionary(); + + public TestXInventoryDataPlugin(string conn, string realm) {} + + public XInventoryItem[] GetItems(string[] fields, string[] vals) + { + List origItems = Get(fields, vals, m_allItems.Values.ToList()); + + return origItems.Select(i => i.Clone()).ToArray(); + } + + public XInventoryFolder[] GetFolders(string[] fields, string[] vals) + { + List origFolders + = Get(fields, vals, m_allFolders.Values.ToList()); + + return origFolders.Select(f => f.Clone()).ToArray(); + } + + private List Get(string[] fields, string[] vals, List inputEntities) + { + List entities = inputEntities; + + for (int i = 0; i < fields.Length; i++) + { + entities + = entities.Where( + e => + { + FieldInfo fi = typeof(T).GetField(fields[i]); + if (fi == null) + throw new NotImplementedException(string.Format("No field {0} for val {1}", fields[i], vals[i])); + + return fi.GetValue(e).ToString() == vals[i]; + } + ).ToList(); + } + + return entities; + } + + public bool StoreFolder(XInventoryFolder folder) + { + m_allFolders[folder.folderID] = folder.Clone(); + +// Console.WriteLine("Added folder {0} {1}", folder.folderName, folder.folderID); + + return true; + } + + public bool StoreItem(XInventoryItem item) + { + m_allItems[item.inventoryID] = item.Clone(); + +// Console.WriteLine("Added item {0} {1}, creator {2}, owner {3}", item.inventoryName, item.inventoryID, item.creatorID, item.avatarID); + + return true; + } + + public bool DeleteFolders(string field, string val) + { + return DeleteFolders(new string[] { field }, new string[] { val }); + } + + public bool DeleteFolders(string[] fields, string[] vals) + { + XInventoryFolder[] foldersToDelete = GetFolders(fields, vals); + Array.ForEach(foldersToDelete, f => m_allFolders.Remove(f.folderID)); + + return true; + } + + public bool DeleteItems(string field, string val) + { + return DeleteItems(new string[] { field }, new string[] { val }); + } + + public bool DeleteItems(string[] fields, string[] vals) + { + XInventoryItem[] itemsToDelete = GetItems(fields, vals); + Array.ForEach(itemsToDelete, i => m_allItems.Remove(i.inventoryID)); + + return true; + } + + public bool MoveItem(string id, string newParent) { throw new NotImplementedException(); } + public XInventoryItem[] GetActiveGestures(UUID principalID) { throw new NotImplementedException(); } + public int GetAssetPermissions(UUID principalID, UUID assetID) { throw new NotImplementedException(); } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Common/TestHelpers.cs b/OpenSim/Tests/Common/TestHelpers.cs index 30121fe..57da802 100644 --- a/OpenSim/Tests/Common/TestHelpers.cs +++ b/OpenSim/Tests/Common/TestHelpers.cs @@ -95,6 +95,7 @@ namespace OpenSim.Tests.Common public static void EnableLogging() { log4net.Config.XmlConfigurator.Configure(EnableLoggingConfigStream); + EnableLoggingConfigStream.Position = 0; } /// -- cgit v1.1 From 3bf7bd6359ffbbc2a00b6870b72cc78287a70bc7 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Tue, 28 Aug 2012 03:21:04 +0100 Subject: track originating IScriptApi method for SL-like error messages. Will add rule number tracking in next commit. --- .../Shared/Api/Implementation/LSL_Api.cs | 26 +++++++++++++--------- .../Shared/Api/Implementation/OSSL_Api.cs | 2 +- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b001c51..709cac2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7208,7 +7208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules); + setLinkPrimParams(ScriptBaseClass.LINK_THIS, rules, "llSetPrimitiveParams"); ScriptSleep(200); } @@ -7217,7 +7217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - setLinkPrimParams(linknumber, rules); + setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); ScriptSleep(200); } @@ -7226,17 +7226,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - setLinkPrimParams(linknumber, rules); + setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); } - protected void setLinkPrimParams(int linknumber, LSL_List rules) + protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) { List parts = GetLinkParts(linknumber); LSL_List remaining = null; foreach (SceneObjectPart part in parts) - remaining = SetPrimParams(part, rules); + remaining = SetPrimParams(part, rules, originFunc); while (remaining != null && remaining.Length > 2) { @@ -7245,13 +7245,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parts = GetLinkParts(linknumber); foreach (SceneObjectPart part in parts) - remaining = SetPrimParams(part, rules); + remaining = SetPrimParams(part, rules, originFunc); } } - protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) + protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc) { int idx = 0; + int idxStart = 0; bool positionChanged = false; LSL_Vector currentPosition = GetPartLocalPos(part); @@ -7263,6 +7264,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int code = rules.GetLSLIntegerItem(idx++); int remain = rules.Length - idx; + idxStart = idx; int face; LSL_Vector v; @@ -7639,7 +7641,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } catch (InvalidCastException e) { - ShoutError(e.Message); + ShoutError(string.Format( + "{0} error running rule #{1}: arg #{2} ", + originFunc, "unknown", idx - idxStart) + e.Message); } finally { @@ -10761,7 +10765,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return tid.ToString(); } - public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) + public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc) { SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); if (obj == null) @@ -10770,14 +10774,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (obj.OwnerID != m_host.OwnerID) return; - LSL_List remaining = SetPrimParams(obj, rules); + LSL_List remaining = SetPrimParams(obj, rules, originFunc); while ((object)remaining != null && remaining.Length > 2) { LSL_Integer newLink = remaining.GetLSLIntegerItem(0); LSL_List newrules = remaining.GetSublist(1, -1); foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ - remaining = SetPrimParams(part, newrules); + remaining = SetPrimParams(part, newrules, originFunc); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 1afa4fb..09fcf50 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2988,7 +2988,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); InitLSL(); - m_LSL_Api.SetPrimitiveParamsEx(prim, rules); + m_LSL_Api.SetPrimitiveParamsEx(prim, rules, "osSetPrimitiveParams"); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index cd58614..e97ff9d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -424,7 +424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_String llXorBase64StringsCorrect(string str1, string str2); void print(string str); - void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); + void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); } } -- cgit v1.1 From 0c3061f973417ecce8f412c82139cfad82504921 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Tue, 28 Aug 2012 03:40:27 +0100 Subject: implementing rule tracking --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 709cac2..ae92716 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7234,9 +7234,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api List parts = GetLinkParts(linknumber); LSL_List remaining = null; + uint rulesParsed = 0; foreach (SceneObjectPart part in parts) - remaining = SetPrimParams(part, rules, originFunc); + remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); while (remaining != null && remaining.Length > 2) { @@ -7245,11 +7246,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parts = GetLinkParts(linknumber); foreach (SceneObjectPart part in parts) - remaining = SetPrimParams(part, rules, originFunc); + remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); } } - protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc) + protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) { int idx = 0; int idxStart = 0; @@ -7261,6 +7262,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { while (idx < rules.Length) { + ++rulesParsed; int code = rules.GetLSLIntegerItem(idx++); int remain = rules.Length - idx; @@ -7643,7 +7645,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { ShoutError(string.Format( "{0} error running rule #{1}: arg #{2} ", - originFunc, "unknown", idx - idxStart) + e.Message); + originFunc, rulesParsed, idx - idxStart) + e.Message); } finally { @@ -10774,14 +10776,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (obj.OwnerID != m_host.OwnerID) return; - LSL_List remaining = SetPrimParams(obj, rules, originFunc); + uint rulesParsed = 0; + LSL_List remaining = SetPrimParams(obj, rules, originFunc, ref rulesParsed); while ((object)remaining != null && remaining.Length > 2) { LSL_Integer newLink = remaining.GetLSLIntegerItem(0); LSL_List newrules = remaining.GetSublist(1, -1); foreach(SceneObjectPart part in GetLinkParts(obj, newLink)){ - remaining = SetPrimParams(part, newrules, originFunc); + remaining = SetPrimParams(part, newrules, originFunc, ref rulesParsed); } } } -- cgit v1.1