Merge branch 'master' into careminster

avinationmerge
Melanie 2013-08-13 22:53:47 +01:00
commit 4a6eff1ee8
15 changed files with 246 additions and 42 deletions

View File

@ -1223,12 +1223,16 @@ namespace OpenSim.Groups
{
if (m_debugEnabled) m_log.InfoFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name);
// NPCs currently don't have a CAPs structure or event queues. There is a strong argument for conveying this information
// to them anyway since it makes writing server-side bots a lot easier, but for now we don't do anything.
if (remoteClient.SceneAgent.PresenceType == PresenceType.Npc)
return;
OSDArray AgentData = new OSDArray(1);
OSDMap AgentDataMap = new OSDMap(1);
AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
AgentData.Add(AgentDataMap);
OSDArray GroupData = new OSDArray(data.Length);
OSDArray NewGroupData = new OSDArray(data.Length);
@ -1274,8 +1278,7 @@ namespace OpenSim.Groups
if (queue != null)
{
queue.Enqueue(queue.BuildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient));
}
}
}
private void SendScenePresenceUpdate(UUID AgentID, string Title)
@ -1337,6 +1340,7 @@ namespace OpenSim.Groups
GroupMembershipData[] membershipArray = GetProfileListedGroupMemberships(remoteClient, dataForAgentID);
SendGroupMembershipInfoViaCaps(remoteClient, dataForAgentID, membershipArray);
//remoteClient.SendAvatarGroupsReply(dataForAgentID, membershipArray);
if (remoteClient.AgentId == dataForAgentID)
remoteClient.RefreshGroupMembership();

View File

@ -404,7 +404,7 @@ namespace OpenSim.Groups
url = m_UserManagement.GetUserServerURL(uid, "GroupsServerURI");
if (url == string.Empty)
{
reason = "You don't have have an accessible groups server in your home world. You membership to this group in only within this grid.";
reason = "You don't have an accessible groups server in your home world. You membership to this group in only within this grid.";
return true;
}

View File

@ -229,7 +229,12 @@ namespace OpenSim.Region.ClientStack.Linden
queue.Enqueue(ev);
}
else
m_log.WarnFormat("[EVENTQUEUE]: (Enqueue) No queue found for agent {0} in region {1}", avatarID, m_scene.RegionInfo.RegionName);
{
OSDMap evMap = (OSDMap)ev;
m_log.WarnFormat(
"[EVENTQUEUE]: (Enqueue) No queue found for agent {0} when placing message {1} in region {2}",
avatarID, evMap["message"], m_scene.Name);
}
}
catch (NullReferenceException e)
{
@ -365,14 +370,14 @@ namespace OpenSim.Region.ClientStack.Linden
OSDMap ev = (OSDMap)element;
m_log.DebugFormat(
"Eq OUT {0,-30} to {1,-20} {2,-20}",
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.RegionInfo.RegionName);
ev["message"], m_scene.GetScenePresence(agentId).Name, m_scene.Name);
}
}
public Hashtable GetEvents(UUID requestID, UUID pAgentId)
{
if (DebugLevel >= 2)
m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.RegionInfo.RegionName);
m_log.WarnFormat("POLLED FOR EQ MESSAGES BY {0} in {1}", pAgentId, m_scene.Name);
Queue<OSD> queue = GetQueue(pAgentId);
if (queue == null)

View File

