Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
227685bea4
|
@ -134,6 +134,7 @@ what it is today.
|
|||
* Micheil Merlin
|
||||
* Mike Osias (IBM)
|
||||
* Mike Pitman (IBM)
|
||||
* mikemig
|
||||
* mikkopa/_someone - RealXtend
|
||||
* Misterblue
|
||||
* Mircea Kitsune
|
||||
|
|
|
@ -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(
|
||||
@"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)", RegexOptions.Singleline | RegexOptions.Compiled);
|
||||
|
||||
private int m_cursorYPosition = -1;
|
||||
private int m_cursorXPosition = 0;
|
||||
private StringBuilder m_commandLine = new StringBuilder();
|
||||
|
@ -281,10 +286,7 @@ namespace OpenSim.Framework.Console
|
|||
|
||||
if (level != LOGLEVEL_NONE)
|
||||
{
|
||||
string regex = @"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)";
|
||||
|
||||
Regex RE = new Regex(regex, RegexOptions.Multiline);
|
||||
MatchCollection matches = RE.Matches(text);
|
||||
MatchCollection matches = m_categoryRegex.Matches(text);
|
||||
|
||||
if (matches.Count == 1)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests chat between neighbour regions on the east-west axis
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Really, this is a combination of a child agent position update test and a chat range test. These need
|
||||
/// to be separated later on.
|
||||
/// </remarks>
|
||||
[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);
|
||||
|
||||
SceneHelpers sh = new SceneHelpers();
|
||||
TestScene sceneWest = sh.SetupScene("sceneWest", TestHelpers.ParseTail(0x1), 1000, 1000);
|
||||
TestScene sceneEast = sh.SetupScene("sceneEast", TestHelpers.ParseTail(0x2), 1001, 1000);
|
||||
|
||||
SetupNeighbourRegions(sceneWest, sceneEast);
|
||||
|
||||
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;
|
||||
|
||||
// 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;
|
||||
sp2.Flying = true;
|
||||
|
||||
ScenePresence sp2Child = SceneHelpers.AddChildScenePresence(sceneEast, 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.
|
||||
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);
|
||||
|
||||
Assert.AreEqual(
|
||||
new Vector3(sp2Position.X - sceneWest.RegionInfo.RegionSizeX, sp2Position.Y, 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;
|
||||
sceneEast.Update(1);
|
||||
|
||||
// Check child position is correct.
|
||||
Assert.AreEqual(
|
||||
new Vector3(sp1Position.X + sceneEast.RegionInfo.RegionSizeX, sp1Position.Y, sp1Position.Z),
|
||||
sp1ChildClient.SceneAgent.AbsolutePosition);
|
||||
|
||||
TestUserOutOfRange(sp1Client, "beef", ref receivedSp2ChatMessage);
|
||||
TestUserOutOfRange(sp2Client, "lentils", ref receivedSp1ChatMessage);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests chat between neighbour regions on the north-south axis
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Really, this is a combination of a child agent position update test and a chat range test. These need
|
||||
/// to be separated later on.
|
||||
/// </remarks>
|
||||
[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);
|
||||
|
||||
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 = "";
|
||||
|
||||
speakClient.Chat(0, ChatTypeEnum.Say, testMessage);
|
||||
|
||||
Assert.AreNotEqual(testMessage, receivedMessage);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
|||
/// <summary>
|
||||
/// delegate for sending a grid instant message asynchronously
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="prevRegionHandle">
|
||||
/// Pass in 0 the first time this method is called. It will be called recursively with the last
|
||||
/// regionhandle tried
|
||||
/// </param>
|
||||
protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
|
||||
/// <remarks>
|
||||
/// This is called from within a dedicated thread.
|
||||
/// </remarks>
|
||||
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)
|
||||
UUID foundRegionID = UUID.Zero;
|
||||
|
||||
if (presences != null)
|
||||
{
|
||||
lookupAgent = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lookupAgent = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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 (p.RegionID != UUID.Zero)
|
||||
foreach (PresenceInfo p in presences)
|
||||
{
|
||||
upd = p;
|
||||
break;
|
||||
if (p.RegionID != UUID.Zero)
|
||||
{
|
||||
foundRegionID = p.RegionID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (upd != null)
|
||||
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, regionID);
|
||||
if (reginfo == 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;
|
||||
}
|
||||
m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
// 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)
|
||||
{
|
||||
// m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
|
||||
HandleUndeliverableMessage(im, result);
|
||||
lock (m_UserRegionMap)
|
||||
{
|
||||
m_UserRegionMap[toAgentID] = regionID;
|
||||
}
|
||||
result(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 (upd != null)
|
||||
{
|
||||
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID,
|
||||
upd.RegionID);
|
||||
if (reginfo != null)
|
||||
{
|
||||
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
|
||||
{
|
||||
// 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
|
||||
// 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);
|
||||
|
||||
// This is recursive!!!!!
|
||||
SendGridInstantMessageViaXMLRPCAsync(im, result,
|
||||
upd.RegionID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", upd.RegionID);
|
||||
HandleUndeliverableMessage(im, result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HandleUndeliverableMessage(im, result);
|
||||
}
|
||||
// m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
|
||||
HandleUndeliverableMessage(im, result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -584,7 +533,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
|
|||
/// <returns>Bool if the message was successfully delivered at the other side.</returns>
|
||||
protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata)
|
||||
{
|
||||
|
||||
ArrayList SendParams = new ArrayList();
|
||||
SendParams.Add(xmlrpcdata);
|
||||
XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);
|
||||
|
|
|
@ -4133,7 +4133,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <returns>true if we handled it.</returns>
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -2754,7 +2754,34 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
part.AddSittingAvatar(this);
|
||||
|
||||
cameraAtOffset = part.GetCameraAtOffset();
|
||||
|
||||
if (!part.IsRoot && cameraAtOffset == Vector3.Zero)
|
||||
cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
|
||||
|
||||
bool cameraEyeOffsetFromRootForChild = false;
|
||||
cameraEyeOffset = part.GetCameraEyeOffset();
|
||||
|
||||
if (!part.IsRoot && cameraEyeOffset == Vector3.Zero)
|
||||
{
|
||||
cameraEyeOffset = part.ParentGroup.RootPart.GetCameraEyeOffset();
|
||||
cameraEyeOffsetFromRootForChild = true;
|
||||
}
|
||||
|
||||
if ((cameraEyeOffset != Vector3.Zero && !cameraEyeOffsetFromRootForChild) || 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();
|
||||
|
||||
// An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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: " +
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -90,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.
|
||||
/// </summary>
|
||||
//[Test]
|
||||
[Test]
|
||||
public void TestUseUndeclaredVariable()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
@ -106,25 +108,37 @@ 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<int, int>, KeyValuePair<int, int>> positionMap = cg.PositionMap;
|
||||
|
||||
m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output);
|
||||
//
|
||||
// foreach (KeyValuePair<int, int> key in positionMap.Keys)
|
||||
// {
|
||||
// KeyValuePair<int, int> 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<int, int>(5, 21),
|
||||
positionMap[new KeyValuePair<int, int>(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]);
|
||||
Assert.AreEqual(
|
||||
new KeyValuePair<int, int>(5, 21),
|
||||
positionMap[new KeyValuePair<int, int>(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test that a string can be cast to string and another string
|
||||
/// concatenated.
|
||||
/// </summary>
|
||||
//[Test]
|
||||
[Test]
|
||||
public void TestCastAndConcatString()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
|
@ -143,15 +157,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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -62,14 +62,23 @@ namespace OpenSim.Tests.Common.Mock
|
|||
public event Action<RegionInfo, Vector3, Vector3> OnReceivedMoveAgentIntoRegion;
|
||||
public event Action<ulong, IPEndPoint> OnTestClientInformClientOfNeighbour;
|
||||
public event TestClientOnSendRegionTeleportDelegate OnTestClientSendRegionTeleport;
|
||||
|
||||
public event Action<ISceneEntity, PrimUpdateFlags> OnReceivedEntityUpdate;
|
||||
|
||||
public event OnReceivedChatMessageDelegate OnReceivedChatMessage;
|
||||
public event Action<GridInstantMessage> OnReceivedInstantMessage;
|
||||
|
||||
public event Action<UUID> 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
|
||||
|
||||
|
@ -466,6 +475,34 @@ namespace OpenSim.Tests.Common.Mock
|
|||
SentImageNotInDatabasePackets = new List<ImageNotInDatabasePacket>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Trigger chat coming from this connection.
|
||||
/// </summary>
|
||||
/// <param name="channel"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="message"></param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempt a teleport to the given region.
|
||||
/// </summary>
|
||||
|
@ -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)
|
||||
|
|
|
@ -3082,6 +3082,7 @@
|
|||
<Match path="Asset/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="Avatar/Attachments/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="Avatar/AvatarFactory/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="Avatar/Chat/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="Avatar/Friends/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="Avatar/Inventory/Archiver/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="Avatar/Inventory/Transfer/Tests" pattern="*.cs" recurse="true"/>
|
||||
|
|
Loading…
Reference in New Issue