From 3d736d575ff9670ac813f13eb1cff07dea10328b Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Wed, 29 Aug 2012 14:56:51 -0700 Subject: This partially implements the LSL function to set the response type for an HTTP request. Since the "official" LSL function limits the use of the response type, it is implemented as osSetContentType with a string for the content mime type and a threat level of high. With this function you should be able to implement rather functional media-on-a-prim application with much less difficulty. --- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 20 +++++++++++++++++++- OpenSim/Region/Framework/Interfaces/IUrlModule.cs | 2 ++ .../Shared/Api/Implementation/OSSL_Api.cs | 18 +++++++++++++++++- .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 6 ++++++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 +++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 05d54f0..53a9679 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public string body; public int responseCode; public string responseBody; + public string responseType = "text/plain"; //public ManualResetEvent ev; public bool requestDone; public int startTime; @@ -302,6 +303,22 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp } } + public void HttpContentType(UUID request, string type) + { + lock (m_UrlMap) + { + if (m_RequestMap.ContainsKey(request)) + { + UrlData urlData = m_RequestMap[request]; + urlData.requests[request].responseType = type; + } + else + { + m_log.Info("[HttpRequestHandler] There is no http-in request with id " + request.ToString()); + } + } + } + public void HttpResponse(UUID request, int status, string body) { lock (m_UrlMap) @@ -504,7 +521,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp //put response response["int_response_code"] = requestData.responseCode; response["str_response_string"] = requestData.responseBody; - response["content_type"] = "text/plain"; + response["content_type"] = requestData.responseType; + // response["content_type"] = "text/plain"; response["keepalive"] = false; response["reusecontext"] = false; diff --git a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs index 457444c..79e9f9d 100644 --- a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs @@ -39,6 +39,8 @@ namespace OpenSim.Region.Framework.Interfaces UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); void ReleaseURL(string url); void HttpResponse(UUID request, int status, string body); + void HttpContentType(UUID request, string type); + string GetHttpHeader(UUID request, string header); int GetFreeUrls(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 09fcf50..e245684 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -140,12 +140,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal float m_ScriptDistanceFactor = 1.0f; internal Dictionary m_FunctionPerms = new Dictionary(); + protected IUrlModule m_UrlModule = null; + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { m_ScriptEngine = ScriptEngine; m_host = host; m_item = item; + m_UrlModule = m_ScriptEngine.World.RequestModuleInterface(); + if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) m_OSFunctionsEnabled = true; @@ -3358,5 +3362,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); } - } + + /// + /// Sets the response type for an HTTP request/response + /// + /// + public void osSetContentType(LSL_Key id, string type) + { + CheckThreatLevel(ThreatLevel.High,"osSetResponseType"); + if (m_UrlModule != null) + m_UrlModule.HttpContentType(new UUID(id),type); + } + + } } \ No newline at end of file diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index ce1845c..06729ab 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -365,5 +365,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces /// /// Rezzing object key or NULL_KEY if rezzed by agent or otherwise unknown. LSL_Key osGetRezzingObject(); + + /// + /// Sets the response type for an HTTP request/response + /// + /// + void osSetContentType(LSL_Key id, string type); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index e9131e4..ba1ade2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -955,5 +955,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osGetRezzingObject(); } + + public void osSetContentType(LSL_Key id, string type) + { + m_OSSL_Functions.osSetContentType(id,type); + } } } -- cgit v1.1 From ec726413ddcd8632efb2603b968554647419708d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 29 Aug 2012 23:04:00 +0100 Subject: Add VectorRenderModuleStressTests that contains a long running test that generates thousands of vector textures concurrently. Intended for use if there are future issues with mono crashes whilst generate dynamic textures. This test is triggered via a new test-stress nant target. Not run by default. --- .nant/local.include | 13 +- .../Tests/Stress/VectorRenderModuleStressTests.cs | 132 +++++++++++++++++++++ prebuild.xml | 40 +++++++ 3 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs diff --git a/.nant/local.include b/.nant/local.include index 6d3e972..181c875 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -135,6 +135,17 @@ + + + + + + + + + + + @@ -142,7 +153,7 @@ - + diff --git a/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs new file mode 100644 index 0000000..1f220c0 --- /dev/null +++ b/OpenSim/Tests/Stress/VectorRenderModuleStressTests.cs @@ -0,0 +1,132 @@ +/* + * 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.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using log4net.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenMetaverse.Assets; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.DynamicTexture; +using OpenSim.Region.CoreModules.Scripting.VectorRender; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Tests.Stress +{ + [TestFixture] + public class VectorRenderModuleStressTests : OpenSimTestCase + { + public Scene Scene { get; private set; } + public DynamicTextureModule Dtm { get; private set; } + public VectorRenderModule Vrm { get; private set; } + + private void SetupScene(bool reuseTextures) + { + Scene = new SceneHelpers().SetupScene(); + + Dtm = new DynamicTextureModule(); + Dtm.ReuseTextures = reuseTextures; + + Vrm = new VectorRenderModule(); + + SceneHelpers.SetupSceneModules(Scene, Dtm, Vrm); + } + + [Test] + public void TestConcurrentRepeatedDraw() + { + int threads = 4; + TestHelpers.InMethod(); + + SetupScene(false); + + List drawers = new List(); + + for (int i = 0; i < threads; i++) + { + Drawer d = new Drawer(this, i); + drawers.Add(d); + Console.WriteLine("Starting drawer {0}", i); + Util.FireAndForget(o => d.Draw()); + } + + Thread.Sleep(10 * 60 * 1000); + + drawers.ForEach(d => d.Ready = false); + drawers.ForEach(d => Console.WriteLine("Drawer {0} drew {1} textures", d.Number, d.Pass + 1)); + } + + class Drawer + { + public int Number { get; private set; } + public int Pass { get; private set; } + public bool Ready { get; set; } + + private VectorRenderModuleStressTests m_tests; + + public Drawer(VectorRenderModuleStressTests tests, int number) + { + m_tests = tests; + Number = number; + Ready = true; + } + + public void Draw() + { + SceneObjectGroup so = SceneHelpers.AddSceneObject(m_tests.Scene); + + while (Ready) + { + UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; + + // Ensure unique text + string text = string.Format("{0:D2}{1}", Number, Pass); + + m_tests.Dtm.AddDynamicTextureData( + m_tests.Scene.RegionInfo.RegionID, + so.UUID, + m_tests.Vrm.GetContentType(), + string.Format("PenColour BLACK; MoveTo 40,220; FontSize 32; Text {0};", text), + "", + 0); + + Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); + + Pass++; + } + } + } + } +} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index 1765899..d9c1607 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3250,6 +3250,46 @@ + + + + ../../../bin/ + + + + + ../../../bin/ + + + + ../../../bin/ + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.1 From adce58b33a39c9456468f6d25834a8a7bded5adf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 29 Aug 2012 23:19:21 +0100 Subject: Renaming existing 'torture' tests to 'performance' tests instead, since this better matches what they really do. nant target name changes to test-perf instead of torture, to match test-stress still not run by default --- .nant/local.include | 8 +- OpenSim/Tests/Performance/NPCPerformanceTests.cs | 190 +++++++++++++++++++++ .../Tests/Performance/ObjectPerformanceTests.cs | 175 +++++++++++++++++++ .../Tests/Performance/ScriptPerformanceTests.cs | 168 ++++++++++++++++++ OpenSim/Tests/Torture/NPCTortureTests.cs | 190 --------------------- OpenSim/Tests/Torture/ObjectTortureTests.cs | 175 ------------------- OpenSim/Tests/Torture/ScriptTortureTests.cs | 168 ------------------ prebuild.xml | 2 +- 8 files changed, 538 insertions(+), 538 deletions(-) create mode 100644 OpenSim/Tests/Performance/NPCPerformanceTests.cs create mode 100644 OpenSim/Tests/Performance/ObjectPerformanceTests.cs create mode 100644 OpenSim/Tests/Performance/ScriptPerformanceTests.cs delete mode 100644 OpenSim/Tests/Torture/NPCTortureTests.cs delete mode 100644 OpenSim/Tests/Torture/ObjectTortureTests.cs delete mode 100644 OpenSim/Tests/Torture/ScriptTortureTests.cs diff --git a/.nant/local.include b/.nant/local.include index 181c875..35f0058 100644 --- a/.nant/local.include +++ b/.nant/local.include @@ -146,14 +146,14 @@ - + - - + + - + diff --git a/OpenSim/Tests/Performance/NPCPerformanceTests.cs b/OpenSim/Tests/Performance/NPCPerformanceTests.cs new file mode 100644 index 0000000..627765b --- /dev/null +++ b/OpenSim/Tests/Performance/NPCPerformanceTests.cs @@ -0,0 +1,190 @@ +/* + * 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.Diagnostics; +using System.Reflection; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.CoreModules.Avatar.Attachments; +using OpenSim.Region.CoreModules.Avatar.AvatarFactory; +using OpenSim.Region.CoreModules.Framework.InventoryAccess; +using OpenSim.Region.CoreModules.Framework.UserManagement; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.OptionalModules.World.NPC; +using OpenSim.Services.AvatarService; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Tests.Performance +{ + /// + /// NPC performance tests + /// + /// + /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, + /// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller + /// earlier tests. + /// + [TestFixture] + public class NPCPerformanceTests + { + private TestScene scene; + private AvatarFactoryModule afm; + private UserManagementModule umm; + private AttachmentsModule am; + + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + Util.FireAndForgetMethod = FireAndForgetMethod.None; + } + + [TestFixtureTearDown] + public void TearDown() + { + scene.Close(); + scene = null; + GC.Collect(); + GC.WaitForPendingFinalizers(); + + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten not to worry about such things. + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + [SetUp] + public void Init() + { + IConfigSource config = new IniConfigSource(); + config.AddConfig("NPC"); + config.Configs["NPC"].Set("Enabled", "true"); + config.AddConfig("Modules"); + config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); + + afm = new AvatarFactoryModule(); + umm = new UserManagementModule(); + am = new AttachmentsModule(); + + scene = new SceneHelpers().SetupScene(); + SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule()); + } + + [Test] + public void Test_0001_AddRemove100NPCs() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddRemoveNPCs(100); + } + + [Test] + public void Test_0002_AddRemove1000NPCs() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddRemoveNPCs(1000); + } + + [Test] + public void Test_0003_AddRemove2000NPCs() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddRemoveNPCs(2000); + } + + private void TestAddRemoveNPCs(int numberOfNpcs) + { + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); +// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); + + // 8 is the index of the first baked texture in AvatarAppearance + UUID originalFace8TextureId = TestHelpers.ParseTail(0x10); + Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); + Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); + originalTef.TextureID = originalFace8TextureId; + + // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell + // ScenePresence.SendInitialData() to reset our entire appearance. + scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); + + afm.SetAppearance(sp, originalTe, null); + + INPCModule npcModule = scene.RequestModuleInterface(); + + List npcs = new List(); + + long startGcMemory = GC.GetTotalMemory(true); + Stopwatch sw = new Stopwatch(); + sw.Start(); + + for (int i = 0; i < numberOfNpcs; i++) + { + npcs.Add( + npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance)); + } + + for (int i = 0; i < numberOfNpcs; i++) + { + Assert.That(npcs[i], Is.Not.Null); + + ScenePresence npc = scene.GetScenePresence(npcs[i]); + Assert.That(npc, Is.Not.Null); + } + + for (int i = 0; i < numberOfNpcs; i++) + { + Assert.That(npcModule.DeleteNPC(npcs[i], scene), Is.True); + ScenePresence npc = scene.GetScenePresence(npcs[i]); + Assert.That(npc, Is.Null); + } + + sw.Stop(); + + long endGcMemory = GC.GetTotalMemory(true); + + Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds); + Console.WriteLine( + "End {0} MB, Start {1} MB, Diff {2} MB", + endGcMemory / 1024 / 1024, + startGcMemory / 1024 / 1024, + (endGcMemory - startGcMemory) / 1024 / 1024); + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Performance/ObjectPerformanceTests.cs b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs new file mode 100644 index 0000000..2264d86 --- /dev/null +++ b/OpenSim/Tests/Performance/ObjectPerformanceTests.cs @@ -0,0 +1,175 @@ +/* + * 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.Diagnostics; +using System.Reflection; +using log4net; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Tests.Performance +{ + /// + /// Object performance tests + /// + /// + /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, + /// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller + /// earlier tests. + /// + [TestFixture] + public class ObjectPerformanceTests + { + [TearDown] + public void TearDown() + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + +// [Test] +// public void Test0000Clean() +// { +// TestHelpers.InMethod(); +//// log4net.Config.XmlConfigurator.Configure(); +// +// TestAddObjects(200000); +// } + + [Test] + public void Test_0001_10K_1PrimObjects() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddObjects(1, 10000); + } + + [Test] + public void Test_0002_100K_1PrimObjects() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddObjects(1, 100000); + } + + [Test] + public void Test_0003_200K_1PrimObjects() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddObjects(1, 200000); + } + + [Test] + public void Test_0011_100_100PrimObjects() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddObjects(100, 100); + } + + [Test] + public void Test_0012_1K_100PrimObjects() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddObjects(100, 1000); + } + + [Test] + public void Test_0013_2K_100PrimObjects() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + TestAddObjects(100, 2000); + } + + private void TestAddObjects(int primsInEachObject, int objectsToAdd) + { + UUID ownerId = new UUID("F0000000-0000-0000-0000-000000000000"); + + // Using a local variable for scene, at least on mono 2.6.7, means that it's much more likely to be garbage + // collected when we teardown this test. If it's done in a member variable, even if that is subsequently + // nulled out, the garbage collect can be delayed. + TestScene scene = new SceneHelpers().SetupScene(); + +// Process process = Process.GetCurrentProcess(); +// long startProcessMemory = process.PrivateMemorySize64; + long startGcMemory = GC.GetTotalMemory(true); + DateTime start = DateTime.Now; + + for (int i = 1; i <= objectsToAdd; i++) + { + SceneObjectGroup so = SceneHelpers.CreateSceneObject(primsInEachObject, ownerId, "part_", i); + Assert.That(scene.AddNewSceneObject(so, false), Is.True, string.Format("Object {0} was not created", i)); + } + + TimeSpan elapsed = DateTime.Now - start; +// long processMemoryAlloc = process.PrivateMemorySize64 - startProcessMemory; + long endGcMemory = GC.GetTotalMemory(false); + + for (int i = 1; i <= objectsToAdd; i++) + { + Assert.That( + scene.GetSceneObjectGroup(TestHelpers.ParseTail(i)), + Is.Not.Null, + string.Format("Object {0} could not be retrieved", i)); + } + + // When a scene object is added to a scene, it is placed in the update list for sending to viewers + // (though in this case we have none). When it is deleted, it is not removed from the update which is + // fine since it will later be ignored. + // + // However, that means that we need to manually run an update here to clear out that list so that deleted + // objects will be clean up by the garbage collector before the next stress test is run. + scene.Update(1); + + Console.WriteLine( + "Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)", + Math.Round(elapsed.TotalMilliseconds), + (endGcMemory - startGcMemory) / 1024 / 1024, + endGcMemory / 1024 / 1024, + startGcMemory / 1024 / 1024, + objectsToAdd, + primsInEachObject); + + scene.Close(); +// scene = null; + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Performance/ScriptPerformanceTests.cs b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs new file mode 100644 index 0000000..d708abd --- /dev/null +++ b/OpenSim/Tests/Performance/ScriptPerformanceTests.cs @@ -0,0 +1,168 @@ +/* + * 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.Diagnostics; +using System.Reflection; +using System.Threading; +using log4net; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Scripting.WorldComm; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.XEngine; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Tests.Performance +{ + /// + /// Script performance tests + /// + /// + /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, + /// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller + /// earlier tests. + /// + [TestFixture] + public class ScriptPerformanceTests + { + private TestScene m_scene; + private XEngine m_xEngine; + private AutoResetEvent m_chatEvent = new AutoResetEvent(false); + + private int m_expectedChatMessages; + private List m_osChatMessagesReceived = new List(); + + [SetUp] + public void Init() + { + //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); +// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); + m_xEngine = new XEngine(); + + // Necessary to stop serialization complaining + WorldCommModule wcModule = new WorldCommModule(); + + IniConfigSource configSource = new IniConfigSource(); + + IConfig startupConfig = configSource.AddConfig("Startup"); + startupConfig.Set("DefaultScriptEngine", "XEngine"); + + IConfig xEngineConfig = configSource.AddConfig("XEngine"); + xEngineConfig.Set("Enabled", "true"); + + // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call + // to AssemblyResolver.OnAssemblyResolve fails. + xEngineConfig.Set("AppDomainLoading", "false"); + + m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); + SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule); + + m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; + m_scene.StartScripts(); + } + + [TearDown] + public void TearDown() + { + m_scene.Close(); + m_scene = null; + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + + [Test] + public void TestCompileAndStart100Scripts() + { + TestHelpers.InMethod(); + log4net.Config.XmlConfigurator.Configure(); + + TestCompileAndStartScripts(100); + } + + private void TestCompileAndStartScripts(int scriptsToCreate) + { + UUID userId = TestHelpers.ParseTail(0x1); + + m_expectedChatMessages = scriptsToCreate; + int startingObjectIdTail = 0x100; + + GC.Collect(); + + for (int idTail = startingObjectIdTail;idTail < startingObjectIdTail + scriptsToCreate; idTail++) + { + AddObjectAndScript(idTail, userId); + } + + m_chatEvent.WaitOne(40000 + scriptsToCreate * 1000); + + Assert.That(m_osChatMessagesReceived.Count, Is.EqualTo(m_expectedChatMessages)); + + foreach (OSChatMessage msg in m_osChatMessagesReceived) + Assert.That( + msg.Message, + Is.EqualTo("Script running"), + string.Format( + "Message from {0} was {1} rather than {2}", msg.SenderUUID, msg.Message, "Script running")); + } + + private void AddObjectAndScript(int objectIdTail, UUID userId) + { +// UUID itemId = TestHelpers.ParseTail(0x3); + string itemName = string.Format("AddObjectAndScript() Item for object {0}", objectIdTail); + + SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "AddObjectAndScriptPart_", objectIdTail); + m_scene.AddNewSceneObject(so, true); + + InventoryItemBase itemTemplate = new InventoryItemBase(); +// itemTemplate.ID = itemId; + itemTemplate.Name = itemName; + itemTemplate.Folder = so.UUID; + itemTemplate.InvType = (int)InventoryType.LSL; + + m_scene.RezNewScript(userId, itemTemplate); + } + + private void OnChatFromWorld(object sender, OSChatMessage oscm) + { +// Console.WriteLine("Got chat [{0}]", oscm.Message); + + lock (m_osChatMessagesReceived) + { + m_osChatMessagesReceived.Add(oscm); + + if (m_osChatMessagesReceived.Count == m_expectedChatMessages) + m_chatEvent.Set(); + } + } + } +} \ No newline at end of file diff --git a/OpenSim/Tests/Torture/NPCTortureTests.cs b/OpenSim/Tests/Torture/NPCTortureTests.cs deleted file mode 100644 index 731df68..0000000 --- a/OpenSim/Tests/Torture/NPCTortureTests.cs +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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.Diagnostics; -using System.Reflection; -using log4net; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.CoreModules.Avatar.Attachments; -using OpenSim.Region.CoreModules.Avatar.AvatarFactory; -using OpenSim.Region.CoreModules.Framework.InventoryAccess; -using OpenSim.Region.CoreModules.Framework.UserManagement; -using OpenSim.Region.CoreModules.ServiceConnectorsOut.Avatar; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.OptionalModules.World.NPC; -using OpenSim.Services.AvatarService; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Tests.Torture -{ - /// - /// NPC torture tests - /// - /// - /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, - /// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller - /// earlier tests. - /// - [TestFixture] - public class NPCTortureTests - { - private TestScene scene; - private AvatarFactoryModule afm; - private UserManagementModule umm; - private AttachmentsModule am; - - [TestFixtureSetUp] - public void FixtureInit() - { - // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. - Util.FireAndForgetMethod = FireAndForgetMethod.None; - } - - [TestFixtureTearDown] - public void TearDown() - { - scene.Close(); - scene = null; - GC.Collect(); - GC.WaitForPendingFinalizers(); - - // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple - // threads. Possibly, later tests should be rewritten not to worry about such things. - Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; - } - - [SetUp] - public void Init() - { - IConfigSource config = new IniConfigSource(); - config.AddConfig("NPC"); - config.Configs["NPC"].Set("Enabled", "true"); - config.AddConfig("Modules"); - config.Configs["Modules"].Set("InventoryAccessModule", "BasicInventoryAccessModule"); - - afm = new AvatarFactoryModule(); - umm = new UserManagementModule(); - am = new AttachmentsModule(); - - scene = new SceneHelpers().SetupScene(); - SceneHelpers.SetupSceneModules(scene, config, afm, umm, am, new BasicInventoryAccessModule(), new NPCModule()); - } - - [Test] - public void Test_0001_AddRemove100NPCs() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddRemoveNPCs(100); - } - - [Test] - public void Test_0002_AddRemove1000NPCs() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddRemoveNPCs(1000); - } - - [Test] - public void Test_0003_AddRemove2000NPCs() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddRemoveNPCs(2000); - } - - private void TestAddRemoveNPCs(int numberOfNpcs) - { - ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); -// ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); - - // 8 is the index of the first baked texture in AvatarAppearance - UUID originalFace8TextureId = TestHelpers.ParseTail(0x10); - Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); - Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); - originalTef.TextureID = originalFace8TextureId; - - // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell - // ScenePresence.SendInitialData() to reset our entire appearance. - scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); - - afm.SetAppearance(sp, originalTe, null); - - INPCModule npcModule = scene.RequestModuleInterface(); - - List npcs = new List(); - - long startGcMemory = GC.GetTotalMemory(true); - Stopwatch sw = new Stopwatch(); - sw.Start(); - - for (int i = 0; i < numberOfNpcs; i++) - { - npcs.Add( - npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance)); - } - - for (int i = 0; i < numberOfNpcs; i++) - { - Assert.That(npcs[i], Is.Not.Null); - - ScenePresence npc = scene.GetScenePresence(npcs[i]); - Assert.That(npc, Is.Not.Null); - } - - for (int i = 0; i < numberOfNpcs; i++) - { - Assert.That(npcModule.DeleteNPC(npcs[i], scene), Is.True); - ScenePresence npc = scene.GetScenePresence(npcs[i]); - Assert.That(npc, Is.Null); - } - - sw.Stop(); - - long endGcMemory = GC.GetTotalMemory(true); - - Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds); - Console.WriteLine( - "End {0} MB, Start {1} MB, Diff {2} MB", - endGcMemory / 1024 / 1024, - startGcMemory / 1024 / 1024, - (endGcMemory - startGcMemory) / 1024 / 1024); - } - } -} \ No newline at end of file diff --git a/OpenSim/Tests/Torture/ObjectTortureTests.cs b/OpenSim/Tests/Torture/ObjectTortureTests.cs deleted file mode 100644 index 195d47b..0000000 --- a/OpenSim/Tests/Torture/ObjectTortureTests.cs +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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.Diagnostics; -using System.Reflection; -using log4net; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Tests.Torture -{ - /// - /// Object torture tests - /// - /// - /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, - /// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller - /// earlier tests. - /// - [TestFixture] - public class ObjectTortureTests - { - [TearDown] - public void TearDown() - { - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - -// [Test] -// public void Test0000Clean() -// { -// TestHelpers.InMethod(); -//// log4net.Config.XmlConfigurator.Configure(); -// -// TestAddObjects(200000); -// } - - [Test] - public void Test_0001_10K_1PrimObjects() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddObjects(1, 10000); - } - - [Test] - public void Test_0002_100K_1PrimObjects() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddObjects(1, 100000); - } - - [Test] - public void Test_0003_200K_1PrimObjects() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddObjects(1, 200000); - } - - [Test] - public void Test_0011_100_100PrimObjects() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddObjects(100, 100); - } - - [Test] - public void Test_0012_1K_100PrimObjects() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddObjects(100, 1000); - } - - [Test] - public void Test_0013_2K_100PrimObjects() - { - TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); - - TestAddObjects(100, 2000); - } - - private void TestAddObjects(int primsInEachObject, int objectsToAdd) - { - UUID ownerId = new UUID("F0000000-0000-0000-0000-000000000000"); - - // Using a local variable for scene, at least on mono 2.6.7, means that it's much more likely to be garbage - // collected when we teardown this test. If it's done in a member variable, even if that is subsequently - // nulled out, the garbage collect can be delayed. - TestScene scene = new SceneHelpers().SetupScene(); - -// Process process = Process.GetCurrentProcess(); -// long startProcessMemory = process.PrivateMemorySize64; - long startGcMemory = GC.GetTotalMemory(true); - DateTime start = DateTime.Now; - - for (int i = 1; i <= objectsToAdd; i++) - { - SceneObjectGroup so = SceneHelpers.CreateSceneObject(primsInEachObject, ownerId, "part_", i); - Assert.That(scene.AddNewSceneObject(so, false), Is.True, string.Format("Object {0} was not created", i)); - } - - TimeSpan elapsed = DateTime.Now - start; -// long processMemoryAlloc = process.PrivateMemorySize64 - startProcessMemory; - long endGcMemory = GC.GetTotalMemory(false); - - for (int i = 1; i <= objectsToAdd; i++) - { - Assert.That( - scene.GetSceneObjectGroup(TestHelpers.ParseTail(i)), - Is.Not.Null, - string.Format("Object {0} could not be retrieved", i)); - } - - // When a scene object is added to a scene, it is placed in the update list for sending to viewers - // (though in this case we have none). When it is deleted, it is not removed from the update which is - // fine since it will later be ignored. - // - // However, that means that we need to manually run an update here to clear out that list so that deleted - // objects will be clean up by the garbage collector before the next stress test is run. - scene.Update(1); - - Console.WriteLine( - "Took {0}ms, {1}MB ({2} - {3}) to create {4} objects each containing {5} prim(s)", - Math.Round(elapsed.TotalMilliseconds), - (endGcMemory - startGcMemory) / 1024 / 1024, - endGcMemory / 1024 / 1024, - startGcMemory / 1024 / 1024, - objectsToAdd, - primsInEachObject); - - scene.Close(); -// scene = null; - } - } -} \ No newline at end of file diff --git a/OpenSim/Tests/Torture/ScriptTortureTests.cs b/OpenSim/Tests/Torture/ScriptTortureTests.cs deleted file mode 100644 index 24f278f..0000000 --- a/OpenSim/Tests/Torture/ScriptTortureTests.cs +++ /dev/null @@ -1,168 +0,0 @@ -/* - * 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.Diagnostics; -using System.Reflection; -using System.Threading; -using log4net; -using Nini.Config; -using NUnit.Framework; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Scripting.WorldComm; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.ScriptEngine.XEngine; -using OpenSim.Tests.Common; -using OpenSim.Tests.Common.Mock; - -namespace OpenSim.Tests.Torture -{ - /// - /// Script torture tests - /// - /// - /// Don't rely on the numbers given by these tests - they will vary a lot depending on what is already cached, - /// how much memory is free, etc. In some cases, later larger tests will apparently take less time than smaller - /// earlier tests. - /// - [TestFixture] - public class ScriptTortureTests - { - private TestScene m_scene; - private XEngine m_xEngine; - private AutoResetEvent m_chatEvent = new AutoResetEvent(false); - - private int m_expectedChatMessages; - private List m_osChatMessagesReceived = new List(); - - [SetUp] - public void Init() - { - //AppDomain.CurrentDomain.SetData("APPBASE", Environment.CurrentDirectory + "/bin"); -// Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); - m_xEngine = new XEngine(); - - // Necessary to stop serialization complaining - WorldCommModule wcModule = new WorldCommModule(); - - IniConfigSource configSource = new IniConfigSource(); - - IConfig startupConfig = configSource.AddConfig("Startup"); - startupConfig.Set("DefaultScriptEngine", "XEngine"); - - IConfig xEngineConfig = configSource.AddConfig("XEngine"); - xEngineConfig.Set("Enabled", "true"); - - // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call - // to AssemblyResolver.OnAssemblyResolve fails. - xEngineConfig.Set("AppDomainLoading", "false"); - - m_scene = new SceneHelpers().SetupScene("My Test", UUID.Random(), 1000, 1000, configSource); - SceneHelpers.SetupSceneModules(m_scene, configSource, m_xEngine, wcModule); - - m_scene.EventManager.OnChatFromWorld += OnChatFromWorld; - m_scene.StartScripts(); - } - - [TearDown] - public void TearDown() - { - m_scene.Close(); - m_scene = null; - GC.Collect(); - GC.WaitForPendingFinalizers(); - } - - [Test] - public void TestCompileAndStart100Scripts() - { - TestHelpers.InMethod(); - log4net.Config.XmlConfigurator.Configure(); - - TestCompileAndStartScripts(100); - } - - private void TestCompileAndStartScripts(int scriptsToCreate) - { - UUID userId = TestHelpers.ParseTail(0x1); - - m_expectedChatMessages = scriptsToCreate; - int startingObjectIdTail = 0x100; - - GC.Collect(); - - for (int idTail = startingObjectIdTail;idTail < startingObjectIdTail + scriptsToCreate; idTail++) - { - AddObjectAndScript(idTail, userId); - } - - m_chatEvent.WaitOne(40000 + scriptsToCreate * 1000); - - Assert.That(m_osChatMessagesReceived.Count, Is.EqualTo(m_expectedChatMessages)); - - foreach (OSChatMessage msg in m_osChatMessagesReceived) - Assert.That( - msg.Message, - Is.EqualTo("Script running"), - string.Format( - "Message from {0} was {1} rather than {2}", msg.SenderUUID, msg.Message, "Script running")); - } - - private void AddObjectAndScript(int objectIdTail, UUID userId) - { -// UUID itemId = TestHelpers.ParseTail(0x3); - string itemName = string.Format("AddObjectAndScript() Item for object {0}", objectIdTail); - - SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId, "AddObjectAndScriptPart_", objectIdTail); - m_scene.AddNewSceneObject(so, true); - - InventoryItemBase itemTemplate = new InventoryItemBase(); -// itemTemplate.ID = itemId; - itemTemplate.Name = itemName; - itemTemplate.Folder = so.UUID; - itemTemplate.InvType = (int)InventoryType.LSL; - - m_scene.RezNewScript(userId, itemTemplate); - } - - private void OnChatFromWorld(object sender, OSChatMessage oscm) - { -// Console.WriteLine("Got chat [{0}]", oscm.Message); - - lock (m_osChatMessagesReceived) - { - m_osChatMessagesReceived.Add(oscm); - - if (m_osChatMessagesReceived.Count == m_expectedChatMessages) - m_chatEvent.Set(); - } - } - } -} \ No newline at end of file diff --git a/prebuild.xml b/prebuild.xml index d9c1607..0f34713 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3290,7 +3290,7 @@ - + ../../../bin/ -- cgit v1.1 From 6b277394c080f5ad50d07e94f3e21340da4913b3 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Wed, 29 Aug 2012 17:21:01 +0100 Subject: refactoring as the list funcs either skip invalid values or recall ToDoubleList --- .../Shared/Api/Implementation/LSL_Api.cs | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ae92716..45286c0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10119,31 +10119,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Float llListStatistics(int operation, LSL_List src) { m_host.AddScriptLPS(1); - LSL_List nums = LSL_List.ToDoubleList(src); switch (operation) { case ScriptBaseClass.LIST_STAT_RANGE: - return nums.Range(); + return src.Range(); case ScriptBaseClass.LIST_STAT_MIN: - return nums.Min(); + return src.Min(); case ScriptBaseClass.LIST_STAT_MAX: - return nums.Max(); + return src.Max(); case ScriptBaseClass.LIST_STAT_MEAN: - return nums.Mean(); + return src.Mean(); case ScriptBaseClass.LIST_STAT_MEDIAN: - return nums.Median(); + return LSL_List.ToDoubleList(src).Median(); case ScriptBaseClass.LIST_STAT_NUM_COUNT: - return nums.NumericLength(); + return src.NumericLength(); case ScriptBaseClass.LIST_STAT_STD_DEV: - return nums.StdDev(); + return src.StdDev(); case ScriptBaseClass.LIST_STAT_SUM: - return nums.Sum(); + return src.Sum(); case ScriptBaseClass.LIST_STAT_SUM_SQUARES: - return nums.SumSqrs(); + return src.SumSqrs(); case ScriptBaseClass.LIST_STAT_GEOMETRIC_MEAN: - return nums.GeometricMean(); + return src.GeometricMean(); case ScriptBaseClass.LIST_STAT_HARMONIC_MEAN: - return nums.HarmonicMean(); + return src.HarmonicMean(); default: return 0.0; } -- cgit v1.1 From c76c63725bedb1f7e22dba23d3a8034885ff60e5 Mon Sep 17 00:00:00 2001 From: SignpostMarv Date: Wed, 29 Aug 2012 17:21:16 +0100 Subject: fixing bug where last element in list is ignored --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 9d9df9c..fcb98a5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -1137,7 +1137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared { list ret = new list(); double entry; - for (int i = 0; i < src.Data.Length - 1; i++) + for (int i = 0; i < src.Data.Length; i++) { if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) { -- cgit v1.1 From d89b974680af52a2d950237962240dde82ff4a85 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 30 Aug 2012 22:28:45 +0100 Subject: If the compile-time DynamicTextureModule.ReuseTextures flag is set, check metadata still exists for any reused asset in case some other process has removed it from the cache. --- .../DynamicTexture/DynamicTextureModule.cs | 102 ++++++++++++--------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 13b7498..f169117 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -186,63 +186,79 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) { - 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; + if (!RenderPlugins.ContainsKey(contentType)) + return UUID.Zero; - DynamicTextureUpdater updater = new DynamicTextureUpdater(); - updater.SimUUID = simID; - updater.PrimID = primID; - updater.ContentType = contentType; - updater.BodyData = data; - updater.UpdateTimer = updateTimer; - updater.UpdaterID = UUID.Random(); - updater.Params = extraParams; - updater.BlendWithOldTexture = SetBlending; - updater.FrontAlpha = AlphaValue; - updater.Face = face; - updater.Url = "Local image"; - updater.Disp = disp; + Scene scene; + RegisteredScenes.TryGetValue(simID, out scene); + + if (scene == null) + return UUID.Zero; - object reusableTextureUUID = null; + SceneObjectPart part = scene.GetSceneObjectPart(primID); - if (ReuseTextures) - reusableTextureUUID - = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams)); + if (part == null) + return UUID.Zero; + + // 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; + updater.ContentType = contentType; + updater.BodyData = data; + updater.UpdateTimer = updateTimer; + updater.UpdaterID = UUID.Random(); + updater.Params = extraParams; + updater.BlendWithOldTexture = SetBlending; + updater.FrontAlpha = AlphaValue; + updater.Face = face; + updater.Url = "Local image"; + updater.Disp = disp; + + object objReusableTextureUUID = null; + + if (ReuseTextures && !updater.BlendWithOldTexture) + { + string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams); + objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey); - // We cannot reuse a dynamic texture if the data is going to be blended with something already there. - if (reusableTextureUUID == null || updater.BlendWithOldTexture) + if (objReusableTextureUUID != null) { - lock (Updaters) + // If something else has removed this temporary asset from the cache, detect and invalidate + // our cached uuid. + if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null) { - if (!Updaters.ContainsKey(updater.UpdaterID)) - { - Updaters.Add(updater.UpdaterID, updater); - } + m_reuseableDynamicTextures.Invalidate(reuseableTextureKey); + objReusableTextureUUID = null; } - - RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); } - else + } + + // We cannot reuse a dynamic texture if the data is going to be blended with something already there. + if (objReusableTextureUUID == null) + { + lock (Updaters) { - // 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)) + if (!Updaters.ContainsKey(updater.UpdaterID)) { - SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID); - - if (part != null) - updater.UpdatePart(part, (UUID)reusableTextureUUID); + Updaters.Add(updater.UpdaterID, updater); } } - return updater.UpdaterID; + RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); } - - return UUID.Zero; + else + { + // No need to add to updaters as the texture is always the same. Not that this functionality + // apppears to be implemented anyway. + updater.UpdatePart(part, (UUID)objReusableTextureUUID); + } + + return updater.UpdaterID; } private string GenerateReusableTextureKey(string data, string extraParams) -- cgit v1.1 From 3ed0d79b00c313eacb2a7df7d5519e840d2fc5c4 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 30 Aug 2012 22:57:40 +0100 Subject: Make ReuseDynamicTextures an experimental config setting in [Textures]. Default is false, as before. If true, this setting reuses dynamically generated textures (i.e. created through osSetDynamicTextureData() and similar OSSL functions) where possible rather than always regenerating them. This results in much quicker updates viewer-side but may bloat the asset cache (though this is fixable). Also, sometimes issue have been seen where dynamic textures do not transfer to the viewer properly (permanently blurry). If this happens and that flag is set then they are not regenerated, the viewer has to clear cache or wait for 24 hours before all cached uuids are invalidated. CUrrently experimental. Default is false, as before. --- .../Scripting/DynamicTexture/DynamicTextureModule.cs | 5 ++++- bin/OpenSimDefaults.ini | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index f169117..3eedf49 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -283,6 +283,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public void Initialise(Scene scene, IConfigSource config) { + IConfig texturesConfig = config.Configs["Textures"]; + if (texturesConfig != null) + ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false); + if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { RegisteredScenes.Add(scene.RegionInfo.RegionID, scene); @@ -292,7 +296,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture public void PostInitialise() { -// ReuseTextures = true; if (ReuseTextures) { m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative); diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index b2fca0c..42b295f 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -693,6 +693,17 @@ ;LevelUpload = 0 +[Textures] + ; If true, textures generated dynamically (i.e. through osSetDynamicTextureData() and similar OSSL functions) are reused where possible + ; Chiefly, reuse occurs if a texture has already been generated with identical data and settings, and that texture contains no dynamic components + ; (e.g. images pulled from an external HTTP address). + ; Reusing previously generated textures results in a much faster update on the viewer but may cause issues if the viewer didn't receive all resolutions of the texture. + ; Currently, it will also increase asset cache use since temporary dynamic textures are no longer deleted. + ; Hence, currently considered experimental. + ; Default is false. + ReuseDynamicTextures = false + + [ODEPhysicsSettings] ; ## ; ## Physics stats settings -- cgit v1.1 From 7c6e8fab155ff24d460e8de4597531849c291957 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 31 Aug 2012 00:29:57 +0100 Subject: Do Windlight storage and removal calls in MySQL under m_dbLock, as is done with all the other database calls. --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 210 +++++++++++++++--------------- 1 file changed, 108 insertions(+), 102 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index 3fc04ee..a021590 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -853,118 +853,124 @@ namespace OpenSim.Data.MySQL public void StoreRegionWindlightSettings(RegionLightShareData wl) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; - cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; - cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; - cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; - cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; - cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; - cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; - cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; - cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; - cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; - cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; - cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; - cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; - cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; - cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; - cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; - cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; - cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; - cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; - cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; - cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; - cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; - cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; - cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; - cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; - - cmd.Parameters.AddWithValue("region_id", wl.regionID); - cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); - cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); - cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); - cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); - cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); - cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); - cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); - cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); - cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); - cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); - cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); - cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); - cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); - cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); - cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); - cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); - cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); - cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); - cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); - cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); - cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); - cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); - cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); - cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); - cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); - cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); - cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); - cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); - cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); - cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); - cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); - cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); - cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); - cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); - cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); - cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); - cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); - cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); - cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); - cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); - cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); - cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); - cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); - cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); - cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); - cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); - cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); - cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); - cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); - cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); - cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); - cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); - cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); - cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); - cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); - cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); - cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); - cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); - cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); - cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); - - ExecuteNonQuery(cmd); + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; + cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; + cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; + cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; + cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; + cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; + cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; + cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; + cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; + cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; + cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; + cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; + cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; + cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; + cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; + cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; + cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; + cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; + cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; + cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; + cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; + cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; + cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; + cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; + cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; + + cmd.Parameters.AddWithValue("region_id", wl.regionID); + cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); + cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); + cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); + cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); + cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); + cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); + cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); + cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); + cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); + cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); + cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); + cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); + cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); + cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); + cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); + cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); + cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); + cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); + cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); + cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); + cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); + cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); + cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); + cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); + cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); + cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); + cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); + cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); + cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); + cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); + cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); + cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); + cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); + cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); + cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); + cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); + cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); + cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); + cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); + cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); + cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); + cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); + cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); + cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); + cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); + cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); + cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); + cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); + cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); + cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); + cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); + cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); + cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); + cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); + cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); + cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); + cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); + cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); + cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); + + ExecuteNonQuery(cmd); + } } } } public void RemoveRegionWindlightSettings(UUID regionID) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; - cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); - ExecuteNonQuery(cmd); + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from `regionwindlight` where `region_id`=?regionID"; + cmd.Parameters.AddWithValue("?regionID", regionID.ToString()); + ExecuteNonQuery(cmd); + } } } } -- cgit v1.1 From 3bd3f448a2d5b64b267427a0f8f820109338a7bb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 31 Aug 2012 00:33:06 +0100 Subject: Also do other MySQL region settings related calls under m_dbLock, in common with other calls. --- OpenSim/Data/MySQL/MySQLSimulationData.cs | 247 ++++++++++++++++-------------- 1 file changed, 130 insertions(+), 117 deletions(-) diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs index a021590..d562783 100644 --- a/OpenSim/Data/MySQL/MySQLSimulationData.cs +++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs @@ -719,95 +719,99 @@ namespace OpenSim.Data.MySQL RegionLightShareData nWP = new RegionLightShareData(); nWP.OnSave += StoreRegionWindlightSettings; - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - string command = "select * from `regionwindlight` where region_id = ?regionID"; - - using (MySqlCommand cmd = new MySqlCommand(command)) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Connection = dbcon; - - cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); - - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) - { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; - StoreRegionWindlightSettings(nWP); - return nWP; - } - else + dbcon.Open(); + + string command = "select * from `regionwindlight` where region_id = ?regionID"; + + using (MySqlCommand cmd = new MySqlCommand(command)) { - nWP.regionID = DBGuid.FromDB(result["region_id"]); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); - nWP.valid = true; + cmd.Connection = dbcon; + + cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); + + IDataReader result = ExecuteReader(cmd); + if (!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; + StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + nWP.regionID = DBGuid.FromDB(result["region_id"]); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + nWP.valid = true; + } } } } + return nWP; } @@ -978,26 +982,29 @@ namespace OpenSim.Data.MySQL #region RegionEnvironmentSettings public string LoadRegionEnvironmentSettings(UUID regionUUID) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - string command = "select * from `regionenvironment` where region_id = ?region_id"; - - using (MySqlCommand cmd = new MySqlCommand(command)) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.Connection = dbcon; - - cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); - - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) - { - return String.Empty; - } - else + dbcon.Open(); + + string command = "select * from `regionenvironment` where region_id = ?region_id"; + + using (MySqlCommand cmd = new MySqlCommand(command)) { - return Convert.ToString(result["llsd_settings"]); + cmd.Connection = dbcon; + + cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); + + IDataReader result = ExecuteReader(cmd); + if (!result.Read()) + { + return String.Empty; + } + else + { + return Convert.ToString(result["llsd_settings"]); + } } } } @@ -1005,33 +1012,39 @@ namespace OpenSim.Data.MySQL public void StoreRegionEnvironmentSettings(UUID regionUUID, string settings) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; - - cmd.Parameters.AddWithValue("region_id", regionUUID); - cmd.Parameters.AddWithValue("llsd_settings", settings); - - ExecuteNonQuery(cmd); + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "REPLACE INTO `regionenvironment` (`region_id`, `llsd_settings`) VALUES (?region_id, ?llsd_settings)"; + + cmd.Parameters.AddWithValue("region_id", regionUUID); + cmd.Parameters.AddWithValue("llsd_settings", settings); + + ExecuteNonQuery(cmd); + } } } } public void RemoveRegionEnvironmentSettings(UUID regionUUID) { - using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + lock (m_dbLock) { - dbcon.Open(); - - using (MySqlCommand cmd = dbcon.CreateCommand()) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; - cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); - ExecuteNonQuery(cmd); + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "delete from `regionenvironment` where region_id = ?region_id"; + cmd.Parameters.AddWithValue("?region_id", regionUUID.ToString()); + ExecuteNonQuery(cmd); + } } } } -- cgit v1.1 From 68814f904e1f0c5be961791f3f475dcda4a88248 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 31 Aug 2012 00:37:27 +0100 Subject: Replace SendBannedUserList with Avination's version. Untested in core. Not even test compiled. --- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 57 ++++++++++++---------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 148d0e0..d05ffea 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -4451,37 +4451,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (bl[i].BannedUserID == UUID.Zero) continue; BannedUsers.Add(bl[i].BannedUserID); - } - EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); - packet.AgentData.TransactionID = UUID.Random(); - packet.AgentData.AgentID = AgentId; - packet.AgentData.SessionID = SessionId; - packet.MethodData.Invoice = invoice; - packet.MethodData.Method = Utils.StringToBytes("setaccess"); + if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0)) + { + EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket(); + packet.AgentData.TransactionID = UUID.Random(); + packet.AgentData.AgentID = AgentId; + packet.AgentData.SessionID = SessionId; + packet.MethodData.Invoice = invoice; + packet.MethodData.Method = Utils.StringToBytes("setaccess"); - EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; + EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count]; - for (int i = 0; i < (6 + BannedUsers.Count); i++) - { - returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock(); - } - int j = 0; + int j; + for (j = 0; j < (6 + BannedUsers.Count); j++) + { + returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock(); + } + j = 0; - returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; - returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; - returnblock[j].Parameter = Utils.StringToBytes("0"); j++; - returnblock[j].Parameter = Utils.StringToBytes("0"); j++; - returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; - returnblock[j].Parameter = Utils.StringToBytes("0"); j++; + returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++; + returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++; + returnblock[j].Parameter = Utils.StringToBytes("0"); j++; + returnblock[j].Parameter = Utils.StringToBytes("0"); j++; + returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++; + returnblock[j].Parameter = Utils.StringToBytes("0"); j++; - foreach (UUID banned in BannedUsers) - { - returnblock[j].Parameter = banned.GetBytes(); j++; + foreach (UUID banned in BannedUsers) + { + returnblock[j].Parameter = banned.GetBytes(); j++; + } + packet.ParamList = returnblock; + packet.Header.Reliable = true; + OutPacket(packet, ThrottleOutPacketType.Task); + + BannedUsers.Clear(); + } } - packet.ParamList = returnblock; - packet.Header.Reliable = false; - OutPacket(packet, ThrottleOutPacketType.Task); + } public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args) -- cgit v1.1