@ -799,7 +799,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
}
[Test]
public void TestSameSimulatorNeighbouringRegionsTeleport()
public void TestSameSimulatorNeighbouringRegionsTeleportV1()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
@ -904,5 +904,116 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests
// Check events
Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
}
[Test]
public void TestSameSimulatorNeighbouringRegionsTeleportV2()
{
TestHelpers.InMethod();
// TestHelpers.EnableLogging();
BaseHttpServer httpServer = new BaseHttpServer(99999);
MainServer.AddHttpServer(httpServer);
MainServer.Instance = httpServer;
AttachmentsModule attModA = new AttachmentsModule();
AttachmentsModule attModB = new AttachmentsModule();
EntityTransferModule etmA = new EntityTransferModule();
EntityTransferModule etmB = new EntityTransferModule();
LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule();
IConfigSource config = new IniConfigSource();
IConfig modulesConfig = config.AddConfig("Modules");
modulesConfig.Set("EntityTransferModule", etmA.Name);
modulesConfig.Set("SimulationServices", lscm.Name);
IConfig entityTransferConfig = config.AddConfig("EntityTransfer");
modulesConfig.Set("InventoryAccessModule", "BasicInventoryAccessModule");
SceneHelpers sh = new SceneHelpers();
TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000);
TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000);
SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm);
SceneHelpers.SetupSceneModules(
sceneA, config, new CapabilitiesModule(), etmA, attModA, new BasicInventoryAccessModule());
SceneHelpers.SetupSceneModules(
sceneB, config, new CapabilitiesModule(), etmB, attModB, new BasicInventoryAccessModule());
UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(sceneA, 0x1);
AgentCircuitData acd = SceneHelpers.GenerateAgentData(ua1.PrincipalID);
TestClient tc = new TestClient(acd, sceneA);
List<TestClient> destinationTestClients = new List<TestClient>();
EntityTransferHelpers.SetUpInformClientOfNeighbour(tc, destinationTestClients);
ScenePresence beforeTeleportSp = SceneHelpers.AddScenePresence(sceneA, tc, acd);
beforeTeleportSp.AbsolutePosition = new Vector3(30, 31, 32);
Assert.That(destinationTestClients.Count, Is.EqualTo(1));
Assert.That(destinationTestClients[0], Is.Not.Null);
InventoryItemBase attItem = CreateAttachmentItem(sceneA, ua1.PrincipalID, "att", 0x10, 0x20);
sceneA.AttachmentsModule.RezSingleAttachmentFromInventory(
beforeTeleportSp, attItem.ID, (uint)AttachmentPoint.Chest);
Vector3 teleportPosition = new Vector3(10, 11, 12);
Vector3 teleportLookAt = new Vector3(20, 21, 22);
// Here, we need to make clientA's receipt of SendRegionTeleport trigger clientB's CompleteMovement(). This
// is to operate the teleport V2 mechanism where the EntityTransferModule will first request the client to
// CompleteMovement to the region and then call UpdateAgent to the destination region to confirm the receipt
// Both these operations will occur on different threads and will wait for each other.
// We have to do this via ThreadPool directly since FireAndForget has been switched to sync for the V1
// test protocol, where we are trying to avoid unpredictable async operations in regression tests.
((TestClient)beforeTeleportSp.ControllingClient).OnTestClientSendRegionTeleport
+= (regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL)
=> ThreadPool.UnsafeQueueUserWorkItem(o => destinationTestClients[0].CompleteMovement(), null);
m_numberOfAttachEventsFired = 0;
sceneA.RequestTeleportLocation(
beforeTeleportSp.ControllingClient,
sceneB.RegionInfo.RegionHandle,
teleportPosition,
teleportLookAt,
(uint)TeleportFlags.ViaLocation);
// Check attachments have made it into sceneB
ScenePresence afterTeleportSceneBSp = sceneB.GetScenePresence(ua1.PrincipalID);
// This is appearance data, as opposed to actually rezzed attachments
List<AvatarAttachment> sceneBAttachments = afterTeleportSceneBSp.Appearance.GetAttachments();
Assert.That(sceneBAttachments.Count, Is.EqualTo(1));
Assert.That(sceneBAttachments[0].AttachPoint, Is.EqualTo((int)AttachmentPoint.Chest));
Assert.That(sceneBAttachments[0].ItemID, Is.EqualTo(attItem.ID));
Assert.That(sceneBAttachments[0].AssetID, Is.EqualTo(attItem.AssetID));
Assert.That(afterTeleportSceneBSp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
// This is the actual attachment
List<SceneObjectGroup> actualSceneBAttachments = afterTeleportSceneBSp.GetAttachments();
Assert.That(actualSceneBAttachments.Count, Is.EqualTo(1));
SceneObjectGroup actualSceneBAtt = actualSceneBAttachments[0];
Assert.That(actualSceneBAtt.Name, Is.EqualTo(attItem.Name));
Assert.That(actualSceneBAtt.AttachmentPoint, Is.EqualTo((uint)AttachmentPoint.Chest));
Assert.That(sceneB.GetSceneObjectGroups().Count, Is.EqualTo(1));
// Check attachments have been removed from sceneA
ScenePresence afterTeleportSceneASp = sceneA.GetScenePresence(ua1.PrincipalID);
// Since this is appearance data, it is still present on the child avatar!
List<AvatarAttachment> sceneAAttachments = afterTeleportSceneASp.Appearance.GetAttachments();
Assert.That(sceneAAttachments.Count, Is.EqualTo(1));
Assert.That(afterTeleportSceneASp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest));
// This is the actual attachment, which should no longer exist
List<SceneObjectGroup> actualSceneAAttachments = afterTeleportSceneASp.GetAttachments();
Assert.That(actualSceneAAttachments.Count, Is.EqualTo(0));
Assert.That(sceneA.GetSceneObjectGroups().Count, Is.EqualTo(0));
// Check events
Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(0));
}
}
}

