Merge branch 'master' into bigmerge
commit
a8270cb48c
|
@ -102,12 +102,28 @@ namespace OpenSim.Framework
|
|||
|
||||
bool TryGetScenePresence(UUID agentID, out object scenePresence);
|
||||
|
||||
T RequestModuleInterface<T>();
|
||||
T[] RequestModuleInterfaces<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Register an interface to a region module. This allows module methods to be called directly as
|
||||
/// well as via events. If there is already a module registered for this interface, it is not replaced
|
||||
/// (is this the best behaviour?)
|
||||
/// </summary>
|
||||
/// <param name="mod"></param>
|
||||
void RegisterModuleInterface<M>(M mod);
|
||||
|
||||
void StackModuleInterface<M>(M mod);
|
||||
|
||||
/// <summary>
|
||||
/// For the given interface, retrieve the region module which implements it.
|
||||
/// </summary>
|
||||
/// <returns>null if there is no registered module implementing that interface</returns>
|
||||
T RequestModuleInterface<T>();
|
||||
|
||||
/// <summary>
|
||||
/// For the given interface, retrieve an array of region modules that implement it.
|
||||
/// </summary>
|
||||
/// <returns>an empty array if there are no registered modules implementing that interface</returns>
|
||||
T[] RequestModuleInterfaces<T>();
|
||||
|
||||
// void AddCommand(object module, string command, string shorthelp, string longhelp, CommandDelegate callback);
|
||||
|
||||
ISceneObject DeserializeObject(string representation);
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace OpenSim
|
|||
/// <param name="networkInfo"></param>
|
||||
/// <returns>A configuration that gets passed to modules</returns>
|
||||
public OpenSimConfigSource LoadConfigSettings(
|
||||
IConfigSource argvSource, out ConfigSettings configSettings,
|
||||
IConfigSource argvSource, EnvConfigSource envConfigSource, out ConfigSettings configSettings,
|
||||
out NetworkServersInfo networkInfo)
|
||||
{
|
||||
m_configSettings = configSettings = new ConfigSettings();
|
||||
|
@ -195,6 +195,24 @@ namespace OpenSim
|
|||
// Make sure command line options take precedence
|
||||
m_config.Source.Merge(argvSource);
|
||||
|
||||
|
||||
IConfig enVars = m_config.Source.Configs["Environment"];
|
||||
|
||||
if( enVars != null )
|
||||
{
|
||||
string[] env_keys = enVars.GetKeys();
|
||||
|
||||
foreach ( string key in env_keys )
|
||||
{
|
||||
envConfigSource.AddEnv(key, string.Empty);
|
||||
}
|
||||
|
||||
envConfigSource.LoadEnv();
|
||||
m_config.Source.Merge(envConfigSource);
|
||||
m_config.Source.ExpandKeyValues();
|
||||
}
|
||||
|
||||
|
||||
ReadConfigSettings();
|
||||
|
||||
return m_config;
|
||||
|
|
|
@ -112,6 +112,13 @@ namespace OpenSim
|
|||
get { return m_clientServers; }
|
||||
}
|
||||
|
||||
protected EnvConfigSource m_EnvConfigSource = new EnvConfigSource();
|
||||
|
||||
public EnvConfigSource envConfigSource
|
||||
{
|
||||
get { return m_EnvConfigSource; }
|
||||
}
|
||||
|
||||
protected List<IClientNetworkServer> m_clientServers = new List<IClientNetworkServer>();
|
||||
|
||||
public uint HttpServerPort
|
||||
|
@ -146,7 +153,7 @@ namespace OpenSim
|
|||
protected virtual void LoadConfigSettings(IConfigSource configSource)
|
||||
{
|
||||
m_configLoader = new ConfigurationLoader();
|
||||
m_config = m_configLoader.LoadConfigSettings(configSource, out m_configSettings, out m_networkServersInfo);
|
||||
m_config = m_configLoader.LoadConfigSettings(configSource, envConfigSource, out m_configSettings, out m_networkServersInfo);
|
||||
ReadExtraConfigSettings();
|
||||
}
|
||||
|
||||
|
|
|
@ -82,16 +82,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
m_log.Info("[PRIM INVENTORY]: Starting scripts in scene");
|
||||
|
||||
IScriptModule[] engines = RequestModuleInterfaces<IScriptModule>();
|
||||
if (engines != null)
|
||||
{
|
||||
foreach (IScriptModule engine in engines)
|
||||
{
|
||||
if (engine != null)
|
||||
{
|
||||
engine.StartProcessing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (IScriptModule engine in engines)
|
||||
engine.StartProcessing();
|
||||
}
|
||||
|
||||
public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item)
|
||||
|
|
|
@ -451,7 +451,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
}
|
||||
else
|
||||
{
|
||||
return new T[] { default(T) };
|
||||
return new T[] {};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -252,7 +252,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private byte[] m_TextureAnimation;
|
||||
private byte m_clickAction;
|
||||
private Color m_color = Color.Black;
|
||||
private string m_description = String.Empty;
|
||||
private readonly List<uint> m_lastColliders = new List<uint>();
|
||||
private int m_linkNum;
|
||||
|
||||
|
@ -331,11 +330,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// </summary>
|
||||
public SceneObjectPart()
|
||||
{
|
||||
// It's not necessary to persist this
|
||||
m_TextureAnimation = Utils.EmptyBytes;
|
||||
m_particleSystem = Utils.EmptyBytes;
|
||||
Rezzed = DateTime.UtcNow;
|
||||
Description = String.Empty;
|
||||
|
||||
// Prims currently only contain a single folder (Contents). From looking at the Second Life protocol,
|
||||
// this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
|
||||
// the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
|
||||
m_inventory = new SceneObjectPartInventory(this);
|
||||
}
|
||||
|
||||
|
@ -349,11 +351,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="offsetPosition"></param>
|
||||
public SceneObjectPart(
|
||||
UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
|
||||
Quaternion rotationOffset, Vector3 offsetPosition)
|
||||
Quaternion rotationOffset, Vector3 offsetPosition) : this()
|
||||
{
|
||||
m_name = "Object";
|
||||
|
||||
Rezzed = DateTime.UtcNow;
|
||||
CreationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
|
||||
LastOwnerID = CreatorID = OwnerID = ownerID;
|
||||
UUID = UUID.Random();
|
||||
|
@ -368,19 +369,10 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
Velocity = Vector3.Zero;
|
||||
AngularVelocity = Vector3.Zero;
|
||||
Acceleration = Vector3.Zero;
|
||||
m_TextureAnimation = Utils.EmptyBytes;
|
||||
m_particleSystem = Utils.EmptyBytes;
|
||||
|
||||
// Prims currently only contain a single folder (Contents). From looking at the Second Life protocol,
|
||||
// this appears to have the same UUID (!) as the prim. If this isn't the case, one can't drag items from
|
||||
// the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log
|
||||
|
||||
Flags = 0;
|
||||
CreateSelected = true;
|
||||
|
||||
TrimPermissions();
|
||||
|
||||
m_inventory = new SceneObjectPartInventory(this);
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
@ -938,19 +930,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
set { m_acceleration = value; }
|
||||
}
|
||||
|
||||
public string Description
|
||||
{
|
||||
get { return m_description; }
|
||||
set
|
||||
{
|
||||
m_description = value;
|
||||
PhysicsActor actor = PhysActor;
|
||||
if (actor != null)
|
||||
{
|
||||
actor.SOPDescription = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
public string Description { get; set; }
|
||||
|
||||
/// <value>
|
||||
/// Text color.
|
||||
|
@ -1595,8 +1575,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Basic Physics returns null.. joy joy joy.
|
||||
if (PhysActor != null)
|
||||
{
|
||||
PhysActor.SOPName = this.Name; // save object name and desc into the PhysActor so ODE internals know the joint/body info
|
||||
PhysActor.SOPDescription = this.Description;
|
||||
PhysActor.SOPName = this.Name; // save object into the PhysActor so ODE internals know the joint/body info
|
||||
PhysActor.SetMaterial(Material);
|
||||
DoPhysicsPropertyUpdate(RigidBody, true);
|
||||
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
|
||||
|
|
|
@ -282,8 +282,6 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
ArrayList ret = new ArrayList();
|
||||
|
||||
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||
if (engines == null) // No engine at all
|
||||
return ret;
|
||||
|
||||
foreach (IScriptModule e in engines)
|
||||
{
|
||||
|
@ -397,7 +395,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
private void RestoreSavedScriptState(UUID oldID, UUID newID)
|
||||
{
|
||||
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||
if (engines == null) // No engine at all
|
||||
if (engines.Length == 0) // No engine at all
|
||||
return;
|
||||
|
||||
if (m_part.ParentGroup.m_savedScriptState.ContainsKey(oldID))
|
||||
|
@ -437,6 +435,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
m_part.ParentGroup.m_savedScriptState[oldID] = newDoc.OuterXml;
|
||||
}
|
||||
|
||||
foreach (IScriptModule e in engines)
|
||||
{
|
||||
if (e != null)
|
||||
|
@ -445,6 +444,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_part.ParentGroup.m_savedScriptState.Remove(oldID);
|
||||
}
|
||||
}
|
||||
|
@ -1327,7 +1327,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||
|
||||
if (engines == null) // No engine at all
|
||||
if (engines.Length == 0) // No engine at all
|
||||
return ret;
|
||||
|
||||
Items.LockItemsForRead(true);
|
||||
|
@ -1365,7 +1365,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
public void ResumeScripts()
|
||||
{
|
||||
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||
if (engines == null)
|
||||
if (engines.Length == 0)
|
||||
return;
|
||||
|
||||
|
||||
|
|
|
@ -3535,23 +3535,23 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
/// <param name="args">The arguments for the event</param>
|
||||
public void SendScriptEventToAttachments(string eventName, Object[] args)
|
||||
{
|
||||
if (m_scriptEngines != null)
|
||||
{
|
||||
lock (m_attachments)
|
||||
{
|
||||
foreach (SceneObjectGroup grp in m_attachments)
|
||||
{
|
||||
// 16384 is CHANGED_ANIMATION
|
||||
//
|
||||
// Send this to all attachment root prims
|
||||
//
|
||||
foreach (IScriptModule m in m_scriptEngines)
|
||||
{
|
||||
if (m == null) // No script engine loaded
|
||||
continue;
|
||||
if (m_scriptEngines.Length == 0)
|
||||
return;
|
||||
|
||||
m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION });
|
||||
}
|
||||
lock (m_attachments)
|
||||
{
|
||||
foreach (SceneObjectGroup grp in m_attachments)
|
||||
{
|
||||
// 16384 is CHANGED_ANIMATION
|
||||
//
|
||||
// Send this to all attachment root prims
|
||||
//
|
||||
foreach (IScriptModule m in m_scriptEngines)
|
||||
{
|
||||
if (m == null) // No script engine loaded
|
||||
continue;
|
||||
|
||||
m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace OpenSim.Region.OptionalModules.PhysicsParameters
|
|||
public class PhysicsParameters : ISharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static string LogHeader = "[PHYSICS PARAMETERS]";
|
||||
// private static string LogHeader = "[PHYSICS PARAMETERS]";
|
||||
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
private static bool m_commandsLoaded = false;
|
||||
|
|
|
@ -160,8 +160,19 @@ namespace OpenSim.Region.Physics.Manager
|
|||
|
||||
public abstract bool Selected { set; }
|
||||
|
||||
/// <summary>
|
||||
/// Name of this actor.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// XXX: Bizarrely, this cannot be "Terrain" or "Water" right now unless it really is simulating terrain or
|
||||
/// water. This is not a problem due to the formatting of names given by prims and avatars.
|
||||
/// </remarks>
|
||||
public string Name { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is being used by ODE joint code.
|
||||
/// </summary>
|
||||
public string SOPName;
|
||||
public string SOPDescription;
|
||||
|
||||
public abstract void CrossingFailure();
|
||||
|
||||
|
|
|
@ -224,15 +224,9 @@ namespace OpenSim.Region.Physics.Manager
|
|||
return false;
|
||||
}
|
||||
|
||||
public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents)
|
||||
{
|
||||
return;
|
||||
}
|
||||
public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
|
||||
|
||||
public virtual void UnCombine(PhysicsScene pScene)
|
||||
{
|
||||
|
||||
}
|
||||
public virtual void UnCombine(PhysicsScene pScene) {}
|
||||
|
||||
/// <summary>
|
||||
/// Queue a raycast against the physics scene.
|
||||
|
|
|
@ -70,7 +70,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
private Vector3 _position;
|
||||
private d.Vector3 _zeroPosition;
|
||||
// private d.Matrix3 m_StandUpRotation;
|
||||
private bool _zeroFlag = false;
|
||||
private bool m_lastUpdateSent = false;
|
||||
private Vector3 _velocity;
|
||||
|
@ -123,9 +122,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private float m_buoyancy = 0f;
|
||||
|
||||
// private CollisionLocker ode;
|
||||
|
||||
private string m_name = String.Empty;
|
||||
|
||||
private bool[] m_colliderarr = new bool[11];
|
||||
private bool[] m_colliderGroundarr = new bool[11];
|
||||
|
||||
|
@ -181,7 +177,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f);
|
||||
m_taintPosition = _position;
|
||||
|
||||
m_log.Warn("[PHYSICS]: Got NaN Position on Character Create");
|
||||
m_log.WarnFormat("[ODE CHARACTER]: Got NaN Position on Character Create for {0}", avName);
|
||||
}
|
||||
|
||||
_parent_scene = parent_scene;
|
||||
|
@ -204,7 +200,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
m_colliderarr[i] = false;
|
||||
}
|
||||
CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
|
||||
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
|
||||
//m_log.Info("[ODE CHARACTER]: " + CAPSULE_LENGTH.ToString());
|
||||
m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH;
|
||||
|
||||
m_isPhysical = false; // current status: no ODE information exists
|
||||
|
@ -212,7 +208,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
|
||||
m_name = avName;
|
||||
Name = avName;
|
||||
}
|
||||
|
||||
public override int PhysicsActorType
|
||||
|
@ -269,7 +265,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
set
|
||||
{
|
||||
flying = value;
|
||||
// m_log.DebugFormat("[PHYSICS]: Set OdeCharacter Flying to {0}", flying);
|
||||
// m_log.DebugFormat("[ODE CHARACTER]: Set OdeCharacter Flying to {0}", flying);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,7 +436,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character");
|
||||
m_log.WarnFormat("[ODE CHARACTER]: Got a NaN Position from Scene on character {0}", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -467,7 +463,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
Vector3 SetSize = value;
|
||||
m_tainted_CAPSULE_LENGTH = (SetSize.Z * 1.15f) - CAPSULE_RADIUS * 2.0f;
|
||||
// m_log.Info("[SIZE]: " + CAPSULE_LENGTH);
|
||||
// m_log.Info("[ODE CHARACTER]: " + CAPSULE_LENGTH);
|
||||
|
||||
// If we reset velocity here, then an avatar stalls when it crosses a border for the first time
|
||||
// (as the height of the new root agent is set).
|
||||
|
@ -477,7 +473,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character");
|
||||
m_log.WarnFormat("[ODE CHARACTER]: Got a NaN Size from Scene on {0}", Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -529,7 +525,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// movementVector.Z is zero
|
||||
|
||||
// calculate tilt components based on desired amount of tilt and current (snapped) heading.
|
||||
|
@ -537,7 +532,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane;
|
||||
float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane;
|
||||
|
||||
//m_log.Debug("[PHYSICS] changing avatar tilt");
|
||||
//m_log.Debug("[ODE CHARACTER]: changing avatar tilt");
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent);
|
||||
|
@ -546,124 +541,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This creates the Avatar's physical Surrogate at the position supplied
|
||||
/// </summary>
|
||||
/// <param name="npositionX"></param>
|
||||
/// <param name="npositionY"></param>
|
||||
/// <param name="npositionZ"></param>
|
||||
|
||||
// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
|
||||
// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
|
||||
// place that is safe to call this routine AvatarGeomAndBodyCreation.
|
||||
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor)
|
||||
{
|
||||
//CAPSULE_LENGTH = -5;
|
||||
//CAPSULE_RADIUS = -5;
|
||||
int dAMotorEuler = 1;
|
||||
_parent_scene.waitForSpaceUnlock(_parent_scene.space);
|
||||
if (CAPSULE_LENGTH <= 0)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_LENGTH = 0.01f;
|
||||
|
||||
}
|
||||
|
||||
if (CAPSULE_RADIUS <= 0)
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_RADIUS = 0.01f;
|
||||
|
||||
}
|
||||
Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
|
||||
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
|
||||
|
||||
d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
Body = d.BodyCreate(_parent_scene.world);
|
||||
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
|
||||
|
||||
_position.X = npositionX;
|
||||
_position.Y = npositionY;
|
||||
_position.Z = npositionZ;
|
||||
|
||||
m_taintPosition = _position;
|
||||
|
||||
d.BodySetMass(Body, ref ShellMass);
|
||||
d.Matrix3 m_caprot;
|
||||
// 90 Stand up on the cap of the capped cyllinder
|
||||
if (_parent_scene.IsAvCapsuleTilted)
|
||||
{
|
||||
d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2));
|
||||
}
|
||||
|
||||
|
||||
d.GeomSetRotation(Shell, ref m_caprot);
|
||||
d.BodySetRotation(Body, ref m_caprot);
|
||||
|
||||
d.GeomSetBody(Shell, Body);
|
||||
|
||||
|
||||
// The purpose of the AMotor here is to keep the avatar's physical
|
||||
// surrogate from rotating while moving
|
||||
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
|
||||
d.JointAttach(Amotor, Body, IntPtr.Zero);
|
||||
d.JointSetAMotorMode(Amotor, dAMotorEuler);
|
||||
d.JointSetAMotorNumAxes(Amotor, 3);
|
||||
d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
|
||||
d.JointSetAMotorAngle(Amotor, 0, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 1, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 2, 0);
|
||||
|
||||
// These lowstops and high stops are effectively (no wiggle room)
|
||||
if (_parent_scene.IsAvCapsuleTilted)
|
||||
{
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Documentation of capsule motor LowStop and HighStop parameters
|
||||
// Intentionally introduce some tilt into the capsule by setting
|
||||
// the motor stops to small epsilon values. This small tilt prevents
|
||||
// the capsule from falling into the terrain; a straight-up capsule
|
||||
// (with -0..0 motor stops) falls into the terrain for reasons yet
|
||||
// to be comprehended in their entirety.
|
||||
#endregion
|
||||
AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop
|
||||
}
|
||||
|
||||
// Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the
|
||||
// capped cyllinder will fall over
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor);
|
||||
|
||||
//d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
|
||||
//d.QfromR(
|
||||
//d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068,
|
||||
//
|
||||
//m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
|
||||
//standupStraight();
|
||||
}
|
||||
|
||||
//
|
||||
/// <summary>
|
||||
/// Uses the capped cyllinder volume formula to calculate the avatar's mass.
|
||||
/// This may be used in calculations in the scene/scenepresence
|
||||
|
@ -774,7 +651,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character");
|
||||
m_log.WarnFormat("[ODE CHARACTER]: Got a NaN velocity from Scene for {0}", Name);
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[PHYSICS]: Set target velocity of {0}", m_taintTargetVelocity);
|
||||
|
@ -836,7 +713,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
m_taintForce += force;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
|
||||
//doForce(force);
|
||||
// If uncommented, things get pushed off world
|
||||
//
|
||||
// m_log.Debug("Push!");
|
||||
|
@ -852,7 +728,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Got a NaN force applied to a Character");
|
||||
m_log.WarnFormat("[ODE CHARACTER]: Got a NaN force applied to {0}", Name);
|
||||
}
|
||||
//m_lastUpdateSent = false;
|
||||
}
|
||||
|
@ -861,15 +737,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// After all of the forces add up with 'add force' we apply them with doForce
|
||||
/// </summary>
|
||||
/// <param name="force"></param>
|
||||
public void doForce(Vector3 force)
|
||||
{
|
||||
d.BodyAddForce(Body, force.X, force.Y, force.Z);
|
||||
}
|
||||
|
||||
public override void SetMomentum(Vector3 momentum)
|
||||
{
|
||||
}
|
||||
|
@ -878,9 +745,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
/// Called from Simulate
|
||||
/// This is the avatar's movement control + PID Controller
|
||||
/// </summary>
|
||||
/// <param name="defects">
|
||||
/// If there is something wrong with the character (e.g. its position is non-finite)
|
||||
/// then it is added to this list. The ODE structures associated with it are also destroyed.
|
||||
/// <param name="defects">The character will be added to this list if there is something wrong (non-finite
|
||||
/// position or velocity).
|
||||
/// </param>
|
||||
internal void Move(List<OdeCharacter> defects)
|
||||
{
|
||||
|
@ -903,12 +769,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
if (!localPos.IsFinite())
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Avatar Position is non-finite!");
|
||||
m_log.WarnFormat(
|
||||
"[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.",
|
||||
localPos, Name);
|
||||
|
||||
defects.Add(this);
|
||||
// _parent_scene.RemoveCharacter(this);
|
||||
|
||||
DestroyOdeStructures();
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1035,26 +900,31 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
if (vec.IsFinite())
|
||||
{
|
||||
doForce(vec);
|
||||
// Apply the total force acting on this avatar
|
||||
d.BodyAddForce(Body, vec.X, vec.Y, vec.Z);
|
||||
|
||||
if (!_zeroFlag)
|
||||
AlignAvatarTiltWithCurrentDirectionOfMovement(vec);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()");
|
||||
m_log.Warn("[PHYSICS]: Avatar Position is non-finite!");
|
||||
defects.Add(this);
|
||||
// _parent_scene.RemoveCharacter(this);
|
||||
m_log.WarnFormat(
|
||||
"[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.",
|
||||
vec, Name);
|
||||
|
||||
DestroyOdeStructures();
|
||||
defects.Add(this);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the reported position and velocity. This essentially sends the data up to ScenePresence.
|
||||
/// </summary>
|
||||
internal void UpdatePositionAndVelocity()
|
||||
/// <param name="defects">The character will be added to this list if there is something wrong (non-finite
|
||||
/// position or velocity).
|
||||
/// </param>
|
||||
internal void UpdatePositionAndVelocity(List<OdeCharacter> defects)
|
||||
{
|
||||
// no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
|
||||
d.Vector3 newPos;
|
||||
|
@ -1065,10 +935,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
catch (NullReferenceException)
|
||||
{
|
||||
bad = true;
|
||||
_parent_scene.BadCharacter(this);
|
||||
defects.Add(this);
|
||||
newPos = new d.Vector3(_position.X, _position.Y, _position.Z);
|
||||
base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem!
|
||||
m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid);
|
||||
m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
|
||||
|
@ -1136,6 +1008,123 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This creates the Avatar's physical Surrogate in ODE at the position supplied
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access
|
||||
/// to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only
|
||||
/// place that is safe to call this routine AvatarGeomAndBodyCreation.
|
||||
/// </remarks>
|
||||
/// <param name="npositionX"></param>
|
||||
/// <param name="npositionY"></param>
|
||||
/// <param name="npositionZ"></param>
|
||||
/// <param name="tensor"></param>
|
||||
private void CreateOdeStructures(float npositionX, float npositionY, float npositionZ, float tensor)
|
||||
{
|
||||
int dAMotorEuler = 1;
|
||||
// _parent_scene.waitForSpaceUnlock(_parent_scene.space);
|
||||
if (CAPSULE_LENGTH <= 0)
|
||||
{
|
||||
m_log.Warn("[ODE CHARACTER]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_LENGTH = 0.01f;
|
||||
}
|
||||
|
||||
if (CAPSULE_RADIUS <= 0)
|
||||
{
|
||||
m_log.Warn("[ODE CHARACTER]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!");
|
||||
CAPSULE_RADIUS = 0.01f;
|
||||
}
|
||||
|
||||
Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
|
||||
d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
|
||||
d.GeomSetCollideBits(Shell, (int)m_collisionFlags);
|
||||
|
||||
d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH);
|
||||
Body = d.BodyCreate(_parent_scene.world);
|
||||
d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
|
||||
|
||||
_position.X = npositionX;
|
||||
_position.Y = npositionY;
|
||||
_position.Z = npositionZ;
|
||||
|
||||
m_taintPosition = _position;
|
||||
|
||||
d.BodySetMass(Body, ref ShellMass);
|
||||
d.Matrix3 m_caprot;
|
||||
// 90 Stand up on the cap of the capped cyllinder
|
||||
if (_parent_scene.IsAvCapsuleTilted)
|
||||
{
|
||||
d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2));
|
||||
}
|
||||
|
||||
d.GeomSetRotation(Shell, ref m_caprot);
|
||||
d.BodySetRotation(Body, ref m_caprot);
|
||||
|
||||
d.GeomSetBody(Shell, Body);
|
||||
|
||||
// The purpose of the AMotor here is to keep the avatar's physical
|
||||
// surrogate from rotating while moving
|
||||
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
|
||||
d.JointAttach(Amotor, Body, IntPtr.Zero);
|
||||
d.JointSetAMotorMode(Amotor, dAMotorEuler);
|
||||
d.JointSetAMotorNumAxes(Amotor, 3);
|
||||
d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
|
||||
d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
|
||||
d.JointSetAMotorAngle(Amotor, 0, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 1, 0);
|
||||
d.JointSetAMotorAngle(Amotor, 2, 0);
|
||||
|
||||
// These lowstops and high stops are effectively (no wiggle room)
|
||||
if (_parent_scene.IsAvCapsuleTilted)
|
||||
{
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
|
||||
}
|
||||
else
|
||||
{
|
||||
#region Documentation of capsule motor LowStop and HighStop parameters
|
||||
// Intentionally introduce some tilt into the capsule by setting
|
||||
// the motor stops to small epsilon values. This small tilt prevents
|
||||
// the capsule from falling into the terrain; a straight-up capsule
|
||||
// (with -0..0 motor stops) falls into the terrain for reasons yet
|
||||
// to be comprehended in their entirety.
|
||||
#endregion
|
||||
AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop
|
||||
}
|
||||
|
||||
// Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the
|
||||
// capped cyllinder will fall over
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
|
||||
d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor);
|
||||
|
||||
//d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
|
||||
//d.QfromR(
|
||||
//d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068,
|
||||
//
|
||||
//m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
|
||||
//standupStraight();
|
||||
|
||||
_parent_scene.geom_name_map[Shell] = Name;
|
||||
_parent_scene.actor_name_map[Shell] = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cleanup the things we use in the scene.
|
||||
/// </summary>
|
||||
|
@ -1148,7 +1137,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
/// <summary>
|
||||
/// Used internally to destroy the ODE structures associated with this character.
|
||||
/// </summary>
|
||||
private void DestroyOdeStructures()
|
||||
internal void DestroyOdeStructures()
|
||||
{
|
||||
// destroy avatar capsule and related ODE data
|
||||
if (Amotor != IntPtr.Zero)
|
||||
|
@ -1159,13 +1148,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
}
|
||||
|
||||
//kill the Geometry
|
||||
_parent_scene.waitForSpaceUnlock(_parent_scene.space);
|
||||
// _parent_scene.waitForSpaceUnlock(_parent_scene.space);
|
||||
|
||||
if (Body != IntPtr.Zero)
|
||||
{
|
||||
//kill the body
|
||||
d.BodyDestroy(Body);
|
||||
|
||||
Body = IntPtr.Zero;
|
||||
}
|
||||
|
||||
|
@ -1173,6 +1161,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
d.GeomDestroy(Shell);
|
||||
_parent_scene.geom_name_map.Remove(Shell);
|
||||
_parent_scene.actor_name_map.Remove(Shell);
|
||||
|
||||
Shell = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
@ -1261,7 +1251,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// FIXME: This is not a good solution since it's subject to a race condition if a force is another
|
||||
// thread sets a new force while we're in this loop (since it could be obliterated by
|
||||
// m_taintForce = Vector3.Zero. Need to lock ProcessTaints() when we set a new tainted force.
|
||||
doForce(m_taintForce);
|
||||
d.BodyAddForce(Body, m_taintForce.X, m_taintForce.Y, m_taintForce.Z);
|
||||
}
|
||||
|
||||
m_taintForce = Vector3.Zero;
|
||||
|
@ -1277,15 +1267,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// Create avatar capsule and related ODE data
|
||||
if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero))
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - "
|
||||
m_log.Warn("[ODE CHARACTER]: re-creating the following avatar ODE data for " + Name + ", even though it already exists - "
|
||||
+ (Shell!=IntPtr.Zero ? "Shell ":"")
|
||||
+ (Body!=IntPtr.Zero ? "Body ":"")
|
||||
+ (Amotor!=IntPtr.Zero ? "Amotor ":""));
|
||||
}
|
||||
AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor);
|
||||
|
||||
_parent_scene.geom_name_map[Shell] = m_name;
|
||||
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
|
||||
CreateOdeStructures(_position.X, _position.Y, _position.Z, m_tensor);
|
||||
_parent_scene.AddCharacter(this);
|
||||
}
|
||||
else
|
||||
|
@ -1301,17 +1289,19 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
{
|
||||
if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero)
|
||||
{
|
||||
// m_log.DebugFormat("[PHYSICS]: Changing capsule size");
|
||||
// m_log.DebugFormat(
|
||||
// "[ODE CHARACTER]: Changing capsule size from {0} to {1} for {2}",
|
||||
// CAPSULE_LENGTH, m_tainted_CAPSULE_LENGTH, Name);
|
||||
|
||||
m_pidControllerActive = true;
|
||||
|
||||
// no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate()
|
||||
d.JointDestroy(Amotor);
|
||||
DestroyOdeStructures();
|
||||
|
||||
float prevCapsule = CAPSULE_LENGTH;
|
||||
CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH;
|
||||
//m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
|
||||
d.BodyDestroy(Body);
|
||||
d.GeomDestroy(Shell);
|
||||
AvatarGeomAndBodyCreation(
|
||||
|
||||
CreateOdeStructures(
|
||||
_position.X,
|
||||
_position.Y,
|
||||
_position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
|
||||
|
@ -1319,13 +1309,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
// As with Size, we reset velocity. However, this isn't strictly necessary since it doesn't
|
||||
// appear to stall initial region crossings when done here. Being done for consistency.
|
||||
// Velocity = Vector3.Zero;
|
||||
|
||||
_parent_scene.geom_name_map[Shell] = m_name;
|
||||
_parent_scene.actor_name_map[Shell] = (PhysicsActor)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - "
|
||||
m_log.Warn("[ODE CHARACTER]: trying to change capsule size for " + Name + ", but the following ODE data is missing - "
|
||||
+ (Shell==IntPtr.Zero ? "Shell ":"")
|
||||
+ (Body==IntPtr.Zero ? "Body ":"")
|
||||
+ (Amotor==IntPtr.Zero ? "Amotor ":""));
|
||||
|
|
|
@ -184,7 +184,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
private bool m_lastUpdateSent;
|
||||
|
||||
public IntPtr Body = IntPtr.Zero;
|
||||
public String Name { get; private set; }
|
||||
private Vector3 _target_velocity;
|
||||
private d.Mass pMass;
|
||||
|
||||
|
@ -273,7 +272,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
|
||||
m_taintadd = true;
|
||||
_parent_scene.AddPhysicsActorTaint(this);
|
||||
// don't do .add() here; old geoms get recycled with the same hash
|
||||
}
|
||||
|
||||
public override int PhysicsActorType
|
||||
|
@ -857,7 +855,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
|||
m_MeshToTriMeshMap[mesh] = _triMeshData;
|
||||
}
|
||||
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
try
|
||||
{
|
||||
if (prim_geom == IntPtr.Zero)
|
||||
|
@ -1380,7 +1378,7 @@ Console.WriteLine("CreateGeom:");
|
|||
{
|
||||
if (((_size.X / 2f) > 0f))
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
try
|
||||
{
|
||||
//Console.WriteLine(" CreateGeom 1");
|
||||
|
@ -1394,7 +1392,7 @@ Console.WriteLine("CreateGeom:");
|
|||
}
|
||||
else
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
try
|
||||
{
|
||||
//Console.WriteLine(" CreateGeom 2");
|
||||
|
@ -1409,7 +1407,7 @@ Console.WriteLine("CreateGeom:");
|
|||
}
|
||||
else
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
try
|
||||
{
|
||||
//Console.WriteLine(" CreateGeom 3");
|
||||
|
@ -1424,7 +1422,7 @@ Console.WriteLine("CreateGeom:");
|
|||
}
|
||||
else
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
try
|
||||
{
|
||||
//Console.WriteLine(" CreateGeom 4");
|
||||
|
@ -1577,17 +1575,17 @@ Console.WriteLine(" JointCreateFixed");
|
|||
{
|
||||
// string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
|
||||
// int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
|
||||
IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
|
||||
m_targetSpace = tempspace;
|
||||
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
if (prim_geom != IntPtr.Zero)
|
||||
{
|
||||
d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
|
||||
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
d.SpaceAdd(m_targetSpace, prim_geom);
|
||||
}
|
||||
}
|
||||
|
@ -1978,7 +1976,7 @@ Console.WriteLine(" JointCreateFixed");
|
|||
|
||||
if (d.SpaceQuery(m_targetSpace, prim_geom))
|
||||
{
|
||||
_parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
// _parent_scene.waitForSpaceUnlock(m_targetSpace);
|
||||
d.SpaceRemove(m_targetSpace, prim_geom);
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -759,33 +759,33 @@ namespace OpenSim.Region.RegionCombinerModule
|
|||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TODO:
|
||||
/// </summary>
|
||||
/// <param name="rdata"></param>
|
||||
public void UnCombineRegion(RegionData rdata)
|
||||
{
|
||||
lock (m_regions)
|
||||
{
|
||||
if (m_regions.ContainsKey(rdata.RegionId))
|
||||
{
|
||||
// uncombine root region and virtual regions
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (RegionConnections r in m_regions.Values)
|
||||
{
|
||||
foreach (RegionData rd in r.ConnectedRegions)
|
||||
{
|
||||
if (rd.RegionId == rdata.RegionId)
|
||||
{
|
||||
// uncombine virtual region
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// /// <summary>
|
||||
// /// TODO:
|
||||
// /// </summary>
|
||||
// /// <param name="rdata"></param>
|
||||
// public void UnCombineRegion(RegionData rdata)
|
||||
// {
|
||||
// lock (m_regions)
|
||||
// {
|
||||
// if (m_regions.ContainsKey(rdata.RegionId))
|
||||
// {
|
||||
// // uncombine root region and virtual regions
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// foreach (RegionConnections r in m_regions.Values)
|
||||
// {
|
||||
// foreach (RegionData rd in r.ConnectedRegions)
|
||||
// {
|
||||
// if (rd.RegionId == rdata.RegionId)
|
||||
// {
|
||||
// // uncombine virtual region
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Create a set of infinite borders around the whole aabb of the combined island.
|
||||
private void AdjustLargeRegionBounds()
|
||||
|
|
|
@ -87,12 +87,26 @@ namespace OpenSim.Services.Connectors
|
|||
public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion)
|
||||
{
|
||||
string uri = region.ServerURI + "region/" + thisRegion.RegionID + "/";
|
||||
//m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri);
|
||||
// m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri);
|
||||
|
||||
WebRequest HelloNeighbourRequest = WebRequest.Create(uri);
|
||||
HelloNeighbourRequest.Method = "POST";
|
||||
HelloNeighbourRequest.ContentType = "application/json";
|
||||
HelloNeighbourRequest.Timeout = 10000;
|
||||
WebRequest helloNeighbourRequest;
|
||||
|
||||
try
|
||||
{
|
||||
helloNeighbourRequest = WebRequest.Create(uri);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat(
|
||||
"[NEIGHBOUR SERVICE CONNCTOR]: Unable to parse uri {0} to send HelloNeighbour from {1} to {2}. Exception {3}{4}",
|
||||
uri, thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
helloNeighbourRequest.Method = "POST";
|
||||
helloNeighbourRequest.ContentType = "application/json";
|
||||
helloNeighbourRequest.Timeout = 10000;
|
||||
|
||||
// Fill it in
|
||||
OSDMap args = null;
|
||||
|
@ -102,38 +116,48 @@ namespace OpenSim.Services.Connectors
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Debug("[REST COMMS]: PackRegionInfoData failed with exception: " + e.Message);
|
||||
m_log.WarnFormat(
|
||||
"[NEIGHBOUR SERVICE CONNCTOR]: PackRegionInfoData failed for HelloNeighbour from {0} to {1}. Exception {2}{3}",
|
||||
thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add the regionhandle of the destination region
|
||||
args["destination_handle"] = OSD.FromString(region.RegionHandle.ToString());
|
||||
|
||||
string strBuffer = "";
|
||||
byte[] buffer = new byte[1];
|
||||
|
||||
try
|
||||
{
|
||||
strBuffer = OSDParser.SerializeJsonString(args);
|
||||
UTF8Encoding str = new UTF8Encoding();
|
||||
buffer = str.GetBytes(strBuffer);
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of HelloNeighbour: {0}", e.Message);
|
||||
m_log.WarnFormat(
|
||||
"[NEIGHBOUR SERVICE CONNCTOR]: Exception thrown on serialization of HelloNeighbour from {0} to {1}. Exception {2}{3}",
|
||||
thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Stream os = null;
|
||||
try
|
||||
{ // send the Post
|
||||
HelloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send
|
||||
os = HelloNeighbourRequest.GetRequestStream();
|
||||
helloNeighbourRequest.ContentLength = buffer.Length; //Count bytes to send
|
||||
os = helloNeighbourRequest.GetRequestStream();
|
||||
os.Write(buffer, 0, strBuffer.Length); //Send it
|
||||
//m_log.InfoFormat("[REST COMMS]: Posted HelloNeighbour request to remote sim {0}", uri);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.InfoFormat("[REST COMMS]: Unable to send HelloNeighbour to {0}: {1}", region.RegionName, ex.Message);
|
||||
m_log.WarnFormat(
|
||||
"[NEIGHBOUR SERVICE CONNCTOR]: Unable to send HelloNeighbour from {0} to {1}. Exception {2}{3}",
|
||||
thisRegion.RegionName, region.RegionName, e.Message, e.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
|
@ -148,10 +172,12 @@ namespace OpenSim.Services.Connectors
|
|||
StreamReader sr = null;
|
||||
try
|
||||
{
|
||||
WebResponse webResponse = HelloNeighbourRequest.GetResponse();
|
||||
WebResponse webResponse = helloNeighbourRequest.GetResponse();
|
||||
if (webResponse == null)
|
||||
{
|
||||
m_log.Info("[REST COMMS]: Null reply on DoHelloNeighbourCall post");
|
||||
m_log.DebugFormat(
|
||||
"[REST COMMS]: Null reply on DoHelloNeighbourCall post from {0} to {1}",
|
||||
thisRegion.RegionName, region.RegionName);
|
||||
}
|
||||
|
||||
sr = new StreamReader(webResponse.GetResponseStream());
|
||||
|
@ -160,9 +186,12 @@ namespace OpenSim.Services.Connectors
|
|||
//m_log.InfoFormat("[REST COMMS]: DoHelloNeighbourCall reply was {0} ", reply);
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.InfoFormat("[REST COMMS]: exception on reply of DoHelloNeighbourCall {0}", ex.Message);
|
||||
m_log.WarnFormat(
|
||||
"[NEIGHBOUR SERVICE CONNCTOR]: Exception on reply of DoHelloNeighbourCall from {0} back to {1}. Exception {2}{3}",
|
||||
region.RegionName, thisRegion.RegionName, e.Message, e.StackTrace);
|
||||
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
|
@ -172,8 +201,6 @@ namespace OpenSim.Services.Connectors
|
|||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -334,7 +334,9 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
// Make the remote storage request
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl);
|
||||
// Simian does not require the asset ID to be in the URL because it's in the post data.
|
||||
// By appending it to the URL also, we allow caching proxies (squid) to invalidate asset URLs
|
||||
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(m_serverUrl + asset.FullID.ToString());
|
||||
|
||||
HttpWebResponse response = MultipartForm.Post(request, postParameters);
|
||||
using (Stream responseStream = response.GetResponseStream())
|
||||
|
|
|
@ -109,11 +109,13 @@ namespace OpenSim.Tests
|
|||
// Prepare call to ConfigurationLoader.LoadConfigSettings()
|
||||
ConfigurationLoader cl = new ConfigurationLoader();
|
||||
IConfigSource argvSource = new IniConfigSource();
|
||||
EnvConfigSource envConfigSource = new EnvConfigSource();
|
||||
argvSource.AddConfig("Startup").Set("inifile", mainIniFile);
|
||||
ConfigSettings configSettings;
|
||||
NetworkServersInfo networkInfo;
|
||||
|
||||
OpenSimConfigSource source = cl.LoadConfigSettings(argvSource, out configSettings, out networkInfo);
|
||||
OpenSimConfigSource source = cl.LoadConfigSettings(argvSource, envConfigSource,
|
||||
out configSettings, out networkInfo);
|
||||
|
||||
// Remove default config
|
||||
config = source.Source.Configs["Startup"];
|
||||
|
|
|
@ -41,6 +41,8 @@ namespace pCampBot
|
|||
/// </remarks>
|
||||
public class GrabbingBehaviour : IBehaviour
|
||||
{
|
||||
public string Name { get { return "Grabbing"; } }
|
||||
|
||||
public void Action(Bot bot)
|
||||
{
|
||||
Dictionary<UUID, Primitive> objects = bot.Objects;
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace pCampBot
|
|||
/// </remarks>
|
||||
public class PhysicsBehaviour : IBehaviour
|
||||
{
|
||||
public string Name { get { return "Physics"; } }
|
||||
|
||||
private string[] talkarray;
|
||||
|
||||
public PhysicsBehaviour()
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) Contributors, http://opensimulator.org/
|
||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the OpenSimulator Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using pCampBot.Interfaces;
|
||||
|
||||
namespace pCampBot
|
||||
{
|
||||
/// <summary>
|
||||
/// Teleport to a random region on the grid.
|
||||
/// </summary>
|
||||
public class TeleportBehaviour : IBehaviour
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public string Name { get { return "Teleport"; } }
|
||||
|
||||
public void Action(Bot bot)
|
||||
{
|
||||
Random rng = bot.Manager.Rng;
|
||||
GridRegion[] knownRegions;
|
||||
|
||||
lock (bot.Manager.RegionsKnown)
|
||||
{
|
||||
if (bot.Manager.RegionsKnown.Count == 0)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[TELEPORT BEHAVIOUR]: Ignoring teleport action for {0} since no regions are known yet", bot.Name);
|
||||
return;
|
||||
}
|
||||
|
||||
knownRegions = bot.Manager.RegionsKnown.Values.ToArray();
|
||||
}
|
||||
|
||||
Simulator sourceRegion = bot.Client.Network.CurrentSim;
|
||||
GridRegion destRegion = knownRegions[rng.Next(knownRegions.Length)];
|
||||
Vector3 destPosition = new Vector3(rng.Next(255), rng.Next(255), 50);
|
||||
|
||||
m_log.DebugFormat(
|
||||
"[TELEPORT BEHAVIOUR]: Teleporting {0} from {1} {2} to {3} {4}",
|
||||
bot.Name, sourceRegion.Name, bot.Client.Self.SimPosition, destRegion.Name, destPosition);
|
||||
|
||||
bot.Client.Self.Teleport(destRegion.RegionHandle, destPosition);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -49,8 +49,15 @@ namespace pCampBot
|
|||
|
||||
public delegate void AnEvent(Bot callbot, EventType someevent); // event delegate for bot events
|
||||
|
||||
public BotManager BotManager { get; private set; }
|
||||
private IConfig startupConfig; // bot config, passed from BotManager
|
||||
/// <summary>
|
||||
/// Bot manager.
|
||||
/// </summary>
|
||||
public BotManager Manager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Bot config, passed from BotManager.
|
||||
/// </summary>
|
||||
private IConfig startupConfig;
|
||||
|
||||
/// <summary>
|
||||
/// Behaviours implemented by this bot.
|
||||
|
@ -132,7 +139,7 @@ namespace pCampBot
|
|||
Password = password;
|
||||
LoginUri = loginUri;
|
||||
|
||||
BotManager = bm;
|
||||
Manager = bm;
|
||||
startupConfig = bm.Config;
|
||||
readconfig();
|
||||
|
||||
|
@ -218,7 +225,19 @@ namespace pCampBot
|
|||
{
|
||||
MakeDefaultAppearance(wear);
|
||||
}
|
||||
|
||||
Client.Self.Jump(true);
|
||||
|
||||
// Extract nearby region information.
|
||||
Client.Grid.GridRegion += Manager.Grid_GridRegion;
|
||||
uint xUint, yUint;
|
||||
Utils.LongToUInts(Client.Network.CurrentSim.Handle, out xUint, out yUint);
|
||||
ushort minX, minY, maxX, maxY;
|
||||
minX = (ushort)Math.Min(0, xUint - 5);
|
||||
minY = (ushort)Math.Min(0, yUint - 5);
|
||||
maxX = (ushort)(xUint + 5);
|
||||
maxY = (ushort)(yUint + 5);
|
||||
Client.Grid.RequestMapBlocks(GridLayerType.Terrain, minX, minY, maxX, maxY, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -472,13 +491,13 @@ namespace pCampBot
|
|||
|
||||
private void GetTexture(UUID textureID)
|
||||
{
|
||||
lock (BotManager.AssetsReceived)
|
||||
lock (Manager.AssetsReceived)
|
||||
{
|
||||
// Don't request assets more than once.
|
||||
if (BotManager.AssetsReceived.ContainsKey(textureID))
|
||||
if (Manager.AssetsReceived.ContainsKey(textureID))
|
||||
return;
|
||||
|
||||
BotManager.AssetsReceived[textureID] = false;
|
||||
Manager.AssetsReceived[textureID] = false;
|
||||
Client.Assets.RequestImage(textureID, ImageType.Normal, Asset_TextureCallback_Texture);
|
||||
}
|
||||
}
|
||||
|
@ -490,8 +509,8 @@ namespace pCampBot
|
|||
|
||||
public void Asset_ReceivedCallback(AssetDownload transfer, Asset asset)
|
||||
{
|
||||
lock (BotManager.AssetsReceived)
|
||||
BotManager.AssetsReceived[asset.AssetID] = true;
|
||||
lock (Manager.AssetsReceived)
|
||||
Manager.AssetsReceived[asset.AssetID] = true;
|
||||
|
||||
// if (wear == "save")
|
||||
// {
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using OpenMetaverse;
|
||||
|
@ -48,9 +49,24 @@ namespace pCampBot
|
|||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
/// <summary>
|
||||
/// Command console
|
||||
/// </summary>
|
||||
protected CommandConsole m_console;
|
||||
|
||||
/// <summary>
|
||||
/// Created bots, whether active or inactive.
|
||||
/// </summary>
|
||||
protected List<Bot> m_lBot;
|
||||
protected Random somthing = new Random(Environment.TickCount);
|
||||
|
||||
/// <summary>
|
||||
/// Random number generator.
|
||||
/// </summary>
|
||||
public Random Rng { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Overall configuration.
|
||||
/// </summary>
|
||||
public IConfig Config { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -58,12 +74,19 @@ namespace pCampBot
|
|||
/// </summary>
|
||||
public Dictionary<UUID, bool> AssetsReceived { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The regions that we know about.
|
||||
/// </summary>
|
||||
public Dictionary<ulong, GridRegion> RegionsKnown { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructor Creates MainConsole.Instance to take commands and provide the place to write data
|
||||
/// </summary>
|
||||
public BotManager()
|
||||
{
|
||||
Rng = new Random(Environment.TickCount);
|
||||
AssetsReceived = new Dictionary<UUID, bool>();
|
||||
RegionsKnown = new Dictionary<ulong, GridRegion>();
|
||||
|
||||
m_console = CreateConsole();
|
||||
MainConsole.Instance = m_console;
|
||||
|
@ -93,8 +116,13 @@ namespace pCampBot
|
|||
"Shutdown bots and exit",
|
||||
HandleShutdown);
|
||||
|
||||
m_console.Commands.AddCommand("bot", false, "show status",
|
||||
"show status",
|
||||
m_console.Commands.AddCommand("bot", false, "show regions",
|
||||
"show regions",
|
||||
"Show regions known to bots",
|
||||
HandleShowRegions);
|
||||
|
||||
m_console.Commands.AddCommand("bot", false, "show bots",
|
||||
"show bots",
|
||||
"Shows the status of all bots",
|
||||
HandleShowStatus);
|
||||
|
||||
|
@ -123,19 +151,26 @@ namespace pCampBot
|
|||
Array.ForEach<string>(
|
||||
cs.GetString("behaviours", "p").Split(new char[] { ',' }), b => behaviourSwitches.Add(b));
|
||||
|
||||
List<IBehaviour> behaviours = new List<IBehaviour>();
|
||||
|
||||
// Hard-coded for now
|
||||
if (behaviourSwitches.Contains("p"))
|
||||
behaviours.Add(new PhysicsBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("g"))
|
||||
behaviours.Add(new GrabbingBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("t"))
|
||||
behaviours.Add(new TeleportBehaviour());
|
||||
|
||||
MainConsole.Instance.OutputFormat(
|
||||
"[BOT MANAGER]: Bots configured for behaviours {0}",
|
||||
string.Join(",", behaviours.ConvertAll<string>(b => b.Name).ToArray()));
|
||||
|
||||
for (int i = 0; i < botcount; i++)
|
||||
{
|
||||
string lastName = string.Format("{0}_{1}", lastNameStem, i);
|
||||
|
||||
List<IBehaviour> behaviours = new List<IBehaviour>();
|
||||
|
||||
// Hard-coded for now
|
||||
if (behaviourSwitches.Contains("p"))
|
||||
behaviours.Add(new PhysicsBehaviour());
|
||||
|
||||
if (behaviourSwitches.Contains("g"))
|
||||
behaviours.Add(new GrabbingBehaviour());
|
||||
|
||||
StartBot(this, behaviours, firstName, lastName, password, loginUri);
|
||||
}
|
||||
}
|
||||
|
@ -240,17 +275,33 @@ namespace pCampBot
|
|||
});
|
||||
}
|
||||
|
||||
private void HandleShowRegions(string module, string[] cmd)
|
||||
{
|
||||
string outputFormat = "{0,-30} {1, -20} {2, -5} {3, -5}";
|
||||
MainConsole.Instance.OutputFormat(outputFormat, "Name", "Handle", "X", "Y");
|
||||
|
||||
lock (RegionsKnown)
|
||||
{
|
||||
foreach (GridRegion region in RegionsKnown.Values)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
outputFormat, region.Name, region.RegionHandle, region.X, region.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShowStatus(string module, string[] cmd)
|
||||
{
|
||||
string outputFormat = "{0,-30} {1,-14}";
|
||||
MainConsole.Instance.OutputFormat(outputFormat, "Name", "Status");
|
||||
string outputFormat = "{0,-30} {1, -30} {2,-14}";
|
||||
MainConsole.Instance.OutputFormat(outputFormat, "Name", "Region", "Status");
|
||||
|
||||
lock (m_lBot)
|
||||
{
|
||||
foreach (Bot pb in m_lBot)
|
||||
{
|
||||
MainConsole.Instance.OutputFormat(
|
||||
outputFormat, pb.Name, (pb.IsConnected ? "Connected" : "Disconnected"));
|
||||
outputFormat,
|
||||
pb.Name, pb.Client.Network.CurrentSim.Name, pb.IsConnected ? "Connected" : "Disconnected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -274,5 +325,24 @@ namespace pCampBot
|
|||
// if (newbots > 0)
|
||||
// addbots(newbots);
|
||||
// }
|
||||
|
||||
internal void Grid_GridRegion(object o, GridRegionEventArgs args)
|
||||
{
|
||||
lock (RegionsKnown)
|
||||
{
|
||||
GridRegion newRegion = args.Region;
|
||||
|
||||
if (RegionsKnown.ContainsKey(newRegion.RegionHandle))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
"[BOT MANAGER]: Adding {0} {1} to known regions", newRegion.Name, newRegion.RegionHandle);
|
||||
RegionsKnown[newRegion.RegionHandle] = newRegion;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,15 @@ namespace pCampBot.Interfaces
|
|||
{
|
||||
public interface IBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of this behaviour.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Action to take when this behaviour is invoked.
|
||||
/// </summary>
|
||||
/// <param name="bot"></param>
|
||||
void Action(Bot bot);
|
||||
}
|
||||
}
|
|
@ -111,7 +111,7 @@ namespace pCampBot
|
|||
" -firstname first name for the bots\n" +
|
||||
" -lastname lastname for the bots. Each lastname will have _<bot-number> appended, e.g. Ima Bot_0\n" +
|
||||
" -password password for the bots\n" +
|
||||
" -b, behaviours behaviours for bots. Current options p (physics), g (grab). Comma separated, e.g. p,g. Default is p",
|
||||
" -b, behaviours behaviours for bots. Current options p (physics), g (grab), t (teleport). Comma separated, e.g. p,g. Default is p",
|
||||
" -wear set appearance folder to load from (default: no)\n" +
|
||||
" -h, -help show this message"
|
||||
);
|
||||
|
|
BIN
bin/Nini.dll
BIN
bin/Nini.dll
Binary file not shown.
|
@ -231,13 +231,6 @@
|
|||
;; server to send mail through.
|
||||
; emailmodule = DefaultEmailModule
|
||||
|
||||
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
|
||||
;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
|
||||
;; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
|
||||
;; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
|
||||
;; by scripts have changed.
|
||||
; DeleteScriptsOnStartup = true
|
||||
|
||||
[SMTP]
|
||||
;; The SMTP server enabled the email module to send email to external
|
||||
;; destinations.
|
||||
|
@ -571,6 +564,13 @@
|
|||
;; Stack size per thread created
|
||||
; ThreadStackSize = 262144
|
||||
|
||||
;# {DeleteScriptsOnStartup} {} {Delete previously compiled script DLLs on startup?} (true false) true
|
||||
;; Controls whether previously compiled scripts DLLs are deleted on sim restart. If you set this to false
|
||||
;; then startup will be considerably faster since scripts won't need to be recompiled. However, then it becomes your responsibility to delete the
|
||||
;; compiled scripts if you're recompiling OpenSim from source code and internal interfaces used
|
||||
;; by scripts have changed.
|
||||
; DeleteScriptsOnStartup = true
|
||||
|
||||
;; Set this to true (the default) to load each script into a separate
|
||||
;; AppDomain. Setting this to false will load all script assemblies into the
|
||||
;; current AppDomain, which will reduce the per-script overhead at the
|
||||
|
|
Loading…
Reference in New Issue