From 1b156b7fe84bf132b51ff198d6d730708f5930b7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 19:18:24 +0100 Subject: Add regression test for in-range chat between neighbouring regions from east to west. --- .../Avatar/Chat/Tests/ChatModuleTests.cs | 158 +++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 5 +- .../BasicPhysicsPlugin/BasicPhysicsScene.cs | 1 + OpenSim/Tests/Common/Mock/TestClient.cs | 40 ++++++ prebuild.xml | 1 + 5 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs new file mode 100644 index 0000000..315cc19 --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs @@ -0,0 +1,158 @@ +/* + * 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 log4net.Config; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.CoreModules.Avatar.Chat; +using OpenSim.Region.CoreModules.Framework; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; +using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenSim.Tests.Common; +using OpenSim.Tests.Common.Mock; + +namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests +{ + [TestFixture] + public class ChatModuleTests : OpenSimTestCase + { + [TestFixtureSetUp] + public void FixtureInit() + { + // Don't allow tests to be bamboozled by asynchronous events. Execute everything on the same thread. + // We must do this here so that child agent positions are updated in a predictable manner. + Util.FireAndForgetMethod = FireAndForgetMethod.RegressionTest; + } + + [TestFixtureTearDown] + public void TearDown() + { + // We must set this back afterwards, otherwise later tests will fail since they're expecting multiple + // threads. Possibly, later tests should be rewritten so none of them require async stuff (which regression + // tests really shouldn't). + Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; + } + + /// + /// Tests chat between neighbour regions on the east-west axis + /// + /// + /// Really, this is a combination of a child agent position update test and a chat range test. These need + /// to be separated later on. + /// + [Test] + public void TestInterRegionChatDistanceEastWest() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + UUID sp1Uuid = TestHelpers.ParseTail(0x11); + UUID sp2Uuid = TestHelpers.ParseTail(0x12); + + Vector3 sp1Position = new Vector3(6, 128, 20); + Vector3 sp2Position = new Vector3(250, 128, 20); + + // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the + // CapabilitiesModule complain when it can't set up HTTP endpoints. +// BaseHttpServer httpServer = new BaseHttpServer(99999); +// MainServer.AddHttpServer(httpServer); +// MainServer.Instance = httpServer; + + // We need entity transfer modules so that when sp2 logs into the east region, the region calls + // EntityTransferModuleto set up a child agent on the west region. + // XXX: However, this is not an entity transfer so is misleading. + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Chat"); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etmA.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + + SceneHelpers sh = new SceneHelpers(); + + TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000); + TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000); + SceneHelpers.SetupSceneModules(new Scene[] { sceneWest, sceneEast }, config, lscm); + + SceneHelpers.SetupSceneModules(sceneWest, config, new CapabilitiesModule(), etmA, new ChatModule()); + SceneHelpers.SetupSceneModules(sceneEast, config, new CapabilitiesModule(), etmB, new ChatModule()); + + ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneEast, sp1Uuid); + TestClient sp1Client = (TestClient)sp1.ControllingClient; + + // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0. + // TODO: May need to create special complete no-op test physics module rather than basic physics, since + // physics is irrelevant to this test. + sp1.Flying = true; + sp1.AbsolutePosition = sp1Position; + + AgentCircuitData acd = SceneHelpers.GenerateAgentData(sp2Uuid); + TestClient tc = new TestClient(acd, sceneEast); + List destinationTestClients = new List(); + EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); + + ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, tc, acd); + TestClient sp2Client = (TestClient)sp2.ControllingClient; + + sp2.Flying = true; + sp2.AbsolutePosition = sp2Position; + + TestClient sp2ChildClient = destinationTestClients[0]; + + // We must update the scene in order to make the new root agent sp2 in sceneWest trigger a position update to its + // child in sceneEast. + sceneWest.Update(1); + + // Check child position is correct. + Assert.AreEqual( + new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z), + sp2ChildClient.SceneAgent.AbsolutePosition); + + // Check chat received + string receivedChatMessage = ""; + + sp2ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedChatMessage = message; + + string testMessage = "'ello darling"; + sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); + + Assert.AreEqual(testMessage, receivedChatMessage); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3b8fbfd..7005c0a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4133,7 +4133,10 @@ namespace OpenSim.Region.Framework.Scenes /// true if we handled it. public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData) { - //m_log.Debug(" XXX Scene IncomingChildAgentDataUpdate POSITION in " + RegionInfo.RegionName); +// m_log.DebugFormat( +// "[SCENE PRESENCE]: IncomingChildAgentDataUpdate POSITION for {0} in {1}, position {2}", +// cAgentData.AgentID, Name, cAgentData.Position); + ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) { diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs index 8e40561..f53adcb 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsScene.cs @@ -147,6 +147,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin terrainHeight = _heightMap[(int)actor.Position.Y * (int)m_regionExtent.Y + (int)actor.Position.X]; float height = terrainHeight + actor.Size.Z; +// Console.WriteLine("height {0}, actorPosition {1}", height, actorPosition); if (actor.Flying) { diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index c2b0935..8eeaf99 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -62,14 +62,23 @@ namespace OpenSim.Tests.Common.Mock public event Action OnReceivedMoveAgentIntoRegion; public event Action OnTestClientInformClientOfNeighbour; public event TestClientOnSendRegionTeleportDelegate OnTestClientSendRegionTeleport; + public event Action OnReceivedEntityUpdate; + + public event OnReceivedChatMessageDelegate OnReceivedChatMessage; public event Action OnReceivedInstantMessage; + public event Action OnReceivedSendRebakeAvatarTextures; public delegate void TestClientOnSendRegionTeleportDelegate( ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL); + public delegate void OnReceivedChatMessageDelegate( + string message, byte type, Vector3 fromPos, string fromName, + UUID fromAgentID, UUID ownerID, byte source, byte audible); + + // disable warning: public events, part of the public API #pragma warning disable 67 @@ -467,6 +476,34 @@ namespace OpenSim.Tests.Common.Mock } /// + /// Trigger chat coming from this connection. + /// + /// + /// + /// + public bool Chat(int channel, ChatTypeEnum type, string message) + { + ChatMessage handlerChatFromClient = OnChatFromClient; + + if (handlerChatFromClient != null) + { + OSChatMessage args = new OSChatMessage(); + args.Channel = channel; + args.From = Name; + args.Message = message; + args.Type = type; + + args.Scene = Scene; + args.Sender = this; + args.SenderUUID = AgentId; + + handlerChatFromClient(this, args); + } + + return true; + } + + /// /// Attempt a teleport to the given region. /// /// @@ -550,6 +587,9 @@ namespace OpenSim.Tests.Common.Mock string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, UUID ownerID, byte source, byte audible) { +// Console.WriteLine("mmm {0} {1} {2}", message, Name, AgentId); + if (OnReceivedChatMessage != null) + OnReceivedChatMessage(message, type, fromPos, fromName, fromAgentID, ownerID, source, audible); } public void SendInstantMessage(GridInstantMessage im) diff --git a/prebuild.xml b/prebuild.xml index 9a419eb..196bfd2 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -3081,6 +3081,7 @@ + -- cgit v1.1 From 65a135f4d33fc0be3738f11c51a6c27c344a10aa Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 19:47:33 +0100 Subject: Simplify regression TestInterRegionChatDistanceEastWest() by making the child presence connection directly rather than routing through TestClient. This code isn't relevant to this test and is already exercised by other tests. --- .../Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs | 13 ++++++------- OpenSim/Tests/Common/Helpers/SceneHelpers.cs | 6 +++++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs index 315cc19..c5eb2ad 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs @@ -121,18 +121,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests sp1.Flying = true; sp1.AbsolutePosition = sp1Position; - AgentCircuitData acd = SceneHelpers.GenerateAgentData(sp2Uuid); - TestClient tc = new TestClient(acd, sceneEast); - List destinationTestClients = new List(); - EntityTransferHelpers.SetupInformClientOfNeighbourTriggersNeighbourClientCreate(tc, destinationTestClients); - - ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, tc, acd); + ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, sp2Uuid); TestClient sp2Client = (TestClient)sp2.ControllingClient; + // When sp2 logs in to sceneWest, it sets up a child agent in sceneEast and informs the sp2 client to + // make the connection. For this test, will simplify this chain by making the connection separately here. + ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid); + sp2.Flying = true; sp2.AbsolutePosition = sp2Position; - TestClient sp2ChildClient = destinationTestClients[0]; + TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient; // We must update the scene in order to make the new root agent sp2 in sceneWest trigger a position update to its // child in sceneEast. diff --git a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs index 874ff62..342cd06 100644 --- a/OpenSim/Tests/Common/Helpers/SceneHelpers.cs +++ b/OpenSim/Tests/Common/Helpers/SceneHelpers.cs @@ -574,7 +574,11 @@ namespace OpenSim.Tests.Common public static ScenePresence AddChildScenePresence(Scene scene, UUID agentId) { - AgentCircuitData acd = GenerateAgentData(agentId); + return AddChildScenePresence(scene, GenerateAgentData(agentId)); + } + + public static ScenePresence AddChildScenePresence(Scene scene, AgentCircuitData acd) + { acd.child = true; // XXX: ViaLogin may not be correct for child agents -- cgit v1.1 From 15b50ae737cf316cfe9db6843f06f7b3799f139e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 19:55:34 +0100 Subject: Extend regression TestInterRegionChatDistanceEastWest() to test in range chat both ways. --- .../Avatar/Chat/Tests/ChatModuleTests.cs | 55 +++++++++++++++------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs index c5eb2ad..fac9bd4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs @@ -119,39 +119,60 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests // TODO: May need to create special complete no-op test physics module rather than basic physics, since // physics is irrelevant to this test. sp1.Flying = true; + + // When sp1 logs in to sceneEast, it sets up a child agent in sceneWest and informs the sp2 client to + // make the connection. For this test, will simplify this chain by making the connection directly. + ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneWest, sp1Uuid); + TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient; + sp1.AbsolutePosition = sp1Position; ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneWest, sp2Uuid); TestClient sp2Client = (TestClient)sp2.ControllingClient; - - // When sp2 logs in to sceneWest, it sets up a child agent in sceneEast and informs the sp2 client to - // make the connection. For this test, will simplify this chain by making the connection separately here. - ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid); - sp2.Flying = true; - sp2.AbsolutePosition = sp2Position; + ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, sp2Uuid); TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient; - // We must update the scene in order to make the new root agent sp2 in sceneWest trigger a position update to its - // child in sceneEast. + sp2.AbsolutePosition = sp2Position; + + // We must update the scenes in order to make the root new root agents trigger position updates in their + // children. sceneWest.Update(1); + sceneEast.Update(1); + + // Check child positions are correct. + Assert.AreEqual( + new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z), + sp1ChildClient.SceneAgent.AbsolutePosition); - // Check child position is correct. Assert.AreEqual( new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z), sp2ChildClient.SceneAgent.AbsolutePosition); - // Check chat received - string receivedChatMessage = ""; + // Check chat from sp1 + { + string receivedChatMessage = ""; + + sp2ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedChatMessage = message; + + string testMessage = "'ello darling"; + sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); + } + + // Check chat from sp2 + { + string receivedChatMessage = ""; - sp2ChildClient.OnReceivedChatMessage - += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedChatMessage = message; + sp1ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedChatMessage = message; - string testMessage = "'ello darling"; - sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); - - Assert.AreEqual(testMessage, receivedChatMessage); + string testMessage = "fantastic cats"; + sp2Client.Chat(0, ChatTypeEnum.Say, testMessage); + + Assert.AreEqual(testMessage, receivedChatMessage); + } } } } \ No newline at end of file -- cgit v1.1 From bffc9ad18471076360692731597f89d232bb07b9 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 20:04:32 +0100 Subject: Extend regression TestInterRegionChatDistanceEastWest() to test out of range chat --- .../Avatar/Chat/Tests/ChatModuleTests.cs | 49 +++++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs index fac9bd4..bdaa97b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs @@ -150,28 +150,55 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, sp2Position.Z), sp2ChildClient.SceneAgent.AbsolutePosition); - // Check chat from sp1 - { - string receivedChatMessage = ""; + string receivedSp1ChatMessage = ""; + string receivedSp2ChatMessage = ""; - sp2ChildClient.OnReceivedChatMessage - += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedChatMessage = message; + sp1ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message; + sp2ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message; + // Check chat from sp1 + { string testMessage = "'ello darling"; sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); + +// Assert.AreEqual(testMessage, receivedSp1ChatMessage); + Assert.AreEqual(testMessage, receivedSp2ChatMessage); } // Check chat from sp2 + { + string testMessage = "fantastic cats"; + sp2Client.Chat(0, ChatTypeEnum.Say, testMessage); + + Assert.AreEqual(testMessage, receivedSp1ChatMessage); +// Assert.AreEqual(testMessage, receivedSp2ChatMessage); + } + + sp1Position = new Vector3(30, 128, 20); + sp1.AbsolutePosition = sp1Position; + sceneEast.Update(1); + + // Check child position is correct. + Assert.AreEqual( + new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z), + sp1ChildClient.SceneAgent.AbsolutePosition); + + // sp2 should now be out of range for chat from sp1 { - string receivedChatMessage = ""; + string testMessage = "beef"; + sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); - sp1ChildClient.OnReceivedChatMessage - += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedChatMessage = message; + Assert.AreNotEqual(testMessage, receivedSp2ChatMessage); + } - string testMessage = "fantastic cats"; + // sp1 should now be out of range for chat from sp2 + { + string testMessage = "lentils"; sp2Client.Chat(0, ChatTypeEnum.Say, testMessage); - - Assert.AreEqual(testMessage, receivedChatMessage); + + Assert.AreNotEqual(testMessage, receivedSp1ChatMessage); } } } -- cgit v1.1 From f8b824123970418211bbc5ea501ead98a1781084 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 20:28:26 +0100 Subject: Add regression test for north-south chat across neighbour regions. --- .../Avatar/Chat/Tests/ChatModuleTests.cs | 185 +++++++++++++++------ 1 file changed, 133 insertions(+), 52 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs index bdaa97b..7b8c418 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/Tests/ChatModuleTests.cs @@ -65,6 +65,32 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; } + private void SetupNeighbourRegions(TestScene sceneA, TestScene sceneB) + { + // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the + // CapabilitiesModule complain when it can't set up HTTP endpoints. + // BaseHttpServer httpServer = new BaseHttpServer(99999); + // MainServer.AddHttpServer(httpServer); + // MainServer.Instance = httpServer; + + // We need entity transfer modules so that when sp2 logs into the east region, the region calls + // EntityTransferModuleto set up a child agent on the west region. + // XXX: However, this is not an entity transfer so is misleading. + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Chat"); + IConfig modulesConfig = config.AddConfig("Modules"); + modulesConfig.Set("EntityTransferModule", etmA.Name); + modulesConfig.Set("SimulationServices", lscm.Name); + + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA, new ChatModule()); + SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB, new ChatModule()); + } + /// /// Tests chat between neighbour regions on the east-west axis /// @@ -84,33 +110,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests Vector3 sp1Position = new Vector3(6, 128, 20); Vector3 sp2Position = new Vector3(250, 128, 20); - // XXX: HTTP server is not (and should not be) necessary for this test, though it's absence makes the - // CapabilitiesModule complain when it can't set up HTTP endpoints. -// BaseHttpServer httpServer = new BaseHttpServer(99999); -// MainServer.AddHttpServer(httpServer); -// MainServer.Instance = httpServer; - - // We need entity transfer modules so that when sp2 logs into the east region, the region calls - // EntityTransferModuleto set up a child agent on the west region. - // XXX: However, this is not an entity transfer so is misleading. - EntityTransferModule etmA = new EntityTransferModule(); - EntityTransferModule etmB = new EntityTransferModule(); - LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); - - IConfigSource config = new IniConfigSource(); - config.AddConfig("Chat"); - IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etmA.Name); - modulesConfig.Set("SimulationServices", lscm.Name); - SceneHelpers sh = new SceneHelpers(); - TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000); TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneWest, sceneEast }, config, lscm); - SceneHelpers.SetupSceneModules(sceneWest, config, new CapabilitiesModule(), etmA, new ChatModule()); - SceneHelpers.SetupSceneModules(sceneEast, config, new CapabilitiesModule(), etmB, new ChatModule()); + SetupNeighbourRegions(sceneWest, sceneEast); ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneEast, sp1Uuid); TestClient sp1Client = (TestClient)sp1.ControllingClient; @@ -158,23 +162,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests sp2ChildClient.OnReceivedChatMessage += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message; - // Check chat from sp1 - { - string testMessage = "'ello darling"; - sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); - -// Assert.AreEqual(testMessage, receivedSp1ChatMessage); - Assert.AreEqual(testMessage, receivedSp2ChatMessage); - } - - // Check chat from sp2 - { - string testMessage = "fantastic cats"; - sp2Client.Chat(0, ChatTypeEnum.Say, testMessage); - - Assert.AreEqual(testMessage, receivedSp1ChatMessage); -// Assert.AreEqual(testMessage, receivedSp2ChatMessage); - } + TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage); + TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage); sp1Position = new Vector3(30, 128, 20); sp1.AbsolutePosition = sp1Position; @@ -185,21 +174,113 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat.Tests new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z), sp1ChildClient.SceneAgent.AbsolutePosition); - // sp2 should now be out of range for chat from sp1 - { - string testMessage = "beef"; - sp1Client.Chat(0, ChatTypeEnum.Say, testMessage); + TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage); + TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage); + } + + /// + /// Tests chat between neighbour regions on the north-south axis + /// + /// + /// Really, this is a combination of a child agent position update test and a chat range test. These need + /// to be separated later on. + /// + [Test] + public void TestInterRegionChatDistanceNorthSouth() + { + TestHelpers.InMethod(); + // TestHelpers.EnableLogging(); + + UUID sp1Uuid = TestHelpers.ParseTail(0x11); + UUID sp2Uuid = TestHelpers.ParseTail(0x12); + + Vector3 sp1Position = new Vector3(128, 250, 20); + Vector3 sp2Position = new Vector3(128, 6, 20); + + SceneHelpers sh = new SceneHelpers(); + TestScene sceneNorth = sh.SetupScene("sceneNorth", TestHelpers.ParseTail(0x1), 1000, 1000); + TestScene sceneSouth = sh.SetupScene("sceneSouth", TestHelpers.ParseTail(0x2), 1000, 1001); - Assert.AreNotEqual(testMessage, receivedSp2ChatMessage); - } + SetupNeighbourRegions(sceneNorth, sceneSouth); + + ScenePresence sp1 = SceneHelpers.AddScenePresence(sceneNorth, sp1Uuid); + TestClient sp1Client = (TestClient)sp1.ControllingClient; + + // If we don't set agents to flying, test will go wrong as they instantly fall to z = 0. + // TODO: May need to create special complete no-op test physics module rather than basic physics, since + // physics is irrelevant to this test. + sp1.Flying = true; + + // When sp1 logs in to sceneEast, it sets up a child agent in sceneNorth and informs the sp2 client to + // make the connection. For this test, will simplify this chain by making the connection directly. + ScenePresence sp1Child = SceneHelpers.AddChildScenePresence(sceneSouth, sp1Uuid); + TestClient sp1ChildClient = (TestClient)sp1Child.ControllingClient; + + sp1.AbsolutePosition = sp1Position; + + ScenePresence sp2 = SceneHelpers.AddScenePresence(sceneSouth, sp2Uuid); + TestClient sp2Client = (TestClient)sp2.ControllingClient; + sp2.Flying = true; + + ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneNorth, sp2Uuid); + TestClient sp2ChildClient = (TestClient)sp2Child.ControllingClient; + + sp2.AbsolutePosition = sp2Position; + + // We must update the scenes in order to make the root new root agents trigger position updates in their + // children. + sceneNorth.Update(1); + sceneSouth.Update(1); + + // Check child positions are correct. + Assert.AreEqual( + new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z), + sp1ChildClient.SceneAgent.AbsolutePosition); + + Assert.AreEqual( + new Vector3(sp2Position.X, sp2Position.Y + sceneSouth.RegionInfo.RegionSizeY, sp2Position.Z), + sp2ChildClient.SceneAgent.AbsolutePosition); + + string receivedSp1ChatMessage = ""; + string receivedSp2ChatMessage = ""; + + sp1ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp1ChatMessage = message; + sp2ChildClient.OnReceivedChatMessage + += (message, type, fromPos, fromName, fromAgentID, ownerID, source, audible) => receivedSp2ChatMessage = message; + + TestUserInRange(sp1Client, "ello darling", ref receivedSp2ChatMessage); + TestUserInRange(sp2Client, "fantastic cats", ref receivedSp1ChatMessage); + + sp1Position = new Vector3(30, 128, 20); + sp1.AbsolutePosition = sp1Position; + sceneNorth.Update(1); + + // Check child position is correct. + Assert.AreEqual( + new Vector3(sp1Position.X, sp1Position.Y - sceneNorth.RegionInfo.RegionSizeY, sp1Position.Z), + sp1ChildClient.SceneAgent.AbsolutePosition); + + TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage); + TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage); + } + + private void TestUserInRange(TestClient speakClient, string testMessage, ref string receivedMessage) + { + receivedMessage = ""; + + speakClient.Chat(0, ChatTypeEnum.Say, testMessage); + + Assert.AreEqual(testMessage, receivedMessage); + } + + private void TestUserOutOfRange(TestClient speakClient, string testMessage, ref string receivedMessage) + { + receivedMessage = ""; - // sp1 should now be out of range for chat from sp2 - { - string testMessage = "lentils"; - sp2Client.Chat(0, ChatTypeEnum.Say, testMessage); + speakClient.Chat(0, ChatTypeEnum.Say, testMessage); - Assert.AreNotEqual(testMessage, receivedSp1ChatMessage); - } + Assert.AreNotEqual(testMessage, receivedMessage); } } } \ No newline at end of file -- cgit v1.1 From 16bf38e1abd3a6235008a38ba7ca29e836c925c7 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 23:39:22 +0100 Subject: Fix issue where llSetCameraAtOffset() and llSetCameraEyeOffset() in non-root prims moved camera/focus to wrong position. For non-root prim, eye offsets now need to be made relative to root prim if either camera-at or camera-eye are set. Probably a regression since November 2013 when all sits were made relative to root prim to match viewer expections (and fix other bugs). Addresses http://opensimulator.org/mantis/view.php?id=7176 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 398d394..ed107e4 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2755,6 +2755,10 @@ namespace OpenSim.Region.Framework.Scenes cameraAtOffset = part.GetCameraAtOffset(); cameraEyeOffset = part.GetCameraEyeOffset(); + + if (cameraEyeOffset != Vector3.Zero || cameraAtOffset != Vector3.Zero) + cameraEyeOffset += part.OffsetPosition; + forceMouselook = part.GetForceMouselook(); // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is -- cgit v1.1 From 3fbaef9275dbb1767dc734e2d8dbe1d2cabfb566 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 23:52:28 +0100 Subject: If the root prim has a camera-at or camera-eye setting and a sat upon child prim does not, use the root prim offsets. This matches behaviour just tested on the Linden Lab grid. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ed107e4..026b0b6 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2754,8 +2754,15 @@ namespace OpenSim.Region.Framework.Scenes part.AddSittingAvatar(this); cameraAtOffset = part.GetCameraAtOffset(); + + if (cameraAtOffset == Vector3.Zero) + cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset(); + cameraEyeOffset = part.GetCameraEyeOffset(); + if (cameraEyeOffset == Vector3.Zero) + cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset(); + if (cameraEyeOffset != Vector3.Zero || cameraAtOffset != Vector3.Zero) cameraEyeOffset += part.OffsetPosition; -- cgit v1.1 From 174df941720bc45c1e73224919c34f059129b9e1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 May 2014 23:58:28 +0100 Subject: If a script calls llSetCameraAtOffset() or llSetCameraEyeOffset() on a child prim and the root prim has no corresponding value set, then also set the root prim. This matches behaviour just tested on the Linden Lab grid. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5590cd5..7d8821c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6846,12 +6846,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); m_host.SetCameraEyeOffset(offset); + + if (m_host.ParentGroup.RootPart.GetCameraEyeOffset() == Vector3.Zero) + m_host.ParentGroup.RootPart.SetCameraEyeOffset(offset); } public void llSetCameraAtOffset(LSL_Vector offset) { m_host.AddScriptLPS(1); m_host.SetCameraAtOffset(offset); + + if (m_host.ParentGroup.RootPart.GetCameraAtOffset() == Vector3.Zero) + m_host.ParentGroup.RootPart.SetCameraAtOffset(offset); } public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at) -- cgit v1.1 From fbed2455965283e7cec92f8cceb89a333e1dca14 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 01:34:02 +0100 Subject: Compensate camera-at and camera-eye for child prim rotation when sitting on child prim with camera-eye set --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 026b0b6..eaac71d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2764,7 +2764,19 @@ namespace OpenSim.Region.Framework.Scenes cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset(); if (cameraEyeOffset != Vector3.Zero || cameraAtOffset != Vector3.Zero) + { + if (!part.IsRoot) + { + cameraEyeOffset = cameraEyeOffset * part.RotationOffset; + cameraAtOffset = part.OffsetPosition; + } + cameraEyeOffset += part.OffsetPosition; + } + +// m_log.DebugFormat( +// "[SCENE PRESENCE]: Using cameraAtOffset {0}, cameraEyeOffset {1} for sit on {2} by {3} in {4}", +// cameraAtOffset, cameraEyeOffset, part.Name, Name, Scene.Name); forceMouselook = part.GetForceMouselook(); -- cgit v1.1 From c78a8271c44c581e4c939fa6347fd967ffdee847 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 01:38:05 +0100 Subject: Add any camera at compensation for sat upon child prims to any existing camera-at value, rather than replace. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index eaac71d..f067f9d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2768,7 +2768,7 @@ namespace OpenSim.Region.Framework.Scenes if (!part.IsRoot) { cameraEyeOffset = cameraEyeOffset * part.RotationOffset; - cameraAtOffset = part.OffsetPosition; + cameraAtOffset += part.OffsetPosition; } cameraEyeOffset += part.OffsetPosition; -- cgit v1.1 From 5015b0b485058db5bf1f2b56cf375c23349749ad Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 01:55:05 +0100 Subject: If one is sitting on a child with an unset camera-eye and so using one set in a root prim, the focus should remain on the root prim. Matches behaviour just tested on the Linden grid. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f067f9d..17f54c2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2755,15 +2755,19 @@ namespace OpenSim.Region.Framework.Scenes cameraAtOffset = part.GetCameraAtOffset(); - if (cameraAtOffset == Vector3.Zero) + if (!part.IsRoot && cameraAtOffset == Vector3.Zero) cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset(); + bool cameraEyeOffsetFromRootForChild = false; cameraEyeOffset = part.GetCameraEyeOffset(); - if (cameraEyeOffset == Vector3.Zero) + if (!part.IsRoot && cameraEyeOffset == Vector3.Zero) + { cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset(); + cameraEyeOffsetFromRootForChild = true; + } - if (cameraEyeOffset != Vector3.Zero || cameraAtOffset != Vector3.Zero) + if ((cameraEyeOffset != Vector3.Zero && !cameraEyeOffsetFromRootForChild) || cameraAtOffset != Vector3.Zero) { if (!part.IsRoot) { -- cgit v1.1 From 72c67c50911e31937826314c825fdf13baa1cc28 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 20:14:49 +0100 Subject: Fix possible infinite recursion in MessageTransferModule.SendGridInstantMessageViaXMLRPCAsync() whilst preserving retry lookup behaviour. This is based on heavily mikemig's original patch in http://opensimulator.org/mantis/view.php?id=7149 but instead of exiting after the first IM delivery failure to presence information retrieved from the presence service it will retry the lookup until the result matches the previous lookup. This is to deal with the case where the agent is sent an IM whilst they are teleporting. --- .../Avatar/InstantMessage/MessageTransferModule.cs | 164 +++++++-------------- 1 file changed, 56 insertions(+), 108 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 7aa7123..2462ff8 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage /// /// delegate for sending a grid instant message asynchronously /// - public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID); + public delegate void GridInstantMessageDelegate(GridInstantMessage im, MessageResultNotification result); protected virtual void GridInstantMessageCompleted(IAsyncResult iar) { @@ -442,138 +442,87 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; - d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); + d.BeginInvoke(im, result, GridInstantMessageCompleted, d); } /// - /// Recursive SendGridInstantMessage over XMLRPC method. - /// This is called from within a dedicated thread. - /// The first time this is called, prevRegionHandle will be 0 Subsequent times this is called from - /// itself, prevRegionHandle will be the last region handle that we tried to send. - /// If the handles are the same, we look up the user's location using the grid. - /// If the handles are still the same, we end. The send failed. + /// Internal SendGridInstantMessage over XMLRPC method. /// - /// - /// Pass in 0 the first time this method is called. It will be called recursively with the last - /// regionhandle tried - /// - protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID) + /// + /// This is called from within a dedicated thread. + /// + private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result) { UUID toAgentID = new UUID(im.toAgentID); - - PresenceInfo upd = null; - - bool lookupAgent = false; + UUID regionID; + bool needToLookupAgent; lock (m_UserRegionMap) + needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID); + + while (true) { - if (m_UserRegionMap.ContainsKey(toAgentID)) + if (needToLookupAgent) { - upd = new PresenceInfo(); - upd.RegionID = m_UserRegionMap[toAgentID]; + PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); - // We need to compare the current regionhandle with the previous region handle - // or the recursive loop will never end because it will never try to lookup the agent again - if (prevRegionID == upd.RegionID) - { - lookupAgent = true; - } - } - else - { - lookupAgent = true; - } - } - + UUID foundRegionID = UUID.Zero; - // Are we needing to look-up an agent? - if (lookupAgent) - { - // Non-cached user agent lookup. - PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); - if (presences != null && presences.Length > 0) - { - foreach (PresenceInfo p in presences) + if (presences != null) { - if (p.RegionID != UUID.Zero) + foreach (PresenceInfo p in presences) { - upd = p; - break; + if (p.RegionID != UUID.Zero) + { + foundRegionID = p.RegionID; + break; + } } } - } - if (upd != null) - { - // check if we've tried this before.. - // This is one way to end the recursive loop - // - if (upd.RegionID == prevRegionID) - { - // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); - HandleUndeliverableMessage(im, result); - return; - } + // If not found or the found region is the same as the last lookup, then message is undeliverable + if (foundRegionID == UUID.Zero || foundRegionID == regionID) + break; + else + regionID = foundRegionID; } - else + + GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID); + if (reginfo == null) { - // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); - HandleUndeliverableMessage(im, result); - return; + m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID); + break; } - } - if (upd != null) - { - GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, - upd.RegionID); - if (reginfo != null) + // Try to send the message to the agent via the retrieved region. + Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); + msgdata["region_handle"] = 0; + bool imresult = doIMSending(reginfo, msgdata); + + // If the message delivery was successful, then cache the entry. + if (imresult) { - Hashtable msgdata = ConvertGridInstantMessageToXMLRPC(im); - // Not actually used anymore, left in for compatibility - // Remove at next interface change - // - msgdata["region_handle"] = 0; - bool imresult = doIMSending(reginfo, msgdata); - if (imresult) - { - // IM delivery successful, so store the Agent's location in our local cache. - lock (m_UserRegionMap) - { - if (m_UserRegionMap.ContainsKey(toAgentID)) - { - m_UserRegionMap[toAgentID] = upd.RegionID; - } - else - { - m_UserRegionMap.Add(toAgentID, upd.RegionID); - } - } - result(true); - } - else + lock (m_UserRegionMap) { - // try again, but lookup user this time. - // Warning, this must call the Async version - // of this method or we'll be making thousands of threads - // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync - // The version that spawns the thread is SendGridInstantMessageViaXMLRPC - - // This is recursive!!!!! - SendGridInstantMessageViaXMLRPCAsync(im, result, - upd.RegionID); + m_UserRegionMap[toAgentID] = regionID; } + result(true); + return; } - else - { - m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID); - HandleUndeliverableMessage(im, result); - } - } - else - { - HandleUndeliverableMessage(im, result); + + // If we reach this point in the first iteration of the while, then we may have unsuccessfully tried + // to use a locally cached region ID. All subsequent attempts need to lookup agent details from + // the presence service. + needToLookupAgent = true; } + + // If we reached this point then the message was not deliverable. Remove the bad cache entry and + // signal the delivery failure. + lock (m_UserRegionMap) + m_UserRegionMap.Remove(toAgentID); + + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + HandleUndeliverableMessage(im, result); } /// @@ -584,7 +533,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage /// Bool if the message was successfully delivered at the other side. protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata) { - ArrayList SendParams = new ArrayList(); SendParams.Add(xmlrpcdata); XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams); -- cgit v1.1 From fbcb76383d5083a7a1b4c4ba75d37b247859a87d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 20:57:50 +0100 Subject: Allow console output to be multiline by making colourization regex RegexOptions.SingleLine --- OpenSim/Framework/Console/LocalConsole.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index a967db6..b17b8e0 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -283,7 +283,7 @@ namespace OpenSim.Framework.Console { string regex = @"^(?.*?)\[(?[^\]]+)\]:?(?.*)"; - Regex RE = new Regex(regex, RegexOptions.Multiline); + Regex RE = new Regex(regex, RegexOptions.Singleline); MatchCollection matches = RE.Matches(text); if (matches.Count == 1) -- cgit v1.1 From f55e15363665ac885b51fa549c9c1566e9ea0cc6 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 21:09:48 +0100 Subject: Compile the regex that extract categories for colourization just once rather than on every single log. Compiling every time is unnecessary since Regex is thread-safe. --- OpenSim/Framework/Console/LocalConsole.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index b17b8e0..260a86f 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -46,6 +46,11 @@ namespace OpenSim.Framework.Console // private readonly object m_syncRoot = new object(); private const string LOGLEVEL_NONE = "(none)"; + // Used to extract categories for colourization. + private Regex m_categoryRegex + = new Regex( + @"^(?.*?)\[(?[^\]]+)\]:?(?.*)", RegexOptions.Singleline | RegexOptions.Compiled); + private int m_cursorYPosition = -1; private int m_cursorXPosition = 0; private StringBuilder m_commandLine = new StringBuilder(); @@ -280,11 +285,8 @@ namespace OpenSim.Framework.Console string outText = text; if (level != LOGLEVEL_NONE) - { - string regex = @"^(?.*?)\[(?[^\]]+)\]:?(?.*)"; - - Regex RE = new Regex(regex, RegexOptions.Singleline); - MatchCollection matches = RE.Matches(text); + { + MatchCollection matches = m_categoryRegex.Matches(text); if (matches.Count == 1) { -- cgit v1.1 From b3a496d6f2fa09659b0109f745632bc80acc756f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 21:13:37 +0100 Subject: Add mikemig to contributors --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index fa79ea7..1d080ff 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -134,6 +134,7 @@ what it is today. * Micheil Merlin * Mike Osias (IBM) * Mike Pitman (IBM) +* mikemig * mikkopa/_someone - RealXtend * Misterblue * Mircea Kitsune -- cgit v1.1 From 250ea09328253422ff2a0e4877ee9968556328f0 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 22:12:49 +0100 Subject: Reactivate regression test TestCastAndConcatString() in CompilerTests. --- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 4 ++-- .../Shared/CodeTools/Tests/CompilerTest.cs | 24 ++++++++++++++-------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index b4640ef..1efe798 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -444,7 +444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools // return compileScript; // } - private static string CreateCSCompilerScript( + public static string CreateCSCompilerScript( string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) { compileScript = string.Format( @@ -472,7 +472,7 @@ namespace SecondLife return compileScript; } - private static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) + public static string CreateVBCompilerScript(string compileScript, string className, string baseClassName) { compileScript = String.Empty + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs index 05a8756..29b6006 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs @@ -31,6 +31,7 @@ using System.Collections.Generic; using Microsoft.CSharp; using NUnit.Framework; using OpenSim.Region.ScriptEngine.Shared.CodeTools; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; using OpenSim.Tests.Common; namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests @@ -66,9 +67,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests m_CSCodeProvider = new CSharpCodeProvider(); m_compilerParameters = new CompilerParameters(); - string rootPath = Path.Combine(Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory), "bin"); + string rootPath = Path.Combine(Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory)); m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.dll")); m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.dll")); + m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenMetaverseTypes.dll")); m_compilerParameters.GenerateExecutable = false; } @@ -112,6 +114,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests "public Script() { } " + cg.Convert(input) + "} }\n"; + Dictionary, KeyValuePair> positionMap = cg.PositionMap; m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output); @@ -124,7 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests /// Test that a string can be cast to string and another string /// concatenated. /// - //[Test] + [Test] public void TestCastAndConcatString() { TestHelpers.InMethod(); @@ -143,15 +146,20 @@ default } }"; +// System.Console.WriteLine(input); CSCodeGenerator cg = new CSCodeGenerator(); - string output = "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\n" + - "namespace SecondLife { " + - "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass {\n" + - "public Script() { } " + - cg.Convert(input) + - "} }\n"; + string output = cg.Convert(input); + + output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null); +// System.Console.WriteLine(output); + m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output); +// foreach (CompilerError compErr in m_compilerResults.Errors) +// { +// System.Console.WriteLine("Error: {0}", compErr); +// } + Assert.AreEqual(0, m_compilerResults.Errors.Count); } } -- cgit v1.1 From cf95b65c10c285b297257db492fbeb9dc19d1d4c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 May 2014 22:29:47 +0100 Subject: Get regression test TestUseUndeclaredVariable() functional again, though not yet enabled. This reveals the position map problems and will make the fix (and subsequent continual checking) easier. --- .../Shared/CodeTools/Tests/CompilerTest.cs | 27 +++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs index 29b6006..ab68793 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs @@ -108,19 +108,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests }"; CSCodeGenerator cg = new CSCodeGenerator(); - string output = "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\n" + - "namespace SecondLife { " + - "public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass {\n" + - "public Script() { } " + - cg.Convert(input) + - "} }\n"; + string output = cg.Convert(input); + + output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null); + System.Console.WriteLine(output); Dictionary, KeyValuePair> positionMap = cg.PositionMap; m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output); - Assert.AreEqual(new KeyValuePair(5, 21), - positionMap[new KeyValuePair(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]); + foreach (KeyValuePair key in positionMap.Keys) + { + KeyValuePair val = positionMap[key]; + + System.Console.WriteLine("{0},{1} => {2},{3}", key.Key, key.Value, val.Key, val.Value); + } + + foreach (CompilerError compErr in m_compilerResults.Errors) + { + System.Console.WriteLine("Error: {0},{1} => {2}", compErr.Line, compErr.Column, compErr); + } + + Assert.AreEqual( + new KeyValuePair(5, 21), + positionMap[new KeyValuePair(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]); } /// -- cgit v1.1 From 9bae636ff0dc426e913e26c45b6936f16131f6d5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 May 2014 00:12:23 +0100 Subject: Fix issues where reported LSL compiler error line numbers do not match the script. This is probably due to changes in the layout of the generated script preamble (using statements etc, ) in c8afc852 (Jan 17 2013). Re-enabled existing regression test that exercises at least one case of this. --- .../Shared/CodeTools/CSCodeGenerator.cs | 2 +- .../Shared/CodeTools/Tests/CompilerTest.cs | 30 +++++++++++----------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs index 6aa717d..8b8e038 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/CSCodeGenerator.cs @@ -162,7 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools m_braceCount++; // line number - m_CSharpLine += 3; + m_CSharpLine += 9; // here's the payload retstr += GenerateLine(); diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs index ab68793..badf82a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Tests/CompilerTest.cs @@ -92,7 +92,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests /// Test the C# compiler error message can be mapped to the correct /// line/column in the LSL source when an undeclared variable is used. /// - //[Test] + [Test] public void TestUseUndeclaredVariable() { TestHelpers.InMethod(); @@ -110,24 +110,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests CSCodeGenerator cg = new CSCodeGenerator(); string output = cg.Convert(input); - output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null); - System.Console.WriteLine(output); + output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null); +// System.Console.WriteLine(output); Dictionary, KeyValuePair> positionMap = cg.PositionMap; m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output); - - foreach (KeyValuePair key in positionMap.Keys) - { - KeyValuePair val = positionMap[key]; - - System.Console.WriteLine("{0},{1} => {2},{3}", key.Key, key.Value, val.Key, val.Value); - } - - foreach (CompilerError compErr in m_compilerResults.Errors) - { - System.Console.WriteLine("Error: {0},{1} => {2}", compErr.Line, compErr.Column, compErr); - } +// +// foreach (KeyValuePair key in positionMap.Keys) +// { +// KeyValuePair val = positionMap[key]; +// +// System.Console.WriteLine("{0},{1} => {2},{3}", key.Key, key.Value, val.Key, val.Value); +// } +// +// foreach (CompilerError compErr in m_compilerResults.Errors) +// { +// System.Console.WriteLine("Error: {0},{1} => {2}", compErr.Line, compErr.Column, compErr); +// } Assert.AreEqual( new KeyValuePair(5, 21), -- cgit v1.1