View File

@ -1212,7 +1212,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups
AgentDataMap.Add("AgentID", OSD.FromUUID(dataForAgentID));
AgentData.Add(AgentDataMap);
OSDArray GroupData = new OSDArray(data.Length);
OSDArray NewGroupData = new OSDArray(data.Length);

View File

@ -377,7 +377,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
m_log.DebugFormat("[NPC MODULE]: Found {0} {1} to remove",
agentID, av.Name);
*/
scene.RemoveClient(agentID, false);
scene.IncomingCloseAgent(agentID, false);
// scene.RemoveClient(agentID, false);
m_avatars.Remove(agentID);
// m_log.DebugFormat("[NPC MODULE]: Removed NPC {0} {1}", agentID, av.Name);

View File

@ -311,21 +311,28 @@ public class BSActorAvatarMove : BSActor
// Don't care about collisions with the terrain
if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID)
{
OMV.Vector3 touchPosition = kvp.Value.Position;
m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
m_controllingPrim.LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
BSPhysObject collisionObject;
if (m_physicsScene.PhysObjects.TryGetValue(kvp.Key, out collisionObject))
{
// This contact is within the 'near the feet' range.
// The normal should be our contact point to the object so it is pointing away
// thus the difference between our facing orientation and the normal should be small.
OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
if (diff < BSParam.AvatarStepApproachFactor)
if (!collisionObject.IsVolumeDetect)
{
if (highestTouchPosition.Z < touchPosition.Z)
highestTouchPosition = touchPosition;
OMV.Vector3 touchPosition = kvp.Value.Position;
m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
m_controllingPrim.LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
{
// This contact is within the 'near the feet' range.
// The normal should be our contact point to the object so it is pointing away
// thus the difference between our facing orientation and the normal should be small.
OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
if (diff < BSParam.AvatarStepApproachFactor)
{
if (highestTouchPosition.Z < touchPosition.Z)
highestTouchPosition = touchPosition;
}
}
}
}
}

View File

@ -404,6 +404,7 @@ public sealed class BSCharacter : BSPhysObject
// Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more
public override void SetVolumeDetect(int param) { return; }
public override bool IsVolumeDetect { get { return false; } }
public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } }
public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } }

View File

@ -175,6 +175,7 @@ public abstract class BSPhysObject : PhysicsActor
public abstract bool IsSolid { get; }
public abstract bool IsStatic { get; }
public abstract bool IsSelected { get; }
public abstract bool IsVolumeDetect { get; }
// Materialness
public MaterialAttributes.Material Material { get; private set; }

View File

@ -617,6 +617,10 @@ public class BSPrim : BSPhysObject
}
return;
}
public override bool IsVolumeDetect
{
get { return _isVolumeDetect; }
}
public override void SetMaterial(int material)
{
base.SetMaterial(material);

View File

@ -533,7 +533,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
m_log.Warn(
string.Format(
"[SCRIPT INSTANCE]: Could not delete script state {0} for script {1} (id {2}) in part {3} (id {4}) in object {5} in {6}. Exception ",
ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name),
savedState, ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name),
e);
}
}

View File

