Merge branch 'master' of ssh://opensimulator.org/var/git/opensim

bullet-2.82
Diva Canto 2014-05-23 16:20:04 -07:00
commit 227685bea4
14 changed files with 474 additions and 136 deletions

View File

@ -134,6 +134,7 @@ what it is today.
* Micheil Merlin * Micheil Merlin
* Mike Osias (IBM) * Mike Osias (IBM)
* Mike Pitman (IBM) * Mike Pitman (IBM)
* mikemig
* mikkopa/_someone - RealXtend * mikkopa/_someone - RealXtend
* Misterblue * Misterblue
* Mircea Kitsune * Mircea Kitsune

View File

@ -46,6 +46,11 @@ namespace OpenSim.Framework.Console
// private readonly object m_syncRoot = new object(); // private readonly object m_syncRoot = new object();
private const string LOGLEVEL_NONE = "(none)"; 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_cursorYPosition = -1;
private int m_cursorXPosition = 0; private int m_cursorXPosition = 0;
private StringBuilder m_commandLine = new StringBuilder(); private StringBuilder m_commandLine = new StringBuilder();
@ -280,11 +285,8 @@ namespace OpenSim.Framework.Console
string outText = text; string outText = text;
if (level != LOGLEVEL_NONE) if (level != LOGLEVEL_NONE)
{ {
string regex = @"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)"; MatchCollection matches = m_categoryRegex.Matches(text);
Regex RE = new Regex(regex, RegexOptions.Multiline);
MatchCollection matches = RE.Matches(text);
if (matches.Count == 1) if (matches.Count == 1)
{ {

View File

@ -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);
}
}
}

View File