@ -61,8 +61,13 @@ namespace OpenSim.Tests.Common.Mock
// Test client specific events - for use by tests to implement some IClientAPI behaviour.
public event Action<RegionInfo, Vector3, Vector3> OnReceivedMoveAgentIntoRegion;
public event Action<ulong, IPEndPoint> OnTestClientInformClientOfNeighbour;
public event TestClientOnSendRegionTeleportDelegate OnTestClientSendRegionTeleport;
public event Action<GridInstantMessage> OnReceivedInstantMessage;
public delegate void TestClientOnSendRegionTeleportDelegate(
ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
uint locationID, uint flags, string capsURL);
// disable warning: public events, part of the public API
#pragma warning disable 67
@ -475,7 +480,8 @@ namespace OpenSim.Tests.Common.Mock
public void CompleteMovement()
{
OnCompleteMovementToRegion(this, true);
if (OnCompleteMovementToRegion != null)
OnCompleteMovementToRegion(this, true);
}
/// <summary>
@ -615,21 +621,25 @@ namespace OpenSim.Tests.Common.Mock
OnTestClientInformClientOfNeighbour(neighbourHandle, neighbourExternalEndPoint);
}
public virtual void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
uint locationID, uint flags, string capsURL)
public virtual void SendRegionTeleport(
ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint,
uint locationID, uint flags, string capsURL)
{
m_log.DebugFormat("[TEST CLIENT]: Received SendRegionTeleport");
m_log.DebugFormat(
"[TEST CLIENT]: Received SendRegionTeleport for {0} {1} on {2}", m_firstName, m_lastName, m_scene.Name);
CapsSeedUrl = capsURL;
// We don't do this here so that the source region can complete processing first in a single-threaded
// regression test scenario. The test itself will have to call CompleteTeleportClientSide() after a teleport
// CompleteTeleportClientSide();
if (OnTestClientSendRegionTeleport != null)
OnTestClientSendRegionTeleport(
regionHandle, simAccess, regionExternalEndPoint, locationID, flags, capsURL);
}
public virtual void SendTeleportFailed(string reason)
{
m_log.DebugFormat("[TEST CLIENT]: Teleport failed with reason {0}", reason);
m_log.DebugFormat(
"[TEST CLIENT]: Teleport failed for {0} {1} on {2} with reason {3}",
m_firstName, m_lastName, m_scene.Name, reason);
}
public virtual void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt,

View File

@ -0,0 +1,43 @@
/*
* 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 OpenMetaverse;
using System;
using System.Collections.Generic;
using System.Linq;
using pCampBot.Interfaces;
namespace pCampBot
{
/// <summary>
/// Do nothing
/// </summary>
public class NoneBehaviour : AbstractBehaviour
{
public NoneBehaviour() { Name = "None"; }
}
}

View File

@ -177,18 +177,21 @@ namespace pCampBot
// We must give each bot its own list of instantiated behaviours since they store state.
List<IBehaviour> behaviours = new List<IBehaviour>();
// Hard-coded for now
// Hard-coded for now
if (behaviourSwitches.Contains("c"))
behaviours.Add(new CrossBehaviour());
if (behaviourSwitches.Contains("g"))
behaviours.Add(new GrabbingBehaviour());
if (behaviourSwitches.Contains("n"))
behaviours.Add(new NoneBehaviour());
if (behaviourSwitches.Contains("p"))
behaviours.Add(new PhysicsBehaviour());
if (behaviourSwitches.Contains("g"))
behaviours.Add(new GrabbingBehaviour());
if (behaviourSwitches.Contains("t"))
behaviours.Add(new TeleportBehaviour());
if (behaviourSwitches.Contains("c"))
behaviours.Add(new CrossBehaviour());
StartBot(this, behaviours, firstName, lastName, password, loginUri);
}
@ -327,17 +330,30 @@ namespace pCampBot
string outputFormat = "{0,-30} {1, -30} {2,-14}";
MainConsole.Instance.OutputFormat(outputFormat, "Name", "Region", "Status");
Dictionary<ConnectionState, int> totals = new Dictionary<ConnectionState, int>();
foreach (object o in Enum.GetValues(typeof(ConnectionState)))
totals[(ConnectionState)o] = 0;
lock (m_lBot)
{
foreach (Bot pb in m_lBot)
{
Simulator currentSim = pb.Client.Network.CurrentSim;
totals[pb.ConnectionState]++;
MainConsole.Instance.OutputFormat(
outputFormat,
pb.Name, currentSim != null ? currentSim.Name : "(none)", pb.ConnectionState);
}
}
ConsoleDisplayList cdl = new ConsoleDisplayList();
foreach (KeyValuePair<ConnectionState, int> kvp in totals)
cdl.AddRow(kvp.Key, kvp.Value);
MainConsole.Instance.OutputFormat("\n{0}", cdl.ToString());
}
/*

View File

@ -123,9 +123,10 @@ namespace pCampBot
" -password password for the bots\n" +
" -b, behaviours behaviours for bots. Comma separated, e.g. p,g. Default is p\n" +
" current options are:\n" +
" p (physics)\n" +
" g (grab)\n" +
" t (teleport)\n" +
" p (physics - bots constantly move and jump around)\n" +
" g (grab - bots randomly click prims whether set clickable or not)\n" +
" n (none - bots do nothing)\n" +
" t (teleport - bots regularly teleport between regions on the grid)\n" +
// " c (cross)" +
" -wear set appearance folder to load from (default: no)\n" +
" -h, -help show this message");