@ -428,7 +428,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
/// <summary> /// <summary>
/// delegate for sending a grid instant message asynchronously /// delegate for sending a grid instant message asynchronously
/// </summary> /// </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) protected virtual void GridInstantMessageCompleted(IAsyncResult iar)
{ {
@ -442,138 +442,87 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
{ {
GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync; GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
d.BeginInvoke(im, result, UUID.Zero, GridInstantMessageCompleted, d); d.BeginInvoke(im, result, GridInstantMessageCompleted, d);
} }
/// <summary> /// <summary>
/// Recursive SendGridInstantMessage over XMLRPC method. /// Internal 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.
/// </summary> /// </summary>
/// <param name="prevRegionHandle"> /// <remarks>
/// Pass in 0 the first time this method is called. It will be called recursively with the last /// This is called from within a dedicated thread.
/// regionhandle tried /// </remarks>
/// </param> private void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result)
protected virtual void SendGridInstantMessageViaXMLRPCAsync(GridInstantMessage im, MessageResultNotification result, UUID prevRegionID)
{ {
UUID toAgentID = new UUID(im.toAgentID); UUID toAgentID = new UUID(im.toAgentID);
UUID regionID;
PresenceInfo upd = null; bool needToLookupAgent;
bool lookupAgent = false;
lock (m_UserRegionMap) lock (m_UserRegionMap)
{ needToLookupAgent = !m_UserRegionMap.TryGetValue(toAgentID, out regionID);
if (m_UserRegionMap.ContainsKey(toAgentID))
{
upd = new PresenceInfo();
upd.RegionID = m_UserRegionMap[toAgentID];
// We need to compare the current regionhandle with the previous region handle while (true)
// 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;
}
}
// Are we needing to look-up an agent?
if (lookupAgent)
{ {
// Non-cached user agent lookup. if (needToLookupAgent)
PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
if (presences != null && presences.Length > 0)
{ {
foreach (PresenceInfo p in presences) PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() });
UUID foundRegionID = UUID.Zero;
if (presences != null)
{ {
if (p.RegionID != UUID.Zero) foreach (PresenceInfo p in presences)
{ {
upd = p; if (p.RegionID != UUID.Zero)
break; {
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.. m_log.WarnFormat("[GRID INSTANT MESSAGE]: Unable to find region {0}", regionID);
// This is one way to end the recursive loop break;
//
if (upd.RegionID == prevRegionID)
{
// m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
HandleUndeliverableMessage(im, result);
return;
}
} }
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"); lock (m_UserRegionMap)
HandleUndeliverableMessage(im, result); {
m_UserRegionMap[toAgentID] = regionID;
}
result(true);
return; 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) // If we reached this point then the message was not deliverable. Remove the bad cache entry and
{ // signal the delivery failure.
GridRegion reginfo = m_Scenes[0].GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, lock (m_UserRegionMap)
upd.RegionID); m_UserRegionMap.Remove(toAgentID);
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
// This is recursive!!!!! // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
SendGridInstantMessageViaXMLRPCAsync(im, result, HandleUndeliverableMessage(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);
}
} }
/// <summary> /// <summary>
@ -584,7 +533,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
/// <returns>Bool if the message was successfully delivered at the other side.</returns> /// <returns>Bool if the message was successfully delivered at the other side.</returns>
protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata) protected virtual bool doIMSending(GridRegion reginfo, Hashtable xmlrpcdata)
{ {
ArrayList SendParams = new ArrayList(); ArrayList SendParams = new ArrayList();
SendParams.Add(xmlrpcdata); SendParams.Add(xmlrpcdata);
XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams); XmlRpcRequest GridReq = new XmlRpcRequest("grid_instant_message", SendParams);

View File

@ -4133,7 +4133,10 @@ namespace OpenSim.Region.Framework.Scenes
/// <returns>true if we handled it.</returns> /// <returns>true if we handled it.</returns>
public virtual bool IncomingUpdateChildAgent(AgentPosition cAgentData) 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); ScenePresence childAgentUpdate = GetScenePresence(cAgentData.AgentID);
if (childAgentUpdate != null) if (childAgentUpdate != null)
{ {

View File

@ -2754,7 +2754,34 @@ namespace OpenSim.Region.Framework.Scenes
part.AddSittingAvatar(this); part.AddSittingAvatar(this);
cameraAtOffset = part.GetCameraAtOffset(); cameraAtOffset = part.GetCameraAtOffset();
if (!part.IsRoot && cameraAtOffset == Vector3.Zero)
cameraAtOffset = part.ParentGroup.RootPart.GetCameraAtOffset();
bool cameraEyeOffsetFromRootForChild = false;
cameraEyeOffset = part.GetCameraEyeOffset(); 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(); forceMouselook = part.GetForceMouselook();
// An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is // An viewer expects to specify sit positions as offsets to the root prim, even if a child prim is

View File

@ -147,6 +147,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
terrainHeight = _heightMap[(int)actor.Position.Y * (int)m_regionExtent.Y + (int)actor.Position.X]; terrainHeight = _heightMap[(int)actor.Position.Y * (int)m_regionExtent.Y + (int)actor.Position.X];
float height = terrainHeight + actor.Size.Z; float height = terrainHeight + actor.Size.Z;
// Console.WriteLine("height {0}, actorPosition {1}", height, actorPosition);
if (actor.Flying) if (actor.Flying)
{ {

View File

@ -6846,12 +6846,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
m_host.SetCameraEyeOffset(offset); m_host.SetCameraEyeOffset(offset);
if (m_host.ParentGroup.RootPart.GetCameraEyeOffset() == Vector3.Zero)
m_host.ParentGroup.RootPart.SetCameraEyeOffset(offset);
} }
public void llSetCameraAtOffset(LSL_Vector offset) public void llSetCameraAtOffset(LSL_Vector offset)
{ {
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
m_host.SetCameraAtOffset(offset); 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) public void llSetLinkCamera(LSL_Integer link, LSL_Vector eye, LSL_Vector at)

View File

@ -162,7 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
m_braceCount++; m_braceCount++;
// line number // line number
m_CSharpLine += 3; m_CSharpLine += 9;
// here's the payload // here's the payload
retstr += GenerateLine(); retstr += GenerateLine();

View File

@ -444,7 +444,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
// return compileScript; // return compileScript;
// } // }
private static string CreateCSCompilerScript( public static string CreateCSCompilerScript(
string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters) string compileScript, string className, string baseClassName, ParameterInfo[] constructorParameters)
{ {
compileScript = string.Format( compileScript = string.Format(
@ -472,7 +472,7 @@ namespace SecondLife
return compileScript; 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 + compileScript = String.Empty +
"Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " + "Imports OpenSim.Region.ScriptEngine.Shared: Imports System.Collections.Generic: " +

View File

@ -31,6 +31,7 @@ using System.Collections.Generic;
using Microsoft.CSharp; using Microsoft.CSharp;
using NUnit.Framework; using NUnit.Framework;
using OpenSim.Region.ScriptEngine.Shared.CodeTools; using OpenSim.Region.ScriptEngine.Shared.CodeTools;
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
using OpenSim.Tests.Common; using OpenSim.Tests.Common;
namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
@ -66,9 +67,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
m_CSCodeProvider = new CSharpCodeProvider(); m_CSCodeProvider = new CSharpCodeProvider();
m_compilerParameters = new CompilerParameters(); 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.dll"));
m_compilerParameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Shared.Api.Runtime.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; 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 /// Test the C# compiler error message can be mapped to the correct
/// line/column in the LSL source when an undeclared variable is used. /// line/column in the LSL source when an undeclared variable is used.
/// </summary> /// </summary>
//[Test] [Test]
public void TestUseUndeclaredVariable() public void TestUseUndeclaredVariable()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
@ -106,25 +108,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools.Tests
}"; }";
CSCodeGenerator cg = new CSCodeGenerator(); CSCodeGenerator cg = new CSCodeGenerator();
string output = "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\n" + string output = cg.Convert(input);
"namespace SecondLife { " +
"public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass {\n" + output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null);
"public Script() { } " + // System.Console.WriteLine(output);
cg.Convert(input) +
"} }\n";
Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap = cg.PositionMap; Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> positionMap = cg.PositionMap;
m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, output); 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), Assert.AreEqual(
positionMap[new KeyValuePair<int, int>(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]); new KeyValuePair<int, int>(5, 21),
positionMap[new KeyValuePair<int, int>(m_compilerResults.Errors[0].Line, m_compilerResults.Errors[0].Column)]);
} }
/// <summary> /// <summary>
/// Test that a string can be cast to string and another string /// Test that a string can be cast to string and another string
/// concatenated. /// concatenated.
/// </summary> /// </summary>
//[Test] [Test]
public void TestCastAndConcatString() public void TestCastAndConcatString()
{ {
TestHelpers.InMethod(); TestHelpers.InMethod();
@ -143,15 +157,20 @@ default
} }
}"; }";
// System.Console.WriteLine(input);
CSCodeGenerator cg = new CSCodeGenerator(); CSCodeGenerator cg = new CSCodeGenerator();
string output = "using OpenSim.Region.ScriptEngine.Shared; using System.Collections.Generic;\n" + string output = cg.Convert(input);
"namespace SecondLife { " +
"public class Script : OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass {\n" + output = Compiler.CreateCSCompilerScript(output, "script1", typeof(ScriptBaseClass).FullName, null);
"public Script() { } " + // System.Console.WriteLine(output);
cg.Convert(input) +
"} }\n";
m_compilerResults = m_CSCodeProvider.CompileAssemblyFromSource(m_compilerParameters, 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); Assert.AreEqual(0, m_compilerResults.Errors.Count);
} }
} }

View File

@ -574,7 +574,11 @@ namespace OpenSim.Tests.Common
public static ScenePresence AddChildScenePresence(Scene scene, UUID agentId) 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; acd.child = true;
// XXX: ViaLogin may not be correct for child agents // XXX: ViaLogin may not be correct for child agents

View File

@ -62,14 +62,23 @@ namespace OpenSim.Tests.Common.Mock
public event Action<RegionInfo, Vector3, Vector3> OnReceivedMoveAgentIntoRegion; public event Action<RegionInfo, Vector3, Vector3> OnReceivedMoveAgentIntoRegion;
public event Action<ulong, IPEndPoint> OnTestClientInformClientOfNeighbour; public event Action<ulong, IPEndPoint> OnTestClientInformClientOfNeighbour;
public event TestClientOnSendRegionTeleportDelegate OnTestClientSendRegionTeleport; public event TestClientOnSendRegionTeleportDelegate OnTestClientSendRegionTeleport;
public event Action<ISceneEntity, PrimUpdateFlags> OnReceivedEntityUpdate; public event Action<ISceneEntity, PrimUpdateFlags> OnReceivedEntityUpdate;
public event OnReceivedChatMessageDelegate OnReceivedChatMessage;
public event Action<GridInstantMessage> OnReceivedInstantMessage; public event Action<GridInstantMessage> OnReceivedInstantMessage;
public event Action<UUID> OnReceivedSendRebakeAvatarTextures; public event Action<UUID> OnReceivedSendRebakeAvatarTextures;
public delegate void TestClientOnSendRegionTeleportDelegate( public delegate void TestClientOnSendRegionTeleportDelegate(
ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
uint locationID, uint flags, string capsURL); 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 // disable warning: public events, part of the public API
#pragma warning disable 67 #pragma warning disable 67
@ -466,6 +475,34 @@ namespace OpenSim.Tests.Common.Mock
SentImageNotInDatabasePackets = new List<ImageNotInDatabasePacket>(); 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> /// <summary>
/// Attempt a teleport to the given region. /// Attempt a teleport to the given region.
/// </summary> /// </summary>
@ -550,6 +587,9 @@ namespace OpenSim.Tests.Common.Mock
string message, byte type, Vector3 fromPos, string fromName, string message, byte type, Vector3 fromPos, string fromName,
UUID fromAgentID, UUID ownerID, byte source, byte audible) 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) public void SendInstantMessage(GridInstantMessage im)

View File

@ -3082,6 +3082,7 @@
<Match path="Asset/Tests" pattern="*.cs" recurse="true"/> <Match path="Asset/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/Attachments/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/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/Friends/Tests" pattern="*.cs" recurse="true"/>
<Match path="Avatar/Inventory/Archiver/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"/> <Match path="Avatar/Inventory/Transfer/Tests" pattern="*.cs" recurse="true"/>