* Rex merge, remaining Region files.
* This is the last rex merge on /branches/afrisby-3/, all files have been merged, but it's highly unlikely it compiles.afrisby-3
parent
4853884c30
commit
0c77413d1f
|
@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
|
||||||
// You can specify all values by your own or you can build default build and revision
|
// You can specify all values by your own or you can build default build and revision
|
||||||
// numbers with the '*' character (the default):
|
// numbers with the '*' character (the default):
|
||||||
|
|
||||||
[assembly : AssemblyVersion("1.0.*")]
|
[assembly : AssemblyVersion("1.0.*")]
|
||||||
|
|
|
@ -1,336 +1,365 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Axiom.Math;
|
using Axiom.Math;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
namespace OpenSim.Region.Physics.BasicPhysicsPlugin
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Will be the PhysX plugin but for now will be a very basic physics engine
|
/// Will be the PhysX plugin but for now will be a very basic physics engine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BasicPhysicsPlugin : IPhysicsPlugin
|
public class BasicPhysicsPlugin : IPhysicsPlugin
|
||||||
{
|
{
|
||||||
public BasicPhysicsPlugin()
|
public BasicPhysicsPlugin()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Init()
|
public bool Init()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsScene GetScene()
|
public PhysicsScene GetScene()
|
||||||
{
|
{
|
||||||
return new BasicScene();
|
return new BasicScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return ("basicphysics");
|
return ("basicphysics");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BasicScene : PhysicsScene
|
public class BasicScene : PhysicsScene
|
||||||
{
|
{
|
||||||
private List<BasicActor> _actors = new List<BasicActor>();
|
private List<BasicActor> _actors = new List<BasicActor>();
|
||||||
private float[] _heightMap;
|
private float[] _heightMap;
|
||||||
|
|
||||||
public BasicScene()
|
public BasicScene()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Initialise(IMesher meshmerizer)
|
public override void Initialise(IMesher meshmerizer)
|
||||||
{
|
{
|
||||||
// Does nothing right now
|
// Does nothing right now
|
||||||
}
|
}
|
||||||
|
|
||||||
public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
|
public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
|
||||||
{
|
{
|
||||||
BasicActor act = new BasicActor();
|
|
||||||
act.Position = position;
|
}
|
||||||
_actors.Add(act);
|
public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
|
||||||
return act;
|
{
|
||||||
}
|
BasicActor act = new BasicActor();
|
||||||
|
act.Position = position;
|
||||||
public override void RemovePrim(PhysicsActor prim)
|
_actors.Add(act);
|
||||||
{
|
return act;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RemoveAvatar(PhysicsActor actor)
|
public override void RemovePrim(PhysicsActor prim)
|
||||||
{
|
{
|
||||||
BasicActor act = (BasicActor) actor;
|
}
|
||||||
if (_actors.Contains(act))
|
|
||||||
{
|
public override void RemoveAvatar(PhysicsActor actor)
|
||||||
_actors.Remove(act);
|
{
|
||||||
}
|
BasicActor act = (BasicActor) actor;
|
||||||
}
|
if (_actors.Contains(act))
|
||||||
|
{
|
||||||
/*
|
_actors.Remove(act);
|
||||||
public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
|
}
|
||||||
{
|
}
|
||||||
return null;
|
|
||||||
}
|
/*
|
||||||
*/
|
public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
|
||||||
|
{
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
return null;
|
||||||
PhysicsVector size, Quaternion rotation, uint LocalID)
|
}
|
||||||
{
|
*/
|
||||||
return AddPrimShape(primName, pbs, position, size, rotation, false, LocalID);
|
|
||||||
}
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
||||||
|
PhysicsVector size, Quaternion rotation, uint LocalID)
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
{
|
||||||
PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID) // rex, modified
|
return AddPrimShape(primName, pbs, position, size, rotation, false, LocalID);
|
||||||
{
|
}
|
||||||
return null;
|
|
||||||
}
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
||||||
|
PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID) // rex, modified
|
||||||
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
{
|
||||||
{
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float Simulate(float timeStep)
|
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
||||||
{
|
{
|
||||||
float fps = 0;
|
}
|
||||||
for (int i = 0; i < _actors.Count; ++i)
|
|
||||||
{
|
public override float Simulate(float timeStep)
|
||||||
BasicActor actor = _actors[i];
|
{
|
||||||
|
float fps = 0;
|
||||||
actor.Position.X += actor.Velocity.X*timeStep;
|
for (int i = 0; i < _actors.Count; ++i)
|
||||||
actor.Position.Y += actor.Velocity.Y*timeStep;
|
{
|
||||||
|
BasicActor actor = _actors[i];
|
||||||
if (actor.Position.Y < 0)
|
|
||||||
{
|
actor.Position.X += actor.Velocity.X*timeStep;
|
||||||
actor.Position.Y = 0.1F;
|
actor.Position.Y += actor.Velocity.Y*timeStep;
|
||||||
}
|
|
||||||
else if (actor.Position.Y >= 256)
|
if (actor.Position.Y < 0)
|
||||||
{
|
{
|
||||||
actor.Position.Y = 255.9F;
|
actor.Position.Y = 0.1F;
|
||||||
}
|
}
|
||||||
|
else if (actor.Position.Y >= Constants.RegionSize)
|
||||||
if (actor.Position.X < 0)
|
{
|
||||||
{
|
actor.Position.Y = 255.9F;
|
||||||
actor.Position.X = 0.1F;
|
}
|
||||||
}
|
|
||||||
else if (actor.Position.X >= 256)
|
if (actor.Position.X < 0)
|
||||||
{
|
{
|
||||||
actor.Position.X = 255.9F;
|
actor.Position.X = 0.1F;
|
||||||
}
|
}
|
||||||
|
else if (actor.Position.X >= Constants.RegionSize)
|
||||||
float height = _heightMap[(int) actor.Position.Y*256 + (int) actor.Position.X] + 1.0f;
|
{
|
||||||
if (actor.Flying)
|
actor.Position.X = 255.9F;
|
||||||
{
|
}
|
||||||
if (actor.Position.Z + (actor.Velocity.Z*timeStep) <
|
|
||||||
_heightMap[(int) actor.Position.Y*256 + (int) actor.Position.X] + 2)
|
float height = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 1.0f;
|
||||||
{
|
if (actor.Flying)
|
||||||
actor.Position.Z = height;
|
{
|
||||||
actor.Velocity.Z = 0;
|
if (actor.Position.Z + (actor.Velocity.Z*timeStep) <
|
||||||
}
|
_heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2)
|
||||||
else
|
{
|
||||||
{
|
actor.Position.Z = height;
|
||||||
actor.Position.Z += actor.Velocity.Z*timeStep;
|
actor.Velocity.Z = 0;
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
actor.Position.Z += actor.Velocity.Z*timeStep;
|
||||||
actor.Position.Z = height;
|
}
|
||||||
actor.Velocity.Z = 0;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
return fps;
|
actor.Position.Z = height;
|
||||||
}
|
actor.Velocity.Z = 0;
|
||||||
|
}
|
||||||
public override void GetResults()
|
}
|
||||||
{
|
return fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsThreaded
|
public override void GetResults()
|
||||||
{
|
{
|
||||||
get { return (false); // for now we won't be multithreaded
|
}
|
||||||
}
|
|
||||||
}
|
public override bool IsThreaded
|
||||||
|
{
|
||||||
public override void SetTerrain(float[] heightMap)
|
get { return (false); // for now we won't be multithreaded
|
||||||
{
|
}
|
||||||
_heightMap = heightMap;
|
}
|
||||||
}
|
|
||||||
|
public override void SetTerrain(float[] heightMap)
|
||||||
public override void DeleteTerrain()
|
{
|
||||||
{
|
_heightMap = heightMap;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public override void DeleteTerrain()
|
||||||
public class BasicActor : PhysicsActor
|
{
|
||||||
{
|
}
|
||||||
private PhysicsVector _position;
|
}
|
||||||
private PhysicsVector _velocity;
|
|
||||||
private PhysicsVector _acceleration;
|
public class BasicActor : PhysicsActor
|
||||||
private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
|
{
|
||||||
private bool flying;
|
private PhysicsVector _position;
|
||||||
private bool iscolliding;
|
private PhysicsVector _velocity;
|
||||||
|
private PhysicsVector _acceleration;
|
||||||
public BasicActor()
|
private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
|
||||||
{
|
private bool flying;
|
||||||
_velocity = new PhysicsVector();
|
private bool iscolliding;
|
||||||
_position = new PhysicsVector();
|
|
||||||
_acceleration = new PhysicsVector();
|
public BasicActor()
|
||||||
}
|
{
|
||||||
|
_velocity = new PhysicsVector();
|
||||||
public override int PhysicsActorType
|
_position = new PhysicsVector();
|
||||||
{
|
_acceleration = new PhysicsVector();
|
||||||
get { return (int) ActorTypes.Agent; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override int PhysicsActorType
|
||||||
|
{
|
||||||
public override PhysicsVector RotationalVelocity
|
get { return (int) ActorTypes.Agent; }
|
||||||
{
|
set { return; }
|
||||||
get { return m_rotationalVelocity; }
|
}
|
||||||
set { m_rotationalVelocity = value; }
|
|
||||||
}
|
public override PhysicsVector RotationalVelocity
|
||||||
|
{
|
||||||
public override bool SetAlwaysRun
|
get { return m_rotationalVelocity; }
|
||||||
{
|
set { m_rotationalVelocity = value; }
|
||||||
get { return false; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override bool SetAlwaysRun
|
||||||
|
{
|
||||||
public override bool IsPhysical
|
get { return false; }
|
||||||
{
|
set { return; }
|
||||||
get { return false; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override bool Grabbed
|
||||||
|
{
|
||||||
public override bool ThrottleUpdates
|
set { return; }
|
||||||
{
|
}
|
||||||
get { return false; }
|
|
||||||
set { return; }
|
public override bool Selected
|
||||||
}
|
{
|
||||||
|
set { return; }
|
||||||
public override bool Flying
|
}
|
||||||
{
|
|
||||||
get { return flying; }
|
public override bool IsPhysical
|
||||||
set { flying = value; }
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
public override bool IsColliding
|
}
|
||||||
{
|
|
||||||
get { return iscolliding; }
|
public override bool ThrottleUpdates
|
||||||
set { iscolliding = value; }
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
public override bool CollidingGround
|
}
|
||||||
{
|
|
||||||
get { return false; }
|
public override bool Flying
|
||||||
set { return; }
|
{
|
||||||
}
|
get { return flying; }
|
||||||
|
set { flying = value; }
|
||||||
public override bool CollidingObj
|
}
|
||||||
{
|
|
||||||
get { return false; }
|
public override bool IsColliding
|
||||||
set { return; }
|
{
|
||||||
}
|
get { return iscolliding; }
|
||||||
|
set { iscolliding = value; }
|
||||||
public override PhysicsVector Position
|
}
|
||||||
{
|
|
||||||
get { return _position; }
|
public override bool CollidingGround
|
||||||
set { _position = value; }
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
public override PhysicsVector Size
|
}
|
||||||
{
|
|
||||||
get { return PhysicsVector.Zero; }
|
public override bool CollidingObj
|
||||||
set { }
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
public override PrimitiveBaseShape Shape
|
}
|
||||||
{
|
|
||||||
set { return; }
|
public override bool Stopped
|
||||||
}
|
{
|
||||||
|
get { return false; }
|
||||||
public override float Mass
|
}
|
||||||
{
|
|
||||||
get { return 0f; }
|
|
||||||
}
|
public override PhysicsVector Position
|
||||||
|
{
|
||||||
public override PhysicsVector Force
|
get { return _position; }
|
||||||
{
|
set { _position = value; }
|
||||||
get { return PhysicsVector.Zero; }
|
}
|
||||||
}
|
|
||||||
|
public override PhysicsVector Size
|
||||||
public override PhysicsVector CenterOfMass
|
{
|
||||||
{
|
get { return PhysicsVector.Zero; }
|
||||||
get { return PhysicsVector.Zero; }
|
set { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override PhysicsVector GeometricCenter
|
public override PrimitiveBaseShape Shape
|
||||||
{
|
{
|
||||||
get { return PhysicsVector.Zero; }
|
set { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override PhysicsVector Velocity
|
public override float Mass
|
||||||
{
|
{
|
||||||
get { return _velocity; }
|
get { return 0f; }
|
||||||
set { _velocity = value; }
|
}
|
||||||
}
|
|
||||||
|
public override PhysicsVector Force
|
||||||
public override Quaternion Orientation
|
{
|
||||||
{
|
get { return PhysicsVector.Zero; }
|
||||||
get { return Quaternion.Identity; }
|
}
|
||||||
set { }
|
|
||||||
}
|
public override PhysicsVector CenterOfMass
|
||||||
|
{
|
||||||
public override PhysicsVector Acceleration
|
get { return PhysicsVector.Zero; }
|
||||||
{
|
}
|
||||||
get { return _acceleration; }
|
|
||||||
}
|
public override PhysicsVector GeometricCenter
|
||||||
|
{
|
||||||
public override bool Kinematic
|
get { return PhysicsVector.Zero; }
|
||||||
{
|
}
|
||||||
get { return true; }
|
|
||||||
set { }
|
public override PhysicsVector Velocity
|
||||||
}
|
{
|
||||||
|
get { return _velocity; }
|
||||||
public void SetAcceleration(PhysicsVector accel)
|
set { _velocity = value; }
|
||||||
{
|
}
|
||||||
_acceleration = accel;
|
|
||||||
}
|
public override float CollisionScore
|
||||||
|
{
|
||||||
public override void AddForce(PhysicsVector force)
|
get { return 0f; }
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public override Quaternion Orientation
|
||||||
public override void SetMomentum(PhysicsVector momentum)
|
{
|
||||||
{
|
get { return Quaternion.Identity; }
|
||||||
}
|
set { }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public override PhysicsVector Acceleration
|
||||||
|
{
|
||||||
|
get { return _acceleration; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Kinematic
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAcceleration(PhysicsVector accel)
|
||||||
|
{
|
||||||
|
_acceleration = accel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AddForce(PhysicsVector force)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetMomentum(PhysicsVector momentum)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public override void CrossingFailure()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.Manager
|
||||||
|
{
|
||||||
|
public class CollisionLocker
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private List<IntPtr> worldlock = new List<IntPtr>();
|
||||||
|
public CollisionLocker()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public void dlock(IntPtr world)
|
||||||
|
{
|
||||||
|
lock (worldlock)
|
||||||
|
{
|
||||||
|
worldlock.Add(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public void dunlock(IntPtr world)
|
||||||
|
{
|
||||||
|
lock (worldlock)
|
||||||
|
{
|
||||||
|
worldlock.Remove(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public bool lockquery()
|
||||||
|
{
|
||||||
|
return (worldlock.Count > 0);
|
||||||
|
}
|
||||||
|
public void drelease(IntPtr world)
|
||||||
|
{
|
||||||
|
lock (worldlock)
|
||||||
|
{
|
||||||
|
if (worldlock.Contains(world))
|
||||||
|
worldlock.Remove(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,324 +1,368 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Axiom.Math;
|
using Axiom.Math;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Manager
|
namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
public delegate void PositionUpdate(PhysicsVector position);
|
public delegate void PositionUpdate(PhysicsVector position);
|
||||||
|
|
||||||
public delegate void VelocityUpdate(PhysicsVector velocity);
|
public delegate void VelocityUpdate(PhysicsVector velocity);
|
||||||
|
|
||||||
public delegate void OrientationUpdate(Quaternion orientation);
|
public delegate void OrientationUpdate(Quaternion orientation);
|
||||||
|
|
||||||
public enum ActorTypes : int
|
public enum ActorTypes : int
|
||||||
{
|
{
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Agent = 1,
|
Agent = 1,
|
||||||
Prim = 2,
|
Prim = 2,
|
||||||
Ground = 3,
|
Ground = 3,
|
||||||
PrimVolume = 4 // rex
|
PrimVolume = 4 // rex
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CollisionEventUpdate : EventArgs
|
public class CollisionEventUpdate : EventArgs
|
||||||
{
|
{
|
||||||
// Raising the event on the object, so don't need to provide location.. further up the tree knows that info.
|
// Raising the event on the object, so don't need to provide location.. further up the tree knows that info.
|
||||||
public int m_colliderType;
|
public int m_colliderType;
|
||||||
public bool m_startOrEnd;
|
public bool m_startOrEnd;
|
||||||
public uint m_LocalID; // rex
|
public uint m_LocalID; // rex
|
||||||
public List<uint> m_objCollisionList;
|
public List<uint> m_objCollisionList;
|
||||||
|
|
||||||
public CollisionEventUpdate(uint localID, int colliderType, bool startOrEnd, List<uint> objCollisionList)
|
public CollisionEventUpdate(uint localID, int colliderType, bool startOrEnd, List<uint> objCollisionList)
|
||||||
{
|
{
|
||||||
m_LocalID = localID; // rex
|
m_LocalID = localID; // rex
|
||||||
m_colliderType = colliderType;
|
m_colliderType = colliderType;
|
||||||
m_startOrEnd = startOrEnd;
|
m_startOrEnd = startOrEnd;
|
||||||
m_objCollisionList = objCollisionList;
|
m_objCollisionList = objCollisionList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollisionEventUpdate(bool startOrEnd)
|
public CollisionEventUpdate(bool startOrEnd)
|
||||||
{
|
{
|
||||||
m_colliderType = (int) ActorTypes.Unknown;
|
m_colliderType = (int) ActorTypes.Unknown;
|
||||||
m_startOrEnd = startOrEnd;
|
m_startOrEnd = startOrEnd;
|
||||||
m_objCollisionList = null;
|
m_objCollisionList = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CollisionEventUpdate()
|
public CollisionEventUpdate()
|
||||||
{
|
{
|
||||||
m_colliderType = (int) ActorTypes.Unknown;
|
m_colliderType = (int) ActorTypes.Unknown;
|
||||||
m_startOrEnd = false;
|
m_startOrEnd = false;
|
||||||
m_objCollisionList = null;
|
m_objCollisionList = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int collidertype
|
public int collidertype
|
||||||
{
|
{
|
||||||
get { return m_colliderType; }
|
get { return m_colliderType; }
|
||||||
set { m_colliderType = value; }
|
set { m_colliderType = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool startOrEnd
|
public bool startOrEnd
|
||||||
{
|
{
|
||||||
get { return m_startOrEnd; }
|
get { return m_startOrEnd; }
|
||||||
set { m_startOrEnd = value; }
|
set { m_startOrEnd = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addCollider(uint localID)
|
public void addCollider(uint localID)
|
||||||
{
|
{
|
||||||
m_objCollisionList.Add(localID);
|
m_objCollisionList.Add(localID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public abstract class PhysicsActor
|
public abstract class PhysicsActor
|
||||||
{
|
{
|
||||||
public delegate void RequestTerseUpdate();
|
public delegate void RequestTerseUpdate();
|
||||||
|
|
||||||
public delegate void CollisionUpdate(EventArgs e);
|
public delegate void CollisionUpdate(EventArgs e);
|
||||||
|
|
||||||
public delegate void OutOfBounds(PhysicsVector pos);
|
public delegate void OutOfBounds(PhysicsVector pos);
|
||||||
|
|
||||||
#pragma warning disable 67
|
#pragma warning disable 67
|
||||||
public event PositionUpdate OnPositionUpdate;
|
public event PositionUpdate OnPositionUpdate;
|
||||||
public event VelocityUpdate OnVelocityUpdate;
|
public event VelocityUpdate OnVelocityUpdate;
|
||||||
public event OrientationUpdate OnOrientationUpdate;
|
public event OrientationUpdate OnOrientationUpdate;
|
||||||
public event RequestTerseUpdate OnRequestTerseUpdate;
|
public event RequestTerseUpdate OnRequestTerseUpdate;
|
||||||
public event CollisionUpdate OnCollisionUpdate;
|
public event CollisionUpdate OnCollisionUpdate;
|
||||||
public event OutOfBounds OnOutOfBounds;
|
public event OutOfBounds OnOutOfBounds;
|
||||||
#pragma warning restore 67
|
#pragma warning restore 67
|
||||||
|
|
||||||
public static PhysicsActor Null
|
public static PhysicsActor Null
|
||||||
{
|
{
|
||||||
get { return new NullPhysicsActor(); }
|
get { return new NullPhysicsActor(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract PhysicsVector Size { get; set; }
|
public abstract bool Stopped { get; }
|
||||||
|
|
||||||
public abstract PrimitiveBaseShape Shape { set; }
|
public abstract PhysicsVector Size { get; set; }
|
||||||
|
|
||||||
public virtual void RequestPhysicsterseUpdate()
|
public abstract PrimitiveBaseShape Shape { set; }
|
||||||
{
|
|
||||||
// Make a temporary copy of the event to avoid possibility of
|
public abstract bool Grabbed { set; }
|
||||||
// a race condition if the last subscriber unsubscribes
|
|
||||||
// immediately after the null check and before the event is raised.
|
public abstract bool Selected { set; }
|
||||||
RequestTerseUpdate handler = OnRequestTerseUpdate;
|
|
||||||
if (handler != null)
|
public abstract void CrossingFailure();
|
||||||
{
|
|
||||||
OnRequestTerseUpdate();
|
public virtual void RequestPhysicsterseUpdate()
|
||||||
}
|
{
|
||||||
}
|
// Make a temporary copy of the event to avoid possibility of
|
||||||
|
// a race condition if the last subscriber unsubscribes
|
||||||
public virtual void RaiseOutOfBounds(PhysicsVector pos)
|
// immediately after the null check and before the event is raised.
|
||||||
{
|
RequestTerseUpdate handler = OnRequestTerseUpdate;
|
||||||
// Make a temporary copy of the event to avoid possibility of
|
|
||||||
// a race condition if the last subscriber unsubscribes
|
if (handler != null)
|
||||||
// immediately after the null check and before the event is raised.
|
{
|
||||||
OutOfBounds handler = OnOutOfBounds;
|
|
||||||
if (handler != null)
|
handler();
|
||||||
{
|
|
||||||
OnOutOfBounds(pos);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public virtual void RaiseOutOfBounds(PhysicsVector pos)
|
||||||
public virtual void SendCollisionUpdate(EventArgs e)
|
{
|
||||||
{
|
// Make a temporary copy of the event to avoid possibility of
|
||||||
// CollisionUpdate handler = OnCollisionUpdate;
|
// a race condition if the last subscriber unsubscribes
|
||||||
if (OnCollisionUpdate != null)
|
// immediately after the null check and before the event is raised.
|
||||||
OnCollisionUpdate(e);
|
OutOfBounds handler = OnOutOfBounds;
|
||||||
}
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(pos);
|
||||||
public abstract PhysicsVector Position { get; set; }
|
}
|
||||||
|
}
|
||||||
public abstract float Mass { get; }
|
|
||||||
|
public virtual void SendCollisionUpdate(EventArgs e)
|
||||||
public abstract PhysicsVector Force { get; }
|
{
|
||||||
|
CollisionUpdate handler = OnCollisionUpdate;
|
||||||
public abstract PhysicsVector GeometricCenter { get; }
|
|
||||||
|
if (handler != null)
|
||||||
public abstract PhysicsVector CenterOfMass { get; }
|
{
|
||||||
|
handler(e);
|
||||||
public abstract PhysicsVector Velocity { get; set; }
|
}
|
||||||
|
|
||||||
public abstract PhysicsVector Acceleration { get; }
|
}
|
||||||
|
|
||||||
public abstract Quaternion Orientation { get; set; }
|
|
||||||
public abstract int PhysicsActorType { get; set; }
|
public abstract PhysicsVector Position { get; set; }
|
||||||
|
|
||||||
public abstract bool IsPhysical { get; set; }
|
public abstract float Mass { get; }
|
||||||
|
|
||||||
public abstract bool Flying { get; set; }
|
public abstract PhysicsVector Force { get; }
|
||||||
public abstract bool SetAlwaysRun { get; set; }
|
|
||||||
public abstract bool ThrottleUpdates { get; set; }
|
public abstract PhysicsVector GeometricCenter { get; }
|
||||||
|
|
||||||
public abstract bool IsColliding { get; set; }
|
public abstract PhysicsVector CenterOfMass { get; }
|
||||||
public abstract bool CollidingGround { get; set; }
|
|
||||||
public abstract bool CollidingObj { get; set; }
|
public abstract PhysicsVector Velocity { get; set; }
|
||||||
|
|
||||||
public abstract PhysicsVector RotationalVelocity { get; set; }
|
public abstract float CollisionScore { get;}
|
||||||
|
|
||||||
public abstract bool Kinematic { get; set; }
|
public abstract PhysicsVector Acceleration { get; }
|
||||||
|
|
||||||
public abstract void AddForce(PhysicsVector force);
|
public abstract Quaternion Orientation { get; set; }
|
||||||
|
public abstract int PhysicsActorType { get; set; }
|
||||||
public abstract void SetMomentum(PhysicsVector momentum);
|
|
||||||
|
public abstract bool IsPhysical { get; set; }
|
||||||
public virtual void SetCollisionMesh(byte[] vData, string MeshName, bool vbScaleMesh) { } // rex
|
|
||||||
public virtual void SetBoundsScaling(bool vbScaleMesh) { } // rex
|
public abstract bool Flying { get; set; }
|
||||||
public int NextPrimVolumeTime = 0; // rex
|
public abstract bool SetAlwaysRun { get; set; }
|
||||||
public uint m_localID; // rex
|
public abstract bool ThrottleUpdates { get; set; }
|
||||||
}
|
|
||||||
|
public abstract bool IsColliding { get; set; }
|
||||||
public class NullPhysicsActor : PhysicsActor
|
public abstract bool CollidingGround { get; set; }
|
||||||
{
|
public abstract bool CollidingObj { get; set; }
|
||||||
public override PhysicsVector Position
|
|
||||||
{
|
public abstract PhysicsVector RotationalVelocity { get; set; }
|
||||||
get { return PhysicsVector.Zero; }
|
|
||||||
set { return; }
|
public abstract bool Kinematic { get; set; }
|
||||||
}
|
|
||||||
|
public abstract void AddForce(PhysicsVector force);
|
||||||
public override bool SetAlwaysRun
|
|
||||||
{
|
public abstract void SetMomentum(PhysicsVector momentum);
|
||||||
get { return false; }
|
|
||||||
set { return; }
|
public virtual void SetCollisionMesh(byte[] vData, string MeshName, bool vbScaleMesh) { } // rex
|
||||||
}
|
public virtual void SetBoundsScaling(bool vbScaleMesh) { } // rex
|
||||||
|
public int NextPrimVolumeTime = 0; // rex
|
||||||
public override bool CollidingGround
|
public uint m_localID; // rex
|
||||||
{
|
}
|
||||||
get { return false; }
|
|
||||||
set { return; }
|
public class NullPhysicsActor : PhysicsActor
|
||||||
}
|
{
|
||||||
|
public override bool Stopped
|
||||||
public override bool CollidingObj
|
{
|
||||||
{
|
get{ return false; }
|
||||||
get { return false; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override PhysicsVector Position
|
||||||
|
{
|
||||||
public override PhysicsVector Size
|
get { return PhysicsVector.Zero; }
|
||||||
{
|
set { return; }
|
||||||
get { return PhysicsVector.Zero; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override bool SetAlwaysRun
|
||||||
|
{
|
||||||
public override float Mass
|
get { return false; }
|
||||||
{
|
set { return; }
|
||||||
get { return 0f; }
|
}
|
||||||
}
|
|
||||||
|
public override bool Grabbed
|
||||||
public override PhysicsVector Force
|
{
|
||||||
{
|
set { return; }
|
||||||
get { return PhysicsVector.Zero; }
|
}
|
||||||
}
|
|
||||||
|
public override bool Selected
|
||||||
public override PhysicsVector CenterOfMass
|
{
|
||||||
{
|
set { return; }
|
||||||
get { return PhysicsVector.Zero; }
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public override PhysicsVector GeometricCenter
|
public override bool CollidingGround
|
||||||
{
|
{
|
||||||
get { return PhysicsVector.Zero; }
|
get { return false; }
|
||||||
}
|
set { return; }
|
||||||
|
}
|
||||||
public override PrimitiveBaseShape Shape
|
|
||||||
{
|
public override bool CollidingObj
|
||||||
set { return; }
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
public override PhysicsVector Velocity
|
}
|
||||||
{
|
|
||||||
get { return PhysicsVector.Zero; }
|
public override PhysicsVector Size
|
||||||
set { return; }
|
{
|
||||||
}
|
get { return PhysicsVector.Zero; }
|
||||||
|
set { return; }
|
||||||
public override Quaternion Orientation
|
}
|
||||||
{
|
|
||||||
get { return Quaternion.Identity; }
|
public override float Mass
|
||||||
set { }
|
{
|
||||||
}
|
get { return 0f; }
|
||||||
|
}
|
||||||
public override PhysicsVector Acceleration
|
|
||||||
{
|
public override PhysicsVector Force
|
||||||
get { return PhysicsVector.Zero; }
|
{
|
||||||
}
|
get { return PhysicsVector.Zero; }
|
||||||
|
}
|
||||||
public override bool IsPhysical
|
|
||||||
{
|
public override PhysicsVector CenterOfMass
|
||||||
get { return false; }
|
{
|
||||||
set { return; }
|
get { return PhysicsVector.Zero; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Flying
|
public override PhysicsVector GeometricCenter
|
||||||
{
|
{
|
||||||
get { return false; }
|
get { return PhysicsVector.Zero; }
|
||||||
set { return; }
|
}
|
||||||
}
|
|
||||||
|
public override PrimitiveBaseShape Shape
|
||||||
public override bool ThrottleUpdates
|
{
|
||||||
{
|
set { return; }
|
||||||
get { return false; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override PhysicsVector Velocity
|
||||||
|
{
|
||||||
public override bool IsColliding
|
get { return PhysicsVector.Zero; }
|
||||||
{
|
set { return; }
|
||||||
get { return false; }
|
}
|
||||||
set { return; }
|
|
||||||
}
|
public override float CollisionScore
|
||||||
|
{
|
||||||
public override int PhysicsActorType
|
get { return 0f; }
|
||||||
{
|
}
|
||||||
get { return (int) ActorTypes.Unknown; }
|
|
||||||
set { return; }
|
public override void CrossingFailure()
|
||||||
}
|
{
|
||||||
|
|
||||||
public override bool Kinematic
|
}
|
||||||
{
|
|
||||||
get { return true; }
|
|
||||||
set { return; }
|
public override Quaternion Orientation
|
||||||
}
|
{
|
||||||
|
get { return Quaternion.Identity; }
|
||||||
public override void AddForce(PhysicsVector force)
|
set { }
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
public override PhysicsVector Acceleration
|
||||||
|
{
|
||||||
public override PhysicsVector RotationalVelocity
|
get { return PhysicsVector.Zero; }
|
||||||
{
|
}
|
||||||
get { return PhysicsVector.Zero; }
|
|
||||||
set { return; }
|
public override bool IsPhysical
|
||||||
}
|
{
|
||||||
|
get { return false; }
|
||||||
public override void SetMomentum(PhysicsVector momentum)
|
set { return; }
|
||||||
{
|
}
|
||||||
return;
|
|
||||||
}
|
public override bool Flying
|
||||||
}
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ThrottleUpdates
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsColliding
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int PhysicsActorType
|
||||||
|
{
|
||||||
|
get { return (int) ActorTypes.Unknown; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Kinematic
|
||||||
|
{
|
||||||
|
get { return true; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AddForce(PhysicsVector force)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override PhysicsVector RotationalVelocity
|
||||||
|
{
|
||||||
|
get { return PhysicsVector.Zero; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SetMomentum(PhysicsVector momentum)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,181 +1,188 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Manager
|
namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of MyClass.
|
/// Description of MyClass.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PhysicsPluginManager
|
public class PhysicsPluginManager
|
||||||
{
|
{
|
||||||
private Dictionary<string, IPhysicsPlugin> _PhysPlugins = new Dictionary<string, IPhysicsPlugin>();
|
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private Dictionary<string, IMeshingPlugin> _MeshPlugins = new Dictionary<string, IMeshingPlugin>();
|
|
||||||
|
private Dictionary<string, IPhysicsPlugin> _PhysPlugins = new Dictionary<string, IPhysicsPlugin>();
|
||||||
public PhysicsPluginManager()
|
private Dictionary<string, IMeshingPlugin> _MeshPlugins = new Dictionary<string, IMeshingPlugin>();
|
||||||
{
|
|
||||||
}
|
public PhysicsPluginManager()
|
||||||
|
|
||||||
public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName)
|
|
||||||
{
|
|
||||||
if (String.IsNullOrEmpty(physEngineName))
|
|
||||||
{
|
|
||||||
return PhysicsScene.Null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (String.IsNullOrEmpty(meshEngineName))
|
|
||||||
{
|
|
||||||
return PhysicsScene.Null;
|
|
||||||
}
|
|
||||||
|
|
||||||
IMesher meshEngine = null;
|
|
||||||
if (_MeshPlugins.ContainsKey(meshEngineName))
|
|
||||||
{
|
|
||||||
MainLog.Instance.Verbose("PHYSICS", "creating meshing engine " + meshEngineName);
|
|
||||||
meshEngine = _MeshPlugins[meshEngineName].GetMesher();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MainLog.Instance.Warn("PHYSICS", "couldn't find meshingEngine: {0}", meshEngineName);
|
|
||||||
throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_PhysPlugins.ContainsKey(physEngineName))
|
|
||||||
{
|
|
||||||
MainLog.Instance.Verbose("PHYSICS", "creating " + physEngineName);
|
|
||||||
PhysicsScene result = _PhysPlugins[physEngineName].GetScene();
|
|
||||||
result.Initialise(meshEngine);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", physEngineName);
|
|
||||||
throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadPlugins()
|
|
||||||
{
|
|
||||||
// Load "plugins", that are hard coded and not existing in form of an external lib
|
|
||||||
IMeshingPlugin plugHard;
|
|
||||||
plugHard = new ZeroMesherPlugin();
|
|
||||||
_MeshPlugins.Add(plugHard.GetName(), plugHard);
|
|
||||||
MainLog.Instance.Verbose("PHYSICS", "Added meshing engine: " + plugHard.GetName());
|
|
||||||
|
|
||||||
// And now walk all assemblies (DLLs effectively) and see if they are home
|
|
||||||
// of a plugin that is of interest for us
|
|
||||||
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Physics");
|
|
||||||
string[] pluginFiles = Directory.GetFiles(path, "*.dll");
|
|
||||||
|
|
||||||
for (int i = 0; i < pluginFiles.Length; i++)
|
|
||||||
{
|
|
||||||
AddPlugin(pluginFiles[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddPlugin(string FileName)
|
|
||||||
{
|
{
|
||||||
try
|
}
|
||||||
{
|
|
||||||
Assembly pluginAssembly = Assembly.LoadFrom(FileName);
|
public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName)
|
||||||
|
{
|
||||||
foreach (Type pluginType in pluginAssembly.GetTypes())
|
if (String.IsNullOrEmpty(physEngineName))
|
||||||
{
|
{
|
||||||
if (pluginType.IsPublic)
|
return PhysicsScene.Null;
|
||||||
{
|
}
|
||||||
if (!pluginType.IsAbstract)
|
|
||||||
{
|
if (String.IsNullOrEmpty(meshEngineName))
|
||||||
Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
|
{
|
||||||
|
return PhysicsScene.Null;
|
||||||
if (physTypeInterface != null)
|
}
|
||||||
{
|
|
||||||
IPhysicsPlugin plug =
|
IMesher meshEngine = null;
|
||||||
(IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
if (_MeshPlugins.ContainsKey(meshEngineName))
|
||||||
plug.Init();
|
{
|
||||||
_PhysPlugins.Add(plug.GetName(), plug);
|
m_log.Info("[PHYSICS]: creating meshing engine " + meshEngineName);
|
||||||
MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName());
|
meshEngine = _MeshPlugins[meshEngineName].GetMesher();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true);
|
{
|
||||||
|
m_log.WarnFormat("[PHYSICS]: couldn't find meshingEngine: {0}", meshEngineName);
|
||||||
if (meshTypeInterface != null)
|
throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
|
||||||
{
|
}
|
||||||
IMeshingPlugin plug =
|
|
||||||
(IMeshingPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
if (_PhysPlugins.ContainsKey(physEngineName))
|
||||||
_MeshPlugins.Add(plug.GetName(), plug);
|
{
|
||||||
MainLog.Instance.Verbose("PHYSICS", "Added meshing engine: " + plug.GetName());
|
m_log.Info("[PHYSICS]: creating " + physEngineName);
|
||||||
}
|
PhysicsScene result = _PhysPlugins[physEngineName].GetScene();
|
||||||
|
result.Initialise(meshEngine);
|
||||||
physTypeInterface = null;
|
return result;
|
||||||
meshTypeInterface = null;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
}
|
m_log.WarnFormat("[PHYSICS]: couldn't find physicsEngine: {0}", physEngineName);
|
||||||
|
throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadPlugins()
|
||||||
|
{
|
||||||
|
// Load "plugins", that are hard coded and not existing in form of an external lib
|
||||||
|
IMeshingPlugin plugHard;
|
||||||
|
plugHard = new ZeroMesherPlugin();
|
||||||
|
_MeshPlugins.Add(plugHard.GetName(), plugHard);
|
||||||
|
m_log.Info("[PHYSICS]: Added meshing engine: " + plugHard.GetName());
|
||||||
|
|
||||||
|
// And now walk all assemblies (DLLs effectively) and see if they are home
|
||||||
|
// of a plugin that is of interest for us
|
||||||
|
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Physics");
|
||||||
|
string[] pluginFiles = Directory.GetFiles(path, "*.dll");
|
||||||
|
|
||||||
|
for (int i = 0; i < pluginFiles.Length; i++)
|
||||||
|
{
|
||||||
|
AddPlugin(pluginFiles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPlugin(string FileName)
|
||||||
|
{
|
||||||
|
// TODO / NOTE
|
||||||
|
// The assembly named 'OpenSim.Region.Physics.BasicPhysicsPlugin' was loaded from
|
||||||
|
// 'file:///C:/OpenSim/trunk2/bin/Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll'
|
||||||
|
// using the LoadFrom context. The use of this context can result in unexpected behavior
|
||||||
|
// for serialization, casting and dependency resolution. In almost all cases, it is recommended
|
||||||
|
// that the LoadFrom context be avoided. This can be done by installing assemblies in the
|
||||||
|
// Global Assembly Cache or in the ApplicationBase directory and using Assembly.
|
||||||
|
// Load when explicitly loading assemblies.
|
||||||
|
Assembly pluginAssembly = Assembly.LoadFrom(FileName);
|
||||||
|
|
||||||
|
foreach (Type pluginType in pluginAssembly.GetTypes())
|
||||||
|
{
|
||||||
|
if (pluginType.IsPublic)
|
||||||
|
{
|
||||||
|
if (!pluginType.IsAbstract)
|
||||||
|
{
|
||||||
|
IPhysicsPlugin plug =
|
||||||
|
(IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
||||||
|
plug.Init();
|
||||||
|
_PhysPlugins.Add(plug.GetName(), plug);
|
||||||
|
m_log.Info("[PHYSICS]: Added physics engine: " + plug.GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (physTypeInterface != null)
|
||||||
|
{
|
||||||
|
IPhysicsPlugin plug =
|
||||||
|
(IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
||||||
|
plug.Init();
|
||||||
|
_PhysPlugins.Add(plug.GetName(), plug);
|
||||||
|
MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshTypeInterface != null)
|
||||||
|
{
|
||||||
|
IMeshingPlugin plug =
|
||||||
|
(IMeshingPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
|
||||||
|
_MeshPlugins.Add(plug.GetName(), plug);
|
||||||
|
m_log.Info("[PHYSICS]: Added meshing engine: " + plug.GetName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pluginAssembly = null;
|
pluginAssembly = null;
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
{
|
{
|
||||||
MainLog.Instance.Warn("PHYSICS", "Error loading plugin " + FileName + ": " + e.Message);
|
MainLog.Instance.Warn("PHYSICS", "Error loading plugin " + FileName + ": " + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
public static void PhysicsPluginMessage(string message, bool isWarning)
|
public static void PhysicsPluginMessage(string message, bool isWarning)
|
||||||
{
|
{
|
||||||
if (isWarning)
|
if (isWarning)
|
||||||
{
|
{
|
||||||
MainLog.Instance.Warn("PHYSICS", message);
|
m_log.Warn("[PHYSICS]: " + message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainLog.Instance.Verbose("PHYSICS", message);
|
m_log.Info("[PHYSICS]: " + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IPhysicsPlugin
|
public interface IPhysicsPlugin
|
||||||
{
|
{
|
||||||
bool Init();
|
bool Init();
|
||||||
PhysicsScene GetScene();
|
PhysicsScene GetScene();
|
||||||
string GetName();
|
string GetName();
|
||||||
void Dispose();
|
void Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IMeshingPlugin
|
public interface IMeshingPlugin
|
||||||
{
|
{
|
||||||
string GetName();
|
string GetName();
|
||||||
IMesher GetMesher();
|
IMesher GetMesher();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,160 +1,168 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
using Axiom.Math;
|
using System;
|
||||||
using OpenSim.Framework;
|
using Axiom.Math;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
namespace OpenSim.Region.Physics.Manager
|
|
||||||
{
|
namespace OpenSim.Region.Physics.Manager
|
||||||
public delegate void physicsCrash();
|
{
|
||||||
|
public delegate void physicsCrash();
|
||||||
public abstract class PhysicsScene
|
|
||||||
{
|
public abstract class PhysicsScene
|
||||||
// The only thing that should register for this event is the InnerScene
|
{
|
||||||
// Anything else could cause problems.
|
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
public event physicsCrash OnPhysicsCrash;
|
// The only thing that should register for this event is the InnerScene
|
||||||
|
// Anything else could cause problems.
|
||||||
public static PhysicsScene Null
|
|
||||||
{
|
public event physicsCrash OnPhysicsCrash;
|
||||||
get { return new NullPhysicsScene(); }
|
|
||||||
}
|
public static PhysicsScene Null
|
||||||
|
{
|
||||||
public virtual void TriggerPhysicsBasedRestart()
|
get { return new NullPhysicsScene(); }
|
||||||
{
|
}
|
||||||
physicsCrash handler = OnPhysicsCrash;
|
|
||||||
if (handler != null)
|
public virtual void TriggerPhysicsBasedRestart()
|
||||||
{
|
{
|
||||||
OnPhysicsCrash();
|
physicsCrash handler = OnPhysicsCrash;
|
||||||
}
|
if (handler != null)
|
||||||
}
|
{
|
||||||
|
OnPhysicsCrash();
|
||||||
|
}
|
||||||
public abstract void Initialise(IMesher meshmerizer);
|
}
|
||||||
|
|
||||||
public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID); // rex, localID added
|
|
||||||
|
public abstract void Initialise(IMesher meshmerizer);
|
||||||
public abstract void RemoveAvatar(PhysicsActor actor);
|
|
||||||
|
public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size);
|
||||||
public abstract void RemovePrim(PhysicsActor prim);
|
|
||||||
|
public abstract void RemoveAvatar(PhysicsActor actor);
|
||||||
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
|
||||||
PhysicsVector size, Quaternion rotation, uint localID); //To be removed, rex, localID added
|
public abstract void RemovePrim(PhysicsActor prim);
|
||||||
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
|
||||||
PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID); // rex, localID added
|
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
||||||
|
PhysicsVector size, Quaternion rotation, uint localID); //To be removed, rex, localID added
|
||||||
public abstract void AddPhysicsActorTaint(PhysicsActor prim);
|
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
||||||
|
PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID); // rex, localID added
|
||||||
public abstract float Simulate(float timeStep);
|
|
||||||
|
public abstract void AddPhysicsActorTaint(PhysicsActor prim);
|
||||||
public abstract void GetResults();
|
|
||||||
|
public abstract float Simulate(float timeStep);
|
||||||
public abstract void SetTerrain(float[] heightMap);
|
|
||||||
|
public abstract void GetResults();
|
||||||
public abstract void DeleteTerrain();
|
|
||||||
|
public abstract void SetTerrain(float[] heightMap);
|
||||||
public abstract bool IsThreaded { get; }
|
|
||||||
|
public abstract void DeleteTerrain();
|
||||||
private class NullPhysicsScene : PhysicsScene
|
|
||||||
{
|
public abstract void Dispose();
|
||||||
private static int m_workIndicator;
|
|
||||||
|
public abstract bool IsThreaded { get; }
|
||||||
|
|
||||||
public override void Initialise(IMesher meshmerizer)
|
private class NullPhysicsScene : PhysicsScene
|
||||||
{
|
{
|
||||||
// Does nothing right now
|
private static int m_workIndicator;
|
||||||
}
|
|
||||||
|
|
||||||
public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
|
public override void Initialise(IMesher meshmerizer)
|
||||||
{
|
{
|
||||||
MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : AddAvatar({0})", position);
|
// Does nothing right now
|
||||||
return PhysicsActor.Null;
|
}
|
||||||
}
|
|
||||||
|
public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
|
||||||
public override void RemoveAvatar(PhysicsActor actor)
|
{
|
||||||
{
|
m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddAvatar({0})", position);
|
||||||
}
|
return PhysicsActor.Null;
|
||||||
|
}
|
||||||
public override void RemovePrim(PhysicsActor prim)
|
|
||||||
{
|
public override void RemoveAvatar(PhysicsActor actor)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
/*
|
|
||||||
public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
|
public override void RemovePrim(PhysicsActor prim)
|
||||||
{
|
{
|
||||||
MainLog.Instance.Verbose("NullPhysicsScene : AddPrim({0},{1})", position, size);
|
}
|
||||||
return PhysicsActor.Null;
|
|
||||||
}
|
/*
|
||||||
*/
|
public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
|
||||||
|
{
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
m_log.InfoFormat("NullPhysicsScene : AddPrim({0},{1})", position, size);
|
||||||
PhysicsVector size, Quaternion rotation, uint localID) //To be removed
|
return PhysicsActor.Null;
|
||||||
{
|
}
|
||||||
return AddPrimShape(primName, pbs, position, size, rotation, false, localID);
|
*/
|
||||||
}
|
|
||||||
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
PhysicsVector size, Quaternion rotation, uint localID) //To be removed
|
||||||
PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
|
{
|
||||||
{
|
return AddPrimShape(primName, pbs, position, size, rotation, false, localID);
|
||||||
MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : AddPrim({0},{1})", position, size);
|
}
|
||||||
return PhysicsActor.Null;
|
|
||||||
}
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
|
||||||
|
PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
|
||||||
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
{
|
||||||
{
|
m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddPrim({0},{1})", position, size);
|
||||||
}
|
return PhysicsActor.Null;
|
||||||
|
}
|
||||||
public override float Simulate(float timeStep)
|
|
||||||
{
|
public override void AddPhysicsActorTaint(PhysicsActor prim)
|
||||||
m_workIndicator = (m_workIndicator + 1)%10;
|
{
|
||||||
|
}
|
||||||
//MainLog.Instance.SetStatus(m_workIndicator.ToString());
|
|
||||||
return 0f;
|
public override float Simulate(float timeStep)
|
||||||
}
|
{
|
||||||
|
m_workIndicator = (m_workIndicator + 1) % 10;
|
||||||
public override void GetResults()
|
|
||||||
{
|
return 0f;
|
||||||
MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : GetResults()");
|
}
|
||||||
}
|
|
||||||
|
public override void GetResults()
|
||||||
public override void SetTerrain(float[] heightMap)
|
{
|
||||||
{
|
m_log.Info("[PHYSICS]: NullPhysicsScene : GetResults()");
|
||||||
MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : SetTerrain({0} items)", heightMap.Length);
|
}
|
||||||
}
|
|
||||||
|
public override void SetTerrain(float[] heightMap)
|
||||||
public override void DeleteTerrain()
|
{
|
||||||
{
|
m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : SetTerrain({0} items)", heightMap.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsThreaded
|
public override void DeleteTerrain()
|
||||||
{
|
{
|
||||||
get { return false; }
|
}
|
||||||
}
|
|
||||||
}
|
public override bool IsThreaded
|
||||||
}
|
{
|
||||||
}
|
get { return false; }
|
||||||
|
}
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Timers;
|
||||||
|
using Axiom.Math;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.Manager
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum SenseType : uint
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
AGENT = 1,
|
||||||
|
ACTIVE = 2,
|
||||||
|
PASSIVE = 3,
|
||||||
|
SCRIPTED = 4
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract class PhysicsSensor
|
||||||
|
{
|
||||||
|
|
||||||
|
public static PhysicsSensor Null
|
||||||
|
{
|
||||||
|
get { return new NullPhysicsSensor(); }
|
||||||
|
}
|
||||||
|
public abstract PhysicsVector Position {get; set;}
|
||||||
|
public abstract void TimerCallback (object obj, ElapsedEventArgs eea);
|
||||||
|
public abstract float radianarc {get; set;}
|
||||||
|
public abstract string targetname {get; set;}
|
||||||
|
public abstract Guid targetKey{get;set;}
|
||||||
|
public abstract SenseType sensetype { get;set;}
|
||||||
|
public abstract float range { get;set;}
|
||||||
|
public abstract float rateSeconds { get;set;}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NullPhysicsSensor : PhysicsSensor
|
||||||
|
{
|
||||||
|
|
||||||
|
public override PhysicsVector Position
|
||||||
|
{
|
||||||
|
get { return PhysicsVector.Zero; }
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
public override void TimerCallback(object obj, ElapsedEventArgs eea)
|
||||||
|
{
|
||||||
|
// don't do squat
|
||||||
|
}
|
||||||
|
public override float radianarc { get { return 0f; } set { } }
|
||||||
|
public override string targetname { get { return ""; } set { } }
|
||||||
|
public override Guid targetKey { get { return Guid.Empty; } set { } }
|
||||||
|
public override SenseType sensetype { get { return SenseType.NONE; } set { } }
|
||||||
|
public override float range { get { return 0; } set { } }
|
||||||
|
public override float rateSeconds { get { return 0; } set { } }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,103 +1,158 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Manager
|
namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
public class PhysicsVector
|
public class PhysicsVector
|
||||||
{
|
{
|
||||||
public float X;
|
public float X;
|
||||||
public float Y;
|
public float Y;
|
||||||
public float Z;
|
public float Z;
|
||||||
|
|
||||||
public PhysicsVector()
|
public PhysicsVector()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsVector(float x, float y, float z)
|
public PhysicsVector(float x, float y, float z)
|
||||||
{
|
{
|
||||||
X = x;
|
X = x;
|
||||||
Y = y;
|
Y = y;
|
||||||
Z = z;
|
Z = z;
|
||||||
}
|
}
|
||||||
|
public void setValues(float x, float y, float z)
|
||||||
public static readonly PhysicsVector Zero = new PhysicsVector(0f, 0f, 0f);
|
{
|
||||||
|
X = x;
|
||||||
public override string ToString()
|
Y = y;
|
||||||
{
|
Z = z;
|
||||||
return "<" + X + "," + Y + "," + Z + ">";
|
}
|
||||||
}
|
public static readonly PhysicsVector Zero = new PhysicsVector(0f, 0f, 0f);
|
||||||
|
|
||||||
// Operations
|
public override string ToString()
|
||||||
public static PhysicsVector operator +(PhysicsVector a, PhysicsVector b)
|
{
|
||||||
{
|
return "<" + X + "," + Y + "," + Z + ">";
|
||||||
return new PhysicsVector(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
public static PhysicsVector operator -(PhysicsVector a, PhysicsVector b)
|
/// These routines are the easiest way to store XYZ values in an LLVector3 without requiring 3 calls.
|
||||||
{
|
/// </summary>
|
||||||
return new PhysicsVector(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
/// <returns></returns>
|
||||||
}
|
public byte[] GetBytes()
|
||||||
|
{
|
||||||
public static PhysicsVector cross(PhysicsVector a, PhysicsVector b)
|
byte[] byteArray = new byte[12];
|
||||||
{
|
|
||||||
return new PhysicsVector(a.Y*b.Z - a.Z*b.Y, a.Z*b.X - a.X*b.Z, a.X*b.Y - a.Y*b.X);
|
Buffer.BlockCopy(BitConverter.GetBytes(X), 0, byteArray, 0, 4);
|
||||||
}
|
Buffer.BlockCopy(BitConverter.GetBytes(Y), 0, byteArray, 4, 4);
|
||||||
|
Buffer.BlockCopy(BitConverter.GetBytes(Z), 0, byteArray, 8, 4);
|
||||||
public float length()
|
|
||||||
{
|
if (!BitConverter.IsLittleEndian)
|
||||||
return (float) Math.Sqrt(X*X + Y*Y + Z*Z);
|
{
|
||||||
}
|
Array.Reverse(byteArray, 0, 4);
|
||||||
|
Array.Reverse(byteArray, 4, 4);
|
||||||
public static PhysicsVector operator /(PhysicsVector v, float f)
|
Array.Reverse(byteArray, 8, 4);
|
||||||
{
|
}
|
||||||
return new PhysicsVector(v.X/f, v.Y/f, v.Z/f);
|
|
||||||
}
|
return byteArray;
|
||||||
|
}
|
||||||
public static PhysicsVector operator *(PhysicsVector v, float f)
|
|
||||||
{
|
public void FromBytes(byte[] byteArray, int pos)
|
||||||
return new PhysicsVector(v.X*f, v.Y*f, v.Z*f);
|
{
|
||||||
}
|
byte[] conversionBuffer = null;
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
public static PhysicsVector operator *(float f, PhysicsVector v)
|
{
|
||||||
{
|
// Big endian architecture
|
||||||
return v*f;
|
if (conversionBuffer == null)
|
||||||
}
|
conversionBuffer = new byte[12];
|
||||||
|
|
||||||
public virtual bool IsIdentical(PhysicsVector v, float tolerance)
|
Buffer.BlockCopy(byteArray, pos, conversionBuffer, 0, 12);
|
||||||
{
|
|
||||||
PhysicsVector diff = this - v;
|
Array.Reverse(conversionBuffer, 0, 4);
|
||||||
float d = diff.length();
|
Array.Reverse(conversionBuffer, 4, 4);
|
||||||
if (d < tolerance)
|
Array.Reverse(conversionBuffer, 8, 4);
|
||||||
return true;
|
|
||||||
|
X = BitConverter.ToSingle(conversionBuffer, 0);
|
||||||
return false;
|
Y = BitConverter.ToSingle(conversionBuffer, 4);
|
||||||
}
|
Z = BitConverter.ToSingle(conversionBuffer, 8);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
// Little endian architecture
|
||||||
|
X = BitConverter.ToSingle(byteArray, pos);
|
||||||
|
Y = BitConverter.ToSingle(byteArray, pos + 4);
|
||||||
|
Z = BitConverter.ToSingle(byteArray, pos + 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operations
|
||||||
|
public static PhysicsVector operator +(PhysicsVector a, PhysicsVector b)
|
||||||
|
{
|
||||||
|
return new PhysicsVector(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PhysicsVector operator -(PhysicsVector a, PhysicsVector b)
|
||||||
|
{
|
||||||
|
return new PhysicsVector(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PhysicsVector cross(PhysicsVector a, PhysicsVector b)
|
||||||
|
{
|
||||||
|
return new PhysicsVector(a.Y*b.Z - a.Z*b.Y, a.Z*b.X - a.X*b.Z, a.X*b.Y - a.Y*b.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float length()
|
||||||
|
{
|
||||||
|
return (float) Math.Sqrt(X*X + Y*Y + Z*Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PhysicsVector operator /(PhysicsVector v, float f)
|
||||||
|
{
|
||||||
|
return new PhysicsVector(v.X/f, v.Y/f, v.Z/f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PhysicsVector operator *(PhysicsVector v, float f)
|
||||||
|
{
|
||||||
|
return new PhysicsVector(v.X*f, v.Y*f, v.Z*f);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PhysicsVector operator *(float f, PhysicsVector v)
|
||||||
|
{
|
||||||
|
return v*f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool IsIdentical(PhysicsVector v, float tolerance)
|
||||||
|
{
|
||||||
|
PhysicsVector diff = this - v;
|
||||||
|
float d = diff.length();
|
||||||
|
if (d < tolerance)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,69 +1,69 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is the zero mesher.
|
* This is the zero mesher.
|
||||||
* Whatever you want him to mesh, he can't, telling you that by responding with a null pointer.
|
* Whatever you want him to mesh, he can't, telling you that by responding with a null pointer.
|
||||||
* Effectivly this is for switching off meshing and for testing as each physics machine should deal
|
* Effectivly this is for switching off meshing and for testing as each physics machine should deal
|
||||||
* with the null pointer situation.
|
* with the null pointer situation.
|
||||||
* But it's also a convenience thing, as physics machines can rely on having a mesher in any situation, even
|
* But it's also a convenience thing, as physics machines can rely on having a mesher in any situation, even
|
||||||
* if it's a dump one like this.
|
* if it's a dump one like this.
|
||||||
* Note, that this mesher is *not* living in a module but in the manager itself, so
|
* Note, that this mesher is *not* living in a module but in the manager itself, so
|
||||||
* it's always availabe and thus the default in case of configuration errors
|
* it's always availabe and thus the default in case of configuration errors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Manager
|
namespace OpenSim.Region.Physics.Manager
|
||||||
{
|
{
|
||||||
public class ZeroMesherPlugin : IMeshingPlugin
|
public class ZeroMesherPlugin : IMeshingPlugin
|
||||||
{
|
{
|
||||||
public ZeroMesherPlugin()
|
public ZeroMesherPlugin()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName()
|
public string GetName()
|
||||||
{
|
{
|
||||||
return "ZeroMesher";
|
return "ZeroMesher";
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMesher GetMesher()
|
public IMesher GetMesher()
|
||||||
{
|
{
|
||||||
return new ZeroMesher();
|
return new ZeroMesher();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ZeroMesher : IMesher
|
public class ZeroMesher : IMesher
|
||||||
{
|
{
|
||||||
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
|
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,110 +1,125 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Meshing
|
namespace OpenSim.Region.Physics.Meshing
|
||||||
{
|
{
|
||||||
internal class Extruder
|
internal class Extruder
|
||||||
{
|
{
|
||||||
public float startParameter;
|
public float startParameter;
|
||||||
public float stopParameter;
|
public float stopParameter;
|
||||||
public PhysicsVector size;
|
public PhysicsVector size;
|
||||||
|
|
||||||
public Mesh Extrude(Mesh m)
|
public float taperTopFactorX = 1f;
|
||||||
{
|
public float taperTopFactorY = 1f;
|
||||||
// Currently only works for iSteps=1;
|
public float taperBotFactorX = 1f;
|
||||||
Mesh result = new Mesh();
|
public float taperBotFactorY = 1f;
|
||||||
|
public float pushX = 0f;
|
||||||
Mesh workingPlus = m.Clone();
|
public float pushY = 0f;
|
||||||
Mesh workingMinus = m.Clone();
|
|
||||||
|
public Mesh Extrude(Mesh m)
|
||||||
foreach (Vertex v in workingPlus.vertices)
|
{
|
||||||
{
|
// Currently only works for iSteps=1;
|
||||||
if (v == null)
|
Mesh result = new Mesh();
|
||||||
continue;
|
|
||||||
|
Mesh workingPlus = m.Clone();
|
||||||
v.Z = +.5f;
|
Mesh workingMinus = m.Clone();
|
||||||
v.X *= size.X;
|
|
||||||
v.Y *= size.Y;
|
foreach (Vertex v in workingPlus.vertices)
|
||||||
v.Z *= size.Z;
|
{
|
||||||
}
|
if (v == null)
|
||||||
|
continue;
|
||||||
foreach (Vertex v in workingMinus.vertices)
|
|
||||||
{
|
// This is the top
|
||||||
if (v == null)
|
// Set the Z + .5 to match the rest of the scale of the mesh
|
||||||
continue;
|
// Scale it by Size, and Taper the scaling
|
||||||
|
v.Z = +.5f;
|
||||||
v.Z = -.5f;
|
v.X *= (size.X * taperTopFactorX);
|
||||||
v.X *= size.X;
|
v.Y *= (size.Y * taperTopFactorY);
|
||||||
v.Y *= size.Y;
|
v.Z *= size.Z;
|
||||||
v.Z *= size.Z;
|
|
||||||
}
|
//Push the top of the object over by the Top Shear amount
|
||||||
|
v.X += pushX * size.X;
|
||||||
foreach (Triangle t in workingMinus.triangles)
|
v.Y += pushY * size.X;
|
||||||
{
|
}
|
||||||
t.invertNormal();
|
|
||||||
}
|
foreach (Vertex v in workingMinus.vertices)
|
||||||
|
{
|
||||||
result.Append(workingMinus);
|
if (v == null)
|
||||||
result.Append(workingPlus);
|
continue;
|
||||||
|
|
||||||
int iLastNull = 0;
|
// This is the bottom
|
||||||
for (int i = 0; i < workingPlus.vertices.Count; i++)
|
v.Z = -.5f;
|
||||||
{
|
v.X *= (size.X * taperBotFactorX);
|
||||||
int iNext = (i + 1);
|
v.Y *= (size.Y * taperBotFactorY);
|
||||||
|
v.Z *= size.Z;
|
||||||
if (workingPlus.vertices[i] == null) // Can't make a simplex here
|
}
|
||||||
{
|
|
||||||
iLastNull = i + 1;
|
foreach (Triangle t in workingMinus.triangles)
|
||||||
continue;
|
{
|
||||||
}
|
t.invertNormal();
|
||||||
|
}
|
||||||
if (i == workingPlus.vertices.Count - 1) // End of list
|
|
||||||
{
|
result.Append(workingMinus);
|
||||||
iNext = iLastNull;
|
result.Append(workingPlus);
|
||||||
}
|
|
||||||
|
int iLastNull = 0;
|
||||||
if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
|
for (int i = 0; i < workingPlus.vertices.Count; i++)
|
||||||
{
|
{
|
||||||
iNext = iLastNull;
|
int iNext = (i + 1);
|
||||||
}
|
|
||||||
|
if (workingPlus.vertices[i] == null) // Can't make a simplex here
|
||||||
Triangle tSide;
|
{
|
||||||
tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
|
iLastNull = i + 1;
|
||||||
result.Add(tSide);
|
continue;
|
||||||
|
}
|
||||||
tSide =
|
|
||||||
new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
|
if (i == workingPlus.vertices.Count - 1) // End of list
|
||||||
result.Add(tSide);
|
{
|
||||||
}
|
iNext = iLastNull;
|
||||||
|
}
|
||||||
return result;
|
|
||||||
}
|
if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
|
||||||
}
|
{
|
||||||
}
|
iNext = iLastNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Triangle tSide;
|
||||||
|
tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
|
||||||
|
result.Add(tSide);
|
||||||
|
|
||||||
|
tSide =
|
||||||
|
new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
|
||||||
|
result.Add(tSide);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,304 +1,304 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
using OpenSim.Region.Physics.Meshing;
|
using OpenSim.Region.Physics.Meshing;
|
||||||
|
|
||||||
public class Vertex : PhysicsVector, IComparable<Vertex>
|
public class Vertex : PhysicsVector, IComparable<Vertex>
|
||||||
{
|
{
|
||||||
public Vertex(float x, float y, float z)
|
public Vertex(float x, float y, float z)
|
||||||
: base(x, y, z)
|
: base(x, y, z)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vertex(PhysicsVector v)
|
public Vertex(PhysicsVector v)
|
||||||
: base(v.X, v.Y, v.Z)
|
: base(v.X, v.Y, v.Z)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vertex Clone()
|
public Vertex Clone()
|
||||||
{
|
{
|
||||||
return new Vertex(X, Y, Z);
|
return new Vertex(X, Y, Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vertex FromAngle(double angle)
|
public static Vertex FromAngle(double angle)
|
||||||
{
|
{
|
||||||
return new Vertex((float) Math.Cos(angle), (float) Math.Sin(angle), 0.0f);
|
return new Vertex((float) Math.Cos(angle), (float) Math.Sin(angle), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public virtual bool Equals(Vertex v, float tolerance)
|
public virtual bool Equals(Vertex v, float tolerance)
|
||||||
{
|
{
|
||||||
PhysicsVector diff = this - v;
|
PhysicsVector diff = this - v;
|
||||||
float d = diff.length();
|
float d = diff.length();
|
||||||
if (d < tolerance)
|
if (d < tolerance)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int CompareTo(Vertex other)
|
public int CompareTo(Vertex other)
|
||||||
{
|
{
|
||||||
if (X < other.X)
|
if (X < other.X)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (X > other.X)
|
if (X > other.X)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (Y < other.Y)
|
if (Y < other.Y)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (Y > other.Y)
|
if (Y > other.Y)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (Z < other.Z)
|
if (Z < other.Z)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (Z > other.Z)
|
if (Z > other.Z)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator >(Vertex me, Vertex other)
|
public static bool operator >(Vertex me, Vertex other)
|
||||||
{
|
{
|
||||||
return me.CompareTo(other) > 0;
|
return me.CompareTo(other) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool operator <(Vertex me, Vertex other)
|
public static bool operator <(Vertex me, Vertex other)
|
||||||
{
|
{
|
||||||
return me.CompareTo(other) < 0;
|
return me.CompareTo(other) < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String ToRaw()
|
public String ToRaw()
|
||||||
{
|
{
|
||||||
// Why this stuff with the number formatter?
|
// Why this stuff with the number formatter?
|
||||||
// Well, the raw format uses the english/US notation of numbers
|
// Well, the raw format uses the english/US notation of numbers
|
||||||
// where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
|
// where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
|
||||||
// The german notation uses these characters exactly vice versa!
|
// The german notation uses these characters exactly vice versa!
|
||||||
// The Float.ToString() routine is a localized one, giving different results depending on the country
|
// The Float.ToString() routine is a localized one, giving different results depending on the country
|
||||||
// settings your machine works with. Unusable for a machine readable file format :-(
|
// settings your machine works with. Unusable for a machine readable file format :-(
|
||||||
NumberFormatInfo nfi = new NumberFormatInfo();
|
NumberFormatInfo nfi = new NumberFormatInfo();
|
||||||
nfi.NumberDecimalSeparator = ".";
|
nfi.NumberDecimalSeparator = ".";
|
||||||
nfi.NumberDecimalDigits = 3;
|
nfi.NumberDecimalDigits = 3;
|
||||||
|
|
||||||
String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
|
String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
|
||||||
|
|
||||||
return s1;
|
return s1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Triangle
|
public class Triangle
|
||||||
{
|
{
|
||||||
public Vertex v1;
|
public Vertex v1;
|
||||||
public Vertex v2;
|
public Vertex v2;
|
||||||
public Vertex v3;
|
public Vertex v3;
|
||||||
|
|
||||||
private float radius_square;
|
private float radius_square;
|
||||||
private float cx;
|
private float cx;
|
||||||
private float cy;
|
private float cy;
|
||||||
|
|
||||||
public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
|
public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
|
||||||
{
|
{
|
||||||
v1 = _v1;
|
v1 = _v1;
|
||||||
v2 = _v2;
|
v2 = _v2;
|
||||||
v3 = _v3;
|
v3 = _v3;
|
||||||
|
|
||||||
CalcCircle();
|
CalcCircle();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool isInCircle(float x, float y)
|
public bool isInCircle(float x, float y)
|
||||||
{
|
{
|
||||||
float dx, dy;
|
float dx, dy;
|
||||||
float dd;
|
float dd;
|
||||||
|
|
||||||
dx = x - cx;
|
dx = x - cx;
|
||||||
dy = y - cy;
|
dy = y - cy;
|
||||||
|
|
||||||
dd = dx*dx + dy*dy;
|
dd = dx*dx + dy*dy;
|
||||||
if (dd < radius_square)
|
if (dd < radius_square)
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool isDegraded()
|
public bool isDegraded()
|
||||||
{
|
{
|
||||||
// This means, the vertices of this triangle are somewhat strange.
|
// This means, the vertices of this triangle are somewhat strange.
|
||||||
// They either line up or at least two of them are identical
|
// They either line up or at least two of them are identical
|
||||||
return (radius_square == 0.0);
|
return (radius_square == 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalcCircle()
|
private void CalcCircle()
|
||||||
{
|
{
|
||||||
// Calculate the center and the radius of a circle given by three points p1, p2, p3
|
// Calculate the center and the radius of a circle given by three points p1, p2, p3
|
||||||
// It is assumed, that the triangles vertices are already set correctly
|
// It is assumed, that the triangles vertices are already set correctly
|
||||||
double p1x, p2x, p1y, p2y, p3x, p3y;
|
double p1x, p2x, p1y, p2y, p3x, p3y;
|
||||||
|
|
||||||
// Deviation of this routine:
|
// Deviation of this routine:
|
||||||
// A circle has the general equation (M-p)^2=r^2, where M and p are vectors
|
// A circle has the general equation (M-p)^2=r^2, where M and p are vectors
|
||||||
// this gives us three equations f(p)=r^2, each for one point p1, p2, p3
|
// this gives us three equations f(p)=r^2, each for one point p1, p2, p3
|
||||||
// putting respectively two equations together gives two equations
|
// putting respectively two equations together gives two equations
|
||||||
// f(p1)=f(p2) and f(p1)=f(p3)
|
// f(p1)=f(p2) and f(p1)=f(p3)
|
||||||
// bringing all constant terms to one side brings them to the form
|
// bringing all constant terms to one side brings them to the form
|
||||||
// M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
|
// M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
|
||||||
// and c1, c2 are scalars (Naming conventions like the variables below)
|
// and c1, c2 are scalars (Naming conventions like the variables below)
|
||||||
// Now using the equations that are formed by the components of the vectors
|
// Now using the equations that are formed by the components of the vectors
|
||||||
// and isolate Mx lets you make one equation that only holds My
|
// and isolate Mx lets you make one equation that only holds My
|
||||||
// The rest is straight forward and eaasy :-)
|
// The rest is straight forward and eaasy :-)
|
||||||
//
|
//
|
||||||
|
|
||||||
/* helping variables for temporary results */
|
/* helping variables for temporary results */
|
||||||
double c1, c2;
|
double c1, c2;
|
||||||
double v1x, v1y, v2x, v2y;
|
double v1x, v1y, v2x, v2y;
|
||||||
|
|
||||||
double z, n;
|
double z, n;
|
||||||
|
|
||||||
double rx, ry;
|
double rx, ry;
|
||||||
|
|
||||||
// Readout the three points, the triangle consists of
|
// Readout the three points, the triangle consists of
|
||||||
p1x = v1.X;
|
p1x = v1.X;
|
||||||
p1y = v1.Y;
|
p1y = v1.Y;
|
||||||
|
|
||||||
p2x = v2.X;
|
p2x = v2.X;
|
||||||
p2y = v2.Y;
|
p2y = v2.Y;
|
||||||
|
|
||||||
p3x = v3.X;
|
p3x = v3.X;
|
||||||
p3y = v3.Y;
|
p3y = v3.Y;
|
||||||
|
|
||||||
/* calc helping values first */
|
/* calc helping values first */
|
||||||
c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
|
c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
|
||||||
c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
|
c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
|
||||||
|
|
||||||
v1x = p1x - p2x;
|
v1x = p1x - p2x;
|
||||||
v1y = p1y - p2y;
|
v1y = p1y - p2y;
|
||||||
|
|
||||||
v2x = p1x - p3x;
|
v2x = p1x - p3x;
|
||||||
v2y = p1y - p3y;
|
v2y = p1y - p3y;
|
||||||
|
|
||||||
z = (c1*v2x - c2*v1x);
|
z = (c1*v2x - c2*v1x);
|
||||||
n = (v1y*v2x - v2y*v1x);
|
n = (v1y*v2x - v2y*v1x);
|
||||||
|
|
||||||
if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
|
if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
|
||||||
{
|
{
|
||||||
radius_square = 0.0f;
|
radius_square = 0.0f;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cy = (float) (z/n);
|
cy = (float) (z/n);
|
||||||
|
|
||||||
if (v2x != 0.0)
|
if (v2x != 0.0)
|
||||||
{
|
{
|
||||||
cx = (float) ((c2 - v2y*cy)/v2x);
|
cx = (float) ((c2 - v2y*cy)/v2x);
|
||||||
}
|
}
|
||||||
else if (v1x != 0.0)
|
else if (v1x != 0.0)
|
||||||
{
|
{
|
||||||
cx = (float) ((c1 - v1y*cy)/v1x);
|
cx = (float) ((c1 - v1y*cy)/v1x);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
|
Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
|
||||||
}
|
}
|
||||||
|
|
||||||
rx = (p1x - cx);
|
rx = (p1x - cx);
|
||||||
ry = (p1y - cy);
|
ry = (p1y - cy);
|
||||||
|
|
||||||
radius_square = (float) (rx*rx + ry*ry);
|
radius_square = (float) (rx*rx + ry*ry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Simplex> GetSimplices()
|
public List<Simplex> GetSimplices()
|
||||||
{
|
{
|
||||||
List<Simplex> result = new List<Simplex>();
|
List<Simplex> result = new List<Simplex>();
|
||||||
Simplex s1 = new Simplex(v1, v2);
|
Simplex s1 = new Simplex(v1, v2);
|
||||||
Simplex s2 = new Simplex(v2, v3);
|
Simplex s2 = new Simplex(v2, v3);
|
||||||
Simplex s3 = new Simplex(v3, v1);
|
Simplex s3 = new Simplex(v3, v1);
|
||||||
|
|
||||||
result.Add(s1);
|
result.Add(s1);
|
||||||
result.Add(s2);
|
result.Add(s2);
|
||||||
result.Add(s3);
|
result.Add(s3);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override String ToString()
|
public override String ToString()
|
||||||
{
|
{
|
||||||
NumberFormatInfo nfi = new NumberFormatInfo();
|
NumberFormatInfo nfi = new NumberFormatInfo();
|
||||||
nfi.CurrencyDecimalDigits = 2;
|
nfi.CurrencyDecimalDigits = 2;
|
||||||
nfi.CurrencyDecimalSeparator = ".";
|
nfi.CurrencyDecimalSeparator = ".";
|
||||||
|
|
||||||
String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
|
String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
|
||||||
String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
|
String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
|
||||||
String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
|
String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
|
||||||
|
|
||||||
return s1 + ";" + s2 + ";" + s3;
|
return s1 + ";" + s2 + ";" + s3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PhysicsVector getNormal()
|
public PhysicsVector getNormal()
|
||||||
{
|
{
|
||||||
// Vertices
|
// Vertices
|
||||||
|
|
||||||
// Vectors for edges
|
// Vectors for edges
|
||||||
PhysicsVector e1;
|
PhysicsVector e1;
|
||||||
PhysicsVector e2;
|
PhysicsVector e2;
|
||||||
|
|
||||||
e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
|
e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
|
||||||
e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
|
e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
|
||||||
|
|
||||||
// Cross product for normal
|
// Cross product for normal
|
||||||
PhysicsVector n = PhysicsVector.cross(e1, e2);
|
PhysicsVector n = PhysicsVector.cross(e1, e2);
|
||||||
|
|
||||||
// Length
|
// Length
|
||||||
float l = n.length();
|
float l = n.length();
|
||||||
|
|
||||||
// Normalized "normal"
|
// Normalized "normal"
|
||||||
n = n/l;
|
n = n/l;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invertNormal()
|
public void invertNormal()
|
||||||
{
|
{
|
||||||
Vertex vt;
|
Vertex vt;
|
||||||
vt = v1;
|
vt = v1;
|
||||||
v1 = v2;
|
v1 = v2;
|
||||||
v2 = vt;
|
v2 = vt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
|
// Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
|
||||||
// debugging purposes
|
// debugging purposes
|
||||||
public String ToStringRaw()
|
public String ToStringRaw()
|
||||||
{
|
{
|
||||||
String output = v1.ToRaw() + " " + v2.ToRaw() + " " + v3.ToRaw();
|
String output = v1.ToRaw() + " " + v2.ToRaw() + " " + v3.ToRaw();
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,395 +1,395 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.Meshing
|
namespace OpenSim.Region.Physics.Meshing
|
||||||
{
|
{
|
||||||
// A simple hull is a set of vertices building up to simplices that border a region
|
// A simple hull is a set of vertices building up to simplices that border a region
|
||||||
// The word simple referes to the fact, that this class assumes, that all simplices
|
// The word simple referes to the fact, that this class assumes, that all simplices
|
||||||
// do not intersect
|
// do not intersect
|
||||||
// Simple hulls can be added and subtracted.
|
// Simple hulls can be added and subtracted.
|
||||||
// Vertices can be checked to lie inside a hull
|
// Vertices can be checked to lie inside a hull
|
||||||
// Also note, that the sequence of the vertices is important and defines if the region that
|
// Also note, that the sequence of the vertices is important and defines if the region that
|
||||||
// is defined by the hull lies inside or outside the simplex chain
|
// is defined by the hull lies inside or outside the simplex chain
|
||||||
public class SimpleHull
|
public class SimpleHull
|
||||||
{
|
{
|
||||||
private List<Vertex> vertices = new List<Vertex>();
|
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private List<Vertex> holeVertices = new List<Vertex>(); // Only used, when the hull is hollow
|
|
||||||
|
private List<Vertex> vertices = new List<Vertex>();
|
||||||
// Adds a vertex to the end of the list
|
private List<Vertex> holeVertices = new List<Vertex>(); // Only used, when the hull is hollow
|
||||||
public void AddVertex(Vertex v)
|
|
||||||
{
|
// Adds a vertex to the end of the list
|
||||||
vertices.Add(v);
|
public void AddVertex(Vertex v)
|
||||||
}
|
{
|
||||||
|
vertices.Add(v);
|
||||||
public override String ToString()
|
}
|
||||||
{
|
|
||||||
String result = "";
|
public override String ToString()
|
||||||
foreach (Vertex v in vertices)
|
{
|
||||||
{
|
String result = String.Empty;
|
||||||
result += "b:" + v.ToString() + "\n";
|
foreach (Vertex v in vertices)
|
||||||
}
|
{
|
||||||
|
result += "b:" + v.ToString() + "\n";
|
||||||
return result;
|
}
|
||||||
}
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
public List<Vertex> getVertices()
|
|
||||||
{
|
|
||||||
List<Vertex> newVertices = new List<Vertex>();
|
public List<Vertex> getVertices()
|
||||||
|
{
|
||||||
newVertices.AddRange(vertices);
|
List<Vertex> newVertices = new List<Vertex>();
|
||||||
newVertices.Add(null);
|
|
||||||
newVertices.AddRange(holeVertices);
|
newVertices.AddRange(vertices);
|
||||||
|
newVertices.Add(null);
|
||||||
return newVertices;
|
newVertices.AddRange(holeVertices);
|
||||||
}
|
|
||||||
|
return newVertices;
|
||||||
public SimpleHull Clone()
|
}
|
||||||
{
|
|
||||||
SimpleHull result = new SimpleHull();
|
public SimpleHull Clone()
|
||||||
foreach (Vertex v in vertices)
|
{
|
||||||
{
|
SimpleHull result = new SimpleHull();
|
||||||
result.AddVertex(v.Clone());
|
foreach (Vertex v in vertices)
|
||||||
}
|
{
|
||||||
|
result.AddVertex(v.Clone());
|
||||||
foreach (Vertex v in holeVertices)
|
}
|
||||||
{
|
|
||||||
result.holeVertices.Add(v.Clone());
|
foreach (Vertex v in holeVertices)
|
||||||
}
|
{
|
||||||
|
result.holeVertices.Add(v.Clone());
|
||||||
return result;
|
}
|
||||||
}
|
|
||||||
|
return result;
|
||||||
public bool IsPointIn(Vertex v1)
|
}
|
||||||
{
|
|
||||||
int iCounter = 0;
|
public bool IsPointIn(Vertex v1)
|
||||||
List<Simplex> simplices = buildSimplexList();
|
{
|
||||||
foreach (Simplex s in simplices)
|
int iCounter = 0;
|
||||||
{
|
List<Simplex> simplices = buildSimplexList();
|
||||||
// Send a ray along the positive X-Direction
|
foreach (Simplex s in simplices)
|
||||||
// Note, that this direction must correlate with the "below" interpretation
|
{
|
||||||
// of handling for the special cases below
|
// Send a ray along the positive X-Direction
|
||||||
PhysicsVector intersection = s.RayIntersect(v1, new PhysicsVector(1.0f, 0.0f, 0.0f), true);
|
// Note, that this direction must correlate with the "below" interpretation
|
||||||
|
// of handling for the special cases below
|
||||||
if (intersection == null)
|
PhysicsVector intersection = s.RayIntersect(v1, new PhysicsVector(1.0f, 0.0f, 0.0f), true);
|
||||||
continue; // No intersection. Done. More tests to follow otherwise
|
|
||||||
|
if (intersection == null)
|
||||||
// Did we hit the end of a simplex?
|
continue; // No intersection. Done. More tests to follow otherwise
|
||||||
// Then this can be one of two special cases:
|
|
||||||
// 1. we go through a border exactly at a joint
|
// Did we hit the end of a simplex?
|
||||||
// 2. we have just marginally touched a corner
|
// Then this can be one of two special cases:
|
||||||
// 3. we can slide along a border
|
// 1. we go through a border exactly at a joint
|
||||||
// Solution: If the other vertex is "below" the ray, we don't count it
|
// 2. we have just marginally touched a corner
|
||||||
// Thus corners pointing down are counted twice, corners pointing up are not counted
|
// 3. we can slide along a border
|
||||||
// borders are counted once
|
// Solution: If the other vertex is "below" the ray, we don't count it
|
||||||
if (intersection.IsIdentical(s.v1, 0.001f))
|
// Thus corners pointing down are counted twice, corners pointing up are not counted
|
||||||
{
|
// borders are counted once
|
||||||
if (s.v2.Y < v1.Y)
|
if (intersection.IsIdentical(s.v1, 0.001f))
|
||||||
continue;
|
{
|
||||||
}
|
if (s.v2.Y < v1.Y)
|
||||||
// Do this for the other vertex two
|
continue;
|
||||||
if (intersection.IsIdentical(s.v2, 0.001f))
|
}
|
||||||
{
|
// Do this for the other vertex two
|
||||||
if (s.v1.Y < v1.Y)
|
if (intersection.IsIdentical(s.v2, 0.001f))
|
||||||
continue;
|
{
|
||||||
}
|
if (s.v1.Y < v1.Y)
|
||||||
iCounter++;
|
continue;
|
||||||
}
|
}
|
||||||
|
iCounter++;
|
||||||
return iCounter%2 == 1; // Point is inside if the number of intersections is odd
|
}
|
||||||
}
|
|
||||||
|
return iCounter%2 == 1; // Point is inside if the number of intersections is odd
|
||||||
public bool containsPointsFrom(SimpleHull otherHull)
|
}
|
||||||
{
|
|
||||||
foreach (Vertex v in otherHull.vertices)
|
public bool containsPointsFrom(SimpleHull otherHull)
|
||||||
{
|
{
|
||||||
if (IsPointIn(v))
|
foreach (Vertex v in otherHull.vertices)
|
||||||
return true;
|
{
|
||||||
}
|
if (IsPointIn(v))
|
||||||
|
return true;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
private List<Simplex> buildSimplexList()
|
|
||||||
{
|
|
||||||
List<Simplex> result = new List<Simplex>();
|
private List<Simplex> buildSimplexList()
|
||||||
|
{
|
||||||
// Not asserted but assumed: at least three vertices
|
List<Simplex> result = new List<Simplex>();
|
||||||
for (int i = 0; i < vertices.Count - 1; i++)
|
|
||||||
{
|
// Not asserted but assumed: at least three vertices
|
||||||
Simplex s = new Simplex(vertices[i], vertices[i + 1]);
|
for (int i = 0; i < vertices.Count - 1; i++)
|
||||||
result.Add(s);
|
{
|
||||||
}
|
Simplex s = new Simplex(vertices[i], vertices[i + 1]);
|
||||||
Simplex s1 = new Simplex(vertices[vertices.Count - 1], vertices[0]);
|
result.Add(s);
|
||||||
result.Add(s1);
|
}
|
||||||
|
Simplex s1 = new Simplex(vertices[vertices.Count - 1], vertices[0]);
|
||||||
if (holeVertices.Count == 0)
|
result.Add(s1);
|
||||||
return result;
|
|
||||||
|
if (holeVertices.Count == 0)
|
||||||
// Same here. At least three vertices in hole assumed
|
return result;
|
||||||
for (int i = 0; i < holeVertices.Count - 1; i++)
|
|
||||||
{
|
// Same here. At least three vertices in hole assumed
|
||||||
Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
|
for (int i = 0; i < holeVertices.Count - 1; i++)
|
||||||
result.Add(s);
|
{
|
||||||
}
|
Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
|
||||||
|
result.Add(s);
|
||||||
s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
|
}
|
||||||
result.Add(s1);
|
|
||||||
return result;
|
s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
|
||||||
}
|
result.Add(s1);
|
||||||
|
return result;
|
||||||
private bool InsertVertex(Vertex v, int iAfter)
|
}
|
||||||
{
|
|
||||||
vertices.Insert(iAfter + 1, v);
|
private bool InsertVertex(Vertex v, int iAfter)
|
||||||
return true;
|
{
|
||||||
}
|
vertices.Insert(iAfter + 1, v);
|
||||||
|
return true;
|
||||||
private Vertex getNextVertex(Vertex currentVertex)
|
}
|
||||||
{
|
|
||||||
int iCurrentIndex;
|
private Vertex getNextVertex(Vertex currentVertex)
|
||||||
iCurrentIndex = vertices.IndexOf(currentVertex);
|
{
|
||||||
|
int iCurrentIndex;
|
||||||
// Error handling for iCurrentIndex==-1 should go here (and probably never will)
|
iCurrentIndex = vertices.IndexOf(currentVertex);
|
||||||
|
|
||||||
iCurrentIndex++;
|
// Error handling for iCurrentIndex==-1 should go here (and probably never will)
|
||||||
if (iCurrentIndex == vertices.Count)
|
|
||||||
iCurrentIndex = 0;
|
iCurrentIndex++;
|
||||||
|
if (iCurrentIndex == vertices.Count)
|
||||||
return vertices[iCurrentIndex];
|
iCurrentIndex = 0;
|
||||||
}
|
|
||||||
|
return vertices[iCurrentIndex];
|
||||||
public Vertex FindVertex(Vertex vBase, float tolerance)
|
}
|
||||||
{
|
|
||||||
foreach (Vertex v in vertices)
|
public Vertex FindVertex(Vertex vBase, float tolerance)
|
||||||
{
|
{
|
||||||
if (v.IsIdentical(vBase, tolerance))
|
foreach (Vertex v in vertices)
|
||||||
return v;
|
{
|
||||||
}
|
if (v.IsIdentical(vBase, tolerance))
|
||||||
|
return v;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
return null;
|
||||||
public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
|
}
|
||||||
{
|
|
||||||
Vertex bestIntersection = null;
|
public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
|
||||||
float distToV1 = Single.PositiveInfinity;
|
{
|
||||||
Simplex bestIntersectingSimplex = null;
|
Vertex bestIntersection = null;
|
||||||
|
float distToV1 = Single.PositiveInfinity;
|
||||||
List<Simplex> simple = buildSimplexList();
|
Simplex bestIntersectingSimplex = null;
|
||||||
foreach (Simplex sTest in simple)
|
|
||||||
{
|
List<Simplex> simple = buildSimplexList();
|
||||||
PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
|
foreach (Simplex sTest in simple)
|
||||||
|
{
|
||||||
Vertex vTemp = null;
|
PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
|
||||||
if (vvTemp != null)
|
|
||||||
vTemp = new Vertex(vvTemp);
|
Vertex vTemp = null;
|
||||||
|
if (vvTemp != null)
|
||||||
if (vTemp != null)
|
vTemp = new Vertex(vvTemp);
|
||||||
{
|
|
||||||
PhysicsVector diff = (s.v1 - vTemp);
|
if (vTemp != null)
|
||||||
float distTemp = diff.length();
|
{
|
||||||
|
PhysicsVector diff = (s.v1 - vTemp);
|
||||||
if (bestIntersection == null || distTemp < distToV1)
|
float distTemp = diff.length();
|
||||||
{
|
|
||||||
bestIntersection = vTemp;
|
if (bestIntersection == null || distTemp < distToV1)
|
||||||
distToV1 = distTemp;
|
{
|
||||||
bestIntersectingSimplex = sTest;
|
bestIntersection = vTemp;
|
||||||
}
|
distToV1 = distTemp;
|
||||||
} // end if vTemp
|
bestIntersectingSimplex = sTest;
|
||||||
} // end foreach
|
}
|
||||||
|
}
|
||||||
Intersection = bestIntersection;
|
}
|
||||||
if (bestIntersectingSimplex != null)
|
|
||||||
nextVertex = bestIntersectingSimplex.v2;
|
Intersection = bestIntersection;
|
||||||
else
|
if (bestIntersectingSimplex != null)
|
||||||
nextVertex = null;
|
nextVertex = bestIntersectingSimplex.v2;
|
||||||
}
|
else
|
||||||
|
nextVertex = null;
|
||||||
|
}
|
||||||
public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
|
|
||||||
{
|
|
||||||
SimpleHull baseHullClone = baseHull.Clone();
|
public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
|
||||||
SimpleHull otherHullClone = otherHull.Clone();
|
{
|
||||||
bool intersects = false;
|
SimpleHull baseHullClone = baseHull.Clone();
|
||||||
|
SimpleHull otherHullClone = otherHull.Clone();
|
||||||
MainLog.Instance.Debug("State before intersection detection");
|
bool intersects = false;
|
||||||
MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
|
|
||||||
MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
|
//m_log.Debug("State before intersection detection");
|
||||||
|
//m_log.DebugFormat("The baseHull is:\n{1}", 0, baseHullClone.ToString());
|
||||||
{
|
//m_log.DebugFormat("The otherHull is:\n{1}", 0, otherHullClone.ToString());
|
||||||
int iBase, iOther;
|
|
||||||
|
{
|
||||||
// Insert into baseHull
|
int iBase, iOther;
|
||||||
for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
|
|
||||||
{
|
// Insert into baseHull
|
||||||
int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
|
for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
|
||||||
Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
|
{
|
||||||
|
int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
|
||||||
for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
|
Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
|
||||||
{
|
|
||||||
int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
|
for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
|
||||||
Simplex sOther =
|
{
|
||||||
new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
|
int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
|
||||||
|
Simplex sOther =
|
||||||
PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
|
new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
|
||||||
if (intersect != null)
|
|
||||||
{
|
PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
|
||||||
Vertex vIntersect = new Vertex(intersect);
|
if (intersect != null)
|
||||||
baseHullClone.vertices.Insert(iBase + 1, vIntersect);
|
{
|
||||||
sBase.v2 = vIntersect;
|
Vertex vIntersect = new Vertex(intersect);
|
||||||
intersects = true;
|
baseHullClone.vertices.Insert(iBase + 1, vIntersect);
|
||||||
}
|
sBase.v2 = vIntersect;
|
||||||
}
|
intersects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
MainLog.Instance.Debug("State after intersection detection for the base hull");
|
}
|
||||||
MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
|
|
||||||
|
//m_log.Debug("State after intersection detection for the base hull");
|
||||||
{
|
//m_log.DebugFormat("The baseHull is:\n{1}", 0, baseHullClone.ToString());
|
||||||
int iOther, iBase;
|
|
||||||
|
{
|
||||||
// Insert into otherHull
|
int iOther, iBase;
|
||||||
for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
|
|
||||||
{
|
// Insert into otherHull
|
||||||
int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
|
for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
|
||||||
Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
|
{
|
||||||
|
int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
|
||||||
for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
|
Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
|
||||||
{
|
|
||||||
int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
|
for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
|
||||||
Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
|
{
|
||||||
|
int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
|
||||||
PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
|
Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
|
||||||
if (intersect != null)
|
|
||||||
{
|
PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
|
||||||
Vertex vIntersect = new Vertex(intersect);
|
if (intersect != null)
|
||||||
otherHullClone.vertices.Insert(iOther + 1, vIntersect);
|
{
|
||||||
sOther.v2 = vIntersect;
|
Vertex vIntersect = new Vertex(intersect);
|
||||||
intersects = true;
|
otherHullClone.vertices.Insert(iOther + 1, vIntersect);
|
||||||
}
|
sOther.v2 = vIntersect;
|
||||||
}
|
intersects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
MainLog.Instance.Debug("State after intersection detection for the base hull");
|
}
|
||||||
MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
|
|
||||||
|
//m_log.Debug("State after intersection detection for the base hull");
|
||||||
|
//m_log.DebugFormat("The otherHull is:\n{1}", 0, otherHullClone.ToString());
|
||||||
bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
|
|
||||||
if (!intersects && otherIsInBase)
|
bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
|
||||||
{
|
if (!intersects && otherIsInBase)
|
||||||
// We have a hole here
|
{
|
||||||
baseHullClone.holeVertices = otherHullClone.vertices;
|
// We have a hole here
|
||||||
return baseHullClone;
|
baseHullClone.holeVertices = otherHullClone.vertices;
|
||||||
}
|
return baseHullClone;
|
||||||
|
}
|
||||||
|
|
||||||
SimpleHull result = new SimpleHull();
|
SimpleHull result = new SimpleHull();
|
||||||
|
|
||||||
// Find a good starting Simplex from baseHull
|
// Find a good starting Simplex from baseHull
|
||||||
// A good starting simplex is one that is outside otherHull
|
// A good starting simplex is one that is outside otherHull
|
||||||
// Such a simplex must exist, otherwise the result will be empty
|
// Such a simplex must exist, otherwise the result will be empty
|
||||||
Vertex baseStartVertex = null;
|
Vertex baseStartVertex = null;
|
||||||
{
|
{
|
||||||
int iBase;
|
int iBase;
|
||||||
for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
|
for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
|
||||||
{
|
{
|
||||||
int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
|
int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
|
||||||
Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext])/2.0f);
|
Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext])/2.0f);
|
||||||
bool isOutside = !otherHullClone.IsPointIn(center);
|
bool isOutside = !otherHullClone.IsPointIn(center);
|
||||||
if (isOutside)
|
if (isOutside)
|
||||||
{
|
{
|
||||||
baseStartVertex = baseHullClone.vertices[iBaseNext];
|
baseStartVertex = baseHullClone.vertices[iBaseNext];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
|
if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
|
||||||
// In otherwords, subtractHull completely embraces baseHull
|
// In otherwords, subtractHull completely embraces baseHull
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The simplex that *starts* with baseStartVertex is outside the cutting hull,
|
// The simplex that *starts* with baseStartVertex is outside the cutting hull,
|
||||||
// so we can start our walk with the next vertex without loosing a branch
|
// so we can start our walk with the next vertex without loosing a branch
|
||||||
Vertex V1 = baseStartVertex;
|
Vertex V1 = baseStartVertex;
|
||||||
bool onBase = true;
|
bool onBase = true;
|
||||||
|
|
||||||
// And here is how we do the magic :-)
|
// And here is how we do the magic :-)
|
||||||
// Start on the base hull.
|
// Start on the base hull.
|
||||||
// Walk the vertices in the positive direction
|
// Walk the vertices in the positive direction
|
||||||
// For each vertex check, whether it is a vertex shared with the other hull
|
// For each vertex check, whether it is a vertex shared with the other hull
|
||||||
// if this is the case, switch over to walking the other vertex list.
|
// if this is the case, switch over to walking the other vertex list.
|
||||||
// Note: The other hull *must* go backwards to our starting point (via several orther vertices)
|
// Note: The other hull *must* go backwards to our starting point (via several orther vertices)
|
||||||
// Thus it is important that the cutting hull has the inverse directional sense than the
|
// Thus it is important that the cutting hull has the inverse directional sense than the
|
||||||
// base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
|
// base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
result.AddVertex(V1);
|
result.AddVertex(V1);
|
||||||
Vertex nextVertex = null;
|
Vertex nextVertex = null;
|
||||||
if (onBase)
|
if (onBase)
|
||||||
{
|
{
|
||||||
nextVertex = otherHullClone.FindVertex(V1, 0.001f);
|
nextVertex = otherHullClone.FindVertex(V1, 0.001f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nextVertex = baseHullClone.FindVertex(V1, 0.001f);
|
nextVertex = baseHullClone.FindVertex(V1, 0.001f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextVertex != null) // A node that represents an intersection
|
if (nextVertex != null) // A node that represents an intersection
|
||||||
{
|
{
|
||||||
V1 = nextVertex; // Needed to find the next vertex on the other hull
|
V1 = nextVertex; // Needed to find the next vertex on the other hull
|
||||||
onBase = !onBase;
|
onBase = !onBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onBase)
|
if (onBase)
|
||||||
V1 = baseHullClone.getNextVertex(V1);
|
V1 = baseHullClone.getNextVertex(V1);
|
||||||
else
|
else
|
||||||
V1 = otherHullClone.getNextVertex(V1);
|
V1 = otherHullClone.getNextVertex(V1);
|
||||||
|
|
||||||
if (V1 == baseStartVertex)
|
if (V1 == baseStartVertex)
|
||||||
done = true;
|
done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MainLog.Instance.Debug("The resulting Hull is:\n{1}", 0, result.ToString());
|
//m_log.DebugFormat("The resulting Hull is:\n{1}", 0, result.ToString());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
|
||||||
// You can specify all values by your own or you can build default build and revision
|
// You can specify all values by your own or you can build default build and revision
|
||||||
// numbers with the '*' character (the default):
|
// numbers with the '*' character (the default):
|
||||||
|
|
||||||
[assembly : AssemblyVersion("1.0.*")]
|
[assembly : AssemblyVersion("1.0.*")]
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
|
||||||
// You can specify all values by your own or you can build default build and revision
|
// You can specify all values by your own or you can build default build and revision
|
||||||
// numbers with the '*' character (the default):
|
// numbers with the '*' character (the default):
|
||||||
|
|
||||||
[assembly : AssemblyVersion("1.0.*")]
|
[assembly : AssemblyVersion("1.0.*")]
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,146 +1,92 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Remoting.Lifetime;
|
using System.Runtime.Remoting.Lifetime;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.Common
|
namespace OpenSim.Region.ScriptEngine.Common
|
||||||
{
|
{
|
||||||
public class Executor : MarshalByRefObject
|
public class Executor : ExecutorBase
|
||||||
{
|
{
|
||||||
// Private instance for each script
|
// Cache functions by keeping a reference to them in a dictionary
|
||||||
|
private Dictionary<string, MethodInfo> Events = new Dictionary<string, MethodInfo>();
|
||||||
private IScript m_Script;
|
|
||||||
private Dictionary<string, MethodInfo> Events = new Dictionary<string, MethodInfo>();
|
public Executor(IScript script) : base(script)
|
||||||
private bool m_Running = true;
|
{
|
||||||
//private List<IScript> Scripts = new List<IScript>();
|
}
|
||||||
|
|
||||||
public Executor(IScript Script)
|
protected override void DoExecuteEvent(string FunctionName, object[] args)
|
||||||
{
|
{
|
||||||
m_Script = Script;
|
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
||||||
}
|
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
|
||||||
|
|
||||||
// Object never expires
|
string EventName = m_Script.State + "_event_" + FunctionName;
|
||||||
public override Object InitializeLifetimeService()
|
|
||||||
{
|
//#if DEBUG
|
||||||
//Console.WriteLine("Executor: InitializeLifetimeService()");
|
// Console.WriteLine("ScriptEngine: Script event function name: " + EventName);
|
||||||
// return null;
|
//#endif
|
||||||
ILease lease = (ILease) base.InitializeLifetimeService();
|
|
||||||
|
if (Events.ContainsKey(EventName) == false)
|
||||||
if (lease.CurrentState == LeaseState.Initial)
|
{
|
||||||
{
|
// Not found, create
|
||||||
lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
|
Type type = m_Script.GetType();
|
||||||
// lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
|
try
|
||||||
// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
|
{
|
||||||
}
|
MethodInfo mi = type.GetMethod(EventName);
|
||||||
return lease;
|
Events.Add(EventName, mi);
|
||||||
}
|
}
|
||||||
|
catch
|
||||||
public AppDomain GetAppDomain()
|
{
|
||||||
{
|
// Event name not found, cache it as not found
|
||||||
return AppDomain.CurrentDomain;
|
Events.Add(EventName, null);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public void ExecuteEvent(string FunctionName, object[] args)
|
|
||||||
{
|
// Get event
|
||||||
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
MethodInfo ev = null;
|
||||||
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
|
Events.TryGetValue(EventName, out ev);
|
||||||
//try
|
|
||||||
//{
|
if (ev == null) // No event by that name!
|
||||||
if (m_Running == false)
|
{
|
||||||
{
|
//Console.WriteLine("ScriptEngine Can not find any event named: \String.Empty + EventName + "\String.Empty);
|
||||||
// Script is inactive, do not execute!
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
|
||||||
string EventName = m_Script.State() + "_event_" + FunctionName;
|
#if DEBUG
|
||||||
|
Console.WriteLine("ScriptEngine: Executing function name: " + EventName);
|
||||||
#if DEBUG
|
#endif
|
||||||
Console.WriteLine("ScriptEngine: Script event function name: " + EventName);
|
// Found
|
||||||
#endif
|
ev.Invoke(m_Script, args);
|
||||||
|
|
||||||
//type.InvokeMember(EventName, BindingFlags.InvokeMethod, null, m_Script, args);
|
}
|
||||||
|
|
||||||
//Console.WriteLine("ScriptEngine Executor.ExecuteEvent: \"" + EventName + "\"");
|
}
|
||||||
|
}
|
||||||
if (Events.ContainsKey(EventName) == false)
|
|
||||||
{
|
|
||||||
// Not found, create
|
|
||||||
Type type = m_Script.GetType();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MethodInfo mi = type.GetMethod(EventName);
|
|
||||||
Events.Add(EventName, mi);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// Event name not found, cache it as not found
|
|
||||||
Events.Add(EventName, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get event
|
|
||||||
MethodInfo ev = null;
|
|
||||||
Events.TryGetValue(EventName, out ev);
|
|
||||||
|
|
||||||
if (ev == null) // No event by that name!
|
|
||||||
{
|
|
||||||
//Console.WriteLine("ScriptEngine Can not find any event named: \"" + EventName + "\"");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
Console.WriteLine("ScriptEngine: Executing function name: " + EventName);
|
|
||||||
#endif
|
|
||||||
// Found
|
|
||||||
//try
|
|
||||||
//{
|
|
||||||
// Invoke it
|
|
||||||
ev.Invoke(m_Script, args);
|
|
||||||
|
|
||||||
//}
|
|
||||||
//catch (Exception e)
|
|
||||||
//{
|
|
||||||
// // TODO: Send to correct place
|
|
||||||
// Console.WriteLine("ScriptEngine Exception attempting to executing script function: " + e.ToString());
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
//}
|
|
||||||
//catch { }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void StopScript()
|
|
||||||
{
|
|
||||||
m_Running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Runtime.Remoting.Lifetime;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common
|
||||||
|
{
|
||||||
|
public abstract class ExecutorBase : MarshalByRefObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the script to execute functions in.
|
||||||
|
/// </summary>
|
||||||
|
protected IScript m_Script;
|
||||||
|
/// <summary>
|
||||||
|
/// If set to False events will not be executed.
|
||||||
|
/// </summary>
|
||||||
|
protected bool m_Running = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new instance of ExecutorBase
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Script"></param>
|
||||||
|
public ExecutorBase(IScript Script)
|
||||||
|
{
|
||||||
|
m_Script = Script;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make sure our object does not timeout when in AppDomain. (Called by ILease base class)
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override Object InitializeLifetimeService()
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Executor: InitializeLifetimeService()");
|
||||||
|
// return null;
|
||||||
|
ILease lease = (ILease)base.InitializeLifetimeService();
|
||||||
|
|
||||||
|
if (lease.CurrentState == LeaseState.Initial)
|
||||||
|
{
|
||||||
|
lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
|
||||||
|
// lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
|
||||||
|
// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
|
||||||
|
}
|
||||||
|
return lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get current AppDomain
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Current AppDomain</returns>
|
||||||
|
public AppDomain GetAppDomain()
|
||||||
|
{
|
||||||
|
return AppDomain.CurrentDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute a specific function/event in script.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FunctionName">Name of function to execute</param>
|
||||||
|
/// <param name="args">Arguments to pass to function</param>
|
||||||
|
public void ExecuteEvent(string FunctionName, object[] args)
|
||||||
|
{
|
||||||
|
if (m_Running == false)
|
||||||
|
{
|
||||||
|
// Script is inactive, do not execute!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DoExecuteEvent(FunctionName, args);
|
||||||
|
}
|
||||||
|
protected abstract void DoExecuteEvent(string FunctionName, object[] args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stop script from running. Event execution will be ignored.
|
||||||
|
/// </summary>
|
||||||
|
public void StopScript()
|
||||||
|
{
|
||||||
|
m_Running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,36 +1,41 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.Common
|
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
|
||||||
{
|
|
||||||
public interface IScript
|
namespace OpenSim.Region.ScriptEngine.Common
|
||||||
{
|
{
|
||||||
string State();
|
public interface IScript
|
||||||
Executor Exec { get; }
|
{
|
||||||
}
|
string State { get; set; }
|
||||||
}
|
ExecutorBase Exec { get; }
|
||||||
|
string Source { get; set; }
|
||||||
|
void Start(LSL_BuiltIn_Commands_Interface BuiltIn_Commands);
|
||||||
|
EventQueueManager.Queue_llDetectParams_Struct llDetectParams { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,36 +1,64 @@
|
||||||
using System.Reflection;
|
/*
|
||||||
using System.Runtime.InteropServices;
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
// General Information about an assembly is controlled through the following
|
*
|
||||||
// set of attributes. Change these attribute values to modify the information
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// associated with an assembly.
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
[assembly : AssemblyTitle("OpenSim.Region.ScriptEngine.Common")]
|
* notice, this list of conditions and the following disclaimer.
|
||||||
[assembly : AssemblyDescription("")]
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
[assembly : AssemblyConfiguration("")]
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
[assembly : AssemblyCompany("")]
|
* documentation and/or other materials provided with the distribution.
|
||||||
[assembly : AssemblyProduct("OpenSim.Region.ScriptEngine.Common")]
|
* * Neither the name of the OpenSim Project nor the
|
||||||
[assembly : AssemblyCopyright("Copyright © 2007")]
|
* names of its contributors may be used to endorse or promote products
|
||||||
[assembly : AssemblyTrademark("")]
|
* derived from this software without specific prior written permission.
|
||||||
[assembly : AssemblyCulture("")]
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
// to COM components. If you need to access a type in this assembly from
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
[assembly : ComVisible(false)]
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
* 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
|
||||||
[assembly : Guid("0bf07c53-ae51-487f-a907-e9b30c251602")]
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
// Version information for an assembly consists of the following four values:
|
*/
|
||||||
//
|
|
||||||
// Major Version
|
using System.Reflection;
|
||||||
// Minor Version
|
using System.Runtime.InteropServices;
|
||||||
// Build Number
|
|
||||||
// Revision
|
// General Information about an assembly is controlled through the following
|
||||||
//
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
[assembly : AssemblyVersion("1.0.0.0")]
|
|
||||||
[assembly : AssemblyFileVersion("1.0.0.0")]
|
[assembly : AssemblyTitle("OpenSim.Region.ScriptEngine.Common")]
|
||||||
|
[assembly : AssemblyDescription("")]
|
||||||
|
[assembly : AssemblyConfiguration("")]
|
||||||
|
[assembly : AssemblyCompany("")]
|
||||||
|
[assembly : AssemblyProduct("OpenSim.Region.ScriptEngine.Common")]
|
||||||
|
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")]
|
||||||
|
[assembly : AssemblyTrademark("")]
|
||||||
|
[assembly : AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
|
||||||
|
[assembly : ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
|
||||||
|
[assembly : Guid("0bf07c53-ae51-487f-a907-e9b30c251602")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
|
||||||
|
[assembly : AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly : AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
|
@ -1,238 +1,254 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
{
|
{
|
||||||
public class AppDomainManager
|
public class AppDomainManager : iScriptEngineFunctionModule
|
||||||
{
|
{
|
||||||
|
//
|
||||||
//
|
// This class does AppDomain handling and loading/unloading of scripts in it.
|
||||||
// This class does AppDomain handling and loading/unloading of scripts in it.
|
// It is instanced in "ScriptEngine" and controlled from "ScriptManager"
|
||||||
// It is instanced in "ScriptEngine" and controlled from "ScriptManager"
|
//
|
||||||
//
|
// 1. Create a new AppDomain if old one is full (or doesn't exist)
|
||||||
// 1. Create a new AppDomain if old one is full (or doesn't exist)
|
// 2. Load scripts into AppDomain
|
||||||
// 2. Load scripts into AppDomain
|
// 3. Unload scripts from AppDomain (stopping them and marking them as inactive)
|
||||||
// 3. Unload scripts from AppDomain (stopping them and marking them as inactive)
|
// 4. Unload AppDomain completely when all scripts in it has stopped
|
||||||
// 4. Unload AppDomain completely when all scripts in it has stopped
|
//
|
||||||
//
|
|
||||||
|
private int maxScriptsPerAppDomain = 1;
|
||||||
|
|
||||||
private int maxScriptsPerAppDomain = 1;
|
/// <summary>
|
||||||
|
/// Internal list of all AppDomains
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Internal list of all AppDomains
|
private List<AppDomainStructure> appDomains = new List<AppDomainStructure>();
|
||||||
/// </summary>
|
|
||||||
private List<AppDomainStructure> appDomains = new List<AppDomainStructure>();
|
/// <summary>
|
||||||
|
/// Structure to keep track of data around AppDomain
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Structure to keep track of data around AppDomain
|
private class AppDomainStructure
|
||||||
/// </summary>
|
{
|
||||||
private class AppDomainStructure
|
/// <summary>
|
||||||
{
|
/// The AppDomain itself
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// The AppDomain itself
|
public AppDomain CurrentAppDomain;
|
||||||
/// </summary>
|
|
||||||
public AppDomain CurrentAppDomain;
|
/// <summary>
|
||||||
|
/// Number of scripts loaded into AppDomain
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Number of scripts loaded into AppDomain
|
public int ScriptsLoaded;
|
||||||
/// </summary>
|
|
||||||
public int ScriptsLoaded;
|
/// <summary>
|
||||||
|
/// Number of dead scripts
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Number of dead scripts
|
public int ScriptsWaitingUnload;
|
||||||
/// </summary>
|
}
|
||||||
public int ScriptsWaitingUnload;
|
|
||||||
}
|
/// <summary>
|
||||||
|
/// Current AppDomain
|
||||||
/// <summary>
|
/// </summary>
|
||||||
/// Current AppDomain
|
private AppDomainStructure currentAD;
|
||||||
/// </summary>
|
|
||||||
private AppDomainStructure currentAD;
|
private object getLock = new object(); // Mutex
|
||||||
|
private object freeLock = new object(); // Mutex
|
||||||
private object getLock = new object(); // Mutex
|
|
||||||
private object freeLock = new object(); // Mutex
|
private ScriptEngine m_scriptEngine;
|
||||||
|
//public AppDomainManager(ScriptEngine scriptEngine)
|
||||||
//private ScriptEngine m_scriptEngine;
|
public AppDomainManager(ScriptEngine scriptEngine)
|
||||||
//public AppDomainManager(ScriptEngine scriptEngine)
|
{
|
||||||
public AppDomainManager()
|
m_scriptEngine = scriptEngine;
|
||||||
{
|
ReadConfig();
|
||||||
//m_scriptEngine = scriptEngine;
|
}
|
||||||
}
|
|
||||||
|
public void ReadConfig()
|
||||||
/// <summary>
|
{
|
||||||
/// Find a free AppDomain, creating one if necessary
|
maxScriptsPerAppDomain = m_scriptEngine.ScriptConfigSource.GetInt("ScriptsPerAppDomain", 1);
|
||||||
/// </summary>
|
}
|
||||||
/// <returns>Free AppDomain</returns>
|
|
||||||
private AppDomainStructure GetFreeAppDomain()
|
/// <summary>
|
||||||
{
|
/// Find a free AppDomain, creating one if necessary
|
||||||
Console.WriteLine("Finding free AppDomain");
|
/// </summary>
|
||||||
lock (getLock)
|
/// <returns>Free AppDomain</returns>
|
||||||
{
|
private AppDomainStructure GetFreeAppDomain()
|
||||||
// Current full?
|
{
|
||||||
if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain)
|
// Console.WriteLine("Finding free AppDomain");
|
||||||
{
|
lock (getLock)
|
||||||
// Add it to AppDomains list and empty current
|
{
|
||||||
appDomains.Add(currentAD);
|
// Current full?
|
||||||
currentAD = null;
|
if (currentAD != null && currentAD.ScriptsLoaded >= maxScriptsPerAppDomain)
|
||||||
}
|
{
|
||||||
// No current
|
// Add it to AppDomains list and empty current
|
||||||
if (currentAD == null)
|
appDomains.Add(currentAD);
|
||||||
{
|
currentAD = null;
|
||||||
// Create a new current AppDomain
|
}
|
||||||
currentAD = new AppDomainStructure();
|
// No current
|
||||||
currentAD.CurrentAppDomain = PrepareNewAppDomain();
|
if (currentAD == null)
|
||||||
}
|
{
|
||||||
|
// Create a new current AppDomain
|
||||||
Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded);
|
currentAD = new AppDomainStructure();
|
||||||
return currentAD;
|
currentAD.CurrentAppDomain = PrepareNewAppDomain();
|
||||||
} // lock
|
}
|
||||||
}
|
|
||||||
|
// Console.WriteLine("Scripts loaded in this Appdomain: " + currentAD.ScriptsLoaded);
|
||||||
private int AppDomainNameCount;
|
return currentAD;
|
||||||
|
}
|
||||||
/// <summary>
|
}
|
||||||
/// Create and prepare a new AppDomain for scripts
|
|
||||||
/// </summary>
|
private int AppDomainNameCount;
|
||||||
/// <returns>The new AppDomain</returns>
|
|
||||||
private AppDomain PrepareNewAppDomain()
|
/// <summary>
|
||||||
{
|
/// Create and prepare a new AppDomain for scripts
|
||||||
// Create and prepare a new AppDomain
|
/// </summary>
|
||||||
AppDomainNameCount++;
|
/// <returns>The new AppDomain</returns>
|
||||||
// TODO: Currently security match current appdomain
|
private AppDomain PrepareNewAppDomain()
|
||||||
|
{
|
||||||
// Construct and initialize settings for a second AppDomain.
|
// Create and prepare a new AppDomain
|
||||||
AppDomainSetup ads = new AppDomainSetup();
|
AppDomainNameCount++;
|
||||||
ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
|
// TODO: Currently security match current appdomain
|
||||||
ads.DisallowBindingRedirects = false;
|
|
||||||
ads.DisallowCodeDownload = true;
|
// Construct and initialize settings for a second AppDomain.
|
||||||
ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;)
|
AppDomainSetup ads = new AppDomainSetup();
|
||||||
ads.ShadowCopyFiles = "true"; // Enabled shadowing
|
ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
|
ads.DisallowBindingRedirects = false;
|
||||||
|
ads.DisallowCodeDownload = true;
|
||||||
AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
|
ads.LoaderOptimization = LoaderOptimization.MultiDomain; // Sounds good ;)
|
||||||
Console.WriteLine("Loading: " +
|
ads.ShadowCopyFiles = "true"; // Enabled shadowing
|
||||||
AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString());
|
ads.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
|
||||||
AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll"));
|
|
||||||
|
AppDomain AD = AppDomain.CreateDomain("ScriptAppDomain_" + AppDomainNameCount, null, ads);
|
||||||
// Return the new AppDomain
|
m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: AppDomain Loading: " +
|
||||||
return AD;
|
AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll").ToString());
|
||||||
}
|
AD.Load(AssemblyName.GetAssemblyName("OpenSim.Region.ScriptEngine.Common.dll"));
|
||||||
|
|
||||||
/// <summary>
|
// Return the new AppDomain
|
||||||
/// Unload appdomains that are full and have only dead scripts
|
return AD;
|
||||||
/// </summary>
|
}
|
||||||
private void UnloadAppDomains()
|
|
||||||
{
|
/// <summary>
|
||||||
lock (freeLock)
|
/// Unload appdomains that are full and have only dead scripts
|
||||||
{
|
/// </summary>
|
||||||
// Go through all
|
private void UnloadAppDomains()
|
||||||
foreach (AppDomainStructure ads in new ArrayList(appDomains))
|
{
|
||||||
{
|
lock (freeLock)
|
||||||
// Don't process current AppDomain
|
{
|
||||||
if (ads.CurrentAppDomain != currentAD.CurrentAppDomain)
|
// Go through all
|
||||||
{
|
foreach (AppDomainStructure ads in new ArrayList(appDomains))
|
||||||
// Not current AppDomain
|
{
|
||||||
// Is number of unloaded bigger or equal to number of loaded?
|
// Don't process current AppDomain
|
||||||
if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload)
|
if (ads.CurrentAppDomain != currentAD.CurrentAppDomain)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Found empty AppDomain, unloading");
|
// Not current AppDomain
|
||||||
// Remove from internal list
|
// Is number of unloaded bigger or equal to number of loaded?
|
||||||
appDomains.Remove(ads);
|
if (ads.ScriptsLoaded <= ads.ScriptsWaitingUnload)
|
||||||
#if DEBUG
|
{
|
||||||
long m = GC.GetTotalMemory(true);
|
// Remove from internal list
|
||||||
#endif
|
appDomains.Remove(ads);
|
||||||
// Unload
|
#if DEBUG
|
||||||
AppDomain.Unload(ads.CurrentAppDomain);
|
Console.WriteLine("Found empty AppDomain, unloading");
|
||||||
#if DEBUG
|
long m = GC.GetTotalMemory(true);
|
||||||
Console.WriteLine("AppDomain unload freed " + (m - GC.GetTotalMemory(true)) +
|
#endif
|
||||||
" bytes of memory");
|
// Unload
|
||||||
#endif
|
AppDomain.Unload(ads.CurrentAppDomain);
|
||||||
}
|
#if DEBUG
|
||||||
}
|
m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: AppDomain unload freed " + (m - GC.GetTotalMemory(true)) + " bytes of memory");
|
||||||
} // foreach
|
#endif
|
||||||
} // lock
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
public LSL_BaseClass LoadScript(string FileName)
|
}
|
||||||
{
|
|
||||||
// Find next available AppDomain to put it in
|
public IScript LoadScript(string FileName)
|
||||||
AppDomainStructure FreeAppDomain = GetFreeAppDomain();
|
{
|
||||||
|
// Find next available AppDomain to put it in
|
||||||
Console.WriteLine("Loading into AppDomain: " + FileName);
|
AppDomainStructure FreeAppDomain = GetFreeAppDomain();
|
||||||
LSL_BaseClass mbrt =
|
|
||||||
(LSL_BaseClass)
|
#if DEBUG
|
||||||
FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script");
|
m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: Loading into AppDomain: " + FileName);
|
||||||
//Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
|
#endif
|
||||||
FreeAppDomain.ScriptsLoaded++;
|
IScript mbrt =
|
||||||
|
(IScript)
|
||||||
return mbrt;
|
FreeAppDomain.CurrentAppDomain.CreateInstanceFromAndUnwrap(FileName, "SecondLife.Script");
|
||||||
}
|
//Console.WriteLine("ScriptEngine AppDomainManager: is proxy={0}", RemotingServices.IsTransparentProxy(mbrt));
|
||||||
|
FreeAppDomain.ScriptsLoaded++;
|
||||||
|
|
||||||
/// <summary>
|
return mbrt;
|
||||||
/// Increase "dead script" counter for an AppDomain
|
}
|
||||||
/// </summary>
|
|
||||||
/// <param name="ad"></param>
|
|
||||||
//[Obsolete("Needs fixing, needs a real purpose in life!!!")]
|
/// <summary>
|
||||||
public void StopScript(AppDomain ad)
|
/// Increase "dead script" counter for an AppDomain
|
||||||
{
|
/// </summary>
|
||||||
lock (freeLock)
|
/// <param name="ad"></param>
|
||||||
{
|
//[Obsolete("Needs fixing, needs a real purpose in life!!!")]
|
||||||
Console.WriteLine("Stopping script in AppDomain");
|
public void StopScript(AppDomain ad)
|
||||||
// Check if it is current AppDomain
|
{
|
||||||
if (currentAD.CurrentAppDomain == ad)
|
lock (freeLock)
|
||||||
{
|
{
|
||||||
// Yes - increase
|
#if DEBUG
|
||||||
currentAD.ScriptsWaitingUnload++;
|
m_scriptEngine.Log.Info("[" + m_scriptEngine.ScriptEngineName + "]: Stopping script in AppDomain");
|
||||||
return;
|
#endif
|
||||||
}
|
// Check if it is current AppDomain
|
||||||
|
if (currentAD.CurrentAppDomain == ad)
|
||||||
// Lopp through all AppDomains
|
{
|
||||||
foreach (AppDomainStructure ads in new ArrayList(appDomains))
|
// Yes - increase
|
||||||
{
|
currentAD.ScriptsWaitingUnload++;
|
||||||
if (ads.CurrentAppDomain == ad)
|
return;
|
||||||
{
|
}
|
||||||
// Found it
|
|
||||||
ads.ScriptsWaitingUnload++;
|
// Lopp through all AppDomains
|
||||||
break;
|
foreach (AppDomainStructure ads in new ArrayList(appDomains))
|
||||||
}
|
{
|
||||||
} // foreach
|
if (ads.CurrentAppDomain == ad)
|
||||||
} // lock
|
{
|
||||||
|
// Found it
|
||||||
UnloadAppDomains(); // Outsite lock, has its own GetLock
|
ads.ScriptsWaitingUnload++;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UnloadAppDomains(); // Outsite lock, has its own GetLock
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
/// </summary>
|
||||||
|
public bool PleaseShutdown
|
||||||
|
{
|
||||||
|
get { return _PleaseShutdown; }
|
||||||
|
set { _PleaseShutdown = value; }
|
||||||
|
}
|
||||||
|
private bool _PleaseShutdown = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,408 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Modules;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
|
||||||
|
/// </summary>
|
||||||
|
public class AsyncLSLCommandManager : iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
private static Thread cmdHandlerThread;
|
||||||
|
private static int cmdHandlerThreadCycleSleepms;
|
||||||
|
|
||||||
|
private ScriptEngine m_ScriptEngine;
|
||||||
|
|
||||||
|
public AsyncLSLCommandManager(ScriptEngine _ScriptEngine)
|
||||||
|
{
|
||||||
|
m_ScriptEngine = _ScriptEngine;
|
||||||
|
ReadConfig();
|
||||||
|
|
||||||
|
StartThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StartThread()
|
||||||
|
{
|
||||||
|
if (cmdHandlerThread == null)
|
||||||
|
{
|
||||||
|
// Start the thread that will be doing the work
|
||||||
|
cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
|
||||||
|
cmdHandlerThread.Name = "AsyncLSLCmdHandlerThread";
|
||||||
|
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
|
||||||
|
cmdHandlerThread.IsBackground = true;
|
||||||
|
cmdHandlerThread.Start();
|
||||||
|
OpenSim.Framework.ThreadTracker.Add(cmdHandlerThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadConfig()
|
||||||
|
{
|
||||||
|
cmdHandlerThreadCycleSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("AsyncLLCommandLoopms", 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
~AsyncLSLCommandManager()
|
||||||
|
{
|
||||||
|
// Shut down thread
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (cmdHandlerThread != null)
|
||||||
|
{
|
||||||
|
if (cmdHandlerThread.IsAlive == true)
|
||||||
|
{
|
||||||
|
cmdHandlerThread.Abort();
|
||||||
|
//cmdHandlerThread.Join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CmdHandlerThreadLoop()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
Thread.Sleep(cmdHandlerThreadCycleSleepms);
|
||||||
|
//lock (ScriptEngine.ScriptEngines)
|
||||||
|
//{
|
||||||
|
foreach (ScriptEngine se in new ArrayList(ScriptEngine.ScriptEngines))
|
||||||
|
{
|
||||||
|
se.m_ASYNCLSLCommandManager.DoOneCmdHandlerPass();
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
// Sleep before next cycle
|
||||||
|
//Thread.Sleep(cmdHandlerThreadCycleSleepms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DoOneCmdHandlerPass()
|
||||||
|
{
|
||||||
|
// Check timers
|
||||||
|
CheckTimerEvents();
|
||||||
|
// Check HttpRequests
|
||||||
|
CheckHttpRequests();
|
||||||
|
// Check XMLRPCRequests
|
||||||
|
CheckXMLRPCRequests();
|
||||||
|
// Check Listeners
|
||||||
|
CheckListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove a specific script (and all its pending commands)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID"></param>
|
||||||
|
/// <param name="itemID"></param>
|
||||||
|
public void RemoveScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
// Remove a specific script
|
||||||
|
|
||||||
|
// Remove from: Timers
|
||||||
|
UnSetTimerEvents(localID, itemID);
|
||||||
|
// Remove from: HttpRequest
|
||||||
|
IHttpRequests iHttpReq =
|
||||||
|
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
|
||||||
|
iHttpReq.StopHttpRequest(localID, itemID);
|
||||||
|
|
||||||
|
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
comms.DeleteListener(itemID);
|
||||||
|
|
||||||
|
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||||
|
xmlrpc.DeleteChannels(itemID);
|
||||||
|
|
||||||
|
xmlrpc.CancelSRDRequests(itemID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#region TIMER
|
||||||
|
|
||||||
|
//
|
||||||
|
// TIMER
|
||||||
|
//
|
||||||
|
private class TimerClass
|
||||||
|
{
|
||||||
|
public uint localID;
|
||||||
|
public LLUUID itemID;
|
||||||
|
//public double interval;
|
||||||
|
public long interval;
|
||||||
|
//public DateTime next;
|
||||||
|
public long next;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TimerClass> Timers = new List<TimerClass>();
|
||||||
|
private object TimerListLock = new object();
|
||||||
|
|
||||||
|
public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
|
||||||
|
{
|
||||||
|
Console.WriteLine("SetTimerEvent");
|
||||||
|
|
||||||
|
// Always remove first, in case this is a re-set
|
||||||
|
UnSetTimerEvents(m_localID, m_itemID);
|
||||||
|
if (sec == 0) // Disabling timer
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add to timer
|
||||||
|
TimerClass ts = new TimerClass();
|
||||||
|
ts.localID = m_localID;
|
||||||
|
ts.itemID = m_itemID;
|
||||||
|
ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait
|
||||||
|
// 2193386136332921 ticks
|
||||||
|
// 219338613 seconds
|
||||||
|
|
||||||
|
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
|
||||||
|
ts.next = DateTime.Now.Ticks + ts.interval;
|
||||||
|
lock (TimerListLock)
|
||||||
|
{
|
||||||
|
Timers.Add(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
|
||||||
|
{
|
||||||
|
// Remove from timer
|
||||||
|
lock (TimerListLock)
|
||||||
|
{
|
||||||
|
foreach (TimerClass ts in new ArrayList(Timers))
|
||||||
|
{
|
||||||
|
if (ts.localID == m_localID && ts.itemID == m_itemID)
|
||||||
|
Timers.Remove(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Old method: Create new list
|
||||||
|
//List<TimerClass> NewTimers = new List<TimerClass>();
|
||||||
|
//foreach (TimerClass ts in Timers)
|
||||||
|
//{
|
||||||
|
// if (ts.localID != m_localID && ts.itemID != m_itemID)
|
||||||
|
// {
|
||||||
|
// NewTimers.Add(ts);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//Timers.Clear();
|
||||||
|
//Timers = NewTimers;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckTimerEvents()
|
||||||
|
{
|
||||||
|
// Nothing to do here?
|
||||||
|
if (Timers.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (TimerListLock)
|
||||||
|
{
|
||||||
|
// Go through all timers
|
||||||
|
foreach (TimerClass ts in Timers)
|
||||||
|
{
|
||||||
|
// Time has passed?
|
||||||
|
if (ts.next < DateTime.Now.Ticks)
|
||||||
|
{
|
||||||
|
// Console.WriteLine("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
|
||||||
|
// Add it to queue
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull,
|
||||||
|
null);
|
||||||
|
// set next interval
|
||||||
|
|
||||||
|
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
|
||||||
|
ts.next = DateTime.Now.Ticks + ts.interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region HTTP REQUEST
|
||||||
|
|
||||||
|
public void CheckHttpRequests()
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.World == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IHttpRequests iHttpReq =
|
||||||
|
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
|
||||||
|
|
||||||
|
HttpRequestClass httpInfo = null;
|
||||||
|
|
||||||
|
if (iHttpReq != null)
|
||||||
|
httpInfo = iHttpReq.GetNextCompletedRequest();
|
||||||
|
|
||||||
|
while (httpInfo != null)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
|
||||||
|
|
||||||
|
// Deliver data to prim's remote_data handler
|
||||||
|
//
|
||||||
|
// TODO: Returning null for metadata, since the lsl function
|
||||||
|
// only returns the byte for HTTP_BODY_TRUNCATED, which is not
|
||||||
|
// implemented here yet anyway. Should be fixed if/when maxsize
|
||||||
|
// is supported
|
||||||
|
|
||||||
|
if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null)
|
||||||
|
{
|
||||||
|
iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
|
||||||
|
object[] resobj = new object[]
|
||||||
|
{
|
||||||
|
httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
|
||||||
|
};
|
||||||
|
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||||
|
httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
httpInfo = iHttpReq.GetNextCompletedRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Check llRemoteData channels
|
||||||
|
|
||||||
|
public void CheckXMLRPCRequests()
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.World == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||||
|
|
||||||
|
if (xmlrpc != null)
|
||||||
|
{
|
||||||
|
RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
|
||||||
|
|
||||||
|
while (rInfo != null)
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null)
|
||||||
|
{
|
||||||
|
xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
|
||||||
|
|
||||||
|
//Deliver data to prim's remote_data handler
|
||||||
|
object[] resobj = new object[]
|
||||||
|
{
|
||||||
|
2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty,
|
||||||
|
rInfo.GetIntValue(),
|
||||||
|
rInfo.GetStrVal()
|
||||||
|
};
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||||
|
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
rInfo = xmlrpc.GetNextCompletedRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
|
||||||
|
|
||||||
|
while (srdInfo != null)
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.m_ScriptManager.GetScript(srdInfo.m_localID, srdInfo.m_itemID) != null)
|
||||||
|
{
|
||||||
|
xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
|
||||||
|
|
||||||
|
//Deliver data to prim's remote_data handler
|
||||||
|
object[] resobj = new object[]
|
||||||
|
{
|
||||||
|
3, srdInfo.channel.ToString(), srdInfo.GetReqID().ToString(), String.Empty,
|
||||||
|
srdInfo.idata,
|
||||||
|
srdInfo.sdata
|
||||||
|
};
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||||
|
srdInfo.m_localID, srdInfo.m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
srdInfo = xmlrpc.GetNextCompletedSRDRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Check llListeners
|
||||||
|
|
||||||
|
public void CheckListeners()
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.World == null)
|
||||||
|
return;
|
||||||
|
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
|
||||||
|
if (comms != null)
|
||||||
|
{
|
||||||
|
while (comms.HasMessages())
|
||||||
|
{
|
||||||
|
if (m_ScriptEngine.m_ScriptManager.GetScript(
|
||||||
|
comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null)
|
||||||
|
{
|
||||||
|
ListenerInfo lInfo = comms.GetNextMessage();
|
||||||
|
|
||||||
|
//Deliver data to prim's listen handler
|
||||||
|
object[] resobj = new object[]
|
||||||
|
{
|
||||||
|
lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
|
||||||
|
};
|
||||||
|
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||||
|
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
/// </summary>
|
||||||
|
public bool PleaseShutdown
|
||||||
|
{
|
||||||
|
get { return _PleaseShutdown; }
|
||||||
|
set { _PleaseShutdown = value; }
|
||||||
|
}
|
||||||
|
private bool _PleaseShutdown = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,57 +1,57 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
{
|
{
|
||||||
public static class Common
|
public static class Common
|
||||||
{
|
{
|
||||||
public static bool debug = true;
|
public static bool debug = true;
|
||||||
public static ScriptEngine mySE;
|
public static ScriptEngine mySE;
|
||||||
|
|
||||||
// This class just contains some static log stuff used for debugging.
|
// This class just contains some static log stuff used for debugging.
|
||||||
|
|
||||||
//public delegate void SendToDebugEventDelegate(string Message);
|
//public delegate void SendToDebugEventDelegate(string message);
|
||||||
//public delegate void SendToLogEventDelegate(string Message);
|
//public delegate void SendToLogEventDelegate(string message);
|
||||||
//static public event SendToDebugEventDelegate SendToDebugEvent;
|
//static public event SendToDebugEventDelegate SendToDebugEvent;
|
||||||
//static public event SendToLogEventDelegate SendToLogEvent;
|
//static public event SendToLogEventDelegate SendToLogEvent;
|
||||||
|
|
||||||
public static void SendToDebug(string Message)
|
public static void SendToDebug(string message)
|
||||||
{
|
{
|
||||||
//if (Debug == true)
|
//if (Debug == true)
|
||||||
mySE.Log.Verbose("ScriptEngine", "Debug: " + Message);
|
mySE.Log.Info("[" + mySE.ScriptEngineName + "]: Debug: " + message);
|
||||||
//SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
//SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SendToLog(string Message)
|
public static void SendToLog(string message)
|
||||||
{
|
{
|
||||||
//if (Debug == true)
|
//if (Debug == true)
|
||||||
mySE.Log.Verbose("ScriptEngine", "LOG: " + Message);
|
mySE.Log.Info("[" + mySE.ScriptEngineName + "]: LOG: " + message);
|
||||||
//SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
//SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,237 +1,288 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
|
||||||
using System;
|
|
||||||
using libsecondlife;
|
using System;
|
||||||
using OpenSim.Framework;
|
using libsecondlife;
|
||||||
|
using OpenSim.Framework;
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
|
||||||
{
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
/// <summary>
|
{
|
||||||
/// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it.
|
/// <summary>
|
||||||
/// </summary>
|
/// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it.
|
||||||
[Serializable]
|
/// </summary>
|
||||||
public class EventManager : OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.RemoteEvents
|
[Serializable]
|
||||||
{
|
public class EventManager : OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.RemoteEvents, iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine".
|
// Class is instanced in "ScriptEngine" and Uses "EventQueueManager" that is also instanced in "ScriptEngine".
|
||||||
// This class needs a bit of explaining:
|
// This class needs a bit of explaining:
|
||||||
//
|
//
|
||||||
// This class it the link between an event inside OpenSim and the corresponding event in a user script being executed.
|
// This class it the link between an event inside OpenSim and the corresponding event in a user script being executed.
|
||||||
//
|
//
|
||||||
// For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim.
|
// For example when an user touches an object then the "myScriptEngine.World.EventManager.OnObjectGrab" event is fired inside OpenSim.
|
||||||
// We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters.
|
// We hook up to this event and queue a touch_start in EventQueueManager with the proper LSL parameters.
|
||||||
// It will then be delivered to the script by EventQueueManager.
|
// It will then be delivered to the script by EventQueueManager.
|
||||||
//
|
//
|
||||||
// You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed.
|
// You can check debug C# dump of an LSL script if you need to verify what exact parameters are needed.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
private ScriptEngine myScriptEngine;
|
private ScriptEngine myScriptEngine;
|
||||||
//public IScriptHost TEMP_OBJECT_ID;
|
//public IScriptHost TEMP_OBJECT_ID;
|
||||||
public EventManager(ScriptEngine _ScriptEngine)
|
public EventManager(ScriptEngine _ScriptEngine, bool performHookUp)
|
||||||
{
|
{
|
||||||
myScriptEngine = _ScriptEngine;
|
myScriptEngine = _ScriptEngine;
|
||||||
// TODO: HOOK EVENTS UP TO SERVER!
|
ReadConfig();
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventManager Start");
|
|
||||||
// TODO: ADD SERVER HOOK TO LOAD A SCRIPT THROUGH myScriptEngine.ScriptManager
|
// Hook up to events from OpenSim
|
||||||
|
// We may not want to do it because someone is controlling us and will deliver events to us
|
||||||
// Hook up a test event to our test form
|
if (performHookUp)
|
||||||
myScriptEngine.Log.Verbose("ScriptEngine", "Hooking up to server events");
|
{
|
||||||
myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
|
myScriptEngine.Log.Info("[" + myScriptEngine.ScriptEngineName + "]: Hooking up to server events");
|
||||||
myScriptEngine.World.EventManager.OnRezScript += OnRezScript;
|
myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
|
||||||
myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
|
myScriptEngine.World.EventManager.OnRezScript += OnRezScript;
|
||||||
}
|
myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
|
||||||
|
myScriptEngine.World.EventManager.OnScriptChangedEvent += changed;
|
||||||
public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
|
// TODO: HOOK ALL EVENTS UP TO SERVER!
|
||||||
{
|
}
|
||||||
// Add to queue for all scripts in ObjectID object
|
}
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventManager Event: touch_start");
|
|
||||||
//Console.WriteLine("touch_start localID: " + localID);
|
public void ReadConfig()
|
||||||
OpenSim.Region.Environment.Scenes.SceneObjectPart sop = this.myScriptEngine.World.GetSceneObjectPart(localID);
|
{
|
||||||
sop.TouchedBy = remoteClient.AgentId;
|
}
|
||||||
myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_start", new object[] {(int) 1});
|
|
||||||
}
|
public void changed(uint localID, uint change)
|
||||||
|
{
|
||||||
public void OnRezScript(uint localID, LLUUID itemID, string script)
|
// Add to queue for all scripts in localID, Object pass change.
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "changed", EventQueueManager.llDetectNull, new object[] { (int)change });
|
||||||
//myScriptEngine.myScriptManager.StartScript(
|
}
|
||||||
// Path.Combine("ScriptEngines", "Default.lsl"),
|
|
||||||
// new OpenSim.Region.Environment.Scenes.Scripting.NullScriptHost()
|
public void state_entry(uint localID)
|
||||||
//);
|
{
|
||||||
Console.WriteLine("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " +
|
// Add to queue for all scripts in ObjectID object
|
||||||
script.Length);
|
myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "state_entry", EventQueueManager.llDetectNull, new object[] { });
|
||||||
myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script);
|
}
|
||||||
}
|
|
||||||
|
public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
|
||||||
public void OnRemoveScript(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
// Add to queue for all scripts in ObjectID object
|
||||||
//myScriptEngine.myScriptManager.StartScript(
|
myScriptEngine.m_EventQueueManager.AddToObjectQueue(localID, "touch_start", EventQueueManager.llDetectNull, new object[] { (int)1 });
|
||||||
// Path.Combine("ScriptEngines", "Default.lsl"),
|
}
|
||||||
// new OpenSim.Region.Environment.Scenes.Scripting.NullScriptHost()
|
|
||||||
//);
|
public void OnRezScript(uint localID, LLUUID itemID, string script)
|
||||||
Console.WriteLine("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString());
|
{
|
||||||
myScriptEngine.m_ScriptManager.StopScript(
|
Console.WriteLine("OnRezScript localID: " + localID + " LLUID: " + itemID.ToString() + " Size: " +
|
||||||
localID,
|
script.Length);
|
||||||
itemID
|
myScriptEngine.m_ScriptManager.StartScript(localID, itemID, script);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
public void OnRemoveScript(uint localID, LLUUID itemID)
|
||||||
// TODO: Replace placeholders below
|
{
|
||||||
// These needs to be hooked up to OpenSim during init of this class
|
Console.WriteLine("OnRemoveScript localID: " + localID + " LLUID: " + itemID.ToString());
|
||||||
// then queued in EventQueueManager.
|
myScriptEngine.m_ScriptManager.StopScript(
|
||||||
// When queued in EventQueueManager they need to be LSL compatible (name and params)
|
localID,
|
||||||
|
itemID
|
||||||
//public void state_entry() { } //
|
);
|
||||||
public void state_exit(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
// TODO: Replace placeholders below
|
||||||
|
// NOTE! THE PARAMETERS FOR THESE FUNCTIONS ARE NOT CORRECT!
|
||||||
//public void touch_start(uint localID, LLUUID itemID) { }
|
// These needs to be hooked up to OpenSim during init of this class
|
||||||
public void touch(uint localID, LLUUID itemID)
|
// then queued in EventQueueManager.
|
||||||
{
|
// When queued in EventQueueManager they need to be LSL compatible (name and params)
|
||||||
}
|
|
||||||
|
public void state_exit(uint localID, LLUUID itemID)
|
||||||
public void touch_end(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_exit", EventQueueManager.llDetectNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collision_start(uint localID, LLUUID itemID)
|
public void touch(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
}
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
public void collision(uint localID, LLUUID itemID)
|
|
||||||
{
|
public void touch_end(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "touch_end", EventQueueManager.llDetectNull);
|
||||||
public void collision_end(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
public void collision_start(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
public void land_collision_start(uint localID, LLUUID itemID)
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_start", EventQueueManager.llDetectNull);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public void collision(uint localID, LLUUID itemID)
|
||||||
public void land_collision(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision", EventQueueManager.llDetectNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void land_collision_end(uint localID, LLUUID itemID)
|
public void collision_end(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
}
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "collision_end", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
public void timer(uint localID, LLUUID itemID)
|
|
||||||
{
|
public void land_collision_start(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_start", EventQueueManager.llDetectNull);
|
||||||
public void listen(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
public void land_collision(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
public void on_rez(uint localID, LLUUID itemID)
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision", EventQueueManager.llDetectNull);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public void land_collision_end(uint localID, LLUUID itemID)
|
||||||
public void sensor(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "land_collision_end", EventQueueManager.llDetectNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void no_sensor(uint localID, LLUUID itemID)
|
// Handled by long commands
|
||||||
{
|
public void timer(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
//myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, String.Empty);
|
||||||
public void control(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
public void listen(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
public void money(uint localID, LLUUID itemID)
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "listen", EventQueueManager.llDetectNull);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public void on_rez(uint localID, LLUUID itemID)
|
||||||
public void email(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "on_rez", EventQueueManager.llDetectNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void at_target(uint localID, LLUUID itemID)
|
public void sensor(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
}
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "sensor", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
public void not_at_target(uint localID, LLUUID itemID)
|
|
||||||
{
|
public void no_sensor(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "no_sensor", EventQueueManager.llDetectNull);
|
||||||
public void at_rot_target(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
public void control(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
public void not_at_rot_target(uint localID, LLUUID itemID)
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "control", EventQueueManager.llDetectNull);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public void money(uint localID, LLUUID itemID)
|
||||||
public void run_time_permissions(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "money", EventQueueManager.llDetectNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void changed(uint localID, LLUUID itemID)
|
public void email(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
}
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "email", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
public void attach(uint localID, LLUUID itemID)
|
|
||||||
{
|
public void at_target(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_target", EventQueueManager.llDetectNull);
|
||||||
public void dataserver(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
public void not_at_target(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
public void link_message(uint localID, LLUUID itemID)
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_target", EventQueueManager.llDetectNull);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public void at_rot_target(uint localID, LLUUID itemID)
|
||||||
public void moving_start(uint localID, LLUUID itemID)
|
{
|
||||||
{
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "at_rot_target", EventQueueManager.llDetectNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moving_end(uint localID, LLUUID itemID)
|
public void not_at_rot_target(uint localID, LLUUID itemID)
|
||||||
{
|
{
|
||||||
}
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "not_at_rot_target", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
public void object_rez(uint localID, LLUUID itemID)
|
|
||||||
{
|
public void run_time_permissions(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "run_time_permissions", EventQueueManager.llDetectNull);
|
||||||
public void remote_data(uint localID, LLUUID itemID)
|
}
|
||||||
{
|
|
||||||
}
|
public void changed(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
public void http_response(uint localID, LLUUID itemID)
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "changed", EventQueueManager.llDetectNull);
|
||||||
{
|
}
|
||||||
}
|
|
||||||
}
|
public void attach(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "attach", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dataserver(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "dataserver", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void link_message(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "link_message", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moving_start(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_start", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void moving_end(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "moving_end", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void object_rez(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "object_rez", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remote_data(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "remote_data", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handled by long commands
|
||||||
|
public void http_response(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
// myScriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "http_response", EventQueueManager.llDetectNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
/// </summary>
|
||||||
|
public bool PleaseShutdown
|
||||||
|
{
|
||||||
|
get { return _PleaseShutdown; }
|
||||||
|
set { _PleaseShutdown = value; }
|
||||||
|
}
|
||||||
|
private bool _PleaseShutdown = false;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,437 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Scenes.Scripting;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// EventQueueManager handles event queues
|
||||||
|
/// Events are queued and executed in separate thread
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class EventQueueManager : iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Class is instanced in "ScriptEngine" and used by "EventManager" which is also instanced in "ScriptEngine".
|
||||||
|
//
|
||||||
|
// Class purpose is to queue and execute functions that are received by "EventManager":
|
||||||
|
// - allowing "EventManager" to release its event thread immediately, thus not interrupting server execution.
|
||||||
|
// - allowing us to prioritize and control execution of script functions.
|
||||||
|
// Class can use multiple threads for simultaneous execution. Mutexes are used for thread safety.
|
||||||
|
//
|
||||||
|
// 1. Hold an execution queue for scripts
|
||||||
|
// 2. Use threads to process queue, each thread executes one script function on each pass.
|
||||||
|
// 3. Catch any script error and process it
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Notes:
|
||||||
|
// * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts.
|
||||||
|
// Not noticeable unless server is under high load.
|
||||||
|
//
|
||||||
|
|
||||||
|
public ScriptEngine m_ScriptEngine;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of threads (classes) processing event queue
|
||||||
|
/// Note that this may or may not be a reference to a static object depending on PrivateRegionThreads config setting.
|
||||||
|
/// </summary>
|
||||||
|
internal static List<EventQueueThreadClass> eventQueueThreads = new List<EventQueueThreadClass>(); // Thread pool that we work on
|
||||||
|
/// <summary>
|
||||||
|
/// Locking access to eventQueueThreads AND staticGlobalEventQueueThreads.
|
||||||
|
/// </summary>
|
||||||
|
// private object eventQueueThreadsLock = new object();
|
||||||
|
// Static objects for referencing the objects above if we don't have private threads:
|
||||||
|
//internal static List<EventQueueThreadClass> staticEventQueueThreads; // A static reference used if we don't use private threads
|
||||||
|
// internal static object staticEventQueueThreadsLock; // Statick lock object reference for same reason
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Global static list of all threads (classes) processing event queue -- used by max enforcment thread
|
||||||
|
/// </summary>
|
||||||
|
//private List<EventQueueThreadClass> staticGlobalEventQueueThreads = new List<EventQueueThreadClass>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used internally to specify how many threads should exit gracefully
|
||||||
|
/// </summary>
|
||||||
|
public static int ThreadsToExit;
|
||||||
|
public static object ThreadsToExitLock = new object();
|
||||||
|
|
||||||
|
|
||||||
|
//public object queueLock = new object(); // Mutex lock object
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many threads to process queue with
|
||||||
|
/// </summary>
|
||||||
|
internal static int numberOfThreads;
|
||||||
|
|
||||||
|
internal static int EventExecutionMaxQueueSize;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Maximum time one function can use for execution before we perform a thread kill.
|
||||||
|
/// </summary>
|
||||||
|
private static int maxFunctionExecutionTimems
|
||||||
|
{
|
||||||
|
get { return (int)(maxFunctionExecutionTimens / 10000); }
|
||||||
|
set { maxFunctionExecutionTimens = value * 10000; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains nanoseconds version of maxFunctionExecutionTimems so that it matches time calculations better (performance reasons).
|
||||||
|
/// WARNING! ONLY UPDATE maxFunctionExecutionTimems, NEVER THIS DIRECTLY.
|
||||||
|
/// </summary>
|
||||||
|
public static long maxFunctionExecutionTimens;
|
||||||
|
/// <summary>
|
||||||
|
/// Enforce max execution time
|
||||||
|
/// </summary>
|
||||||
|
public static bool EnforceMaxExecutionTime;
|
||||||
|
/// <summary>
|
||||||
|
/// Kill script (unload) when it exceeds execution time
|
||||||
|
/// </summary>
|
||||||
|
private static bool KillScriptOnMaxFunctionExecutionTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// List of localID locks for mutex processing of script events
|
||||||
|
/// </summary>
|
||||||
|
private List<uint> objectLocks = new List<uint>();
|
||||||
|
private object tryLockLock = new object(); // Mutex lock object
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queue containing events waiting to be executed
|
||||||
|
/// </summary>
|
||||||
|
public Queue<QueueItemStruct> eventQueue = new Queue<QueueItemStruct>();
|
||||||
|
|
||||||
|
#region " Queue structures "
|
||||||
|
/// <summary>
|
||||||
|
/// Queue item structure
|
||||||
|
/// </summary>
|
||||||
|
public struct QueueItemStruct
|
||||||
|
{
|
||||||
|
public uint localID;
|
||||||
|
public LLUUID itemID;
|
||||||
|
public string functionName;
|
||||||
|
public Queue_llDetectParams_Struct llDetectParams;
|
||||||
|
public object[] param;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shared empty llDetectNull
|
||||||
|
/// </summary>
|
||||||
|
public readonly static Queue_llDetectParams_Struct llDetectNull = new Queue_llDetectParams_Struct();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Structure to hold data for llDetect* commands
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public struct Queue_llDetectParams_Struct
|
||||||
|
{
|
||||||
|
// More or less just a placeholder for the actual moving of additional data
|
||||||
|
// should be fixed to something better :)
|
||||||
|
public LSL_Types.key[] _key;
|
||||||
|
public LSL_Types.Quaternion[] _Quaternion;
|
||||||
|
public LSL_Types.Vector3[] _Vector3;
|
||||||
|
public bool[] _bool;
|
||||||
|
public int[] _int;
|
||||||
|
public string[] _string;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Initialization / Startup "
|
||||||
|
public EventQueueManager(ScriptEngine _ScriptEngine)
|
||||||
|
{
|
||||||
|
m_ScriptEngine = _ScriptEngine;
|
||||||
|
|
||||||
|
ReadConfig();
|
||||||
|
AdjustNumberOfScriptThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadConfig()
|
||||||
|
{
|
||||||
|
// Refresh config
|
||||||
|
numberOfThreads = m_ScriptEngine.ScriptConfigSource.GetInt("NumberOfScriptThreads", 2);
|
||||||
|
maxFunctionExecutionTimems = m_ScriptEngine.ScriptConfigSource.GetInt("MaxEventExecutionTimeMs", 5000);
|
||||||
|
EnforceMaxExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("EnforceMaxEventExecutionTime", false);
|
||||||
|
KillScriptOnMaxFunctionExecutionTime = m_ScriptEngine.ScriptConfigSource.GetBoolean("DeactivateScriptOnTimeout", false);
|
||||||
|
EventExecutionMaxQueueSize = m_ScriptEngine.ScriptConfigSource.GetInt("EventExecutionMaxQueueSize", 300);
|
||||||
|
|
||||||
|
// Now refresh config in all threads
|
||||||
|
lock (eventQueueThreads)
|
||||||
|
{
|
||||||
|
foreach (EventQueueThreadClass EventQueueThread in eventQueueThreads)
|
||||||
|
{
|
||||||
|
EventQueueThread.ReadConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Shutdown all threads "
|
||||||
|
~EventQueueManager()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Stop()
|
||||||
|
{
|
||||||
|
if (eventQueueThreads != null)
|
||||||
|
{
|
||||||
|
// Kill worker threads
|
||||||
|
lock (eventQueueThreads)
|
||||||
|
{
|
||||||
|
foreach (EventQueueThreadClass EventQueueThread in new ArrayList(eventQueueThreads))
|
||||||
|
{
|
||||||
|
AbortThreadClass(EventQueueThread);
|
||||||
|
}
|
||||||
|
//eventQueueThreads.Clear();
|
||||||
|
//staticGlobalEventQueueThreads.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove all entries from our event queue
|
||||||
|
lock (eventQueue)
|
||||||
|
{
|
||||||
|
eventQueue.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Start / stop script execution threads (ThreadClasses) "
|
||||||
|
private void StartNewThreadClass()
|
||||||
|
{
|
||||||
|
EventQueueThreadClass eqtc = new EventQueueThreadClass();
|
||||||
|
eventQueueThreads.Add(eqtc);
|
||||||
|
m_ScriptEngine.Log.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Started new script execution thread. Current thread count: " + eventQueueThreads.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AbortThreadClass(EventQueueThreadClass threadClass)
|
||||||
|
{
|
||||||
|
if (eventQueueThreads.Contains(threadClass))
|
||||||
|
eventQueueThreads.Remove(threadClass);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
threadClass.Stop();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//m_ScriptEngine.Log.Error("[" + m_ScriptEngine.ScriptEngineName + ":EventQueueManager]: If you see this, could you please report it to Tedd:");
|
||||||
|
//m_ScriptEngine.Log.Error("[" + m_ScriptEngine.ScriptEngineName + ":EventQueueManager]: Script thread execution timeout kill ended in exception: " + ex.ToString());
|
||||||
|
}
|
||||||
|
//m_ScriptEngine.Log.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Killed script execution thread. Remaining thread count: " + eventQueueThreads.Count);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Mutex locks for queue access "
|
||||||
|
/// <summary>
|
||||||
|
/// Try to get a mutex lock on localID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool TryLock(uint localID)
|
||||||
|
{
|
||||||
|
lock (tryLockLock)
|
||||||
|
{
|
||||||
|
if (objectLocks.Contains(localID) == true)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
objectLocks.Add(localID);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Release mutex lock on localID
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID"></param>
|
||||||
|
public void ReleaseLock(uint localID)
|
||||||
|
{
|
||||||
|
lock (tryLockLock)
|
||||||
|
{
|
||||||
|
if (objectLocks.Contains(localID) == true)
|
||||||
|
{
|
||||||
|
objectLocks.Remove(localID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Add events to execution queue "
|
||||||
|
/// <summary>
|
||||||
|
/// Add event to event execution queue
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID">Region object ID</param>
|
||||||
|
/// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
|
||||||
|
/// <param name="param">Array of parameters to match event mask</param>
|
||||||
|
public void AddToObjectQueue(uint localID, string FunctionName, Queue_llDetectParams_Struct qParams, params object[] param)
|
||||||
|
{
|
||||||
|
// Determine all scripts in Object and add to their queue
|
||||||
|
//myScriptEngine.log.Info("[" + ScriptEngineName + "]: EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName);
|
||||||
|
|
||||||
|
// Do we have any scripts in this object at all? If not, return
|
||||||
|
if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Event \String.Empty + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<LLUUID, IScript>.KeyCollection scriptKeys =
|
||||||
|
m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID);
|
||||||
|
|
||||||
|
foreach (LLUUID itemID in scriptKeys)
|
||||||
|
{
|
||||||
|
// Add to each script in that object
|
||||||
|
// TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter?
|
||||||
|
AddToScriptQueue(localID, itemID, FunctionName, qParams, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add event to event execution queue
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID">Region object ID</param>
|
||||||
|
/// <param name="itemID">Region script ID</param>
|
||||||
|
/// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
|
||||||
|
/// <param name="param">Array of parameters to match event mask</param>
|
||||||
|
public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, Queue_llDetectParams_Struct qParams, params object[] param)
|
||||||
|
{
|
||||||
|
lock (eventQueue)
|
||||||
|
{
|
||||||
|
if (eventQueue.Count >= EventExecutionMaxQueueSize)
|
||||||
|
{
|
||||||
|
m_ScriptEngine.Log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: ERROR: Event execution queue item count is at " + eventQueue.Count + ". Config variable \"EventExecutionMaxQueueSize\" is set to " + EventExecutionMaxQueueSize + ", so ignoring new event.");
|
||||||
|
m_ScriptEngine.Log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: Event ignored: localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a structure and add data
|
||||||
|
QueueItemStruct QIS = new QueueItemStruct();
|
||||||
|
QIS.localID = localID;
|
||||||
|
QIS.itemID = itemID;
|
||||||
|
QIS.functionName = FunctionName;
|
||||||
|
QIS.llDetectParams = qParams;
|
||||||
|
QIS.param = param;
|
||||||
|
|
||||||
|
// Add it to queue
|
||||||
|
eventQueue.Enqueue(QIS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region " Maintenance thread "
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adjust number of script thread classes. It can start new, but if it needs to stop it will just set number of threads in "ThreadsToExit" and threads will have to exit themselves.
|
||||||
|
/// Called from MaintenanceThread
|
||||||
|
/// </summary>
|
||||||
|
public void AdjustNumberOfScriptThreads()
|
||||||
|
{
|
||||||
|
// Is there anything here for us to do?
|
||||||
|
if (eventQueueThreads.Count == numberOfThreads)
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock (eventQueueThreads)
|
||||||
|
{
|
||||||
|
int diff = numberOfThreads - eventQueueThreads.Count;
|
||||||
|
// Positive number: Start
|
||||||
|
// Negative number: too many are running
|
||||||
|
if (diff > 0)
|
||||||
|
{
|
||||||
|
// We need to add more threads
|
||||||
|
for (int ThreadCount = eventQueueThreads.Count; ThreadCount < numberOfThreads; ThreadCount++)
|
||||||
|
{
|
||||||
|
StartNewThreadClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (diff < 0)
|
||||||
|
{
|
||||||
|
// We need to kill some threads
|
||||||
|
lock (ThreadsToExitLock)
|
||||||
|
{
|
||||||
|
ThreadsToExit = Math.Abs(diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check if any thread class has been executing an event too long
|
||||||
|
/// </summary>
|
||||||
|
public void CheckScriptMaxExecTime()
|
||||||
|
{
|
||||||
|
// Iterate through all ScriptThreadClasses and check how long their current function has been executing
|
||||||
|
lock (eventQueueThreads)
|
||||||
|
{
|
||||||
|
foreach (EventQueueThreadClass EventQueueThread in eventQueueThreads)
|
||||||
|
{
|
||||||
|
// Is thread currently executing anything?
|
||||||
|
if (EventQueueThread.InExecution)
|
||||||
|
{
|
||||||
|
// Has execution time expired?
|
||||||
|
if (DateTime.Now.Ticks - EventQueueThread.LastExecutionStarted >
|
||||||
|
maxFunctionExecutionTimens)
|
||||||
|
{
|
||||||
|
// Yes! We need to kill this thread!
|
||||||
|
|
||||||
|
// Set flag if script should be removed or not
|
||||||
|
EventQueueThread.KillCurrentScript = KillScriptOnMaxFunctionExecutionTime;
|
||||||
|
|
||||||
|
// Abort this thread
|
||||||
|
AbortThreadClass(EventQueueThread);
|
||||||
|
|
||||||
|
// We do not need to start another, MaintenenceThread will do that for us
|
||||||
|
//StartNewThreadClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
///// </summary>
|
||||||
|
//public bool PleaseShutdown
|
||||||
|
//{
|
||||||
|
// get { return _PleaseShutdown; }
|
||||||
|
// set { _PleaseShutdown = value; }
|
||||||
|
//}
|
||||||
|
//private bool _PleaseShutdown = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,364 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Scenes.Scripting;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Because every thread needs some data set for it (time started to execute current function), it will do its work within a class
|
||||||
|
/// </summary>
|
||||||
|
public class EventQueueThreadClass : iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// How many ms to sleep if queue is empty
|
||||||
|
/// </summary>
|
||||||
|
private static int nothingToDoSleepms;// = 50;
|
||||||
|
private static ThreadPriority MyThreadPriority;
|
||||||
|
|
||||||
|
public long LastExecutionStarted;
|
||||||
|
public bool InExecution = false;
|
||||||
|
public bool KillCurrentScript = false;
|
||||||
|
|
||||||
|
//private EventQueueManager eventQueueManager;
|
||||||
|
public Thread EventQueueThread;
|
||||||
|
private static int ThreadCount = 0;
|
||||||
|
|
||||||
|
private string ScriptEngineName = "ScriptEngine.Common";
|
||||||
|
|
||||||
|
public EventQueueThreadClass()//EventQueueManager eqm
|
||||||
|
{
|
||||||
|
//eventQueueManager = eqm;
|
||||||
|
ReadConfig();
|
||||||
|
Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
~EventQueueThreadClass()
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadConfig()
|
||||||
|
{
|
||||||
|
lock (ScriptEngine.ScriptEngines)
|
||||||
|
{
|
||||||
|
foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines)
|
||||||
|
{
|
||||||
|
ScriptEngineName = m_ScriptEngine.ScriptEngineName;
|
||||||
|
nothingToDoSleepms = m_ScriptEngine.ScriptConfigSource.GetInt("SleepTimeIfNoScriptExecutionMs", 50);
|
||||||
|
|
||||||
|
// Later with ScriptServer we might want to ask OS for stuff too, so doing this a bit manually
|
||||||
|
string pri = m_ScriptEngine.ScriptConfigSource.GetString("ScriptThreadPriority", "BelowNormal");
|
||||||
|
switch (pri.ToLower())
|
||||||
|
{
|
||||||
|
case "lowest":
|
||||||
|
MyThreadPriority = ThreadPriority.Lowest;
|
||||||
|
break;
|
||||||
|
case "belownormal":
|
||||||
|
MyThreadPriority = ThreadPriority.BelowNormal;
|
||||||
|
break;
|
||||||
|
case "normal":
|
||||||
|
MyThreadPriority = ThreadPriority.Normal;
|
||||||
|
break;
|
||||||
|
case "abovenormal":
|
||||||
|
MyThreadPriority = ThreadPriority.AboveNormal;
|
||||||
|
break;
|
||||||
|
case "highest":
|
||||||
|
MyThreadPriority = ThreadPriority.Highest;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MyThreadPriority = ThreadPriority.BelowNormal; // Default
|
||||||
|
m_ScriptEngine.Log.Error("[ScriptEngineBase]: Unknown priority type \"" + pri +
|
||||||
|
"\" in config file. Defaulting to \"BelowNormal\".");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now set that priority
|
||||||
|
if (EventQueueThread != null)
|
||||||
|
if (EventQueueThread.IsAlive)
|
||||||
|
EventQueueThread.Priority = MyThreadPriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start thread
|
||||||
|
/// </summary>
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
EventQueueThread = new Thread(EventQueueThreadLoop);
|
||||||
|
EventQueueThread.IsBackground = true;
|
||||||
|
|
||||||
|
EventQueueThread.Priority = MyThreadPriority;
|
||||||
|
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
|
||||||
|
EventQueueThread.Start();
|
||||||
|
OpenSim.Framework.ThreadTracker.Add(EventQueueThread);
|
||||||
|
|
||||||
|
// Look at this... Don't you wish everyone did that solid coding everywhere? :P
|
||||||
|
if (ThreadCount == int.MaxValue)
|
||||||
|
ThreadCount = 0;
|
||||||
|
ThreadCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
//PleaseShutdown = true; // Set shutdown flag
|
||||||
|
//Thread.Sleep(100); // Wait a bit
|
||||||
|
if (EventQueueThread != null && EventQueueThread.IsAlive == true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
EventQueueThread.Abort(); // Send abort
|
||||||
|
//EventQueueThread.Join(); // Wait for it
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
//myScriptEngine.Log.Info("[" + ScriptEngineName + "]: EventQueueManager Exception killing worker thread: " + e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventQueueManager.QueueItemStruct BlankQIS = new EventQueueManager.QueueItemStruct();
|
||||||
|
private ScriptEngine lastScriptEngine;
|
||||||
|
/// <summary>
|
||||||
|
/// Queue processing thread loop
|
||||||
|
/// </summary>
|
||||||
|
private void EventQueueThreadLoop()
|
||||||
|
{
|
||||||
|
//myScriptEngine.Log.Info("[" + ScriptEngineName + "]: EventQueueManager Worker thread spawned");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
DoProcessQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ThreadAbortException tae)
|
||||||
|
{
|
||||||
|
if (lastScriptEngine != null)
|
||||||
|
lastScriptEngine.Log.Info("[" + ScriptEngineName + "]: ThreadAbortException while executing function.");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
if (lastScriptEngine != null)
|
||||||
|
lastScriptEngine.Log.Error("[" + ScriptEngineName + "]: Exception in EventQueueThreadLoop: " + e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ThreadAbortException)
|
||||||
|
{
|
||||||
|
//myScriptEngine.Log.Info("[" + ScriptEngineName + "]: EventQueueManager Worker thread killed: " + tae.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoProcessQueue()
|
||||||
|
{
|
||||||
|
//lock (ScriptEngine.ScriptEngines)
|
||||||
|
//{
|
||||||
|
foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines))
|
||||||
|
{
|
||||||
|
lastScriptEngine = m_ScriptEngine;
|
||||||
|
// Every now and then check if we should shut down
|
||||||
|
//if (PleaseShutdown || EventQueueManager.ThreadsToExit > 0)
|
||||||
|
//{
|
||||||
|
// // Someone should shut down, lets get exclusive lock
|
||||||
|
// lock (EventQueueManager.ThreadsToExitLock)
|
||||||
|
// {
|
||||||
|
// // Lets re-check in case someone grabbed it
|
||||||
|
// if (EventQueueManager.ThreadsToExit > 0)
|
||||||
|
// {
|
||||||
|
// // Its crowded here so we'll shut down
|
||||||
|
// EventQueueManager.ThreadsToExit--;
|
||||||
|
// Stop();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // We have been asked to shut down
|
||||||
|
// Stop();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
//try
|
||||||
|
// {
|
||||||
|
EventQueueManager.QueueItemStruct QIS = BlankQIS;
|
||||||
|
bool GotItem = false;
|
||||||
|
|
||||||
|
//if (PleaseShutdown)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
if (m_ScriptEngine.m_EventQueueManager == null || m_ScriptEngine.m_EventQueueManager.eventQueue == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (m_ScriptEngine.m_EventQueueManager.eventQueue.Count == 0)
|
||||||
|
{
|
||||||
|
// Nothing to do? Sleep a bit waiting for something to do
|
||||||
|
Thread.Sleep(nothingToDoSleepms);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Something in queue, process
|
||||||
|
//myScriptEngine.Log.Info("[" + ScriptEngineName + "]: Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
|
||||||
|
|
||||||
|
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
|
||||||
|
lock (m_ScriptEngine.m_EventQueueManager.eventQueue)
|
||||||
|
{
|
||||||
|
GotItem = false;
|
||||||
|
for (int qc = 0; qc < m_ScriptEngine.m_EventQueueManager.eventQueue.Count; qc++)
|
||||||
|
{
|
||||||
|
// Get queue item
|
||||||
|
QIS = m_ScriptEngine.m_EventQueueManager.eventQueue.Dequeue();
|
||||||
|
|
||||||
|
// Check if object is being processed by someone else
|
||||||
|
if (m_ScriptEngine.m_EventQueueManager.TryLock(QIS.localID) == false)
|
||||||
|
{
|
||||||
|
// Object is already being processed, requeue it
|
||||||
|
m_ScriptEngine.m_EventQueueManager.eventQueue.Enqueue(QIS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We have lock on an object and can process it
|
||||||
|
GotItem = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GotItem == true)
|
||||||
|
{
|
||||||
|
// Execute function
|
||||||
|
try
|
||||||
|
{
|
||||||
|
///cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
|
||||||
|
#if DEBUG
|
||||||
|
//eventQueueManager.m_ScriptEngine.Log.Debug("[" + ScriptEngineName + "]: " +
|
||||||
|
// "Executing event:\r\n"
|
||||||
|
// + "QIS.localID: " + QIS.localID
|
||||||
|
// + ", QIS.itemID: " + QIS.itemID
|
||||||
|
// + ", QIS.functionName: " +
|
||||||
|
// QIS.functionName);
|
||||||
|
#endif
|
||||||
|
LastExecutionStarted = DateTime.Now.Ticks;
|
||||||
|
KillCurrentScript = false;
|
||||||
|
InExecution = true;
|
||||||
|
m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID,
|
||||||
|
QIS.itemID,
|
||||||
|
QIS.functionName,
|
||||||
|
QIS.llDetectParams,
|
||||||
|
QIS.param);
|
||||||
|
InExecution = false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
InExecution = false;
|
||||||
|
// DISPLAY ERROR INWORLD
|
||||||
|
string text = "Error executing script function \"" + QIS.functionName +
|
||||||
|
"\":\r\n";
|
||||||
|
if (e.InnerException != null)
|
||||||
|
{
|
||||||
|
// Send inner exception
|
||||||
|
text += e.InnerException.Message.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text += "\r\n";
|
||||||
|
// Send normal
|
||||||
|
text += e.Message.ToString();
|
||||||
|
}
|
||||||
|
if (KillCurrentScript)
|
||||||
|
text += "\r\nScript will be deactivated!";
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (text.Length > 1500)
|
||||||
|
text = text.Substring(0, 1500);
|
||||||
|
IScriptHost m_host =
|
||||||
|
m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
|
||||||
|
//if (m_host != null)
|
||||||
|
//{
|
||||||
|
m_ScriptEngine.World.SimChat(Helpers.StringToField(text),
|
||||||
|
ChatTypeEnum.Say, 0,
|
||||||
|
m_host.AbsolutePosition,
|
||||||
|
m_host.Name, m_host.UUID);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// T oconsole
|
||||||
|
m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.Log.Error("[" + ScriptEngineName +
|
||||||
|
"]: " +
|
||||||
|
"Unable to send text in-world:\r\n" +
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// So we are done sending message in-world
|
||||||
|
if (KillCurrentScript)
|
||||||
|
{
|
||||||
|
m_ScriptEngine.m_EventQueueManager.m_ScriptEngine.m_ScriptManager.StopScript(
|
||||||
|
QIS.localID, QIS.itemID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
InExecution = false;
|
||||||
|
m_ScriptEngine.m_EventQueueManager.ReleaseLock(QIS.localID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
///// </summary>
|
||||||
|
//public bool PleaseShutdown
|
||||||
|
//{
|
||||||
|
// get { return _PleaseShutdown; }
|
||||||
|
// set { _PleaseShutdown = value; }
|
||||||
|
//}
|
||||||
|
//private bool _PleaseShutdown = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class does maintenance on script engine.
|
||||||
|
/// </summary>
|
||||||
|
public class MaintenanceThread : iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
//public ScriptEngine m_ScriptEngine;
|
||||||
|
private int MaintenanceLoopms;
|
||||||
|
private int MaintenanceLoopTicks_ScriptLoadUnload;
|
||||||
|
private int MaintenanceLoopTicks_Other;
|
||||||
|
|
||||||
|
|
||||||
|
public MaintenanceThread()
|
||||||
|
{
|
||||||
|
//m_ScriptEngine = _ScriptEngine;
|
||||||
|
|
||||||
|
ReadConfig();
|
||||||
|
|
||||||
|
// Start maintenance thread
|
||||||
|
StartMaintenanceThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
~MaintenanceThread()
|
||||||
|
{
|
||||||
|
StopMaintenanceThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadConfig()
|
||||||
|
{
|
||||||
|
// Bad hack, but we need a m_ScriptEngine :)
|
||||||
|
lock (ScriptEngine.ScriptEngines)
|
||||||
|
{
|
||||||
|
foreach (ScriptEngine m_ScriptEngine in ScriptEngine.ScriptEngines)
|
||||||
|
{
|
||||||
|
MaintenanceLoopms = m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopms", 50);
|
||||||
|
MaintenanceLoopTicks_ScriptLoadUnload =
|
||||||
|
m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopTicks_ScriptLoadUnload", 1);
|
||||||
|
MaintenanceLoopTicks_Other =
|
||||||
|
m_ScriptEngine.ScriptConfigSource.GetInt("MaintenanceLoopTicks_Other", 10);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region " Maintenance thread "
|
||||||
|
/// <summary>
|
||||||
|
/// Maintenance thread. Enforcing max execution time for example.
|
||||||
|
/// </summary>
|
||||||
|
public Thread MaintenanceThreadThread;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts maintenance thread
|
||||||
|
/// </summary>
|
||||||
|
private void StartMaintenanceThread()
|
||||||
|
{
|
||||||
|
if (MaintenanceThreadThread == null)
|
||||||
|
{
|
||||||
|
MaintenanceThreadThread = new Thread(MaintenanceLoop);
|
||||||
|
MaintenanceThreadThread.Name = "ScriptMaintenanceThread";
|
||||||
|
MaintenanceThreadThread.IsBackground = true;
|
||||||
|
MaintenanceThreadThread.Start();
|
||||||
|
OpenSim.Framework.ThreadTracker.Add(MaintenanceThreadThread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stops maintenance thread
|
||||||
|
/// </summary>
|
||||||
|
private void StopMaintenanceThread()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
//m_ScriptEngine.Log.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: StopMaintenanceThread() called");
|
||||||
|
#endif
|
||||||
|
//PleaseShutdown = true;
|
||||||
|
Thread.Sleep(100);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (MaintenanceThreadThread != null && MaintenanceThreadThread.IsAlive)
|
||||||
|
{
|
||||||
|
MaintenanceThreadThread.Abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
//m_ScriptEngine.Log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: Exception stopping maintenence thread: " + ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScriptEngine lastScriptEngine; // Keep track of what ScriptEngine instance we are at so we can give exception
|
||||||
|
/// <summary>
|
||||||
|
/// A thread should run in this loop and check all running scripts
|
||||||
|
/// </summary>
|
||||||
|
public void MaintenanceLoop()
|
||||||
|
{
|
||||||
|
//if (m_ScriptEngine.m_EventQueueManager.maxFunctionExecutionTimens < MaintenanceLoopms)
|
||||||
|
// m_ScriptEngine.Log.Warn("[" + m_ScriptEngine.ScriptEngineName + "]: " +
|
||||||
|
// "Configuration error: MaxEventExecutionTimeMs is less than MaintenanceLoopms. The Maintenance Loop will only check scripts once per run.");
|
||||||
|
|
||||||
|
long Last_maxFunctionExecutionTimens = 0; // DateTime.Now.Ticks;
|
||||||
|
long Last_ReReadConfigFilens = DateTime.Now.Ticks;
|
||||||
|
int MaintenanceLoopTicks_ScriptLoadUnload_Count = 0;
|
||||||
|
int MaintenanceLoopTicks_Other_Count = 0;
|
||||||
|
bool MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = false;
|
||||||
|
bool MaintenanceLoopTicks_Other_ResetCount = false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
System.Threading.Thread.Sleep(MaintenanceLoopms); // Sleep before next pass
|
||||||
|
|
||||||
|
// Reset counters?
|
||||||
|
if (MaintenanceLoopTicks_ScriptLoadUnload_ResetCount)
|
||||||
|
{
|
||||||
|
MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = false;
|
||||||
|
MaintenanceLoopTicks_ScriptLoadUnload_Count = 0;
|
||||||
|
}
|
||||||
|
if (MaintenanceLoopTicks_Other_ResetCount)
|
||||||
|
{
|
||||||
|
MaintenanceLoopTicks_Other_ResetCount = false;
|
||||||
|
MaintenanceLoopTicks_Other_Count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increase our counters
|
||||||
|
MaintenanceLoopTicks_ScriptLoadUnload_Count++;
|
||||||
|
MaintenanceLoopTicks_Other_Count++;
|
||||||
|
|
||||||
|
|
||||||
|
//lock (ScriptEngine.ScriptEngines)
|
||||||
|
//{
|
||||||
|
foreach (ScriptEngine m_ScriptEngine in new ArrayList(ScriptEngine.ScriptEngines))
|
||||||
|
{
|
||||||
|
lastScriptEngine = m_ScriptEngine;
|
||||||
|
// Re-reading config every x seconds
|
||||||
|
if (MaintenanceLoopTicks_Other_Count >= MaintenanceLoopTicks_Other)
|
||||||
|
{
|
||||||
|
MaintenanceLoopTicks_Other_ResetCount = true;
|
||||||
|
if (m_ScriptEngine.RefreshConfigFilens > 0)
|
||||||
|
{
|
||||||
|
// Check if its time to re-read config
|
||||||
|
if (DateTime.Now.Ticks - Last_ReReadConfigFilens >
|
||||||
|
m_ScriptEngine.RefreshConfigFilens)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Time passed: " + (DateTime.Now.Ticks - Last_ReReadConfigFilens) + ">" + m_ScriptEngine.RefreshConfigFilens );
|
||||||
|
// Its time to re-read config file
|
||||||
|
m_ScriptEngine.ReadConfig();
|
||||||
|
Last_ReReadConfigFilens = DateTime.Now.Ticks; // Reset time
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Adjust number of running script threads if not correct
|
||||||
|
if (m_ScriptEngine.m_EventQueueManager != null)
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AdjustNumberOfScriptThreads();
|
||||||
|
|
||||||
|
// Check if any script has exceeded its max execution time
|
||||||
|
if (EventQueueManager.EnforceMaxExecutionTime)
|
||||||
|
{
|
||||||
|
// We are enforcing execution time
|
||||||
|
if (DateTime.Now.Ticks - Last_maxFunctionExecutionTimens >
|
||||||
|
EventQueueManager.maxFunctionExecutionTimens)
|
||||||
|
{
|
||||||
|
// Its time to check again
|
||||||
|
m_ScriptEngine.m_EventQueueManager.CheckScriptMaxExecTime(); // Do check
|
||||||
|
Last_maxFunctionExecutionTimens = DateTime.Now.Ticks; // Reset time
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (MaintenanceLoopTicks_ScriptLoadUnload_Count >= MaintenanceLoopTicks_ScriptLoadUnload)
|
||||||
|
{
|
||||||
|
MaintenanceLoopTicks_ScriptLoadUnload_ResetCount = true;
|
||||||
|
// LOAD / UNLOAD SCRIPTS
|
||||||
|
if (m_ScriptEngine.m_ScriptManager != null)
|
||||||
|
m_ScriptEngine.m_ScriptManager.DoScriptLoadUnload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (lastScriptEngine != null)
|
||||||
|
lastScriptEngine.Log.Error("[" + lastScriptEngine.ScriptEngineName + "]: Exception in MaintenanceLoopThread. Thread will recover after 5 sec throttle. Exception: " + ex.ToString());
|
||||||
|
Thread.Sleep(5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
///// </summary>
|
||||||
|
//public bool PleaseShutdown
|
||||||
|
//{
|
||||||
|
// get { return _PleaseShutdown; }
|
||||||
|
// set { _PleaseShutdown = value; }
|
||||||
|
//}
|
||||||
|
//private bool _PleaseShutdown = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.IO;
|
||||||
|
using Nini.Config;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the root object for ScriptEngine. Objects access each other trough this class.
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
[Serializable]
|
||||||
|
public abstract class ScriptEngine : IRegionModule, OpenSim.Region.ScriptEngine.Common.ScriptServerInterfaces.ScriptEngine, iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
private readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
public static List<ScriptEngine> ScriptEngines = new List<ScriptEngine>();
|
||||||
|
public Scene World;
|
||||||
|
public EventManager m_EventManager; // Handles and queues incoming events from OpenSim
|
||||||
|
public EventQueueManager m_EventQueueManager; // Executes events, handles script threads
|
||||||
|
public ScriptManager m_ScriptManager; // Load, unload and execute scripts
|
||||||
|
public AppDomainManager m_AppDomainManager; // Handles loading/unloading of scripts into AppDomains
|
||||||
|
public AsyncLSLCommandManager m_ASYNCLSLCommandManager; // Asyncronous LSL commands (commands that returns with an event)
|
||||||
|
public static MaintenanceThread m_MaintenanceThread; // Thread that does different kinds of maintenance, for example refreshing config and killing scripts that has been running too long
|
||||||
|
|
||||||
|
public IConfigSource ConfigSource;
|
||||||
|
public IConfig ScriptConfigSource;
|
||||||
|
public abstract string ScriptEngineName { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How many seconds between re-reading config-file. 0 = never. ScriptEngine will try to adjust to new config changes.
|
||||||
|
/// </summary>
|
||||||
|
public int RefreshConfigFileSeconds {
|
||||||
|
get { return (int)(RefreshConfigFilens / 10000000); }
|
||||||
|
set { RefreshConfigFilens = value * 10000000; }
|
||||||
|
}
|
||||||
|
public long RefreshConfigFilens;
|
||||||
|
|
||||||
|
public ScriptManager GetScriptManager()
|
||||||
|
{
|
||||||
|
return _GetScriptManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ScriptManager _GetScriptManager();
|
||||||
|
|
||||||
|
public log4net.ILog Log
|
||||||
|
{
|
||||||
|
get { return m_log; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptEngine()
|
||||||
|
{
|
||||||
|
Common.mySE = this; // For logging, just need any instance, doesn't matter
|
||||||
|
lock (ScriptEngines)
|
||||||
|
{
|
||||||
|
ScriptEngines.Add(this); // Keep a list of ScriptEngines for shared threads to process all instances
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void InitializeEngine(Scene Sceneworld, IConfigSource config, bool HookUpToServer, ScriptManager newScriptManager)
|
||||||
|
{
|
||||||
|
World = Sceneworld;
|
||||||
|
ConfigSource = config;
|
||||||
|
m_log.Info("[" + ScriptEngineName + "]: ScriptEngine initializing");
|
||||||
|
|
||||||
|
// Make sure we have config
|
||||||
|
if (ConfigSource.Configs[ScriptEngineName] == null)
|
||||||
|
ConfigSource.AddConfig(ScriptEngineName);
|
||||||
|
ScriptConfigSource = ConfigSource.Configs[ScriptEngineName];
|
||||||
|
|
||||||
|
//m_log.Info("[" + ScriptEngineName + "]: InitializeEngine");
|
||||||
|
|
||||||
|
// Create all objects we'll be using
|
||||||
|
m_EventQueueManager = new EventQueueManager(this);
|
||||||
|
m_EventManager = new EventManager(this, HookUpToServer);
|
||||||
|
// We need to start it
|
||||||
|
newScriptManager.Start();
|
||||||
|
m_ScriptManager = newScriptManager;
|
||||||
|
m_AppDomainManager = new AppDomainManager(this);
|
||||||
|
m_ASYNCLSLCommandManager = new AsyncLSLCommandManager(this);
|
||||||
|
if (m_MaintenanceThread == null)
|
||||||
|
m_MaintenanceThread = new MaintenanceThread();
|
||||||
|
|
||||||
|
m_log.Info("[" + ScriptEngineName + "]: Reading configuration from config section \"" + ScriptEngineName + "\"");
|
||||||
|
ReadConfig();
|
||||||
|
|
||||||
|
// Should we iterate the region for scripts that needs starting?
|
||||||
|
// Or can we assume we are loaded before anything else so we can use proper events?
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Shutdown()
|
||||||
|
{
|
||||||
|
// We are shutting down
|
||||||
|
lock (ScriptEngines)
|
||||||
|
{
|
||||||
|
ScriptEngines.Remove(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptServerInterfaces.RemoteEvents ScriptServerInterfaces.ScriptEngine.EventManager()
|
||||||
|
{
|
||||||
|
return this.m_EventManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadConfig()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
//m_log.Debug("[" + ScriptEngineName + "]: Refreshing configuration for all modules");
|
||||||
|
#endif
|
||||||
|
RefreshConfigFileSeconds = ScriptConfigSource.GetInt("RefreshConfig", 30);
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new object (probably not necessary?)
|
||||||
|
// ScriptConfigSource = ConfigSource.Configs[ScriptEngineName];
|
||||||
|
|
||||||
|
if (m_EventQueueManager != null) m_EventQueueManager.ReadConfig();
|
||||||
|
if (m_EventManager != null) m_EventManager.ReadConfig();
|
||||||
|
if (m_ScriptManager != null) m_ScriptManager.ReadConfig();
|
||||||
|
if (m_AppDomainManager != null) m_AppDomainManager.ReadConfig();
|
||||||
|
if (m_ASYNCLSLCommandManager != null) m_ASYNCLSLCommandManager.ReadConfig();
|
||||||
|
if (m_MaintenanceThread != null) m_MaintenanceThread.ReadConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
#region IRegionModule
|
||||||
|
|
||||||
|
public abstract void Initialise(Scene scene, IConfigSource config);
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return "Common." + ScriptEngineName; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,435 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Loads scripts
|
||||||
|
/// Compiles them if necessary
|
||||||
|
/// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution)
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
|
||||||
|
// This class is as close as you get to the script without being inside script class. It handles all the dirty work for other classes.
|
||||||
|
// * Keeps track of running scripts
|
||||||
|
// * Compiles script if necessary (through "Compiler")
|
||||||
|
// * Loads script (through "AppDomainManager" called from for example "EventQueueManager")
|
||||||
|
// * Executes functions inside script (called from for example "EventQueueManager" class)
|
||||||
|
// * Unloads script (through "AppDomainManager" called from for example "EventQueueManager")
|
||||||
|
// * Dedicated load/unload thread, and queues loading/unloading.
|
||||||
|
// This so that scripts starting or stopping will not slow down other theads or whole system.
|
||||||
|
//
|
||||||
|
[Serializable]
|
||||||
|
public abstract class ScriptManager : iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
#region Declares
|
||||||
|
|
||||||
|
private Thread scriptLoadUnloadThread;
|
||||||
|
private static Thread staticScriptLoadUnloadThread;
|
||||||
|
private int scriptLoadUnloadThread_IdleSleepms;
|
||||||
|
private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
|
||||||
|
private static bool PrivateThread;
|
||||||
|
private int LoadUnloadMaxQueueSize;
|
||||||
|
private Object scriptLock = new Object();
|
||||||
|
|
||||||
|
// Load/Unload structure
|
||||||
|
private struct LUStruct
|
||||||
|
{
|
||||||
|
public uint localID;
|
||||||
|
public LLUUID itemID;
|
||||||
|
public string script;
|
||||||
|
public LUType Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum LUType
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
Load = 1,
|
||||||
|
Unload = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object<string, Script<string, script>>
|
||||||
|
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
||||||
|
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
|
||||||
|
public Dictionary<uint, Dictionary<LLUUID, IScript>> Scripts =
|
||||||
|
new Dictionary<uint, Dictionary<LLUUID, IScript>>();
|
||||||
|
|
||||||
|
public Scene World
|
||||||
|
{
|
||||||
|
get { return m_scriptEngine.World; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public void ReadConfig()
|
||||||
|
{
|
||||||
|
scriptLoadUnloadThread_IdleSleepms = m_scriptEngine.ScriptConfigSource.GetInt("ScriptLoadUnloadLoopms", 30);
|
||||||
|
// TODO: Requires sharing of all ScriptManagers to single thread
|
||||||
|
PrivateThread = true; // m_scriptEngine.ScriptConfigSource.GetBoolean("PrivateScriptLoadUnloadThread", false);
|
||||||
|
LoadUnloadMaxQueueSize = m_scriptEngine.ScriptConfigSource.GetInt("LoadUnloadMaxQueueSize", 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Object init/shutdown
|
||||||
|
|
||||||
|
public ScriptEngineBase.ScriptEngine m_scriptEngine;
|
||||||
|
|
||||||
|
public ScriptManager(ScriptEngineBase.ScriptEngine scriptEngine)
|
||||||
|
{
|
||||||
|
m_scriptEngine = scriptEngine;
|
||||||
|
}
|
||||||
|
public abstract void Initialize();
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
ReadConfig();
|
||||||
|
Initialize();
|
||||||
|
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
|
||||||
|
|
||||||
|
//
|
||||||
|
// CREATE THREAD
|
||||||
|
// Private or shared
|
||||||
|
//
|
||||||
|
if (PrivateThread)
|
||||||
|
{
|
||||||
|
// Assign one thread per region
|
||||||
|
//scriptLoadUnloadThread = StartScriptLoadUnloadThread();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Shared thread - make sure one exist, then assign it to the private
|
||||||
|
if (staticScriptLoadUnloadThread == null)
|
||||||
|
{
|
||||||
|
//staticScriptLoadUnloadThread = StartScriptLoadUnloadThread();
|
||||||
|
}
|
||||||
|
scriptLoadUnloadThread = staticScriptLoadUnloadThread;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int privateThreadCount = 0;
|
||||||
|
private Thread StartScriptLoadUnloadThread()
|
||||||
|
{
|
||||||
|
Thread t = new Thread(ScriptLoadUnloadThreadLoop);
|
||||||
|
string name = "ScriptLoadUnloadThread:";
|
||||||
|
if (PrivateThread)
|
||||||
|
{
|
||||||
|
name += "Private:" + privateThreadCount;
|
||||||
|
privateThreadCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
name += "Shared";
|
||||||
|
}
|
||||||
|
t.Name = name;
|
||||||
|
t.IsBackground = true;
|
||||||
|
t.Priority = ThreadPriority.Normal;
|
||||||
|
t.Start();
|
||||||
|
OpenSim.Framework.ThreadTracker.Add(t);
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScriptManager()
|
||||||
|
{
|
||||||
|
// Abort load/unload thread
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//PleaseShutdown = true;
|
||||||
|
//Thread.Sleep(100);
|
||||||
|
if (scriptLoadUnloadThread != null && scriptLoadUnloadThread.IsAlive == true)
|
||||||
|
{
|
||||||
|
scriptLoadUnloadThread.Abort();
|
||||||
|
//scriptLoadUnloadThread.Join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Load / Unload scripts (Thread loop)
|
||||||
|
|
||||||
|
private void ScriptLoadUnloadThreadLoop()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (LUQueue.Count == 0)
|
||||||
|
Thread.Sleep(scriptLoadUnloadThread_IdleSleepms);
|
||||||
|
//if (PleaseShutdown)
|
||||||
|
// return;
|
||||||
|
DoScriptLoadUnload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ThreadAbortException tae)
|
||||||
|
{
|
||||||
|
string a = tae.ToString();
|
||||||
|
a = String.Empty;
|
||||||
|
// Expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoScriptLoadUnload()
|
||||||
|
{
|
||||||
|
if (LUQueue.Count > 0)
|
||||||
|
{
|
||||||
|
LUStruct item = LUQueue.Dequeue();
|
||||||
|
lock (startStopLock) // Lock so we have only 1 thread working on loading/unloading of scripts
|
||||||
|
{
|
||||||
|
if (item.Action == LUType.Unload)
|
||||||
|
{
|
||||||
|
_StopScript(item.localID, item.itemID);
|
||||||
|
}
|
||||||
|
if (item.Action == LUType.Load)
|
||||||
|
{
|
||||||
|
_StartScript(item.localID, item.itemID, item.script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Helper functions
|
||||||
|
|
||||||
|
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name);
|
||||||
|
return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region Start/Stop/Reset script
|
||||||
|
|
||||||
|
private readonly Object startStopLock = new Object();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetches, loads and hooks up a script to an objects events
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="itemID"></param>
|
||||||
|
/// <param name="localID"></param>
|
||||||
|
public void StartScript(uint localID, LLUUID itemID, string Script)
|
||||||
|
{
|
||||||
|
if (LUQueue.Count >= LoadUnloadMaxQueueSize)
|
||||||
|
{
|
||||||
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: ERROR: Load/unload queue item count is at " + LUQueue.Count + ". Config variable \"LoadUnloadMaxQueueSize\" is set to " + LoadUnloadMaxQueueSize + ", so ignoring new script.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LUStruct ls = new LUStruct();
|
||||||
|
ls.localID = localID;
|
||||||
|
ls.itemID = itemID;
|
||||||
|
ls.script = Script;
|
||||||
|
ls.Action = LUType.Load;
|
||||||
|
LUQueue.Enqueue(ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disables and unloads a script
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID"></param>
|
||||||
|
/// <param name="itemID"></param>
|
||||||
|
public void StopScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
LUStruct ls = new LUStruct();
|
||||||
|
ls.localID = localID;
|
||||||
|
ls.itemID = itemID;
|
||||||
|
ls.Action = LUType.Unload;
|
||||||
|
LUQueue.Enqueue(ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new instance of the compiler (reuse)
|
||||||
|
//private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler();
|
||||||
|
|
||||||
|
public abstract void _StartScript(uint localID, LLUUID itemID, string Script);
|
||||||
|
public abstract void _StopScript(uint localID, LLUUID itemID);
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Perform event execution in script
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Execute a LL-event-function in Script
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="localID">Object the script is located in</param>
|
||||||
|
/// <param name="itemID">Script ID</param>
|
||||||
|
/// <param name="FunctionName">Name of function</param>
|
||||||
|
/// <param name="args">Arguments to pass to function</param>
|
||||||
|
internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, EventQueueManager.Queue_llDetectParams_Struct qParams, object[] args)
|
||||||
|
{
|
||||||
|
//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
|
||||||
|
///#if DEBUG
|
||||||
|
/// Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName);
|
||||||
|
///#endif
|
||||||
|
// Execute a function in the script
|
||||||
|
//m_scriptEngine.Log.Info("[" + ScriptEngineName + "]: Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
|
||||||
|
//ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID);
|
||||||
|
IScript Script = GetScript(localID, itemID);
|
||||||
|
if (Script == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
|
||||||
|
///#if DEBUG
|
||||||
|
/// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName);
|
||||||
|
///#endif
|
||||||
|
// Must be done in correct AppDomain, so leaving it up to the script itself
|
||||||
|
Script.llDetectParams = qParams;
|
||||||
|
Script.Exec.ExecuteEvent(FunctionName, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Internal functions to keep track of script
|
||||||
|
|
||||||
|
public Dictionary<LLUUID, IScript>.KeyCollection GetScriptKeys(uint localID)
|
||||||
|
{
|
||||||
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Dictionary<LLUUID, IScript> Obj;
|
||||||
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
|
|
||||||
|
return Obj.Keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IScript GetScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
lock (scriptLock)
|
||||||
|
{
|
||||||
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Dictionary<LLUUID, IScript> Obj;
|
||||||
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
|
if (Obj.ContainsKey(itemID) == false)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// Get script
|
||||||
|
IScript Script;
|
||||||
|
Obj.TryGetValue(itemID, out Script);
|
||||||
|
return Script;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetScript(uint localID, LLUUID itemID, IScript Script)
|
||||||
|
{
|
||||||
|
lock (scriptLock)
|
||||||
|
{
|
||||||
|
// Create object if it doesn't exist
|
||||||
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
|
{
|
||||||
|
Scripts.Add(localID, new Dictionary<LLUUID, IScript>());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete script if it exists
|
||||||
|
Dictionary<LLUUID, IScript> Obj;
|
||||||
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
|
if (Obj.ContainsKey(itemID) == true)
|
||||||
|
Obj.Remove(itemID);
|
||||||
|
|
||||||
|
// Add to object
|
||||||
|
Obj.Add(itemID, Script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
// Don't have that object?
|
||||||
|
if (Scripts.ContainsKey(localID) == false)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Delete script if it exists
|
||||||
|
Dictionary<LLUUID, IScript> Obj;
|
||||||
|
Scripts.TryGetValue(localID, out Obj);
|
||||||
|
if (Obj.ContainsKey(itemID) == true)
|
||||||
|
Obj.Remove(itemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
public void ResetScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
string script = GetScript(localID, itemID).Source;
|
||||||
|
StopScript(localID, itemID);
|
||||||
|
StartScript(localID, itemID, script);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region Script serialization/deserialization
|
||||||
|
|
||||||
|
public void GetSerializedScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
// Serialize the script and return it
|
||||||
|
// Should not be a problem
|
||||||
|
FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID);
|
||||||
|
BinaryFormatter b = new BinaryFormatter();
|
||||||
|
b.Serialize(fs, GetScript(localID, itemID));
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PutSerializedScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
// Deserialize the script and inject it into an AppDomain
|
||||||
|
|
||||||
|
// How to inject into an AppDomain?
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
///// <summary>
|
||||||
|
///// If set to true then threads and stuff should try to make a graceful exit
|
||||||
|
///// </summary>
|
||||||
|
//public bool PleaseShutdown
|
||||||
|
//{
|
||||||
|
// get { return _PleaseShutdown; }
|
||||||
|
// set { _PleaseShutdown = value; }
|
||||||
|
//}
|
||||||
|
//private bool _PleaseShutdown = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
||||||
|
{
|
||||||
|
public interface iScriptEngineFunctionModule
|
||||||
|
{
|
||||||
|
void ReadConfig();
|
||||||
|
// bool PleaseShutdown { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,52 +1,90 @@
|
||||||
using libsecondlife;
|
/*
|
||||||
using OpenSim.Framework;
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
namespace OpenSim.Region.ScriptEngine.Common
|
*
|
||||||
{
|
* Redistribution and use in source and binary forms, with or without
|
||||||
public class ScriptServerInterfaces
|
* modification, are permitted provided that the following conditions are met:
|
||||||
{
|
* * Redistributions of source code must retain the above copyright
|
||||||
public interface RemoteEvents
|
* notice, this list of conditions and the following disclaimer.
|
||||||
{
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient);
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
void OnRezScript(uint localID, LLUUID itemID, string script);
|
* documentation and/or other materials provided with the distribution.
|
||||||
void OnRemoveScript(uint localID, LLUUID itemID);
|
* * Neither the name of the OpenSim Project nor the
|
||||||
void state_exit(uint localID, LLUUID itemID);
|
* names of its contributors may be used to endorse or promote products
|
||||||
void touch(uint localID, LLUUID itemID);
|
* derived from this software without specific prior written permission.
|
||||||
void touch_end(uint localID, LLUUID itemID);
|
*
|
||||||
void collision_start(uint localID, LLUUID itemID);
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
void collision(uint localID, LLUUID itemID);
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
void collision_end(uint localID, LLUUID itemID);
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
void land_collision_start(uint localID, LLUUID itemID);
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
void land_collision(uint localID, LLUUID itemID);
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
void land_collision_end(uint localID, LLUUID itemID);
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
void timer(uint localID, LLUUID itemID);
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
void listen(uint localID, LLUUID itemID);
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
void on_rez(uint localID, LLUUID itemID);
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
void sensor(uint localID, LLUUID itemID);
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
void no_sensor(uint localID, LLUUID itemID);
|
*
|
||||||
void control(uint localID, LLUUID itemID);
|
*/
|
||||||
void money(uint localID, LLUUID itemID);
|
|
||||||
void email(uint localID, LLUUID itemID);
|
using libsecondlife;
|
||||||
void at_target(uint localID, LLUUID itemID);
|
using Nini.Config;
|
||||||
void not_at_target(uint localID, LLUUID itemID);
|
using OpenSim.Framework;
|
||||||
void at_rot_target(uint localID, LLUUID itemID);
|
using OpenSim.Framework.Console;
|
||||||
void not_at_rot_target(uint localID, LLUUID itemID);
|
using OpenSim.Region.Environment.Scenes;
|
||||||
void run_time_permissions(uint localID, LLUUID itemID);
|
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
|
||||||
void changed(uint localID, LLUUID itemID);
|
|
||||||
void attach(uint localID, LLUUID itemID);
|
namespace OpenSim.Region.ScriptEngine.Common
|
||||||
void dataserver(uint localID, LLUUID itemID);
|
{
|
||||||
void link_message(uint localID, LLUUID itemID);
|
public class ScriptServerInterfaces
|
||||||
void moving_start(uint localID, LLUUID itemID);
|
{
|
||||||
void moving_end(uint localID, LLUUID itemID);
|
public interface RemoteEvents
|
||||||
void object_rez(uint localID, LLUUID itemID);
|
{
|
||||||
void remote_data(uint localID, LLUUID itemID);
|
void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient);
|
||||||
void http_response(uint localID, LLUUID itemID);
|
void OnRezScript(uint localID, LLUUID itemID, string script);
|
||||||
}
|
void OnRemoveScript(uint localID, LLUUID itemID);
|
||||||
|
void state_exit(uint localID, LLUUID itemID);
|
||||||
public interface ServerRemotingObject
|
void touch(uint localID, LLUUID itemID);
|
||||||
{
|
void touch_end(uint localID, LLUUID itemID);
|
||||||
RemoteEvents Events();
|
void collision_start(uint localID, LLUUID itemID);
|
||||||
}
|
void collision(uint localID, LLUUID itemID);
|
||||||
|
void collision_end(uint localID, LLUUID itemID);
|
||||||
}
|
void land_collision_start(uint localID, LLUUID itemID);
|
||||||
}
|
void land_collision(uint localID, LLUUID itemID);
|
||||||
|
void land_collision_end(uint localID, LLUUID itemID);
|
||||||
|
void timer(uint localID, LLUUID itemID);
|
||||||
|
void listen(uint localID, LLUUID itemID);
|
||||||
|
void on_rez(uint localID, LLUUID itemID);
|
||||||
|
void sensor(uint localID, LLUUID itemID);
|
||||||
|
void no_sensor(uint localID, LLUUID itemID);
|
||||||
|
void control(uint localID, LLUUID itemID);
|
||||||
|
void money(uint localID, LLUUID itemID);
|
||||||
|
void email(uint localID, LLUUID itemID);
|
||||||
|
void at_target(uint localID, LLUUID itemID);
|
||||||
|
void not_at_target(uint localID, LLUUID itemID);
|
||||||
|
void at_rot_target(uint localID, LLUUID itemID);
|
||||||
|
void not_at_rot_target(uint localID, LLUUID itemID);
|
||||||
|
void run_time_permissions(uint localID, LLUUID itemID);
|
||||||
|
void changed(uint localID, LLUUID itemID);
|
||||||
|
void attach(uint localID, LLUUID itemID);
|
||||||
|
void dataserver(uint localID, LLUUID itemID);
|
||||||
|
void link_message(uint localID, LLUUID itemID);
|
||||||
|
void moving_start(uint localID, LLUUID itemID);
|
||||||
|
void moving_end(uint localID, LLUUID itemID);
|
||||||
|
void object_rez(uint localID, LLUUID itemID);
|
||||||
|
void remote_data(uint localID, LLUUID itemID);
|
||||||
|
void http_response(uint localID, LLUUID itemID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ServerRemotingObject
|
||||||
|
{
|
||||||
|
RemoteEvents Events();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ScriptEngine
|
||||||
|
{
|
||||||
|
RemoteEvents EventManager();
|
||||||
|
void InitializeEngine(Scene Sceneworld, IConfigSource config, bool DontHookUp, ScriptManager newScriptManager);
|
||||||
|
ScriptManager GetScriptManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.TRPC
|
||||||
|
{
|
||||||
|
class MyBase
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.TRPC
|
||||||
|
{
|
||||||
|
public class TCPClient : TCPCommon.ClientInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public TCPClient()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
private readonly Dictionary<int, TCPSocket> Clients = new Dictionary<int, TCPSocket>();
|
||||||
|
private int ClientCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public event TCPCommon.ClientConnectedDelegate ClientConnected;
|
||||||
|
public event TCPCommon.DataReceivedDelegate DataReceived;
|
||||||
|
public event TCPCommon.DataSentDelegate DataSent;
|
||||||
|
public event TCPCommon.CloseDelegate Close;
|
||||||
|
public event TCPCommon.ConnectErrorDelegate ConnectError;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates client connection
|
||||||
|
/// </summary>
|
||||||
|
public void Connect(string RemoteHost, int RemotePort)
|
||||||
|
{
|
||||||
|
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(RemoteHost), RemotePort);
|
||||||
|
//newsock.BeginConnect(ipe, new AsyncCallback(asyncConnected), newsock);
|
||||||
|
newsock.Connect(ipe);
|
||||||
|
}
|
||||||
|
public int ConnectAndReturnID(string RemoteHost, int RemotePort)
|
||||||
|
{
|
||||||
|
Socket newsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(RemoteHost), RemotePort);
|
||||||
|
//newsock.BeginConnect(ipe, new AsyncCallback(asyncConnected), newsock);
|
||||||
|
newsock.Connect(ipe);
|
||||||
|
return ProcessConnection(newsock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Disconnect(int ID)
|
||||||
|
{
|
||||||
|
Clients[ID].Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
void asyncConnected(IAsyncResult iar)
|
||||||
|
{
|
||||||
|
Socket client = (Socket)iar.AsyncState;
|
||||||
|
client.EndConnect(iar);
|
||||||
|
ProcessConnection(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int ProcessConnection(Socket client)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int id = ClientCount++;
|
||||||
|
TCPSocket S = new TCPSocket(id, client);
|
||||||
|
|
||||||
|
// Add to dictionary
|
||||||
|
Clients.Add(id, S);
|
||||||
|
|
||||||
|
// Add event handlers
|
||||||
|
S.Close += new TCPSocket.CloseDelegate(S_Close);
|
||||||
|
S.DataReceived += new TCPSocket.DataReceivedDelegate(S_DataReceived);
|
||||||
|
S.DataSent += new TCPSocket.DataSentDelegate(S_DataSent);
|
||||||
|
|
||||||
|
// Start it
|
||||||
|
S.Start();
|
||||||
|
|
||||||
|
Debug.WriteLine("Connection established: " + client.RemoteEndPoint.ToString());
|
||||||
|
|
||||||
|
// Fire Connected-event
|
||||||
|
if (ClientConnected != null)
|
||||||
|
ClientConnected(id, client.RemoteEndPoint);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
catch (SocketException sex)
|
||||||
|
{
|
||||||
|
if (ConnectError != null)
|
||||||
|
ConnectError(sex.Message);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void S_DataSent(int ID, int length)
|
||||||
|
{
|
||||||
|
if (DataSent != null)
|
||||||
|
DataSent(ID, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_DataReceived(int ID, byte[] data, int offset, int length)
|
||||||
|
{
|
||||||
|
if (DataReceived != null)
|
||||||
|
DataReceived(ID, data, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_Close(int ID)
|
||||||
|
{
|
||||||
|
if (Close != null)
|
||||||
|
Close(ID);
|
||||||
|
Clients.Remove(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(int clientID, byte[] data, int offset, int len)
|
||||||
|
{
|
||||||
|
Clients[clientID].Send(clientID, data, offset, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.TRPC
|
||||||
|
{
|
||||||
|
public class TCPCommon
|
||||||
|
{
|
||||||
|
public delegate void ClientConnectedDelegate(int ID, System.Net.EndPoint Remote);
|
||||||
|
public delegate void DataReceivedDelegate(int ID, byte[] data, int offset, int length);
|
||||||
|
public delegate void DataSentDelegate(int ID, int length);
|
||||||
|
public delegate void CloseDelegate(int ID);
|
||||||
|
public delegate void ConnectErrorDelegate(string Reason);
|
||||||
|
|
||||||
|
|
||||||
|
public interface ServerAndClientInterface
|
||||||
|
{
|
||||||
|
void Send(int clientID, byte[] data, int offset, int len);
|
||||||
|
event ClientConnectedDelegate ClientConnected;
|
||||||
|
event DataReceivedDelegate DataReceived;
|
||||||
|
event DataSentDelegate DataSent;
|
||||||
|
event CloseDelegate Close;
|
||||||
|
}
|
||||||
|
public interface ClientInterface : ServerAndClientInterface
|
||||||
|
{
|
||||||
|
event TCPCommon.ConnectErrorDelegate ConnectError;
|
||||||
|
void Connect(string RemoteHost, int RemotePort);
|
||||||
|
void Disconnect(int ID);
|
||||||
|
}
|
||||||
|
public interface ServerInterface : ServerAndClientInterface
|
||||||
|
{
|
||||||
|
void StartListen();
|
||||||
|
void StopListen();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Diagnostics;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using TCPCommon=OpenSim.Region.ScriptEngine.Common.TRPC.TCPCommon;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.TRPC
|
||||||
|
{
|
||||||
|
public class TCPServer: TCPCommon.ServerInterface
|
||||||
|
{
|
||||||
|
public readonly int LocalPort;
|
||||||
|
public TCPServer(int localPort)
|
||||||
|
{
|
||||||
|
LocalPort = localPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Socket server;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts listening for new connections
|
||||||
|
/// </summary>
|
||||||
|
public void StartListen()
|
||||||
|
{
|
||||||
|
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, LocalPort);
|
||||||
|
server.Bind(ipe);
|
||||||
|
server.Listen(10);
|
||||||
|
server.BeginAccept(new AsyncCallback(AsyncAcceptConnections), server);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Stops listening for new connections
|
||||||
|
/// </summary>
|
||||||
|
public void StopListen()
|
||||||
|
{
|
||||||
|
server.Close();
|
||||||
|
server = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Dictionary<int, TCPSocket> Clients = new Dictionary<int, TCPSocket>();
|
||||||
|
private int ClientCount = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public event TCPCommon.ClientConnectedDelegate ClientConnected;
|
||||||
|
public event TCPCommon.DataReceivedDelegate DataReceived;
|
||||||
|
public event TCPCommon.DataSentDelegate DataSent;
|
||||||
|
public event TCPCommon.CloseDelegate Close;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Async callback for new connections
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ar"></param>
|
||||||
|
private void AsyncAcceptConnections(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
int id = ClientCount++;
|
||||||
|
Socket oldserver = (Socket)ar.AsyncState;
|
||||||
|
Socket client = oldserver.EndAccept(ar);
|
||||||
|
TCPSocket S = new TCPSocket(id, client);
|
||||||
|
|
||||||
|
// Add to dictionary
|
||||||
|
Clients.Add(id, S);
|
||||||
|
|
||||||
|
// Add event handlers
|
||||||
|
S.Close += new TCPSocket.CloseDelegate(S_Close);
|
||||||
|
S.DataReceived += new TCPSocket.DataReceivedDelegate(S_DataReceived);
|
||||||
|
S.DataSent += new TCPSocket.DataSentDelegate(S_DataSent);
|
||||||
|
|
||||||
|
// Start it
|
||||||
|
S.Start();
|
||||||
|
|
||||||
|
Debug.WriteLine("Connection received: " + client.RemoteEndPoint.ToString());
|
||||||
|
|
||||||
|
// Fire Connected-event
|
||||||
|
if (ClientConnected != null)
|
||||||
|
ClientConnected(id, client.RemoteEndPoint);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_DataSent(int ID, int length)
|
||||||
|
{
|
||||||
|
if (DataSent != null)
|
||||||
|
DataSent(ID, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_DataReceived(int ID, byte[] data, int offset, int length)
|
||||||
|
{
|
||||||
|
if (DataReceived != null)
|
||||||
|
DataReceived(ID, data, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void S_Close(int ID)
|
||||||
|
{
|
||||||
|
if (Close != null)
|
||||||
|
Close(ID);
|
||||||
|
Clients.Remove(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Send(int clientID, byte[] data, int offset, int len)
|
||||||
|
{
|
||||||
|
Clients[clientID].Send(clientID, data, offset, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Net.Sockets;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common.TRPC
|
||||||
|
{
|
||||||
|
public class TCPSocket
|
||||||
|
{
|
||||||
|
|
||||||
|
public readonly Socket Client;
|
||||||
|
public readonly int ID;
|
||||||
|
|
||||||
|
public delegate void DataReceivedDelegate(int ID, byte[] data, int offset, int length);
|
||||||
|
public delegate void DataSentDelegate(int ID, int length);
|
||||||
|
public delegate void CloseDelegate(int ID);
|
||||||
|
public event DataReceivedDelegate DataReceived;
|
||||||
|
public event DataSentDelegate DataSent;
|
||||||
|
public event CloseDelegate Close;
|
||||||
|
|
||||||
|
private byte[] RecvQueue = new byte[4096];
|
||||||
|
private int RecvQueueSize = 4096;
|
||||||
|
|
||||||
|
public TCPSocket(int id, Socket client)
|
||||||
|
{
|
||||||
|
ID = id;
|
||||||
|
Client = client;
|
||||||
|
}
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
// Start listening
|
||||||
|
BeginReceive();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginReceive()
|
||||||
|
{
|
||||||
|
Client.BeginReceive(RecvQueue, 0, RecvQueueSize, SocketFlags.None, new AsyncCallback(asyncDataReceived), Client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback for successful receive (or connection close)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ar"></param>
|
||||||
|
private void asyncDataReceived(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
Socket client = (Socket)ar.AsyncState;
|
||||||
|
int recv = client.EndReceive(ar);
|
||||||
|
|
||||||
|
// Is connection closed?
|
||||||
|
if (recv == 0)
|
||||||
|
{
|
||||||
|
client.Close();
|
||||||
|
Close(ID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call receive event
|
||||||
|
DataReceived(ID, RecvQueue, 0, recv);
|
||||||
|
|
||||||
|
// Start new receive
|
||||||
|
BeginReceive();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void Send(int clientID, byte[] data, int offset, int len)
|
||||||
|
{
|
||||||
|
Client.BeginSend(data, offset, len, SocketFlags.None, new AsyncCallback(asyncDataSent), Client);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Callback for successful send
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ar"></param>
|
||||||
|
void asyncDataSent(IAsyncResult ar)
|
||||||
|
{
|
||||||
|
Socket client = (Socket)ar.AsyncState;
|
||||||
|
int sent = client.EndSend(ar);
|
||||||
|
DataSent(ID, sent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
Client.Close();
|
||||||
|
Close(ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,205 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Diagnostics;
|
||||||
|
using System.Text;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common.TRPC;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.Common
|
||||||
|
{
|
||||||
|
public class TRPC_Remote
|
||||||
|
{
|
||||||
|
public readonly int MaxQueueSize = 1024 * 10;
|
||||||
|
public readonly TCPCommon.ServerAndClientInterface TCPS;
|
||||||
|
|
||||||
|
public delegate void ReceiveCommandDelegate(int ID, string Command, params object[] p);
|
||||||
|
public event ReceiveCommandDelegate ReceiveCommand;
|
||||||
|
System.Collections.Generic.Dictionary<string, Type> TypeDictionary = new Dictionary<string, Type>();
|
||||||
|
Type[] Types =
|
||||||
|
{
|
||||||
|
typeof(System.String),
|
||||||
|
typeof(System.Int16),
|
||||||
|
typeof(System.Int32),
|
||||||
|
typeof(System.Int64),
|
||||||
|
typeof(System.Double),
|
||||||
|
typeof(System.Decimal),
|
||||||
|
typeof(System.Array),
|
||||||
|
typeof(LLUUID),
|
||||||
|
typeof(System.UInt16),
|
||||||
|
typeof(System.UInt32),
|
||||||
|
typeof(System.UInt64)
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Maybe we should move queue into TCPSocket so we won't have to keep one queue instance per connection
|
||||||
|
private System.Collections.Generic.Dictionary<int, InQueueStruct> InQueue = new Dictionary<int, InQueueStruct>();
|
||||||
|
private class InQueueStruct
|
||||||
|
{
|
||||||
|
public byte[] Queue;
|
||||||
|
public int QueueSize;
|
||||||
|
public object QueueLockObject = new object();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TRPC_Remote(TCPCommon.ServerAndClientInterface TCPClientOrServer)
|
||||||
|
{
|
||||||
|
TCPS = TCPClientOrServer;
|
||||||
|
TCPS.Close += new TCPCommon.CloseDelegate(TCPS_Close);
|
||||||
|
TCPS.ClientConnected += new TCPCommon.ClientConnectedDelegate(TCPS_ClientConnected);
|
||||||
|
TCPS.DataReceived += new TCPCommon.DataReceivedDelegate(TCPS_DataReceived);
|
||||||
|
//TCPS.StartListen();
|
||||||
|
|
||||||
|
// Make a lookup dictionary for types
|
||||||
|
foreach (Type t in Types)
|
||||||
|
{
|
||||||
|
TypeDictionary.Add(t.ToString(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPS_ClientConnected(int ID, System.Net.EndPoint Remote)
|
||||||
|
{
|
||||||
|
// Create a incoming queue for this connection
|
||||||
|
InQueueStruct iq = new InQueueStruct();
|
||||||
|
iq.Queue = new byte[MaxQueueSize];
|
||||||
|
iq.QueueSize = 0;
|
||||||
|
InQueue.Add(ID, iq);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPS_Close(int ID)
|
||||||
|
{
|
||||||
|
// Remove queue
|
||||||
|
InQueue.Remove(ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCPS_DataReceived(int ID, byte[] data, int offset, int length)
|
||||||
|
{
|
||||||
|
// Copy new data to incoming queue
|
||||||
|
lock (InQueue[ID].QueueLockObject)
|
||||||
|
{
|
||||||
|
Array.Copy(data, offset, InQueue[ID].Queue, InQueue[ID].QueueSize, length);
|
||||||
|
InQueue[ID].QueueSize += length;
|
||||||
|
|
||||||
|
// Process incoming queue
|
||||||
|
ProcessQueue(ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessQueue(int ID)
|
||||||
|
{
|
||||||
|
|
||||||
|
// This is just a temp implementation -- not so fast :)
|
||||||
|
|
||||||
|
InQueueStruct myIQS = InQueue[ID];
|
||||||
|
if (myIQS.QueueSize == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
string receivedData = Encoding.ASCII.GetString(myIQS.Queue, 0, myIQS.QueueSize);
|
||||||
|
Debug.WriteLine("RAW: " + receivedData);
|
||||||
|
|
||||||
|
|
||||||
|
byte newLine = 10;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
bool ShouldProcess = false;
|
||||||
|
int lineEndPos = 0;
|
||||||
|
|
||||||
|
// Look for newline
|
||||||
|
for (int i = 0; i < myIQS.QueueSize; i++)
|
||||||
|
{
|
||||||
|
if (myIQS.Queue[i] == newLine)
|
||||||
|
{
|
||||||
|
ShouldProcess = true;
|
||||||
|
lineEndPos = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process it?
|
||||||
|
if (!ShouldProcess)
|
||||||
|
return;
|
||||||
|
// Yes
|
||||||
|
string cmdLine = Encoding.ASCII.GetString(myIQS.Queue, 0, lineEndPos);
|
||||||
|
Debug.WriteLine("Command: " + cmdLine);
|
||||||
|
|
||||||
|
// Fix remaining queue in an inefficient way
|
||||||
|
byte[] newQueue = new byte[MaxQueueSize];
|
||||||
|
Array.Copy(myIQS.Queue, lineEndPos, newQueue, 0, myIQS.QueueSize - lineEndPos);
|
||||||
|
myIQS.Queue = newQueue;
|
||||||
|
myIQS.QueueSize -= (lineEndPos + 1);
|
||||||
|
|
||||||
|
// Now back to the command
|
||||||
|
string[] parts = cmdLine.Split(',');
|
||||||
|
if (parts.Length > 0)
|
||||||
|
{
|
||||||
|
string cmd = parts[0];
|
||||||
|
int paramCount = parts.Length - 1;
|
||||||
|
object[] param = null;
|
||||||
|
|
||||||
|
if (paramCount > 0)
|
||||||
|
{
|
||||||
|
// Process all parameters (decoding them from URL encoding)
|
||||||
|
param = new object[paramCount];
|
||||||
|
for (int i = 1; i < parts.Length; i++)
|
||||||
|
{
|
||||||
|
string[] spl;
|
||||||
|
spl = System.Web.HttpUtility.UrlDecode(parts[i]).Split('|');
|
||||||
|
string t = spl[0];
|
||||||
|
param[i - 1] = Convert.ChangeType(spl[1], TypeLookup(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveCommand(ID, cmd, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Type TypeLookup(string t)
|
||||||
|
{
|
||||||
|
Type ret = TypeDictionary[t];
|
||||||
|
if (ret != null)
|
||||||
|
return ret;
|
||||||
|
return typeof(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendCommand(int ID, string Command, params object[] p)
|
||||||
|
{
|
||||||
|
// Call PacketFactory to have it create a packet for us
|
||||||
|
|
||||||
|
//string[] tmpP = new string[p.Length];
|
||||||
|
string tmpStr = Command;
|
||||||
|
for (int i = 0; i < p.Length; i++)
|
||||||
|
{
|
||||||
|
tmpStr += "," + p[i].GetType().ToString() + "|" + System.Web.HttpUtility.UrlEncode(p[i].ToString()); // .Replace(",", "%44")
|
||||||
|
}
|
||||||
|
tmpStr += "\n";
|
||||||
|
byte[] byteData = Encoding.ASCII.GetBytes(tmpStr);
|
||||||
|
TCPS.Send(ID, byteData, 0, byteData.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,160 +1,441 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.CodeDom.Compiler;
|
using System.CodeDom.Compiler;
|
||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Globalization;
|
||||||
using Microsoft.CSharp;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
|
using Microsoft.CSharp;
|
||||||
{
|
using Microsoft.VisualBasic;
|
||||||
public class Compiler
|
using Microsoft.JScript;
|
||||||
{
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
|
||||||
// * Uses "LSL2Converter" to convert LSL to C# if necessary.
|
{
|
||||||
// * Compiles C#-code into an assembly
|
public class Compiler
|
||||||
// * Returns assembly name ready for AppDomain load.
|
{
|
||||||
//
|
// * Uses "LSL2Converter" to convert LSL to C# if necessary.
|
||||||
// Assembly is compiled using LSL_BaseClass as base. Look at debug C# code file created when LSL script is compiled for full details.
|
// * Compiles C#-code into an assembly
|
||||||
//
|
// * Returns assembly name ready for AppDomain load.
|
||||||
|
//
|
||||||
private LSL2CSConverter LSL_Converter = new LSL2CSConverter();
|
// Assembly is compiled using LSL_BaseClass as base. Look at debug C# code file created when LSL script is compiled for full details.
|
||||||
private CSharpCodeProvider codeProvider = new CSharpCodeProvider();
|
//
|
||||||
private static UInt64 scriptCompileCounter = 0;
|
|
||||||
|
internal enum enumCompileType
|
||||||
private static int instanceID = new Random().Next(0, int.MaxValue);
|
{
|
||||||
// Implemented due to peer preassure --- will cause garbage in ScriptEngines folder ;)
|
lsl = 0,
|
||||||
|
cs = 1,
|
||||||
//private ICodeCompiler icc = codeProvider.CreateCompiler();
|
vb = 2,
|
||||||
public string CompileFromFile(string LSOFileName)
|
js = 3
|
||||||
{
|
}
|
||||||
switch (Path.GetExtension(LSOFileName).ToLower())
|
|
||||||
{
|
/// <summary>
|
||||||
case ".txt":
|
/// This contains number of lines WE use for header when compiling script. User will get error in line x-LinesToRemoveOnError when error occurs.
|
||||||
case ".lsl":
|
/// </summary>
|
||||||
Common.SendToDebug("Source code is LSL, converting to CS");
|
public int LinesToRemoveOnError = 3;
|
||||||
return CompileFromLSLText(File.ReadAllText(LSOFileName));
|
private enumCompileType DefaultCompileLanguage;
|
||||||
case ".cs":
|
private bool WriteScriptSourceToDebugFile;
|
||||||
Common.SendToDebug("Source code is CS");
|
private bool CompileWithDebugInformation;
|
||||||
return CompileFromCSText(File.ReadAllText(LSOFileName));
|
private bool CleanUpOldScriptsOnStartup;
|
||||||
default:
|
private System.Collections.Generic.Dictionary<string, Boolean> AllowedCompilers = new Dictionary<string, bool>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
throw new Exception("Unknown script type.");
|
private System.Collections.Generic.Dictionary<string, enumCompileType> LanguageMapping = new Dictionary<string, enumCompileType>(StringComparer.CurrentCultureIgnoreCase);
|
||||||
}
|
|
||||||
}
|
private string FilePrefix;
|
||||||
|
private string ScriptEnginesPath = "ScriptEngines";
|
||||||
/// <summary>
|
|
||||||
/// Converts script from LSL to CS and calls CompileFromCSText
|
private static LSL2CSConverter LSL_Converter = new LSL2CSConverter();
|
||||||
/// </summary>
|
private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
|
||||||
/// <param name="Script">LSL script</param>
|
private static VBCodeProvider VBcodeProvider = new VBCodeProvider();
|
||||||
/// <returns>Filename to .dll assembly</returns>
|
private static JScriptCodeProvider JScodeProvider = new JScriptCodeProvider();
|
||||||
public string CompileFromLSLText(string Script)
|
|
||||||
{
|
private static int instanceID = new Random().Next(0, int.MaxValue); // Unique number to use on our compiled files
|
||||||
if (Script.Substring(0, 4).ToLower() == "//c#")
|
private static UInt64 scriptCompileCounter = 0; // And a counter
|
||||||
{
|
|
||||||
return CompileFromCSText(Script);
|
public Common.ScriptEngineBase.ScriptEngine m_scriptEngine;
|
||||||
}
|
public Compiler(Common.ScriptEngineBase.ScriptEngine scriptEngine)
|
||||||
else
|
{
|
||||||
{
|
m_scriptEngine = scriptEngine;
|
||||||
return CompileFromCSText(LSL_Converter.Convert(Script));
|
ReadConfig();
|
||||||
}
|
}
|
||||||
}
|
public bool in_startup = true;
|
||||||
|
public void ReadConfig()
|
||||||
/// <summary>
|
{
|
||||||
/// Compile CS script to .Net assembly (.dll)
|
|
||||||
/// </summary>
|
// Get some config
|
||||||
/// <param name="Script">CS script</param>
|
WriteScriptSourceToDebugFile = m_scriptEngine.ScriptConfigSource.GetBoolean("WriteScriptSourceToDebugFile", true);
|
||||||
/// <returns>Filename to .dll assembly</returns>
|
CompileWithDebugInformation = m_scriptEngine.ScriptConfigSource.GetBoolean("CompileWithDebugInformation", true);
|
||||||
public string CompileFromCSText(string Script)
|
CleanUpOldScriptsOnStartup = m_scriptEngine.ScriptConfigSource.GetBoolean("CleanUpOldScriptsOnStartup", true);
|
||||||
{
|
|
||||||
// Output assembly name
|
// Get file prefix from scriptengine name and make it file system safe:
|
||||||
scriptCompileCounter++;
|
FilePrefix = m_scriptEngine.ScriptEngineName;
|
||||||
string OutFile =
|
foreach (char c in Path.GetInvalidFileNameChars())
|
||||||
Path.Combine("ScriptEngines",
|
{
|
||||||
"DotNetScript_" + instanceID.ToString() + "_" + scriptCompileCounter.ToString() + ".dll");
|
FilePrefix = FilePrefix.Replace(c, '_');
|
||||||
try
|
}
|
||||||
{
|
|
||||||
File.Delete(OutFile);
|
// First time we start? Delete old files
|
||||||
}
|
if (in_startup)
|
||||||
catch (Exception e)
|
{
|
||||||
{
|
in_startup = false;
|
||||||
Console.WriteLine("Exception attempting to delete old compiled script: " + e.ToString());
|
DeleteOldFiles();
|
||||||
}
|
}
|
||||||
//string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
|
|
||||||
|
// Map name and enum type of our supported languages
|
||||||
// DEBUG - write source to disk
|
LanguageMapping.Add(enumCompileType.cs.ToString(), enumCompileType.cs);
|
||||||
try
|
LanguageMapping.Add(enumCompileType.vb.ToString(), enumCompileType.vb);
|
||||||
{
|
LanguageMapping.Add(enumCompileType.lsl.ToString(), enumCompileType.lsl);
|
||||||
File.WriteAllText(
|
LanguageMapping.Add(enumCompileType.js.ToString(), enumCompileType.js);
|
||||||
Path.Combine("ScriptEngines", "debug_" + Path.GetFileNameWithoutExtension(OutFile) + ".cs"), Script);
|
|
||||||
}
|
// Allowed compilers
|
||||||
catch
|
string allowComp = m_scriptEngine.ScriptConfigSource.GetString("AllowedCompilers", "lsl,cs,vb,js");
|
||||||
{
|
AllowedCompilers.Clear();
|
||||||
}
|
|
||||||
|
#if DEBUG
|
||||||
// Do actual compile
|
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Allowed languages: " + allowComp);
|
||||||
CompilerParameters parameters = new CompilerParameters();
|
#endif
|
||||||
parameters.IncludeDebugInformation = true;
|
|
||||||
// Add all available assemblies
|
|
||||||
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
|
foreach (string strl in allowComp.Split(','))
|
||||||
{
|
{
|
||||||
//Console.WriteLine("Adding assembly: " + asm.Location);
|
string strlan = strl.Trim(" \t".ToCharArray()).ToLower();
|
||||||
//parameters.ReferencedAssemblies.Add(asm.Location);
|
if (!LanguageMapping.ContainsKey(strlan))
|
||||||
}
|
{
|
||||||
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Config error. Compiler is unable to recognize language type \"" + strlan + "\" specified in \"AllowedCompilers\".");
|
||||||
string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
|
}
|
||||||
string rootPathSE = Path.GetDirectoryName(GetType().Assembly.Location);
|
else
|
||||||
//Console.WriteLine("Assembly location: " + rootPath);
|
{
|
||||||
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Common.dll"));
|
#if DEBUG
|
||||||
parameters.ReferencedAssemblies.Add(Path.Combine(rootPathSE, "OpenSim.Region.ScriptEngine.DotNetEngine.dll"));
|
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Config OK. Compiler recognized language type \"" + strlan + "\" specified in \"AllowedCompilers\".");
|
||||||
|
#endif
|
||||||
//parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment");
|
}
|
||||||
parameters.GenerateExecutable = false;
|
AllowedCompilers.Add(strlan, true);
|
||||||
parameters.OutputAssembly = OutFile;
|
}
|
||||||
parameters.IncludeDebugInformation = false;
|
if (AllowedCompilers.Count == 0)
|
||||||
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, Script);
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Config error. Compiler could not recognize any language in \"AllowedCompilers\". Scripts will not be executed!");
|
||||||
|
|
||||||
// Go through errors
|
// Default language
|
||||||
// TODO: Return errors to user somehow
|
string defaultCompileLanguage = m_scriptEngine.ScriptConfigSource.GetString("DefaultCompileLanguage", "lsl").ToLower();
|
||||||
if (results.Errors.Count > 0)
|
|
||||||
{
|
// Is this language recognized at all?
|
||||||
string errtext = "";
|
if (!LanguageMapping.ContainsKey(defaultCompileLanguage))
|
||||||
foreach (CompilerError CompErr in results.Errors)
|
{
|
||||||
{
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: " +
|
||||||
errtext += "Line number " + (CompErr.Line - 1) +
|
"Config error. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is not recognized as a valid language. Changing default to: \"lsl\".");
|
||||||
", Error Number: " + CompErr.ErrorNumber +
|
defaultCompileLanguage = "lsl";
|
||||||
", '" + CompErr.ErrorText + "'\r\n";
|
}
|
||||||
}
|
|
||||||
throw new Exception(errtext);
|
// Is this language in allow-list?
|
||||||
}
|
if (!AllowedCompilers.ContainsKey(defaultCompileLanguage))
|
||||||
|
{
|
||||||
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: " +
|
||||||
return OutFile;
|
"Config error. Default language \"" + defaultCompileLanguage + "\"specified in \"DefaultCompileLanguage\" is not in list of \"AllowedCompilers\". Scripts may not be executed!");
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
|
#if DEBUG
|
||||||
|
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: " +
|
||||||
|
"Config OK. Default language \"" + defaultCompileLanguage + "\" specified in \"DefaultCompileLanguage\" is recognized as a valid language.");
|
||||||
|
#endif
|
||||||
|
// LANGUAGE IS IN ALLOW-LIST
|
||||||
|
DefaultCompileLanguage = LanguageMapping[defaultCompileLanguage];
|
||||||
|
}
|
||||||
|
|
||||||
|
// We now have an allow-list, a mapping list, and a default language
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Delete old script files
|
||||||
|
/// </summary>
|
||||||
|
private void DeleteOldFiles()
|
||||||
|
{
|
||||||
|
|
||||||
|
// CREATE FOLDER IF IT DOESNT EXIST
|
||||||
|
if (!Directory.Exists(ScriptEnginesPath))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(ScriptEnginesPath);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception trying to create ScriptEngine directory \"" + ScriptEnginesPath + "\": " + ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string file in Directory.GetFiles(ScriptEnginesPath))
|
||||||
|
{
|
||||||
|
//m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: FILE FOUND: " + file);
|
||||||
|
|
||||||
|
if (file.ToLower().StartsWith(FilePrefix + "_compiled_") ||
|
||||||
|
file.ToLower().StartsWith(FilePrefix + "_source_"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(file);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception trying delete old script file \"" + file + "\": " + ex.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
////private ICodeCompiler icc = codeProvider.CreateCompiler();
|
||||||
|
//public string CompileFromFile(string LSOFileName)
|
||||||
|
//{
|
||||||
|
// switch (Path.GetExtension(LSOFileName).ToLower())
|
||||||
|
// {
|
||||||
|
// case ".txt":
|
||||||
|
// case ".lsl":
|
||||||
|
// Common.ScriptEngineBase.Common.SendToDebug("Source code is LSL, converting to CS");
|
||||||
|
// return CompileFromLSLText(File.ReadAllText(LSOFileName));
|
||||||
|
// case ".cs":
|
||||||
|
// Common.ScriptEngineBase.Common.SendToDebug("Source code is CS");
|
||||||
|
// return CompileFromCSText(File.ReadAllText(LSOFileName));
|
||||||
|
// default:
|
||||||
|
// throw new Exception("Unknown script type.");
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts script from LSL to CS and calls CompileFromCSText
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Script">LSL script</param>
|
||||||
|
/// <returns>Filename to .dll assembly</returns>
|
||||||
|
public string PerformScriptCompile(string Script)
|
||||||
|
{
|
||||||
|
enumCompileType l = DefaultCompileLanguage;
|
||||||
|
|
||||||
|
|
||||||
|
if (Script.StartsWith("//c#", true, CultureInfo.InvariantCulture))
|
||||||
|
l = enumCompileType.cs;
|
||||||
|
if (Script.StartsWith("//vb", true, CultureInfo.InvariantCulture))
|
||||||
|
{
|
||||||
|
l = enumCompileType.vb;
|
||||||
|
// We need to remove //vb, it won't compile with that
|
||||||
|
|
||||||
|
Script = Script.Substring(4, Script.Length - 4);
|
||||||
|
}
|
||||||
|
if (Script.StartsWith("//lsl", true, CultureInfo.InvariantCulture))
|
||||||
|
l = enumCompileType.lsl;
|
||||||
|
|
||||||
|
if (Script.StartsWith("//js", true, CultureInfo.InvariantCulture))
|
||||||
|
l = enumCompileType.js;
|
||||||
|
|
||||||
|
if (!AllowedCompilers.ContainsKey(l.ToString()))
|
||||||
|
{
|
||||||
|
// Not allowed to compile to this language!
|
||||||
|
string errtext = String.Empty;
|
||||||
|
errtext += "The compiler for language \"" + l.ToString() + "\" is not in list of allowed compilers. Script will not be executed!";
|
||||||
|
throw new Exception(errtext);
|
||||||
|
}
|
||||||
|
|
||||||
|
string compileScript = Script;
|
||||||
|
|
||||||
|
if (l == enumCompileType.lsl)
|
||||||
|
{
|
||||||
|
// Its LSL, convert it to C#
|
||||||
|
compileScript = LSL_Converter.Convert(Script);
|
||||||
|
l = enumCompileType.cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (l)
|
||||||
|
{
|
||||||
|
case enumCompileType.cs:
|
||||||
|
compileScript = CreateCSCompilerScript(compileScript);
|
||||||
|
break;
|
||||||
|
case enumCompileType.vb:
|
||||||
|
compileScript = CreateVBCompilerScript(compileScript);
|
||||||
|
break;
|
||||||
|
case enumCompileType.js:
|
||||||
|
compileScript = CreateJSCompilerScript(compileScript);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return CompileFromDotNetText(compileScript, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CreateJSCompilerScript(string compileScript)
|
||||||
|
{
|
||||||
|
compileScript = String.Empty +
|
||||||
|
"import OpenSim.Region.ScriptEngine.Common; import System.Collections.Generic;\r\n" +
|
||||||
|
"package SecondLife {\r\n" +
|
||||||
|
"class Script extends OpenSim.Region.ScriptEngine.Common.LSL_BaseClass { \r\n" +
|
||||||
|
compileScript +
|
||||||
|
"} }\r\n";
|
||||||
|
return compileScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CreateCSCompilerScript(string compileScript)
|
||||||
|
{
|
||||||
|
compileScript = String.Empty +
|
||||||
|
"using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;\r\n" +
|
||||||
|
String.Empty + "namespace SecondLife { " +
|
||||||
|
String.Empty + "public class Script : OpenSim.Region.ScriptEngine.Common.LSL_BaseClass { \r\n" +
|
||||||
|
@"public Script() { } " +
|
||||||
|
compileScript +
|
||||||
|
"} }\r\n";
|
||||||
|
return compileScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CreateVBCompilerScript(string compileScript)
|
||||||
|
{
|
||||||
|
compileScript = String.Empty +
|
||||||
|
"Imports OpenSim.Region.ScriptEngine.Common: Imports System.Collections.Generic: " +
|
||||||
|
String.Empty + "NameSpace SecondLife:" +
|
||||||
|
String.Empty + "Public Class Script: Inherits OpenSim.Region.ScriptEngine.Common.LSL_BaseClass: " +
|
||||||
|
"\r\nPublic Sub New()\r\nEnd Sub: " +
|
||||||
|
compileScript +
|
||||||
|
":End Class :End Namespace\r\n";
|
||||||
|
return compileScript;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compile .NET script to .Net assembly (.dll)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Script">CS script</param>
|
||||||
|
/// <returns>Filename to .dll assembly</returns>
|
||||||
|
internal string CompileFromDotNetText(string Script, enumCompileType lang)
|
||||||
|
{
|
||||||
|
string ext = "." + lang.ToString();
|
||||||
|
|
||||||
|
// Output assembly name
|
||||||
|
scriptCompileCounter++;
|
||||||
|
string OutFile =
|
||||||
|
Path.Combine("ScriptEngines",
|
||||||
|
FilePrefix + "_compiled_" + instanceID.ToString() + "_" + scriptCompileCounter.ToString() + ".dll");
|
||||||
|
#if DEBUG
|
||||||
|
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Starting compile of \"" + OutFile + "\".");
|
||||||
|
#endif
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.Delete(OutFile);
|
||||||
|
}
|
||||||
|
catch (Exception e) // NOTLEGIT - Should be just catching FileIOException
|
||||||
|
{
|
||||||
|
//m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString());
|
||||||
|
throw new Exception("Unable to delete old existring script-file before writing new. Compile aborted: " + e.ToString());
|
||||||
|
}
|
||||||
|
//string OutFile = Path.Combine("ScriptEngines", "SecondLife.Script.dll");
|
||||||
|
|
||||||
|
// DEBUG - write source to disk
|
||||||
|
if (WriteScriptSourceToDebugFile)
|
||||||
|
{
|
||||||
|
string srcFileName = FilePrefix + "_source_" + Path.GetFileNameWithoutExtension(OutFile) + ext;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
File.WriteAllText(
|
||||||
|
Path.Combine("ScriptEngines", srcFileName),
|
||||||
|
Script);
|
||||||
|
}
|
||||||
|
catch (Exception ex) // NOTLEGIT - Should be just catching FileIOException
|
||||||
|
{
|
||||||
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception while trying to write script source to file \"" + srcFileName + "\": " + ex.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do actual compile
|
||||||
|
CompilerParameters parameters = new CompilerParameters();
|
||||||
|
|
||||||
|
parameters.IncludeDebugInformation = true;
|
||||||
|
|
||||||
|
// Add all available assemblies
|
||||||
|
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Adding assembly: " + asm.Location);
|
||||||
|
//parameters.ReferencedAssemblies.Add(asm.Location);
|
||||||
|
}
|
||||||
|
|
||||||
|
string rootPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
|
||||||
|
string rootPathSE = Path.GetDirectoryName(GetType().Assembly.Location);
|
||||||
|
//Console.WriteLine("Assembly location: " + rootPath);
|
||||||
|
parameters.ReferencedAssemblies.Add(Path.Combine(rootPath, "OpenSim.Region.ScriptEngine.Common.dll"));
|
||||||
|
parameters.ReferencedAssemblies.Add(Path.Combine(rootPathSE, "OpenSim.Region.ScriptEngine.DotNetEngine.dll"));
|
||||||
|
|
||||||
|
//parameters.ReferencedAssemblies.Add("OpenSim.Region.Environment");
|
||||||
|
parameters.GenerateExecutable = false;
|
||||||
|
parameters.OutputAssembly = OutFile;
|
||||||
|
parameters.IncludeDebugInformation = CompileWithDebugInformation;
|
||||||
|
//parameters.WarningLevel = 1; // Should be 4?
|
||||||
|
parameters.TreatWarningsAsErrors = false;
|
||||||
|
|
||||||
|
CompilerResults results;
|
||||||
|
switch (lang)
|
||||||
|
{
|
||||||
|
case enumCompileType.vb:
|
||||||
|
results = VBcodeProvider.CompileAssemblyFromSource(parameters, Script);
|
||||||
|
break;
|
||||||
|
case enumCompileType.cs:
|
||||||
|
results = CScodeProvider.CompileAssemblyFromSource(parameters, Script);
|
||||||
|
break;
|
||||||
|
case enumCompileType.js:
|
||||||
|
results = JScodeProvider.CompileAssemblyFromSource(parameters, Script);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Compiler is not able to recongnize language type \"" + lang.ToString() + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check result
|
||||||
|
// Go through errors
|
||||||
|
|
||||||
|
//
|
||||||
|
// WARNINGS AND ERRORS
|
||||||
|
//
|
||||||
|
if (results.Errors.Count > 0)
|
||||||
|
{
|
||||||
|
string errtext = String.Empty;
|
||||||
|
foreach (CompilerError CompErr in results.Errors)
|
||||||
|
{
|
||||||
|
errtext += "Line number " + (CompErr.Line - LinesToRemoveOnError) +
|
||||||
|
", Error Number: " + CompErr.ErrorNumber +
|
||||||
|
", '" + CompErr.ErrorText + "'\r\n";
|
||||||
|
}
|
||||||
|
if (!File.Exists(OutFile))
|
||||||
|
{
|
||||||
|
throw new Exception(errtext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// NO ERRORS, BUT NO COMPILED FILE
|
||||||
|
//
|
||||||
|
if (!File.Exists(OutFile))
|
||||||
|
{
|
||||||
|
string errtext = String.Empty;
|
||||||
|
errtext += "No compile error. But not able to locate compiled file.";
|
||||||
|
throw new Exception(errtext);
|
||||||
|
}
|
||||||
|
return OutFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,327 +1,311 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System;
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
|
|
||||||
{
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
|
||||||
public class LSL2CSConverter
|
{
|
||||||
{
|
public class LSL2CSConverter
|
||||||
|
{
|
||||||
|
|
||||||
// Uses regex to convert LSL code to C# code.
|
|
||||||
|
// Uses regex to convert LSL code to C# code.
|
||||||
//private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled);
|
|
||||||
private Dictionary<string, string> dataTypes = new Dictionary<string, string>();
|
//private Regex rnw = new Regex(@"[a-zA-Z0-9_\-]", RegexOptions.Compiled);
|
||||||
private Dictionary<string, string> quotes = new Dictionary<string, string>();
|
private Dictionary<string, string> dataTypes = new Dictionary<string, string>();
|
||||||
|
private Dictionary<string, string> quotes = new Dictionary<string, string>();
|
||||||
public LSL2CSConverter()
|
|
||||||
{
|
public LSL2CSConverter()
|
||||||
// Only the types we need to convert
|
{
|
||||||
dataTypes.Add("void", "void");
|
// Only the types we need to convert
|
||||||
dataTypes.Add("integer", "int");
|
dataTypes.Add("void", "void");
|
||||||
dataTypes.Add("float", "double");
|
dataTypes.Add("integer", "int");
|
||||||
dataTypes.Add("string", "string");
|
dataTypes.Add("float", "double");
|
||||||
dataTypes.Add("key", "string");
|
dataTypes.Add("string", "string");
|
||||||
dataTypes.Add("vector", "LSL_Types.Vector3");
|
dataTypes.Add("key", "string");
|
||||||
dataTypes.Add("rotation", "LSL_Types.Quaternion");
|
dataTypes.Add("vector", "LSL_Types.Vector3");
|
||||||
dataTypes.Add("list", "LSL_Types.list");
|
dataTypes.Add("rotation", "LSL_Types.Quaternion");
|
||||||
dataTypes.Add("null", "null");
|
dataTypes.Add("list", "LSL_Types.list");
|
||||||
}
|
dataTypes.Add("null", "null");
|
||||||
|
}
|
||||||
public string Convert(string Script)
|
|
||||||
{
|
public string Convert(string Script)
|
||||||
quotes.Clear();
|
{
|
||||||
string Return = "";
|
quotes.Clear();
|
||||||
Script = " \r\n" + Script;
|
string Return = System.String.Empty;
|
||||||
|
Script = " \r\n" + Script;
|
||||||
//
|
|
||||||
// Prepare script for processing
|
//
|
||||||
//
|
// Prepare script for processing
|
||||||
|
//
|
||||||
// Clean up linebreaks
|
|
||||||
Script = Regex.Replace(Script, @"\r\n", "\n");
|
// Clean up linebreaks
|
||||||
Script = Regex.Replace(Script, @"\n", "\r\n");
|
Script = Regex.Replace(Script, @"\r\n", "\n");
|
||||||
|
Script = Regex.Replace(Script, @"\n", "\r\n");
|
||||||
|
|
||||||
// QUOTE REPLACEMENT
|
|
||||||
// temporarily replace quotes so we can work our magic on the script without
|
// QUOTE REPLACEMENT
|
||||||
// always considering if we are inside our outside ""'s
|
// temporarily replace quotes so we can work our magic on the script without
|
||||||
string _Script = "";
|
// always considering if we are inside our outside quotes's
|
||||||
string C;
|
// TODO: Does this work on half-quotes in strings? ;)
|
||||||
bool in_quote = false;
|
string _Script = System.String.Empty;
|
||||||
bool quote_replaced = false;
|
string C;
|
||||||
string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_";
|
bool in_quote = false;
|
||||||
string quote = "";
|
bool quote_replaced = false;
|
||||||
bool last_was_escape = false;
|
string quote_replacement_string = "Q_U_O_T_E_REPLACEMENT_";
|
||||||
int quote_replaced_count = 0;
|
string quote = System.String.Empty;
|
||||||
for (int p = 0; p < Script.Length; p++)
|
bool last_was_escape = false;
|
||||||
{
|
int quote_replaced_count = 0;
|
||||||
C = Script.Substring(p, 1);
|
for (int p = 0; p < Script.Length; p++)
|
||||||
while (true)
|
{
|
||||||
{
|
C = Script.Substring(p, 1);
|
||||||
// found " and last was not \ so this is not an escaped \"
|
while (true)
|
||||||
if (C == "\"" && last_was_escape == false)
|
{
|
||||||
{
|
// found " and last was not \ so this is not an escaped \"
|
||||||
// Toggle inside/outside quote
|
if (C == "\"" && last_was_escape == false)
|
||||||
in_quote = !in_quote;
|
{
|
||||||
if (in_quote)
|
// Toggle inside/outside quote
|
||||||
{
|
in_quote = !in_quote;
|
||||||
quote_replaced_count++;
|
if (in_quote)
|
||||||
}
|
{
|
||||||
else
|
quote_replaced_count++;
|
||||||
{
|
}
|
||||||
if (quote == "")
|
else
|
||||||
{
|
{
|
||||||
// We didn't replace quote, probably because of empty string?
|
if (quote == System.String.Empty)
|
||||||
_Script += quote_replacement_string +
|
{
|
||||||
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
|
// We didn't replace quote, probably because of empty string?
|
||||||
}
|
_Script += quote_replacement_string +
|
||||||
// We just left a quote
|
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
|
||||||
quotes.Add(
|
}
|
||||||
quote_replacement_string +
|
// We just left a quote
|
||||||
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote);
|
quotes.Add(
|
||||||
quote = "";
|
quote_replacement_string +
|
||||||
}
|
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]), quote);
|
||||||
break;
|
quote = System.String.Empty;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
if (!in_quote)
|
}
|
||||||
{
|
|
||||||
// We are not inside a quote
|
if (!in_quote)
|
||||||
quote_replaced = false;
|
{
|
||||||
}
|
// We are not inside a quote
|
||||||
else
|
quote_replaced = false;
|
||||||
{
|
}
|
||||||
// We are inside a quote
|
else
|
||||||
if (!quote_replaced)
|
{
|
||||||
{
|
// We are inside a quote
|
||||||
// Replace quote
|
if (!quote_replaced)
|
||||||
_Script += quote_replacement_string +
|
{
|
||||||
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
|
// Replace quote
|
||||||
quote_replaced = true;
|
_Script += quote_replacement_string +
|
||||||
}
|
quote_replaced_count.ToString().PadLeft(5, "0".ToCharArray()[0]);
|
||||||
quote += C;
|
quote_replaced = true;
|
||||||
break;
|
}
|
||||||
}
|
quote += C;
|
||||||
_Script += C;
|
break;
|
||||||
break;
|
}
|
||||||
}
|
_Script += C;
|
||||||
last_was_escape = false;
|
break;
|
||||||
if (C == @"\")
|
}
|
||||||
{
|
last_was_escape = false;
|
||||||
last_was_escape = true;
|
if (C == @"\")
|
||||||
}
|
{
|
||||||
}
|
last_was_escape = true;
|
||||||
Script = _Script;
|
}
|
||||||
//
|
}
|
||||||
// END OF QUOTE REPLACEMENT
|
Script = _Script;
|
||||||
//
|
//
|
||||||
|
// END OF QUOTE REPLACEMENT
|
||||||
|
//
|
||||||
//
|
|
||||||
// PROCESS STATES
|
|
||||||
// Remove state definitions and add state names to start of each event within state
|
//
|
||||||
//
|
// PROCESS STATES
|
||||||
int ilevel = 0;
|
// Remove state definitions and add state names to start of each event within state
|
||||||
int lastlevel = 0;
|
//
|
||||||
string ret = "";
|
int ilevel = 0;
|
||||||
string cache = "";
|
int lastlevel = 0;
|
||||||
bool in_state = false;
|
string ret = System.String.Empty;
|
||||||
string current_statename = "";
|
string cache = System.String.Empty;
|
||||||
for (int p = 0; p < Script.Length; p++)
|
bool in_state = false;
|
||||||
{
|
string current_statename = System.String.Empty;
|
||||||
C = Script.Substring(p, 1);
|
for (int p = 0; p < Script.Length; p++)
|
||||||
while (true)
|
{
|
||||||
{
|
C = Script.Substring(p, 1);
|
||||||
// inc / dec level
|
while (true)
|
||||||
if (C == @"{")
|
{
|
||||||
ilevel++;
|
// inc / dec level
|
||||||
if (C == @"}")
|
if (C == @"{")
|
||||||
ilevel--;
|
ilevel++;
|
||||||
if (ilevel < 0)
|
if (C == @"}")
|
||||||
ilevel = 0;
|
ilevel--;
|
||||||
cache += C;
|
if (ilevel < 0)
|
||||||
|
ilevel = 0;
|
||||||
// if level == 0, add to return
|
cache += C;
|
||||||
if (ilevel == 1 && lastlevel == 0)
|
|
||||||
{
|
// if level == 0, add to return
|
||||||
// 0 => 1: Get last
|
if (ilevel == 1 && lastlevel == 0)
|
||||||
Match m =
|
{
|
||||||
Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{",
|
// 0 => 1: Get last
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Match m =
|
||||||
|
Regex.Match(cache, @"(?![a-zA-Z_]+)\s*([a-zA-Z_]+)[^a-zA-Z_\(\)]*{",
|
||||||
in_state = false;
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
if (m.Success)
|
|
||||||
{
|
in_state = false;
|
||||||
// Go back to level 0, this is not a state
|
if (m.Success)
|
||||||
in_state = true;
|
{
|
||||||
current_statename = m.Groups[1].Captures[0].Value;
|
// Go back to level 0, this is not a state
|
||||||
//Console.WriteLine("Current statename: " + current_statename);
|
in_state = true;
|
||||||
cache =
|
current_statename = m.Groups[1].Captures[0].Value;
|
||||||
Regex.Replace(cache,
|
//Console.WriteLine("Current statename: " + current_statename);
|
||||||
@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"([a-zA-Z_]+)(?<s2>[^a-zA-Z_\(\)]*){",
|
cache =
|
||||||
"${s1}${s2}",
|
Regex.Replace(cache,
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
@"(?<s1>(?![a-zA-Z_]+)\s*)" + @"([a-zA-Z_]+)(?<s2>[^a-zA-Z_\(\)]*){",
|
||||||
}
|
"${s1}${s2}",
|
||||||
ret += cache;
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
cache = "";
|
}
|
||||||
}
|
ret += cache;
|
||||||
if (ilevel == 0 && lastlevel == 1)
|
cache = String.Empty;
|
||||||
{
|
}
|
||||||
// 1 => 0: Remove last }
|
if (ilevel == 0 && lastlevel == 1)
|
||||||
if (in_state == true)
|
{
|
||||||
{
|
// 1 => 0: Remove last }
|
||||||
cache = cache.Remove(cache.Length - 1, 1);
|
if (in_state == true)
|
||||||
//cache = Regex.Replace(cache, "}$", "", RegexOptions.Multiline | RegexOptions.Singleline);
|
{
|
||||||
|
cache = cache.Remove(cache.Length - 1, 1);
|
||||||
//Replace function names
|
//cache = Regex.Replace(cache, "}$", String.Empty, RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
// void dataserver(key query_id, string data) {
|
|
||||||
//cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "<STATE>" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
//Replace function names
|
||||||
//Console.WriteLine("Replacing using statename: " + current_statename);
|
// void dataserver(key query_id, string data) {
|
||||||
cache =
|
//cache = Regex.Replace(cache, @"([^a-zA-Z_]\s*)((?!if|switch|for)[a-zA-Z_]+\s*\([^\)]*\)[^{]*{)", "$1" + "<STATE>" + "$2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
Regex.Replace(cache,
|
//Console.WriteLine("Replacing using statename: " + current_statename);
|
||||||
@"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
|
cache =
|
||||||
@"$1public " + current_statename + "_event_$2",
|
Regex.Replace(cache,
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
@"^(\s*)((?!(if|switch|for|while)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
|
||||||
}
|
@"$1public " + current_statename + "_event_$2",
|
||||||
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
ret += cache;
|
}
|
||||||
cache = "";
|
|
||||||
in_state = true;
|
ret += cache;
|
||||||
current_statename = "";
|
cache = String.Empty;
|
||||||
}
|
in_state = true;
|
||||||
|
current_statename = String.Empty;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
lastlevel = ilevel;
|
break;
|
||||||
}
|
}
|
||||||
ret += cache;
|
lastlevel = ilevel;
|
||||||
cache = "";
|
}
|
||||||
|
ret += cache;
|
||||||
Script = ret;
|
cache = String.Empty;
|
||||||
ret = "";
|
|
||||||
|
Script = ret;
|
||||||
|
ret = String.Empty;
|
||||||
foreach (string key in dataTypes.Keys)
|
|
||||||
{
|
|
||||||
string val;
|
foreach (string key in dataTypes.Keys)
|
||||||
dataTypes.TryGetValue(key, out val);
|
{
|
||||||
|
string val;
|
||||||
// Replace CAST - (integer) with (int)
|
dataTypes.TryGetValue(key, out val);
|
||||||
Script =
|
|
||||||
Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")",
|
// Replace CAST - (integer) with (int)
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
Script =
|
||||||
// Replace return types and function variables - integer a() and f(integer a, integer a)
|
Regex.Replace(Script, @"\(" + key + @"\)", @"(" + val + ")",
|
||||||
Script =
|
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3",
|
// Replace return types and function variables - integer a() and f(integer a, integer a)
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
Script =
|
||||||
Script =
|
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s+)", @"$1$2" + val + "$3",
|
||||||
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,",
|
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline);
|
Script =
|
||||||
}
|
Regex.Replace(Script, @"(^|;|}|[\(,])(\s*)" + key + @"(\s*)[,]", @"$1$2" + val + "$3,",
|
||||||
|
RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
// Add "void" in front of functions that needs it
|
}
|
||||||
Script =
|
|
||||||
Regex.Replace(Script,
|
// Add "void" in front of functions that needs it
|
||||||
@"^(\s*public\s+)((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
|
Script =
|
||||||
@"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Regex.Replace(Script,
|
||||||
|
@"^(\s*public\s+)?((?!(if|switch|for)[^a-zA-Z0-9_])[a-zA-Z0-9_]*\s*\([^\)]*\)[^;]*\{)",
|
||||||
// Replace <x,y,z> and <x,y,z,r>
|
@"$1void $2", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
Script =
|
|
||||||
Regex.Replace(Script, @"<([^,>;\)]*,[^,>;\)]*,[^,>;\)]*,[^,>;\)]*)>", @"new LSL_Types.Quaternion($1)",
|
// Replace <x,y,z> and <x,y,z,r>
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Script =
|
||||||
Script =
|
Regex.Replace(Script, @"<([^,>;]*,[^,>;\)]*,[^,>;\)]*,[^,>;\)]*)>", @"new LSL_Types.Quaternion($1)",
|
||||||
Regex.Replace(Script, @"<([^,>;\)]*,[^,>;\)]*,[^,>;\)]*)>", @"new LSL_Types.Vector3($1)",
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Script =
|
||||||
|
Regex.Replace(Script, @"<([^,>;]*,[^,>;\)]*,[^,>;\)]*)>", @"new LSL_Types.Vector3($1)",
|
||||||
// Replace List []'s
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
Script =
|
|
||||||
Regex.Replace(Script, @"\[([^\]]*)\]", @"new LSL_Types.list($1)",
|
// Replace List []'s
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Script =
|
||||||
|
Regex.Replace(Script, @"\[([^\]]*)\]", @"new LSL_Types.list($1)",
|
||||||
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
// Replace (string) to .ToString() //
|
|
||||||
Script =
|
|
||||||
Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_]+(\s*\([^\)]*\))?)", @"$1.ToString()",
|
// Replace (string) to .ToString() //
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Script =
|
||||||
Script =
|
Regex.Replace(Script, @"\(string\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.ToString()",
|
||||||
Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_]+(\s*\([^\)]*\))?)", @"$1.Parse($2)",
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
Script =
|
||||||
|
Regex.Replace(Script, @"\((float|int)\)\s*([a-zA-Z0-9_.]+(\s*\([^\)]*\))?)", @"$1.Parse($2)",
|
||||||
|
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.Singleline);
|
||||||
// REPLACE BACK QUOTES
|
|
||||||
foreach (string key in quotes.Keys)
|
|
||||||
{
|
// REPLACE BACK QUOTES
|
||||||
string val;
|
foreach (string key in quotes.Keys)
|
||||||
quotes.TryGetValue(key, out val);
|
{
|
||||||
Script = Script.Replace(key, "\"" + val + "\"");
|
string val;
|
||||||
}
|
quotes.TryGetValue(key, out val);
|
||||||
|
Script = Script.Replace(key, "\"" + val + "\"");
|
||||||
|
}
|
||||||
// Add namespace, class name and inheritance
|
|
||||||
|
|
||||||
Return = "" +
|
// Add namespace, class name and inheritance
|
||||||
"using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;";
|
|
||||||
//"using System; " +
|
Return = String.Empty;// +
|
||||||
//"using System.Collections.Generic; " +
|
//"using OpenSim.Region.ScriptEngine.Common; using System.Collections.Generic;";
|
||||||
//"using System.Text; " +
|
|
||||||
//"using OpenSim.Region.ScriptEngine.Common; " +
|
|
||||||
//"using integer = System.Int32; " +
|
//Return += String.Empty +
|
||||||
//"using key = System.String; ";
|
// "namespace SecondLife { ";
|
||||||
|
//Return += String.Empty +
|
||||||
//// Make a Using out of DataTypes
|
// //"[Serializable] " +
|
||||||
//// Using integer = System.Int32;
|
// "public class Script : OpenSim.Region.ScriptEngine.Common.LSL_BaseClass { ";
|
||||||
//string _val;
|
//Return += @"public Script() { } ";
|
||||||
//foreach (string key in DataTypes.Keys)
|
Return += Script;
|
||||||
//{
|
//Return += "} }\r\n";
|
||||||
// DataTypes.TryGetValue(key, out _val);
|
|
||||||
// if (key != _val)
|
|
||||||
// {
|
quotes.Clear();
|
||||||
// Return += "using " + key + " = " + _val + "; ";
|
|
||||||
// }
|
return Return;
|
||||||
//}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Return += "" +
|
|
||||||
"namespace SecondLife { ";
|
|
||||||
Return += "" +
|
|
||||||
//"[Serializable] " +
|
|
||||||
"public class Script : OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL.LSL_BaseClass { ";
|
|
||||||
Return += @"public Script() { } ";
|
|
||||||
Return += Script;
|
|
||||||
Return += "} }\r\n";
|
|
||||||
|
|
||||||
|
|
||||||
quotes.Clear();
|
|
||||||
|
|
||||||
return Return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,364 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 OpenSim 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.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/* Original code: Tedd Hansen */
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using libsecondlife;
|
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Environment.Scenes.Scripting;
|
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// EventQueueManager handles event queues
|
|
||||||
/// Events are queued and executed in separate thread
|
|
||||||
/// </summary>
|
|
||||||
[Serializable]
|
|
||||||
internal class EventQueueManager
|
|
||||||
{
|
|
||||||
|
|
||||||
//
|
|
||||||
// Class is instanced in "ScriptEngine" and used by "EventManager" also instanced in "ScriptEngine".
|
|
||||||
//
|
|
||||||
// Class purpose is to queue and execute functions that are received by "EventManager":
|
|
||||||
// - allowing "EventManager" to release its event thread immediately, thus not interrupting server execution.
|
|
||||||
// - allowing us to prioritize and control execution of script functions.
|
|
||||||
// Class can use multiple threads for simultaneous execution. Mutexes are used for thread safety.
|
|
||||||
//
|
|
||||||
// 1. Hold an execution queue for scripts
|
|
||||||
// 2. Use threads to process queue, each thread executes one script function on each pass.
|
|
||||||
// 3. Catch any script error and process it
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Notes:
|
|
||||||
// * Current execution load balancing is optimized for 1 thread, and can cause unfair execute balancing between scripts.
|
|
||||||
// Not noticeable unless server is under high load.
|
|
||||||
// * This class contains the number of threads used for script executions. Since we are not microthreading scripts yet,
|
|
||||||
// increase number of threads to allow more concurrent script executions in OpenSim.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// List of threads processing event queue
|
|
||||||
/// </summary>
|
|
||||||
private List<Thread> eventQueueThreads = new List<Thread>();
|
|
||||||
|
|
||||||
private object queueLock = new object(); // Mutex lock object
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// How many ms to sleep if queue is empty
|
|
||||||
/// </summary>
|
|
||||||
private int nothingToDoSleepms = 50;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// How many threads to process queue with
|
|
||||||
/// </summary>
|
|
||||||
private int numberOfThreads = 2;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queue containing events waiting to be executed
|
|
||||||
/// </summary>
|
|
||||||
private Queue<QueueItemStruct> eventQueue = new Queue<QueueItemStruct>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queue item structure
|
|
||||||
/// </summary>
|
|
||||||
private struct QueueItemStruct
|
|
||||||
{
|
|
||||||
public uint localID;
|
|
||||||
public LLUUID itemID;
|
|
||||||
public string functionName;
|
|
||||||
public object[] param;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// List of localID locks for mutex processing of script events
|
|
||||||
/// </summary>
|
|
||||||
private List<uint> objectLocks = new List<uint>();
|
|
||||||
|
|
||||||
private object tryLockLock = new object(); // Mutex lock object
|
|
||||||
|
|
||||||
private ScriptEngine m_ScriptEngine;
|
|
||||||
|
|
||||||
public EventQueueManager(ScriptEngine _ScriptEngine)
|
|
||||||
{
|
|
||||||
m_ScriptEngine = _ScriptEngine;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Start event queue processing threads (worker threads)
|
|
||||||
//
|
|
||||||
for (int ThreadCount = 0; ThreadCount <= numberOfThreads; ThreadCount++)
|
|
||||||
{
|
|
||||||
Thread EventQueueThread = new Thread(EventQueueThreadLoop);
|
|
||||||
eventQueueThreads.Add(EventQueueThread);
|
|
||||||
EventQueueThread.IsBackground = true;
|
|
||||||
EventQueueThread.Priority = ThreadPriority.BelowNormal;
|
|
||||||
EventQueueThread.Name = "EventQueueManagerThread_" + ThreadCount;
|
|
||||||
EventQueueThread.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~EventQueueManager()
|
|
||||||
{
|
|
||||||
// Kill worker threads
|
|
||||||
foreach (Thread EventQueueThread in new ArrayList(eventQueueThreads))
|
|
||||||
{
|
|
||||||
if (EventQueueThread != null && EventQueueThread.IsAlive == true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
EventQueueThread.Abort();
|
|
||||||
EventQueueThread.Join();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
//myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Exception killing worker thread: " + e.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventQueueThreads.Clear();
|
|
||||||
// Todo: Clean up our queues
|
|
||||||
eventQueue.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queue processing thread loop
|
|
||||||
/// </summary>
|
|
||||||
private void EventQueueThreadLoop()
|
|
||||||
{
|
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Worker thread spawned");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
QueueItemStruct BlankQIS = new QueueItemStruct();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
QueueItemStruct QIS = BlankQIS;
|
|
||||||
bool GotItem = false;
|
|
||||||
|
|
||||||
if (eventQueue.Count == 0)
|
|
||||||
{
|
|
||||||
// Nothing to do? Sleep a bit waiting for something to do
|
|
||||||
Thread.Sleep(nothingToDoSleepms);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Something in queue, process
|
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "Processing event for localID: " + QIS.localID + ", itemID: " + QIS.itemID + ", FunctionName: " + QIS.FunctionName);
|
|
||||||
|
|
||||||
// OBJECT BASED LOCK - TWO THREADS WORKING ON SAME OBJECT IS NOT GOOD
|
|
||||||
lock (queueLock)
|
|
||||||
{
|
|
||||||
GotItem = false;
|
|
||||||
for (int qc = 0; qc < eventQueue.Count; qc++)
|
|
||||||
{
|
|
||||||
// Get queue item
|
|
||||||
QIS = eventQueue.Dequeue();
|
|
||||||
|
|
||||||
// Check if object is being processed by someone else
|
|
||||||
if (TryLock(QIS.localID) == false)
|
|
||||||
{
|
|
||||||
// Object is already being processed, requeue it
|
|
||||||
eventQueue.Enqueue(QIS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We have lock on an object and can process it
|
|
||||||
GotItem = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} // go through queue
|
|
||||||
} // lock
|
|
||||||
|
|
||||||
if (GotItem == true)
|
|
||||||
{
|
|
||||||
// Execute function
|
|
||||||
try
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
m_ScriptEngine.Log.Debug("ScriptEngine", "Executing event:\r\n"
|
|
||||||
+ "QIS.localID: " + QIS.localID
|
|
||||||
+ ", QIS.itemID: " + QIS.itemID
|
|
||||||
+ ", QIS.functionName: " + QIS.functionName);
|
|
||||||
#endif
|
|
||||||
m_ScriptEngine.m_ScriptManager.ExecuteEvent(QIS.localID, QIS.itemID,
|
|
||||||
QIS.functionName, QIS.param);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
// DISPLAY ERROR INWORLD
|
|
||||||
string text = "Error executing script function \"" + QIS.functionName + "\":\r\n";
|
|
||||||
//if (e.InnerException != null)
|
|
||||||
//{
|
|
||||||
// Send inner exception
|
|
||||||
text += e.InnerException.Message.ToString();
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
text += "\r\n";
|
|
||||||
// Send normal
|
|
||||||
text += e.Message.ToString();
|
|
||||||
//}
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (text.Length > 1500)
|
|
||||||
text = text.Substring(0, 1500);
|
|
||||||
IScriptHost m_host = m_ScriptEngine.World.GetSceneObjectPart(QIS.localID);
|
|
||||||
//if (m_host != null)
|
|
||||||
//{
|
|
||||||
m_ScriptEngine.World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0,
|
|
||||||
m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// T oconsole
|
|
||||||
m_ScriptEngine.Log.Error("ScriptEngine",
|
|
||||||
"Unable to send text in-world:\r\n" + text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
ReleaseLock(QIS.localID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // Something in queue
|
|
||||||
}
|
|
||||||
catch (ThreadAbortException tae)
|
|
||||||
{
|
|
||||||
throw tae;
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_ScriptEngine.Log.Error("ScriptEngine", "Exception in EventQueueThreadLoop: " + e.ToString());
|
|
||||||
}
|
|
||||||
} // while
|
|
||||||
} // try
|
|
||||||
catch (ThreadAbortException)
|
|
||||||
{
|
|
||||||
//myScriptEngine.Log.Verbose("ScriptEngine", "EventQueueManager Worker thread killed: " + tae.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Try to get a mutex lock on localID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="localID"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool TryLock(uint localID)
|
|
||||||
{
|
|
||||||
lock (tryLockLock)
|
|
||||||
{
|
|
||||||
if (objectLocks.Contains(localID) == true)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
objectLocks.Add(localID);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Release mutex lock on localID
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="localID"></param>
|
|
||||||
private void ReleaseLock(uint localID)
|
|
||||||
{
|
|
||||||
lock (tryLockLock)
|
|
||||||
{
|
|
||||||
if (objectLocks.Contains(localID) == true)
|
|
||||||
{
|
|
||||||
objectLocks.Remove(localID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add event to event execution queue
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="localID"></param>
|
|
||||||
/// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
|
|
||||||
/// <param name="param">Array of parameters to match event mask</param>
|
|
||||||
public void AddToObjectQueue(uint localID, string FunctionName, object[] param)
|
|
||||||
{
|
|
||||||
// Determine all scripts in Object and add to their queue
|
|
||||||
//myScriptEngine.m_logger.Verbose("ScriptEngine", "EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName);
|
|
||||||
|
|
||||||
|
|
||||||
// Do we have any scripts in this object at all? If not, return
|
|
||||||
if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("Event \"" + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Dictionary<LLUUID, LSL_BaseClass>.KeyCollection scriptKeys =
|
|
||||||
m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID);
|
|
||||||
|
|
||||||
foreach (LLUUID itemID in scriptKeys)
|
|
||||||
{
|
|
||||||
// Add to each script in that object
|
|
||||||
// TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter?
|
|
||||||
AddToScriptQueue(localID, itemID, FunctionName, param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add event to event execution queue
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="localID"></param>
|
|
||||||
/// <param name="itemID"></param>
|
|
||||||
/// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param>
|
|
||||||
/// <param name="param">Array of parameters to match event mask</param>
|
|
||||||
public void AddToScriptQueue(uint localID, LLUUID itemID, string FunctionName, object[] param)
|
|
||||||
{
|
|
||||||
lock (queueLock)
|
|
||||||
{
|
|
||||||
// Create a structure and add data
|
|
||||||
QueueItemStruct QIS = new QueueItemStruct();
|
|
||||||
QIS.localID = localID;
|
|
||||||
QIS.itemID = itemID;
|
|
||||||
QIS.functionName = FunctionName;
|
|
||||||
QIS.param = param;
|
|
||||||
|
|
||||||
// Add it to queue
|
|
||||||
eventQueue.Enqueue(QIS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,287 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 OpenSim 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.Threading;
|
|
||||||
using libsecondlife;
|
|
||||||
using OpenSim.Region.Environment.Interfaces;
|
|
||||||
using OpenSim.Region.Environment.Modules;
|
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
|
|
||||||
/// </summary>
|
|
||||||
internal class LSLLongCmdHandler
|
|
||||||
{
|
|
||||||
private Thread cmdHandlerThread;
|
|
||||||
private int cmdHandlerThreadCycleSleepms = 100;
|
|
||||||
|
|
||||||
private ScriptEngine m_ScriptEngine;
|
|
||||||
|
|
||||||
public LSLLongCmdHandler(ScriptEngine _ScriptEngine)
|
|
||||||
{
|
|
||||||
m_ScriptEngine = _ScriptEngine;
|
|
||||||
|
|
||||||
// Start the thread that will be doing the work
|
|
||||||
cmdHandlerThread = new Thread(CmdHandlerThreadLoop);
|
|
||||||
cmdHandlerThread.Name = "CmdHandlerThread";
|
|
||||||
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
|
|
||||||
cmdHandlerThread.IsBackground = true;
|
|
||||||
cmdHandlerThread.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
~LSLLongCmdHandler()
|
|
||||||
{
|
|
||||||
// Shut down thread
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (cmdHandlerThread != null)
|
|
||||||
{
|
|
||||||
if (cmdHandlerThread.IsAlive == true)
|
|
||||||
{
|
|
||||||
cmdHandlerThread.Abort();
|
|
||||||
cmdHandlerThread.Join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CmdHandlerThreadLoop()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Check timers
|
|
||||||
CheckTimerEvents();
|
|
||||||
Thread.Sleep(25);
|
|
||||||
// Check HttpRequests
|
|
||||||
CheckHttpRequests();
|
|
||||||
Thread.Sleep(25);
|
|
||||||
// Check XMLRPCRequests
|
|
||||||
CheckXMLRPCRequests();
|
|
||||||
Thread.Sleep(25);
|
|
||||||
// Check Listeners
|
|
||||||
CheckListeners();
|
|
||||||
Thread.Sleep(25);
|
|
||||||
|
|
||||||
// Sleep before next cycle
|
|
||||||
//Thread.Sleep(cmdHandlerThreadCycleSleepms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Remove a specific script (and all its pending commands)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="m_localID"></param>
|
|
||||||
/// <param name="m_itemID"></param>
|
|
||||||
public void RemoveScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
// Remove a specific script
|
|
||||||
|
|
||||||
// Remove from: Timers
|
|
||||||
UnSetTimerEvents(localID, itemID);
|
|
||||||
// Remove from: HttpRequest
|
|
||||||
IHttpRequests iHttpReq =
|
|
||||||
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
|
|
||||||
iHttpReq.StopHttpRequest(localID, itemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region TIMER
|
|
||||||
|
|
||||||
//
|
|
||||||
// TIMER
|
|
||||||
//
|
|
||||||
private class TimerClass
|
|
||||||
{
|
|
||||||
public uint localID;
|
|
||||||
public LLUUID itemID;
|
|
||||||
public double interval;
|
|
||||||
public DateTime next;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<TimerClass> Timers = new List<TimerClass>();
|
|
||||||
private object TimerListLock = new object();
|
|
||||||
|
|
||||||
public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
|
|
||||||
{
|
|
||||||
Console.WriteLine("SetTimerEvent");
|
|
||||||
|
|
||||||
// Always remove first, in case this is a re-set
|
|
||||||
UnSetTimerEvents(m_localID, m_itemID);
|
|
||||||
if (sec == 0) // Disabling timer
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Add to timer
|
|
||||||
TimerClass ts = new TimerClass();
|
|
||||||
ts.localID = m_localID;
|
|
||||||
ts.itemID = m_itemID;
|
|
||||||
ts.interval = sec;
|
|
||||||
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
|
|
||||||
lock (TimerListLock)
|
|
||||||
{
|
|
||||||
Timers.Add(ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
|
|
||||||
{
|
|
||||||
// Remove from timer
|
|
||||||
lock (TimerListLock)
|
|
||||||
{
|
|
||||||
List<TimerClass> NewTimers = new List<TimerClass>();
|
|
||||||
foreach (TimerClass ts in Timers)
|
|
||||||
{
|
|
||||||
if (ts.localID != m_localID && ts.itemID != m_itemID)
|
|
||||||
{
|
|
||||||
NewTimers.Add(ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Timers.Clear();
|
|
||||||
Timers = NewTimers;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckTimerEvents()
|
|
||||||
{
|
|
||||||
// Nothing to do here?
|
|
||||||
if (Timers.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lock (TimerListLock)
|
|
||||||
{
|
|
||||||
// Go through all timers
|
|
||||||
foreach (TimerClass ts in Timers)
|
|
||||||
{
|
|
||||||
// Time has passed?
|
|
||||||
if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
|
|
||||||
{
|
|
||||||
// Add it to queue
|
|
||||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer",
|
|
||||||
new object[] {});
|
|
||||||
// set next interval
|
|
||||||
|
|
||||||
|
|
||||||
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // lock
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region HTTP REQUEST
|
|
||||||
|
|
||||||
public void CheckHttpRequests()
|
|
||||||
{
|
|
||||||
IHttpRequests iHttpReq =
|
|
||||||
m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
|
|
||||||
|
|
||||||
HttpRequestClass httpInfo = null;
|
|
||||||
|
|
||||||
if (iHttpReq != null)
|
|
||||||
httpInfo = iHttpReq.GetNextCompletedRequest();
|
|
||||||
|
|
||||||
while (httpInfo != null)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status);
|
|
||||||
|
|
||||||
// Deliver data to prim's remote_data handler
|
|
||||||
//
|
|
||||||
// TODO: Returning null for metadata, since the lsl function
|
|
||||||
// only returns the byte for HTTP_BODY_TRUNCATED, which is not
|
|
||||||
// implemented here yet anyway. Should be fixed if/when maxsize
|
|
||||||
// is supported
|
|
||||||
|
|
||||||
object[] resobj = new object[]
|
|
||||||
{
|
|
||||||
httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
|
|
||||||
};
|
|
||||||
|
|
||||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
|
||||||
httpInfo.localID, httpInfo.itemID, "http_response", resobj
|
|
||||||
);
|
|
||||||
|
|
||||||
httpInfo.Stop();
|
|
||||||
httpInfo = null;
|
|
||||||
|
|
||||||
httpInfo = iHttpReq.GetNextCompletedRequest();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public void CheckXMLRPCRequests()
|
|
||||||
{
|
|
||||||
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
|
||||||
|
|
||||||
if (xmlrpc != null)
|
|
||||||
{
|
|
||||||
while (xmlrpc.hasRequests())
|
|
||||||
{
|
|
||||||
RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
|
|
||||||
//Console.WriteLine("PICKED REQUEST");
|
|
||||||
|
|
||||||
//Deliver data to prim's remote_data handler
|
|
||||||
object[] resobj = new object[]
|
|
||||||
{
|
|
||||||
2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "",
|
|
||||||
rInfo.GetIntValue(),
|
|
||||||
rInfo.GetStrVal()
|
|
||||||
};
|
|
||||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
|
||||||
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckListeners()
|
|
||||||
{
|
|
||||||
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
|
||||||
|
|
||||||
while (comms.HasMessages())
|
|
||||||
{
|
|
||||||
ListenerInfo lInfo = comms.GetNextMessage();
|
|
||||||
|
|
||||||
//Deliver data to prim's listen handler
|
|
||||||
object[] resobj = new object[]
|
|
||||||
{
|
|
||||||
lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
|
|
||||||
};
|
|
||||||
|
|
||||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
|
||||||
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", resobj
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,38 +1,66 @@
|
||||||
using System.Reflection;
|
/*
|
||||||
using System.Runtime.InteropServices;
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
// General Information about an assembly is controlled through the following
|
*
|
||||||
// set of attributes. Change these attribute values to modify the information
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// associated with an assembly.
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
[assembly : AssemblyTitle("OpenSim.Region.ScriptEngine.DotNetEngine")]
|
* notice, this list of conditions and the following disclaimer.
|
||||||
[assembly : AssemblyDescription("")]
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
[assembly : AssemblyConfiguration("")]
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
[assembly : AssemblyCompany("")]
|
* documentation and/or other materials provided with the distribution.
|
||||||
[assembly : AssemblyProduct("OpenSim.Region.ScriptEngine.DotNetEngine")]
|
* * Neither the name of the OpenSim Project nor the
|
||||||
[assembly : AssemblyCopyright("Copyright © 2007")]
|
* names of its contributors may be used to endorse or promote products
|
||||||
[assembly : AssemblyTrademark("")]
|
* derived from this software without specific prior written permission.
|
||||||
[assembly : AssemblyCulture("")]
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
// to COM components. If you need to access a type in this assembly from
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
[assembly : ComVisible(false)]
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
* 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
|
||||||
[assembly : Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")]
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
// Version information for an assembly consists of the following four values:
|
*/
|
||||||
//
|
|
||||||
// Major Version
|
using System.Reflection;
|
||||||
// Minor Version
|
using System.Runtime.InteropServices;
|
||||||
// Build Number
|
|
||||||
// Revision
|
// General Information about an assembly is controlled through the following
|
||||||
//
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// You can specify all the values or you can default the Revision and Build Numbers
|
// associated with an assembly.
|
||||||
// by using the '*' as shown below:
|
|
||||||
|
[assembly : AssemblyTitle("OpenSim.Region.ScriptEngine.DotNetEngine")]
|
||||||
[assembly : AssemblyVersion("1.0.0.0")]
|
[assembly : AssemblyDescription("")]
|
||||||
[assembly : AssemblyFileVersion("1.0.0.0")]
|
[assembly : AssemblyConfiguration("")]
|
||||||
|
[assembly : AssemblyCompany("")]
|
||||||
|
[assembly : AssemblyProduct("OpenSim.Region.ScriptEngine.DotNetEngine")]
|
||||||
|
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")]
|
||||||
|
[assembly : AssemblyTrademark("")]
|
||||||
|
[assembly : AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
|
||||||
|
[assembly : ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
|
||||||
|
[assembly : Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
|
||||||
|
[assembly : AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly : AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
|
@ -1,118 +1,56 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
/* Original code: Tedd Hansen */
|
||||||
using System;
|
using System;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenSim.Framework.Console;
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Region.Environment.Interfaces;
|
using OpenSim.Region.Environment.Scenes;
|
||||||
using OpenSim.Region.Environment.Scenes;
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
{
|
||||||
{
|
[Serializable]
|
||||||
/// <summary>
|
public class ScriptEngine : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptEngine
|
||||||
/// This is the root object for ScriptEngine. Objects access each other trough this class.
|
{
|
||||||
/// </summary>
|
// We need to override a few things for our DotNetEngine
|
||||||
///
|
public override void Initialise(Scene scene, IConfigSource config)
|
||||||
[Serializable]
|
{
|
||||||
public class ScriptEngine : IRegionModule
|
ConfigSource = config;
|
||||||
{
|
InitializeEngine(scene, config, true, GetScriptManager());
|
||||||
public Scene World;
|
}
|
||||||
public EventManager m_EventManager; // Handles and queues incoming events from OpenSim
|
|
||||||
internal EventQueueManager m_EventQueueManager; // Executes events
|
public override OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager _GetScriptManager()
|
||||||
public ScriptManager m_ScriptManager; // Load, unload and execute scripts
|
{
|
||||||
internal AppDomainManager m_AppDomainManager;
|
return new ScriptManager(this);
|
||||||
internal LSLLongCmdHandler m_LSLLongCmdHandler;
|
}
|
||||||
|
|
||||||
private LogBase m_log;
|
public override string ScriptEngineName
|
||||||
|
{
|
||||||
public ScriptEngine()
|
get { return "ScriptEngine.DotNetEngine"; }
|
||||||
{
|
}
|
||||||
//Common.SendToDebug("ScriptEngine Object Initialized");
|
}
|
||||||
Common.mySE = this;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public LogBase Log
|
|
||||||
{
|
|
||||||
get { return m_log; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void InitializeEngine(Scene Sceneworld, LogBase logger)
|
|
||||||
{
|
|
||||||
World = Sceneworld;
|
|
||||||
m_log = logger;
|
|
||||||
|
|
||||||
Log.Verbose("ScriptEngine", "DotNet & LSL ScriptEngine initializing");
|
|
||||||
|
|
||||||
//m_logger.Status("ScriptEngine", "InitializeEngine");
|
|
||||||
|
|
||||||
// Create all objects we'll be using
|
|
||||||
m_EventQueueManager = new EventQueueManager(this);
|
|
||||||
m_EventManager = new EventManager(this);
|
|
||||||
m_ScriptManager = new ScriptManager(this);
|
|
||||||
m_AppDomainManager = new AppDomainManager();
|
|
||||||
m_LSLLongCmdHandler = new LSLLongCmdHandler(this);
|
|
||||||
|
|
||||||
// Should we iterate the region for scripts that needs starting?
|
|
||||||
// Or can we assume we are loaded before anything else so we can use proper events?
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Shutdown()
|
|
||||||
{
|
|
||||||
// We are shutting down
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region IRegionModule
|
|
||||||
|
|
||||||
public void Initialise(Scene scene, IConfigSource config)
|
|
||||||
{
|
|
||||||
InitializeEngine(scene, MainLog.Instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PostInitialise()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Close()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get { return "DotNetEngine"; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsSharedModule
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,455 +1,164 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
/* Original code: Tedd Hansen */
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System;
|
||||||
using System.IO;
|
using libsecondlife;
|
||||||
using System.Reflection;
|
using OpenSim.Framework;
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
using OpenSim.Region.Environment.Scenes;
|
||||||
using System.Threading;
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
using libsecondlife;
|
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
|
||||||
using OpenSim.Framework;
|
|
||||||
using OpenSim.Region.Environment.Scenes;
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler;
|
{
|
||||||
using OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL;
|
public class ScriptManager : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager
|
||||||
|
{
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
public ScriptManager(Common.ScriptEngineBase.ScriptEngine scriptEngine)
|
||||||
{
|
: base(scriptEngine)
|
||||||
/// <summary>
|
{
|
||||||
/// Loads scripts
|
base.m_scriptEngine = scriptEngine;
|
||||||
/// Compiles them if necessary
|
}
|
||||||
/// Execute functions for EventQueueManager (Sends them to script on other AppDomain for execution)
|
private Compiler.LSL.Compiler LSLCompiler;
|
||||||
/// </summary>
|
|
||||||
///
|
|
||||||
|
public override void Initialize()
|
||||||
// This class is as close as you get to the script without being inside script class. It handles all the dirty work for other classes.
|
{
|
||||||
// * Keeps track of running scripts
|
// Create our compiler
|
||||||
// * Compiles script if necessary (through "Compiler")
|
LSLCompiler = new Compiler.LSL.Compiler(m_scriptEngine);
|
||||||
// * Loads script (through "AppDomainManager" called from for example "EventQueueManager")
|
}
|
||||||
// * Executes functions inside script (called from for example "EventQueueManager" class)
|
|
||||||
// * Unloads script (through "AppDomainManager" called from for example "EventQueueManager")
|
// KEEP TRACK OF SCRIPTS <int id, whatever script>
|
||||||
// * Dedicated load/unload thread, and queues loading/unloading.
|
//internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts = new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>();
|
||||||
// This so that scripts starting or stopping will not slow down other theads or whole system.
|
// LOAD SCRIPT
|
||||||
//
|
// UNLOAD SCRIPT
|
||||||
[Serializable]
|
// PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim
|
||||||
public class ScriptManager
|
|
||||||
{
|
|
||||||
#region Declares
|
public override void _StartScript(uint localID, LLUUID itemID, string Script)
|
||||||
|
{
|
||||||
private Thread scriptLoadUnloadThread;
|
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID);
|
||||||
private int scriptLoadUnloadThread_IdleSleepms = 100;
|
|
||||||
private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
|
|
||||||
|
//IScriptHost root = host.GetRoot();
|
||||||
|
|
||||||
// Load/Unload structure
|
// We will initialize and start the script.
|
||||||
private struct LUStruct
|
// It will be up to the script itself to hook up the correct events.
|
||||||
{
|
string ScriptSource = String.Empty;
|
||||||
public uint localID;
|
|
||||||
public LLUUID itemID;
|
SceneObjectPart m_host = World.GetSceneObjectPart(localID);
|
||||||
public string script;
|
|
||||||
public LUType Action;
|
try
|
||||||
}
|
{
|
||||||
|
// Compile (We assume LSL)
|
||||||
private enum LUType
|
ScriptSource = LSLCompiler.PerformScriptCompile(Script);
|
||||||
{
|
|
||||||
Unknown = 0,
|
#if DEBUG
|
||||||
Load = 1,
|
long before;
|
||||||
Unload = 2
|
before = GC.GetTotalMemory(true);
|
||||||
}
|
#endif
|
||||||
|
|
||||||
// Object<string, Script<string, script>>
|
IScript CompiledScript;
|
||||||
// IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
|
CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(ScriptSource);
|
||||||
// Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
|
|
||||||
internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts =
|
#if DEBUG
|
||||||
new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>();
|
m_scriptEngine.Log.DebugFormat("[" + m_scriptEngine.ScriptEngineName + "]: Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
||||||
|
#endif
|
||||||
public Scene World
|
|
||||||
{
|
CompiledScript.Source = Script;
|
||||||
get { return m_scriptEngine.World; }
|
// Add it to our script memstruct
|
||||||
}
|
m_scriptEngine.m_ScriptManager.SetScript(localID, itemID, CompiledScript);
|
||||||
|
|
||||||
#endregion
|
// We need to give (untrusted) assembly a private instance of BuiltIns
|
||||||
|
// this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
|
||||||
#region Object init/shutdown
|
|
||||||
|
|
||||||
private ScriptEngine m_scriptEngine;
|
LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID);
|
||||||
|
|
||||||
public ScriptManager(ScriptEngine scriptEngine)
|
// Start the script - giving it BuiltIns
|
||||||
{
|
CompiledScript.Start(LSLB);
|
||||||
m_scriptEngine = scriptEngine;
|
|
||||||
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
|
// Fire the first start-event
|
||||||
scriptLoadUnloadThread = new Thread(ScriptLoadUnloadThreadLoop);
|
m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { });
|
||||||
scriptLoadUnloadThread.Name = "ScriptLoadUnloadThread";
|
}
|
||||||
scriptLoadUnloadThread.IsBackground = true;
|
catch (Exception e) // LEGIT: User Scripting
|
||||||
scriptLoadUnloadThread.Priority = ThreadPriority.BelowNormal;
|
{
|
||||||
scriptLoadUnloadThread.Start();
|
//m_scriptEngine.Log.Error("[ScriptEngine]: Error compiling script: " + e.ToString());
|
||||||
}
|
try
|
||||||
|
{
|
||||||
~ScriptManager()
|
// DISPLAY ERROR INWORLD
|
||||||
{
|
string text = "Error compiling script:\r\n" + e.Message.ToString();
|
||||||
// Abort load/unload thread
|
if (text.Length > 1500)
|
||||||
try
|
text = text.Substring(0, 1500);
|
||||||
{
|
World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, m_host.AbsolutePosition,
|
||||||
if (scriptLoadUnloadThread != null)
|
m_host.Name, m_host.UUID);
|
||||||
{
|
}
|
||||||
if (scriptLoadUnloadThread.IsAlive == true)
|
catch (Exception e2) // LEGIT: User Scripting
|
||||||
{
|
{
|
||||||
scriptLoadUnloadThread.Abort();
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Error displaying error in-world: " + e2.ToString());
|
||||||
scriptLoadUnloadThread.Join();
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: " +
|
||||||
}
|
"Errormessage: Error compiling script:\r\n" + e.Message.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch
|
}
|
||||||
{
|
|
||||||
}
|
public override void _StopScript(uint localID, LLUUID itemID)
|
||||||
}
|
{
|
||||||
|
// Stop script
|
||||||
#endregion
|
#if DEBUG
|
||||||
|
m_scriptEngine.Log.Debug("[" + m_scriptEngine.ScriptEngineName + "]: Stop script localID: " + localID + " LLUID: " + itemID.ToString());
|
||||||
#region Load / Unload scripts (Thread loop)
|
#endif
|
||||||
|
|
||||||
private void ScriptLoadUnloadThreadLoop()
|
// Stop long command on script
|
||||||
{
|
m_scriptEngine.m_ASYNCLSLCommandManager.RemoveScript(localID, itemID);
|
||||||
try
|
|
||||||
{
|
IScript LSLBC = GetScript(localID, itemID);
|
||||||
while (true)
|
if (LSLBC == null)
|
||||||
{
|
return;
|
||||||
if (LUQueue.Count == 0)
|
|
||||||
Thread.Sleep(scriptLoadUnloadThread_IdleSleepms);
|
// TEMP: First serialize it
|
||||||
if (LUQueue.Count > 0)
|
//GetSerializedScript(localID, itemID);
|
||||||
{
|
|
||||||
LUStruct item = LUQueue.Dequeue();
|
try
|
||||||
if (item.Action == LUType.Unload)
|
{
|
||||||
_StopScript(item.localID, item.itemID);
|
// Get AppDomain
|
||||||
if (item.Action == LUType.Load)
|
AppDomain ad = LSLBC.Exec.GetAppDomain();
|
||||||
_StartScript(item.localID, item.itemID, item.script);
|
// Tell script not to accept new requests
|
||||||
}
|
m_scriptEngine.m_ScriptManager.GetScript(localID, itemID).Exec.StopScript();
|
||||||
}
|
// Remove from internal structure
|
||||||
}
|
m_scriptEngine.m_ScriptManager.RemoveScript(localID, itemID);
|
||||||
catch (ThreadAbortException tae)
|
// Tell AppDomain that we have stopped script
|
||||||
{
|
m_scriptEngine.m_AppDomainManager.StopScript(ad);
|
||||||
string a = tae.ToString();
|
}
|
||||||
a = "";
|
catch (Exception e) // LEGIT: User Scripting
|
||||||
// Expected
|
{
|
||||||
}
|
m_scriptEngine.Log.Error("[" + m_scriptEngine.ScriptEngineName + "]: Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() +
|
||||||
}
|
": " + e.ToString());
|
||||||
|
}
|
||||||
#endregion
|
}
|
||||||
|
}
|
||||||
#region Helper functions
|
}
|
||||||
|
|
||||||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
|
||||||
{
|
|
||||||
//Console.WriteLine("ScriptManager.CurrentDomain_AssemblyResolve: " + args.Name);
|
|
||||||
return Assembly.GetExecutingAssembly().FullName == args.Name ? Assembly.GetExecutingAssembly() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Internal functions to keep track of script
|
|
||||||
|
|
||||||
internal Dictionary<LLUUID, LSL_BaseClass>.KeyCollection GetScriptKeys(uint localID)
|
|
||||||
{
|
|
||||||
if (Scripts.ContainsKey(localID) == false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
|
||||||
Scripts.TryGetValue(localID, out Obj);
|
|
||||||
|
|
||||||
return Obj.Keys;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal LSL_BaseClass GetScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
if (Scripts.ContainsKey(localID) == false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
|
||||||
Scripts.TryGetValue(localID, out Obj);
|
|
||||||
if (Obj.ContainsKey(itemID) == false)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// Get script
|
|
||||||
LSL_BaseClass Script;
|
|
||||||
Obj.TryGetValue(itemID, out Script);
|
|
||||||
|
|
||||||
return Script;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void SetScript(uint localID, LLUUID itemID, LSL_BaseClass Script)
|
|
||||||
{
|
|
||||||
// Create object if it doesn't exist
|
|
||||||
if (Scripts.ContainsKey(localID) == false)
|
|
||||||
{
|
|
||||||
Scripts.Add(localID, new Dictionary<LLUUID, LSL_BaseClass>());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete script if it exists
|
|
||||||
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
|
||||||
Scripts.TryGetValue(localID, out Obj);
|
|
||||||
if (Obj.ContainsKey(itemID) == true)
|
|
||||||
Obj.Remove(itemID);
|
|
||||||
|
|
||||||
// Add to object
|
|
||||||
Obj.Add(itemID, Script);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void RemoveScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
// Don't have that object?
|
|
||||||
if (Scripts.ContainsKey(localID) == false)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Delete script if it exists
|
|
||||||
Dictionary<LLUUID, LSL_BaseClass> Obj;
|
|
||||||
Scripts.TryGetValue(localID, out Obj);
|
|
||||||
if (Obj.ContainsKey(itemID) == true)
|
|
||||||
Obj.Remove(itemID);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Start/Stop/Reset script
|
|
||||||
|
|
||||||
private Object startStopLock = new Object();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fetches, loads and hooks up a script to an objects events
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="itemID"></param>
|
|
||||||
/// <param name="localID"></param>
|
|
||||||
public void StartScript(uint localID, LLUUID itemID, string Script)
|
|
||||||
{
|
|
||||||
LUStruct ls = new LUStruct();
|
|
||||||
ls.localID = localID;
|
|
||||||
ls.itemID = itemID;
|
|
||||||
ls.script = Script;
|
|
||||||
ls.Action = LUType.Load;
|
|
||||||
LUQueue.Enqueue(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Disables and unloads a script
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="localID"></param>
|
|
||||||
/// <param name="itemID"></param>
|
|
||||||
public void StopScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
LUStruct ls = new LUStruct();
|
|
||||||
ls.localID = localID;
|
|
||||||
ls.itemID = itemID;
|
|
||||||
ls.Action = LUType.Unload;
|
|
||||||
LUQueue.Enqueue(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ResetScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
string script = GetScript(localID, itemID).SourceCode;
|
|
||||||
StopScript(localID, itemID);
|
|
||||||
StartScript(localID, itemID, script);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new instance of the compiler (reuse)
|
|
||||||
private Compiler.LSL.Compiler LSLCompiler = new Compiler.LSL.Compiler();
|
|
||||||
|
|
||||||
private void _StartScript(uint localID, LLUUID itemID, string Script)
|
|
||||||
{
|
|
||||||
lock (startStopLock)
|
|
||||||
{
|
|
||||||
//IScriptHost root = host.GetRoot();
|
|
||||||
Console.WriteLine("ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID);
|
|
||||||
|
|
||||||
// We will initialize and start the script.
|
|
||||||
// It will be up to the script itself to hook up the correct events.
|
|
||||||
string ScriptSource = "";
|
|
||||||
|
|
||||||
SceneObjectPart m_host = World.GetSceneObjectPart(localID);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Script.EndsWith("dll"))
|
|
||||||
{
|
|
||||||
// Compile (We assume LSL)
|
|
||||||
ScriptSource = LSLCompiler.CompileFromLSLText(Script);
|
|
||||||
//Console.WriteLine("Compilation of " + FileName + " done");
|
|
||||||
// * Insert yield into code
|
|
||||||
ScriptSource = ProcessYield(ScriptSource);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ScriptSource = Script;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
long before;
|
|
||||||
before = GC.GetTotalMemory(true);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LSL_BaseClass CompiledScript;
|
|
||||||
CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(ScriptSource);
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CompiledScript.SourceCode = ScriptSource;
|
|
||||||
// Add it to our script memstruct
|
|
||||||
SetScript(localID, itemID, CompiledScript);
|
|
||||||
|
|
||||||
// We need to give (untrusted) assembly a private instance of BuiltIns
|
|
||||||
// this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
|
|
||||||
|
|
||||||
|
|
||||||
LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID);
|
|
||||||
|
|
||||||
// Start the script - giving it BuiltIns
|
|
||||||
CompiledScript.Start(LSLB);
|
|
||||||
|
|
||||||
// Fire the first start-event
|
|
||||||
m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", new object[] {});
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
//m_scriptEngine.Log.Error("ScriptEngine", "Error compiling script: " + e.ToString());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// DISPLAY ERROR INWORLD
|
|
||||||
string text = "Error compiling script:\r\n" + e.Message.ToString();
|
|
||||||
if (text.Length > 1500)
|
|
||||||
text = text.Substring(0, 1500);
|
|
||||||
World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, m_host.AbsolutePosition,
|
|
||||||
m_host.Name, m_host.UUID);
|
|
||||||
}
|
|
||||||
catch (Exception e2)
|
|
||||||
{
|
|
||||||
m_scriptEngine.Log.Error("ScriptEngine", "Error displaying error in-world: " + e2.ToString());
|
|
||||||
m_scriptEngine.Log.Error("ScriptEngine",
|
|
||||||
"Errormessage: Error compiling script:\r\n" + e.Message.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _StopScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
lock (startStopLock)
|
|
||||||
{
|
|
||||||
// Stop script
|
|
||||||
Console.WriteLine("Stop script localID: " + localID + " LLUID: " + itemID.ToString());
|
|
||||||
|
|
||||||
|
|
||||||
// Stop long command on script
|
|
||||||
m_scriptEngine.m_LSLLongCmdHandler.RemoveScript(localID, itemID);
|
|
||||||
|
|
||||||
LSL_BaseClass LSLBC = GetScript(localID, itemID);
|
|
||||||
if (LSLBC == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// TEMP: First serialize it
|
|
||||||
//GetSerializedScript(localID, itemID);
|
|
||||||
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Get AppDomain
|
|
||||||
AppDomain ad = LSLBC.Exec.GetAppDomain();
|
|
||||||
// Tell script not to accept new requests
|
|
||||||
GetScript(localID, itemID).Exec.StopScript();
|
|
||||||
// Remove from internal structure
|
|
||||||
RemoveScript(localID, itemID);
|
|
||||||
// Tell AppDomain that we have stopped script
|
|
||||||
m_scriptEngine.m_AppDomainManager.StopScript(ad);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() +
|
|
||||||
": " + e.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string ProcessYield(string FileName)
|
|
||||||
{
|
|
||||||
// TODO: Create a new assembly and copy old but insert Yield Code
|
|
||||||
//return TempDotNetMicroThreadingCodeInjector.TestFix(FileName);
|
|
||||||
return FileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Perform event execution in script
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Execute a LL-event-function in Script
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="localID">Object the script is located in</param>
|
|
||||||
/// <param name="itemID">Script ID</param>
|
|
||||||
/// <param name="FunctionName">Name of function</param>
|
|
||||||
/// <param name="args">Arguments to pass to function</param>
|
|
||||||
internal void ExecuteEvent(uint localID, LLUUID itemID, string FunctionName, object[] args)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
Console.WriteLine("ScriptEngine: Inside ExecuteEvent for event " + FunctionName);
|
|
||||||
#endif
|
|
||||||
// Execute a function in the script
|
|
||||||
//m_scriptEngine.Log.Verbose("ScriptEngine", "Executing Function localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName);
|
|
||||||
LSL_BaseClass Script = m_scriptEngine.m_ScriptManager.GetScript(localID, itemID);
|
|
||||||
if (Script == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
Console.WriteLine("ScriptEngine: Executing event: " + FunctionName);
|
|
||||||
#endif
|
|
||||||
// Must be done in correct AppDomain, so leaving it up to the script itself
|
|
||||||
Script.Exec.ExecuteEvent(FunctionName, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Script serialization/deserialization
|
|
||||||
|
|
||||||
public void GetSerializedScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
// Serialize the script and return it
|
|
||||||
// Should not be a problem
|
|
||||||
FileStream fs = File.Create("SERIALIZED_SCRIPT_" + itemID);
|
|
||||||
BinaryFormatter b = new BinaryFormatter();
|
|
||||||
b.Serialize(fs, GetScript(localID, itemID));
|
|
||||||
fs.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PutSerializedScript(uint localID, LLUUID itemID)
|
|
||||||
{
|
|
||||||
// Deserialize the script and inject it into an AppDomain
|
|
||||||
|
|
||||||
// How to inject into an AppDomain?
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
public static class Common
|
||||||
|
{
|
||||||
|
public static bool Debug = true;
|
||||||
|
public static bool IL_UseTryCatch = true;
|
||||||
|
public static bool IL_CreateConstructor = true;
|
||||||
|
public static bool IL_CreateFunctionList = true;
|
||||||
|
public static bool IL_ProcessCodeChunks = true;
|
||||||
|
|
||||||
|
public delegate void SendToDebugEventDelegate(string Message);
|
||||||
|
|
||||||
|
public delegate void SendToLogEventDelegate(string Message);
|
||||||
|
|
||||||
|
public static event SendToDebugEventDelegate SendToDebugEvent;
|
||||||
|
public static event SendToLogEventDelegate SendToLogEvent;
|
||||||
|
|
||||||
|
public static void SendToDebug(string Message)
|
||||||
|
{
|
||||||
|
//if (Debug == true)
|
||||||
|
Console.WriteLine("COMPILER:Debug: " + Message);
|
||||||
|
SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendToLog(string Message)
|
||||||
|
{
|
||||||
|
//if (Debug == true)
|
||||||
|
Console.WriteLine("COMPILER:LOG: " + Message);
|
||||||
|
SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class IL_Helper
|
||||||
|
{
|
||||||
|
public static string ReverseFormatString(string text1, string format)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("ReverseFormatString text1: " + text1);
|
||||||
|
Common.SendToDebug("ReverseFormatString format: " + format);
|
||||||
|
return string.Format(format, text1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string ReverseFormatString(string text1, UInt32 text2, string format)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("ReverseFormatString text1: " + text1);
|
||||||
|
Common.SendToDebug("ReverseFormatString text2: " + text2.ToString());
|
||||||
|
Common.SendToDebug("ReverseFormatString format: " + format);
|
||||||
|
return string.Format(format, text1, text2.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Cast_ToString(object obj)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("OBJECT TO BE CASTED: " + obj.GetType().ToString());
|
||||||
|
return "ABCDEFGIHJKLMNOPQ123";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,293 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using OpenSim.Region.ScriptEngine.LSOEngine.LSO;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
public class Engine
|
||||||
|
{
|
||||||
|
//private string LSO_FileName = @"LSO\AdditionTest.lso";
|
||||||
|
private string LSO_FileName; // = @"LSO\CloseToDefault.lso";
|
||||||
|
private AppDomain appDomain;
|
||||||
|
|
||||||
|
public string Compile(string LSOFileName)
|
||||||
|
{
|
||||||
|
LSO_FileName = LSOFileName;
|
||||||
|
|
||||||
|
|
||||||
|
//appDomain = AppDomain.CreateDomain("AlternateAppDomain");
|
||||||
|
appDomain = Thread.GetDomain();
|
||||||
|
|
||||||
|
// Create Assembly Name
|
||||||
|
AssemblyName asmName = new AssemblyName();
|
||||||
|
asmName.Name = Path.GetFileNameWithoutExtension(LSO_FileName);
|
||||||
|
//asmName.Name = "TestAssembly";
|
||||||
|
|
||||||
|
string DLL_FileName = asmName.Name + ".dll";
|
||||||
|
string DLL_FileName_WithPath = Path.GetDirectoryName(LSO_FileName) + @"\" + DLL_FileName;
|
||||||
|
|
||||||
|
LSOEngine.LSO.Common.SendToLog("LSO File Name: " + Path.GetFileName(LSO_FileName));
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Assembly name: " + asmName.Name);
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Assembly File Name: " + asmName.Name + ".dll");
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Starting processing of LSL ByteCode...");
|
||||||
|
LSOEngine.LSO.Common.SendToLog(String.Empty);
|
||||||
|
|
||||||
|
|
||||||
|
// Create Assembly
|
||||||
|
AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly(
|
||||||
|
asmName,
|
||||||
|
AssemblyBuilderAccess.RunAndSave
|
||||||
|
);
|
||||||
|
//// Create Assembly
|
||||||
|
//AssemblyBuilder asmBuilder =
|
||||||
|
// Thread.GetDomain().DefineDynamicAssembly
|
||||||
|
//(asmName, AssemblyBuilderAccess.RunAndSave);
|
||||||
|
|
||||||
|
// Create a module (and save to disk)
|
||||||
|
ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule
|
||||||
|
(asmName.Name,
|
||||||
|
DLL_FileName);
|
||||||
|
|
||||||
|
//Common.SendToDebug("asmName.Name is still \String.Empty + asmName.Name + "\String.Empty);
|
||||||
|
// Create a Class (/Type)
|
||||||
|
TypeBuilder typeBuilder = modBuilder.DefineType(
|
||||||
|
"LSL_ScriptObject",
|
||||||
|
TypeAttributes.Public | TypeAttributes.BeforeFieldInit,
|
||||||
|
typeof (LSL_BaseClass));
|
||||||
|
//,
|
||||||
|
// typeof());
|
||||||
|
//, typeof(LSL_BuiltIn_Commands_Interface));
|
||||||
|
//,
|
||||||
|
// typeof(object),
|
||||||
|
// new Type[] { typeof(LSL_CLRInterface.LSLScript) });
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generate the IL itself
|
||||||
|
*/
|
||||||
|
|
||||||
|
LSO_Parser LSOP = new LSO_Parser(LSO_FileName, typeBuilder);
|
||||||
|
LSOP.OpenFile();
|
||||||
|
LSOP.Parse();
|
||||||
|
|
||||||
|
// Constructor has to be created AFTER LSO_Parser because of accumulated variables
|
||||||
|
if (LSOEngine.LSO.Common.IL_CreateConstructor)
|
||||||
|
IL_CREATE_CONSTRUCTOR(typeBuilder, LSOP);
|
||||||
|
|
||||||
|
LSOP.CloseFile();
|
||||||
|
/*
|
||||||
|
* Done generating. Create a type and run it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Attempting to compile assembly...");
|
||||||
|
// Compile it
|
||||||
|
Type type = typeBuilder.CreateType();
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Compilation successful!");
|
||||||
|
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Saving assembly: " + DLL_FileName);
|
||||||
|
asmBuilder.Save(DLL_FileName);
|
||||||
|
|
||||||
|
LSOEngine.LSO.Common.SendToLog("Returning assembly filename: " + DLL_FileName);
|
||||||
|
|
||||||
|
|
||||||
|
return DLL_FileName;
|
||||||
|
|
||||||
|
|
||||||
|
//Common.SendToLog("Creating an instance of new assembly...");
|
||||||
|
//// Create an instance we can play with
|
||||||
|
////LSLScript hello = (LSLScript)Activator.CreateInstance(type);
|
||||||
|
////LSL_CLRInterface.LSLScript MyScript = (LSL_CLRInterface.LSLScript)Activator.CreateInstance(type);
|
||||||
|
//object MyScript = (object)Activator.CreateInstance(type);
|
||||||
|
|
||||||
|
|
||||||
|
//System.Reflection.MemberInfo[] Members = type.GetMembers();
|
||||||
|
|
||||||
|
//Common.SendToLog("Members of assembly " + type.ToString() + ":");
|
||||||
|
//foreach (MemberInfo member in Members)
|
||||||
|
// Common.SendToLog(member.ToString());
|
||||||
|
|
||||||
|
|
||||||
|
//// Play with it
|
||||||
|
////MyScript.event_state_entry("Test");
|
||||||
|
//object[] args = { null };
|
||||||
|
////System.Collections.Generic.List<string> Functions = (System.Collections.Generic.List<string>)type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null);
|
||||||
|
|
||||||
|
//string[] ret = { };
|
||||||
|
//if (Common.IL_CreateFunctionList)
|
||||||
|
// ret = (string[])type.InvokeMember("GetFunctions", BindingFlags.InvokeMethod, null, MyScript, null);
|
||||||
|
|
||||||
|
//foreach (string s in ret)
|
||||||
|
//{
|
||||||
|
// Common.SendToLog(String.Empty);
|
||||||
|
// Common.SendToLog("*** Executing LSL Server Event: " + s);
|
||||||
|
// //object test = type.GetMember(s);
|
||||||
|
// //object runner = type.InvokeMember(s, BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance, null, MyScript, args);
|
||||||
|
// //runner();
|
||||||
|
// //objBooks_Late = type.InvokeMember(s, BindingFlags.CreateInstance, null, objApp_Late, null);
|
||||||
|
// type.InvokeMember(s, BindingFlags.InvokeMethod, null, MyScript, new object[] { "Test" });
|
||||||
|
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void IL_CREATE_CONSTRUCTOR(TypeBuilder typeBuilder, LSO_Parser LSOP)
|
||||||
|
{
|
||||||
|
LSOEngine.LSO.Common.SendToDebug("IL_CREATE_CONSTRUCTOR()");
|
||||||
|
//ConstructorBuilder constructor = typeBuilder.DefineConstructor(
|
||||||
|
// MethodAttributes.Public,
|
||||||
|
// CallingConventions.Standard,
|
||||||
|
// new Type[0]);
|
||||||
|
ConstructorBuilder constructor = typeBuilder.DefineConstructor(
|
||||||
|
MethodAttributes.Public |
|
||||||
|
MethodAttributes.SpecialName |
|
||||||
|
MethodAttributes.RTSpecialName,
|
||||||
|
CallingConventions.Standard,
|
||||||
|
new Type[0]);
|
||||||
|
|
||||||
|
//Define the reflection ConstructorInfor for System.Object
|
||||||
|
ConstructorInfo conObj = typeof (LSL_BaseClass).GetConstructor(new Type[0]);
|
||||||
|
|
||||||
|
//call constructor of base object
|
||||||
|
ILGenerator il = constructor.GetILGenerator();
|
||||||
|
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
il.Emit(OpCodes.Call, conObj);
|
||||||
|
|
||||||
|
|
||||||
|
//Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: UInt32 State = 0;");
|
||||||
|
//string FieldName;
|
||||||
|
//// Create state object
|
||||||
|
//FieldName = "State";
|
||||||
|
//FieldBuilder State_fb = typeBuilder.DefineField(
|
||||||
|
// FieldName,
|
||||||
|
// typeof(UInt32),
|
||||||
|
// FieldAttributes.Public);
|
||||||
|
//il.Emit(OpCodes.Ldarg_0);
|
||||||
|
//il.Emit(OpCodes.Ldc_I4, 0);
|
||||||
|
//il.Emit(OpCodes.Stfld, State_fb);
|
||||||
|
|
||||||
|
|
||||||
|
//Common.SendToDebug("IL_CREATE_CONSTRUCTOR: Creating global: LSL_BuiltIn_Commands_TestImplementation LSL_BuiltIns = New LSL_BuiltIn_Commands_TestImplementation();");
|
||||||
|
////Type objType1 = typeof(object);
|
||||||
|
//Type objType1 = typeof(LSL_BuiltIn_Commands_TestImplementation);
|
||||||
|
|
||||||
|
//FieldName = "LSL_BuiltIns";
|
||||||
|
//FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField(
|
||||||
|
// FieldName,
|
||||||
|
// objType1,
|
||||||
|
// FieldAttributes.Public);
|
||||||
|
|
||||||
|
////LSL_BuiltIn_Commands_TestImplementation _ti = new LSL_BuiltIn_Commands_TestImplementation();
|
||||||
|
//il.Emit(OpCodes.Ldarg_0);
|
||||||
|
////il.Emit(OpCodes.Ldstr, "Test 123");
|
||||||
|
//il.Emit(OpCodes.Newobj, objType1.GetConstructor(new Type[] { }));
|
||||||
|
//il.Emit(OpCodes.Stfld, LSL_BuiltIns_fb);
|
||||||
|
|
||||||
|
foreach (UInt32 pos in LSOP.StaticBlocks.Keys)
|
||||||
|
{
|
||||||
|
LSO_Struct.StaticBlock sb;
|
||||||
|
LSOP.StaticBlocks.TryGetValue(pos, out sb);
|
||||||
|
|
||||||
|
if (sb.ObjectType > 0 && sb.ObjectType < 8)
|
||||||
|
{
|
||||||
|
// We don't want void or null's
|
||||||
|
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
// Push position to stack
|
||||||
|
il.Emit(OpCodes.Ldc_I4, pos);
|
||||||
|
//il.Emit(OpCodes.Box, typeof(UInt32));
|
||||||
|
|
||||||
|
|
||||||
|
Type datatype = null;
|
||||||
|
|
||||||
|
// Push data to stack
|
||||||
|
LSOEngine.LSO.Common.SendToDebug("Adding to static (" + pos + ") type: " +
|
||||||
|
((LSO_Enums.Variable_Type_Codes) sb.ObjectType).ToString() + " (" + sb.ObjectType +
|
||||||
|
")");
|
||||||
|
switch ((LSO_Enums.Variable_Type_Codes) sb.ObjectType)
|
||||||
|
{
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Float:
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Integer:
|
||||||
|
//UInt32
|
||||||
|
il.Emit(OpCodes.Ldc_I4, BitConverter.ToUInt32(sb.BlockVariable, 0));
|
||||||
|
datatype = typeof (UInt32);
|
||||||
|
il.Emit(OpCodes.Box, datatype);
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Variable_Type_Codes.String:
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Key:
|
||||||
|
//String
|
||||||
|
LSO_Struct.HeapBlock hb =
|
||||||
|
LSOP.GetHeap(LSOP.myHeader.HR + BitConverter.ToUInt32(sb.BlockVariable, 0) - 1);
|
||||||
|
il.Emit(OpCodes.Ldstr, Encoding.UTF8.GetString(hb.Data));
|
||||||
|
datatype = typeof (string);
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Vector:
|
||||||
|
datatype = typeof (LSO_Enums.Vector);
|
||||||
|
//TODO: Not implemented
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Rotation:
|
||||||
|
//Object
|
||||||
|
//TODO: Not implemented
|
||||||
|
datatype = typeof (LSO_Enums.Rotation);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
datatype = typeof (object);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Make call
|
||||||
|
il.Emit(OpCodes.Call,
|
||||||
|
typeof (LSL_BaseClass).GetMethod("AddToStatic", new Type[] {typeof (UInt32), datatype}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////il.Emit(OpCodes.Newobj, typeof(UInt32));
|
||||||
|
//il.Emit(OpCodes.Starg_0);
|
||||||
|
//// Create LSL function library
|
||||||
|
//FieldBuilder LSL_BuiltIns_fb = typeBuilder.DefineField("LSL_BuiltIns", typeof(LSL_BuiltIn_Commands_Interface), FieldAttributes.Public);
|
||||||
|
//il.Emit(OpCodes.Newobj, typeof(LSL_BuiltIn_Commands_Interface));
|
||||||
|
//il.Emit(OpCodes.Stloc_1);
|
||||||
|
|
||||||
|
il.Emit(OpCodes.Ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// End of class
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
internal partial class LSO_Parser
|
||||||
|
{
|
||||||
|
private static TypeBuilder CreateType(ModuleBuilder modBuilder, string typeName)
|
||||||
|
{
|
||||||
|
TypeBuilder typeBuilder = modBuilder.DefineType(typeName,
|
||||||
|
TypeAttributes.Public |
|
||||||
|
TypeAttributes.Class |
|
||||||
|
TypeAttributes.AutoClass |
|
||||||
|
TypeAttributes.AnsiClass |
|
||||||
|
TypeAttributes.BeforeFieldInit |
|
||||||
|
TypeAttributes.AutoLayout,
|
||||||
|
typeof (object),
|
||||||
|
new Type[] {typeof (object)});
|
||||||
|
return typeBuilder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,395 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
//public partial class LSL_BaseClass
|
||||||
|
//{
|
||||||
|
// /*
|
||||||
|
// * OPCODES
|
||||||
|
// *
|
||||||
|
// * These are internal "assembly" commands,
|
||||||
|
// * basic operators like "ADD", "PUSH" and "POP"
|
||||||
|
// *
|
||||||
|
// * It also contains managed stack and keeps track of internal variables, etc.
|
||||||
|
// *
|
||||||
|
// */
|
||||||
|
|
||||||
|
|
||||||
|
// public void StoreToLocal(UInt32 index)
|
||||||
|
// {
|
||||||
|
// // TODO: How to determine local?
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::StoreToLocal " + index);
|
||||||
|
// if (LocalVariables.ContainsKey(index))
|
||||||
|
// LocalVariables.Remove(index);
|
||||||
|
// LocalVariables.Add(index, LSLStack.Peek());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void StoreToGlobal(UInt32 index)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::StoreToGlobal " + index);
|
||||||
|
// if (GlobalVariables.ContainsKey(index))
|
||||||
|
// GlobalVariables.Remove(index);
|
||||||
|
// GlobalVariables.Add(index, LSLStack.Peek());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void StoreToStatic(UInt32 index)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::StoreToStatic " + index);
|
||||||
|
// //if (StaticVariables.ContainsKey(index))
|
||||||
|
// // StaticVariables.Remove(index);
|
||||||
|
// StaticVariables.Add(index, LSLStack.Peek());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void GetFromLocal(UInt32 index)
|
||||||
|
// {
|
||||||
|
// // TODO: How to determine local?
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::GetFromLocal " + index);
|
||||||
|
// object ret;
|
||||||
|
// LocalVariables.TryGetValue(index, out ret);
|
||||||
|
// LSLStack.Push(ret);
|
||||||
|
// //return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void GetFromGlobal(UInt32 index)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::GetFromGlobal " + index);
|
||||||
|
// object ret;
|
||||||
|
// GlobalVariables.TryGetValue(index, out ret);
|
||||||
|
// LSLStack.Push(ret);
|
||||||
|
// //return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void GetFromStatic(UInt32 index)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::GetFromStatic " + index);
|
||||||
|
// object ret;
|
||||||
|
// StaticVariables.TryGetValue(index, out ret);
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::GetFromStatic - ObjectType: " + ret.GetType().ToString());
|
||||||
|
// LSLStack.Push(ret);
|
||||||
|
// //return ret;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public object POPToStack()
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::POPToStack");
|
||||||
|
// //return LSLStack.Pop();
|
||||||
|
// object p = LSLStack.Pop();
|
||||||
|
// if (p.GetType() == typeof (UInt32))
|
||||||
|
// return (UInt32) p;
|
||||||
|
// if (p.GetType() == typeof (string))
|
||||||
|
// return (string) p;
|
||||||
|
// if (p.GetType() == typeof (Int32))
|
||||||
|
// return (Int32) p;
|
||||||
|
// if (p.GetType() == typeof (UInt16))
|
||||||
|
// return (UInt16) p;
|
||||||
|
// if (p.GetType() == typeof (float))
|
||||||
|
// return (float) p;
|
||||||
|
// if (p.GetType() == typeof (LSO_Enums.Vector))
|
||||||
|
// return (LSO_Enums.Vector) p;
|
||||||
|
// if (p.GetType() == typeof (LSO_Enums.Rotation))
|
||||||
|
// return (LSO_Enums.Rotation) p;
|
||||||
|
// if (p.GetType() == typeof (LSO_Enums.Key))
|
||||||
|
// return (LSO_Enums.Key) p;
|
||||||
|
|
||||||
|
// return p;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //public object POPToStack(UInt32 count)
|
||||||
|
// //{
|
||||||
|
// // // POP NUMBER FROM TOP OF STACK
|
||||||
|
// // //LSLStack.SetLength(LSLStack.Length - 4);
|
||||||
|
// // Common.SendToDebug("::POPToStack " + count);
|
||||||
|
// // if (count < 2)
|
||||||
|
// // return LSLStack.Pop();
|
||||||
|
|
||||||
|
// // Stack<object> s = new Stack<object>();
|
||||||
|
// // for (int i = 0; i < count; i++)
|
||||||
|
// // {
|
||||||
|
// // s.Push(LSLStack.Pop);
|
||||||
|
|
||||||
|
// // }
|
||||||
|
|
||||||
|
// //}
|
||||||
|
|
||||||
|
// public void POP()
|
||||||
|
// {
|
||||||
|
// // POP NUMBER FROM TOP OF STACK
|
||||||
|
// //LSLStack.SetLength(LSLStack.Length - 4);
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::POP");
|
||||||
|
// if (LSLStack.Count < 1)
|
||||||
|
// {
|
||||||
|
// //TODO: Temporary fix
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("ERROR: TRYING TO POP EMPTY STACK!");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Pop();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void PUSH(object Param)
|
||||||
|
// {
|
||||||
|
// if (Param == null)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::PUSH: <null>");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// //Common.SendToDebug("::PUSH: " + Param.GetType());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// LSLStack.Push(Param);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void ADD(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::ADD: " + Param);
|
||||||
|
// object o2 = LSLStack.Pop();
|
||||||
|
// object o1 = LSLStack.Pop();
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::ADD: Debug: o1: " + o1.GetType() + " (" + o1.ToString() + "), o2: " + o2.GetType() +
|
||||||
|
// " (" + o2.ToString() + ")");
|
||||||
|
// if (o2.GetType() == typeof (string))
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((string) o1 + (string) o2);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (o2.GetType() == typeof (UInt32))
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) o1 + (UInt32) o2);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void SUB(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::SUB: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1 - i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void MUL(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::SUB: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1*i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void DIV(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::DIV: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1/i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// public void MOD(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::MOD: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1%i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void EQ(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::EQ: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// if (i1 == i2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void NEQ(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::NEQ: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// if (i1 != i2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void LEQ(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::LEQ: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// if (i1 <= i2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void GEQ(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::GEQ: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// if (i1 >= i2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void LESS(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::LESS: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// if (i1 < i2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void GREATER(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::GREATER: " + Param);
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// if (i1 > i2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// public void BITAND()
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::BITAND");
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1 & i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void BITOR()
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::BITOR");
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1 | i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void BITXOR()
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::BITXOR");
|
||||||
|
// UInt32 i2 = (UInt32) LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1 ^ i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void BOOLAND()
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::BOOLAND");
|
||||||
|
// bool b2 = bool.Parse((string) LSLStack.Pop());
|
||||||
|
// bool b1 = bool.Parse((string) LSLStack.Pop());
|
||||||
|
// if (b1 && b2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void BOOLOR()
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::BOOLOR");
|
||||||
|
// bool b2 = bool.Parse((string) LSLStack.Pop());
|
||||||
|
// bool b1 = bool.Parse((string) LSLStack.Pop());
|
||||||
|
|
||||||
|
// if (b1 || b2)
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// LSLStack.Push((UInt32) 0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void NEG(UInt32 Param)
|
||||||
|
// {
|
||||||
|
// LSOEngine.LSO.Common.SendToDebug("::NEG: " + Param);
|
||||||
|
// //UInt32 i2 = (UInt32)LSLStack.Pop();
|
||||||
|
// UInt32 i1 = (UInt32) LSLStack.Pop();
|
||||||
|
// LSLStack.Push((UInt32) (i1*-1));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void BITNOT()
|
||||||
|
// {
|
||||||
|
// //Common.SendToDebug("::BITNOT");
|
||||||
|
// //UInt32 i2 = (UInt32)LSLStack.Pop();
|
||||||
|
// //UInt32 i1 = (UInt32)LSLStack.Pop();
|
||||||
|
// //LSLStack.Push((UInt32)(i1 / i2));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void BOOLNOT()
|
||||||
|
// {
|
||||||
|
// //Common.SendToDebug("::BOOLNOT");
|
||||||
|
// ////UInt32 i2 = (UInt32)LSLStack.Pop();
|
||||||
|
// //UInt32 i1 = (UInt32)LSLStack.Pop();
|
||||||
|
// //LSLStack.Push((UInt32)(i1));
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
|
@ -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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
public class LSL_CLRInterface
|
||||||
|
{
|
||||||
|
public interface LSLScript
|
||||||
|
{
|
||||||
|
//public virtual void Run(object arg)
|
||||||
|
//{
|
||||||
|
//}
|
||||||
|
//void Run(object arg);
|
||||||
|
|
||||||
|
//void event_state_entry(object arg);
|
||||||
|
//void event_state_exit();
|
||||||
|
//void event_touch_start(object arg);
|
||||||
|
//void event_touch();
|
||||||
|
//void event_touch_end();
|
||||||
|
//void event_collision_start();
|
||||||
|
//void event_collision();
|
||||||
|
//void event_collision_end();
|
||||||
|
//void event_land_collision_start();
|
||||||
|
//void event_land_collision();
|
||||||
|
//void event_land_collision_end();
|
||||||
|
//void event_timer();
|
||||||
|
//void event_listen();
|
||||||
|
//void event_on_rez();
|
||||||
|
//void event_sensor();
|
||||||
|
//void event_no_sensor();
|
||||||
|
//void event_control();
|
||||||
|
//void event_money();
|
||||||
|
//void event_email();
|
||||||
|
//void event_at_target();
|
||||||
|
//void event_not_at_target();
|
||||||
|
//void event_at_rot_target();
|
||||||
|
//void event_not_at_rot_target();
|
||||||
|
//void event_run_time_permissions();
|
||||||
|
//void event_changed();
|
||||||
|
//void event_attach();
|
||||||
|
//void event_dataserver();
|
||||||
|
//void event_link_message();
|
||||||
|
//void event_moving_start();
|
||||||
|
//void event_moving_end();
|
||||||
|
//void event_object_rez();
|
||||||
|
//void event_remote_data();
|
||||||
|
//void event_http_response();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,435 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
internal partial class LSO_Parser
|
||||||
|
{
|
||||||
|
//internal Stack<Type> ILStack = new Stack<Type>();
|
||||||
|
//LSO_Enums MyLSO_Enums = new LSO_Enums();
|
||||||
|
|
||||||
|
internal bool LSL_PROCESS_OPCODE(ILGenerator il)
|
||||||
|
{
|
||||||
|
byte bp1;
|
||||||
|
UInt32 u32p1;
|
||||||
|
float fp1;
|
||||||
|
UInt16 opcode = br_read(1)[0];
|
||||||
|
Common.SendToDebug("OPCODE: " + ((LSO_Enums.Operation_Table) opcode).ToString());
|
||||||
|
string idesc = ((LSO_Enums.Operation_Table) opcode).ToString();
|
||||||
|
switch ((LSO_Enums.Operation_Table) opcode)
|
||||||
|
{
|
||||||
|
/***************
|
||||||
|
* IMPLEMENTED *
|
||||||
|
***************/
|
||||||
|
case LSO_Enums.Operation_Table.NOOP:
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Operation_Table.PUSHSP:
|
||||||
|
// Push Stack Top (Memory Address) to stack
|
||||||
|
Common.SendToDebug("Instruction " + idesc);
|
||||||
|
Common.SendToDebug("Instruction " + idesc +
|
||||||
|
": Description: Pushing Stack Top (Memory Address from header) to stack");
|
||||||
|
IL_Push(il, (UInt32) myHeader.SP);
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGB:
|
||||||
|
Common.SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
break;
|
||||||
|
// INTEGER
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGI:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ", Param1: " + u32p1);
|
||||||
|
IL_Push(il, u32p1);
|
||||||
|
break;
|
||||||
|
// FLOAT
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGF:
|
||||||
|
fp1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ", Param1: " + fp1);
|
||||||
|
IL_Push(il, fp1);
|
||||||
|
break;
|
||||||
|
// STRING
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGS:
|
||||||
|
string s = Read_String();
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ", Param1: " + s);
|
||||||
|
IL_Debug(il, "OPCODE: " + idesc + ":" + s);
|
||||||
|
IL_Push(il, s);
|
||||||
|
break;
|
||||||
|
// VECTOR z,y,x
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGV:
|
||||||
|
LSO_Enums.Vector v = new LSO_Enums.Vector();
|
||||||
|
v.Z = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
v.Y = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
v.X = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1 Z: " + v.Z);
|
||||||
|
Common.SendToDebug("Param1 Y: " + v.Y);
|
||||||
|
Common.SendToDebug("Param1 X: " + v.X);
|
||||||
|
IL_Push(il, v);
|
||||||
|
break;
|
||||||
|
// ROTATION s,z,y,x
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGQ:
|
||||||
|
LSO_Enums.Rotation r = new LSO_Enums.Rotation();
|
||||||
|
r.S = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
r.Z = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
r.Y = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
r.X = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1 S: " + r.S);
|
||||||
|
Common.SendToDebug("Param1 Z: " + r.Z);
|
||||||
|
Common.SendToDebug("Param1 Y: " + r.Y);
|
||||||
|
Common.SendToDebug("Param1 X: " + r.X);
|
||||||
|
IL_Push(il, r);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.PUSHE:
|
||||||
|
IL_Push(il, (UInt32) 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.PUSHARGE:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1);
|
||||||
|
//IL_Push(il, new string(" ".ToCharArray()[0], Convert.ToInt32(u32p1)));
|
||||||
|
IL_Push(il, u32p1);
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case LSO_Enums.Operation_Table.ADD:
|
||||||
|
case LSO_Enums.Operation_Table.SUB:
|
||||||
|
case LSO_Enums.Operation_Table.MUL:
|
||||||
|
case LSO_Enums.Operation_Table.DIV:
|
||||||
|
case LSO_Enums.Operation_Table.EQ:
|
||||||
|
case LSO_Enums.Operation_Table.NEQ:
|
||||||
|
case LSO_Enums.Operation_Table.LEQ:
|
||||||
|
case LSO_Enums.Operation_Table.GEQ:
|
||||||
|
case LSO_Enums.Operation_Table.LESS:
|
||||||
|
case LSO_Enums.Operation_Table.GREATER:
|
||||||
|
case LSO_Enums.Operation_Table.NEG:
|
||||||
|
case LSO_Enums.Operation_Table.MOD:
|
||||||
|
bp1 = br_read(1)[0];
|
||||||
|
Common.SendToDebug("Param1: " + bp1);
|
||||||
|
IL_CallBaseFunction(il, idesc, (UInt32) bp1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// NO ARGUMENTS
|
||||||
|
case LSO_Enums.Operation_Table.BITAND:
|
||||||
|
case LSO_Enums.Operation_Table.BITOR:
|
||||||
|
case LSO_Enums.Operation_Table.BITXOR:
|
||||||
|
case LSO_Enums.Operation_Table.BOOLAND:
|
||||||
|
case LSO_Enums.Operation_Table.BOOLOR:
|
||||||
|
case LSO_Enums.Operation_Table.BITNOT:
|
||||||
|
case LSO_Enums.Operation_Table.BOOLNOT:
|
||||||
|
IL_CallBaseFunction(il, idesc);
|
||||||
|
break;
|
||||||
|
// SHORT
|
||||||
|
case LSO_Enums.Operation_Table.CALLLIB_TWO_BYTE:
|
||||||
|
// TODO: What is size of short?
|
||||||
|
UInt16 U16p1 = BitConverter.ToUInt16(br_read(2), 0);
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ": Builtin Command: " +
|
||||||
|
((LSO_Enums.BuiltIn_Functions) U16p1).ToString());
|
||||||
|
//Common.SendToDebug("Param1: " + U16p1);
|
||||||
|
string fname = ((LSO_Enums.BuiltIn_Functions) U16p1).ToString();
|
||||||
|
|
||||||
|
bool cmdFound = false;
|
||||||
|
foreach (MethodInfo mi in typeof (LSL_BuiltIn_Commands_Interface).GetMethods())
|
||||||
|
{
|
||||||
|
// Found command
|
||||||
|
if (mi.Name == fname)
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod("GetLSL_BuiltIn", new Type[] {}));
|
||||||
|
// Pop required number of items from my stack to .Net stack
|
||||||
|
IL_PopToStack(il, mi.GetParameters().Length);
|
||||||
|
il.Emit(OpCodes.Callvirt, mi);
|
||||||
|
cmdFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cmdFound == false)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("ERROR: UNABLE TO LOCATE OPCODE " + idesc + " IN BASECLASS");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// RETURN
|
||||||
|
case LSO_Enums.Operation_Table.RETURN:
|
||||||
|
|
||||||
|
Common.SendToDebug("OPCODE: RETURN");
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.POP:
|
||||||
|
case LSO_Enums.Operation_Table.POPS:
|
||||||
|
case LSO_Enums.Operation_Table.POPL:
|
||||||
|
case LSO_Enums.Operation_Table.POPV:
|
||||||
|
case LSO_Enums.Operation_Table.POPQ:
|
||||||
|
// Pops a specific datatype from the stack
|
||||||
|
// We just ignore the datatype for now
|
||||||
|
IL_Pop(il);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// LONG
|
||||||
|
case LSO_Enums.Operation_Table.STORE:
|
||||||
|
case LSO_Enums.Operation_Table.STORES:
|
||||||
|
case LSO_Enums.Operation_Table.STOREL:
|
||||||
|
case LSO_Enums.Operation_Table.STOREV:
|
||||||
|
case LSO_Enums.Operation_Table.STOREQ:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1.ToString());
|
||||||
|
IL_CallBaseFunction(il, "StoreToLocal", u32p1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.STOREG:
|
||||||
|
case LSO_Enums.Operation_Table.STOREGS:
|
||||||
|
case LSO_Enums.Operation_Table.STOREGL:
|
||||||
|
case LSO_Enums.Operation_Table.STOREGV:
|
||||||
|
case LSO_Enums.Operation_Table.STOREGQ:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1.ToString());
|
||||||
|
IL_CallBaseFunction(il, "StoreToGlobal", u32p1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.LOADP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADSP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADLP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADVP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADQP:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1.ToString());
|
||||||
|
IL_CallBaseFunction(il, "StoreToLocal", u32p1);
|
||||||
|
IL_Pop(il);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.LOADGP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADGSP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADGLP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADGVP:
|
||||||
|
case LSO_Enums.Operation_Table.LOADGQP:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1.ToString());
|
||||||
|
IL_CallBaseFunction(il, "StoreToStatic", u32p1 - 6 + myHeader.GVR);
|
||||||
|
IL_Pop(il);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// PUSH FROM LOCAL FRAME
|
||||||
|
case LSO_Enums.Operation_Table.PUSH:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHS:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHL:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHV:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHQ:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1.ToString());
|
||||||
|
IL_CallBaseFunction(il, "GetFromLocal", u32p1);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// PUSH FROM STATIC FRAME
|
||||||
|
case LSO_Enums.Operation_Table.PUSHG:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHGS:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHGL:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHGV:
|
||||||
|
case LSO_Enums.Operation_Table.PUSHGQ:
|
||||||
|
u32p1 = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Param1: " + u32p1.ToString());
|
||||||
|
IL_CallBaseFunction(il, "GetFromStatic", u32p1 - 6 + myHeader.GVR);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
/***********************
|
||||||
|
* NOT IMPLEMENTED YET *
|
||||||
|
***********************/
|
||||||
|
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.POPIP:
|
||||||
|
case LSO_Enums.Operation_Table.POPSP:
|
||||||
|
case LSO_Enums.Operation_Table.POPSLR:
|
||||||
|
case LSO_Enums.Operation_Table.POPARG:
|
||||||
|
case LSO_Enums.Operation_Table.POPBP:
|
||||||
|
//Common.SendToDebug("Instruction " + idesc + ": Ignored");
|
||||||
|
Common.SendToDebug("Instruction " + idesc +
|
||||||
|
": Description: Drop x bytes from the stack (TODO: Only popping 1)");
|
||||||
|
//Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
|
||||||
|
IL_Pop(il);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
// None
|
||||||
|
case LSO_Enums.Operation_Table.PUSHIP:
|
||||||
|
// PUSH INSTRUCTION POINTER
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Operation_Table.PUSHBP:
|
||||||
|
|
||||||
|
case LSO_Enums.Operation_Table.PUSHEV:
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Operation_Table.PUSHEQ:
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
// LONG
|
||||||
|
case LSO_Enums.Operation_Table.JUMP:
|
||||||
|
Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
|
||||||
|
break;
|
||||||
|
// BYTE, LONG
|
||||||
|
case LSO_Enums.Operation_Table.JUMPIF:
|
||||||
|
case LSO_Enums.Operation_Table.JUMPNIF:
|
||||||
|
Common.SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
Common.SendToDebug("Param2: " + BitConverter.ToUInt32(br_read(4), 0));
|
||||||
|
break;
|
||||||
|
// LONG
|
||||||
|
case LSO_Enums.Operation_Table.STATE:
|
||||||
|
bp1 = br_read(1)[0];
|
||||||
|
//il.Emit(OpCodes.Ld); // Load local variable 0 onto stack
|
||||||
|
//il.Emit(OpCodes.Ldc_I4, 0); // Push index position
|
||||||
|
//il.Emit(OpCodes.Ldstr, EventList[p1]); // Push value
|
||||||
|
//il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value
|
||||||
|
break;
|
||||||
|
case LSO_Enums.Operation_Table.CALL:
|
||||||
|
Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
|
||||||
|
Common.SendToDebug("ERROR: Function CALL not implemented yet.");
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case LSO_Enums.Operation_Table.CAST:
|
||||||
|
bp1 = br_read(1)[0];
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ": Cast to type: " +
|
||||||
|
((LSO_Enums.OpCode_Cast_TypeDefs) bp1));
|
||||||
|
Common.SendToDebug("Param1: " + bp1);
|
||||||
|
switch ((LSO_Enums.OpCode_Cast_TypeDefs) bp1)
|
||||||
|
{
|
||||||
|
case LSO_Enums.OpCode_Cast_TypeDefs.String:
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ": il.Emit(OpCodes.Box, ILStack.Pop());");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Common.SendToDebug("Instruction " + idesc + ": Unknown cast type!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// LONG
|
||||||
|
case LSO_Enums.Operation_Table.STACKTOS:
|
||||||
|
case LSO_Enums.Operation_Table.STACKTOL:
|
||||||
|
Common.SendToDebug("Param1: " + BitConverter.ToUInt32(br_read(4), 0));
|
||||||
|
break;
|
||||||
|
// BYTE
|
||||||
|
case LSO_Enums.Operation_Table.PRINT:
|
||||||
|
case LSO_Enums.Operation_Table.CALLLIB:
|
||||||
|
Common.SendToDebug("Param1: " + br_read(1)[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_PopToStack(ILGenerator il)
|
||||||
|
{
|
||||||
|
IL_PopToStack(il, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_PopToStack(ILGenerator il, int count)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("IL_PopToStack();");
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
IL_CallBaseFunction(il, "POPToStack");
|
||||||
|
//il.Emit(OpCodes.Ldarg_0);
|
||||||
|
//il.Emit(OpCodes.Call,
|
||||||
|
// typeof(LSL_BaseClass).GetMethod("POPToStack",
|
||||||
|
// new Type[] { }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_Pop(ILGenerator il)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("IL_Pop();");
|
||||||
|
IL_CallBaseFunction(il, "POP");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_Debug(ILGenerator il, string text)
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldstr, text);
|
||||||
|
il.Emit(OpCodes.Call, typeof (Common).GetMethod("SendToDebug",
|
||||||
|
new Type[] {typeof (string)}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_CallBaseFunction(ILGenerator il, string methodname)
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod(methodname, new Type[] {}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_CallBaseFunction(ILGenerator il, string methodname, object data)
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
if (data.GetType() == typeof (string))
|
||||||
|
il.Emit(OpCodes.Ldstr, (string) data);
|
||||||
|
if (data.GetType() == typeof (UInt32))
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (UInt32) data);
|
||||||
|
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod(methodname, new Type[] {data.GetType()}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_Push(ILGenerator il, object data)
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldarg_0);
|
||||||
|
Common.SendToDebug("PUSH datatype: " + data.GetType());
|
||||||
|
|
||||||
|
IL_PushDataTypeToILStack(il, data);
|
||||||
|
|
||||||
|
il.Emit(OpCodes.Call, typeof (LSL_BaseClass).GetMethod("PUSH", new Type[] {data.GetType()}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_PushDataTypeToILStack(ILGenerator il, object data)
|
||||||
|
{
|
||||||
|
if (data.GetType() == typeof (UInt16))
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (UInt16) data);
|
||||||
|
il.Emit(OpCodes.Box, data.GetType());
|
||||||
|
}
|
||||||
|
if (data.GetType() == typeof (UInt32))
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (UInt32) data);
|
||||||
|
il.Emit(OpCodes.Box, data.GetType());
|
||||||
|
}
|
||||||
|
if (data.GetType() == typeof (Int32))
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (Int32) data);
|
||||||
|
il.Emit(OpCodes.Box, data.GetType());
|
||||||
|
}
|
||||||
|
if (data.GetType() == typeof (float))
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldc_I4, (float) data);
|
||||||
|
il.Emit(OpCodes.Box, data.GetType());
|
||||||
|
}
|
||||||
|
if (data.GetType() == typeof (string))
|
||||||
|
il.Emit(OpCodes.Ldstr, (string) data);
|
||||||
|
//if (data.GetType() == typeof(LSO_Enums.Rotation))
|
||||||
|
// il.Emit(OpCodes.Ldobj, (LSO_Enums.Rotation)data);
|
||||||
|
//if (data.GetType() == typeof(LSO_Enums.Vector))
|
||||||
|
// il.Emit(OpCodes.Ldobj, (LSO_Enums.Vector)data);
|
||||||
|
//if (data.GetType() == typeof(LSO_Enums.Key))
|
||||||
|
// il.Emit(OpCodes.Ldobj, (LSO_Enums.Key)data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,560 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
public static class LSO_Enums
|
||||||
|
{
|
||||||
|
//public System.Collections.Generic.Dictionary<Byte, Type> OpCode_Add_Types;
|
||||||
|
|
||||||
|
//LSO_Enums() {
|
||||||
|
// OpCode_Add_Types.Add(51, typeof(String));
|
||||||
|
// OpCode_Add_Types.Add(17, typeof(UInt32));
|
||||||
|
//}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public enum OpCode_Add_TypeDefs
|
||||||
|
{
|
||||||
|
String = 51,
|
||||||
|
UInt32 = 17
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public enum OpCode_Cast_TypeDefs
|
||||||
|
{
|
||||||
|
String = 19
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct Key
|
||||||
|
{
|
||||||
|
public string KeyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct Vector
|
||||||
|
{
|
||||||
|
public UInt32 Z;
|
||||||
|
public UInt32 Y;
|
||||||
|
public UInt32 X;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct Rotation
|
||||||
|
{
|
||||||
|
public UInt32 S;
|
||||||
|
public UInt32 Z;
|
||||||
|
public UInt32 Y;
|
||||||
|
public UInt32 X;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public enum Variable_Type_Codes
|
||||||
|
{
|
||||||
|
Void = 0,
|
||||||
|
Integer = 1,
|
||||||
|
Float = 2,
|
||||||
|
String = 3,
|
||||||
|
Key = 4,
|
||||||
|
Vector = 5,
|
||||||
|
Rotation = 6,
|
||||||
|
List = 7,
|
||||||
|
Null = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public enum Event_Mask_Values
|
||||||
|
{
|
||||||
|
state_entry = 0,
|
||||||
|
state_exit = 1,
|
||||||
|
touch_start = 2,
|
||||||
|
touch = 3,
|
||||||
|
touch_end = 4,
|
||||||
|
collision_start = 5,
|
||||||
|
collision = 6,
|
||||||
|
collision_end = 7,
|
||||||
|
land_collision_start = 8,
|
||||||
|
land_collision = 9,
|
||||||
|
land_collision_end = 10,
|
||||||
|
timer = 11,
|
||||||
|
listen = 12,
|
||||||
|
on_rez = 13,
|
||||||
|
sensor = 14,
|
||||||
|
no_sensor = 15,
|
||||||
|
control = 16,
|
||||||
|
money = 17,
|
||||||
|
email = 18,
|
||||||
|
at_target = 19,
|
||||||
|
not_at_target = 20,
|
||||||
|
at_rot_target = 21,
|
||||||
|
not_at_rot_target = 22,
|
||||||
|
run_time_permissions = 23,
|
||||||
|
changed = 24,
|
||||||
|
attach = 25,
|
||||||
|
dataserver = 26,
|
||||||
|
link_message = 27,
|
||||||
|
moving_start = 28,
|
||||||
|
moving_end = 29,
|
||||||
|
object_rez = 30,
|
||||||
|
remote_data = 31,
|
||||||
|
http_response = 32
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public enum Operation_Table
|
||||||
|
{
|
||||||
|
NOOP = 0x0,
|
||||||
|
POP = 0x1,
|
||||||
|
POPS = 0x2,
|
||||||
|
POPL = 0x3,
|
||||||
|
POPV = 0x4,
|
||||||
|
POPQ = 0x5,
|
||||||
|
POPARG = 0x6,
|
||||||
|
POPIP = 0x7,
|
||||||
|
POPBP = 0x8,
|
||||||
|
POPSP = 0x9,
|
||||||
|
POPSLR = 0xa,
|
||||||
|
DUP = 0x20,
|
||||||
|
DUPS = 0x21,
|
||||||
|
DUPL = 0x22,
|
||||||
|
DUPV = 0x23,
|
||||||
|
DUPQ = 0x24,
|
||||||
|
STORE = 0x30,
|
||||||
|
STORES = 0x31,
|
||||||
|
STOREL = 0x32,
|
||||||
|
STOREV = 0x33,
|
||||||
|
STOREQ = 0x34,
|
||||||
|
STOREG = 0x35,
|
||||||
|
STOREGS = 0x36,
|
||||||
|
STOREGL = 0x37,
|
||||||
|
STOREGV = 0x38,
|
||||||
|
STOREGQ = 0x39,
|
||||||
|
LOADP = 0x3a,
|
||||||
|
LOADSP = 0x3b,
|
||||||
|
LOADLP = 0x3c,
|
||||||
|
LOADVP = 0x3d,
|
||||||
|
LOADQP = 0x3e,
|
||||||
|
LOADGP = 0x3f,
|
||||||
|
LOADGSP = 0x40,
|
||||||
|
LOADGLP = 0x41,
|
||||||
|
LOADGVP = 0x42,
|
||||||
|
LOADGQP = 0x43,
|
||||||
|
PUSH = 0x50,
|
||||||
|
PUSHS = 0x51,
|
||||||
|
PUSHL = 0x52,
|
||||||
|
PUSHV = 0x53,
|
||||||
|
PUSHQ = 0x54,
|
||||||
|
PUSHG = 0x55,
|
||||||
|
PUSHGS = 0x56,
|
||||||
|
PUSHGL = 0x57,
|
||||||
|
PUSHGV = 0x58,
|
||||||
|
PUSHGQ = 0x59,
|
||||||
|
PUSHIP = 0x5a,
|
||||||
|
PUSHBP = 0x5b,
|
||||||
|
PUSHSP = 0x5c,
|
||||||
|
PUSHARGB = 0x5d,
|
||||||
|
PUSHARGI = 0x5e,
|
||||||
|
PUSHARGF = 0x5f,
|
||||||
|
PUSHARGS = 0x60,
|
||||||
|
PUSHARGV = 0x61,
|
||||||
|
PUSHARGQ = 0x62,
|
||||||
|
PUSHE = 0x63,
|
||||||
|
PUSHEV = 0x64,
|
||||||
|
PUSHEQ = 0x65,
|
||||||
|
PUSHARGE = 0x66,
|
||||||
|
ADD = 0x70,
|
||||||
|
SUB = 0x71,
|
||||||
|
MUL = 0x72,
|
||||||
|
DIV = 0x73,
|
||||||
|
MOD = 0x74,
|
||||||
|
EQ = 0x75,
|
||||||
|
NEQ = 0x76,
|
||||||
|
LEQ = 0x77,
|
||||||
|
GEQ = 0x78,
|
||||||
|
LESS = 0x79,
|
||||||
|
GREATER = 0x7a,
|
||||||
|
BITAND = 0x7b,
|
||||||
|
BITOR = 0x7c,
|
||||||
|
BITXOR = 0x7d,
|
||||||
|
BOOLAND = 0x7e,
|
||||||
|
BOOLOR = 0x7f,
|
||||||
|
NEG = 0x80,
|
||||||
|
BITNOT = 0x81,
|
||||||
|
BOOLNOT = 0x82,
|
||||||
|
JUMP = 0x90,
|
||||||
|
JUMPIF = 0x91,
|
||||||
|
JUMPNIF = 0x92,
|
||||||
|
STATE = 0x93,
|
||||||
|
CALL = 0x94,
|
||||||
|
RETURN = 0x95,
|
||||||
|
CAST = 0xa0,
|
||||||
|
STACKTOS = 0xb0,
|
||||||
|
STACKTOL = 0xb1,
|
||||||
|
PRINT = 0xc0,
|
||||||
|
CALLLIB = 0xd0,
|
||||||
|
CALLLIB_TWO_BYTE = 0xd1,
|
||||||
|
SHL = 0xe0,
|
||||||
|
SHR = 0xe1
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public enum BuiltIn_Functions
|
||||||
|
{
|
||||||
|
llSin = 0,
|
||||||
|
llCos = 1,
|
||||||
|
llTan = 2,
|
||||||
|
llAtan2 = 3,
|
||||||
|
llSqrt = 4,
|
||||||
|
llPow = 5,
|
||||||
|
llAbs = 6,
|
||||||
|
llFabs = 7,
|
||||||
|
llFrand = 8,
|
||||||
|
llFloor = 9,
|
||||||
|
llCeil = 10,
|
||||||
|
llRound = 11,
|
||||||
|
llVecMag = 12,
|
||||||
|
llVecNorm = 13,
|
||||||
|
llVecDist = 14,
|
||||||
|
llRot2Euler = 15,
|
||||||
|
llEuler2Rot = 16,
|
||||||
|
llAxes2Rot = 17,
|
||||||
|
llRot2Fwd = 18,
|
||||||
|
llRot2Left = 19,
|
||||||
|
llRot2Up = 20,
|
||||||
|
llRotBetween = 21,
|
||||||
|
llWhisper = 22,
|
||||||
|
llSay = 23,
|
||||||
|
llShout = 24,
|
||||||
|
llListen = 25,
|
||||||
|
llListenControl = 26,
|
||||||
|
llListenRemove = 27,
|
||||||
|
llSensor = 28,
|
||||||
|
llSensorRepeat = 29,
|
||||||
|
llSensorRemove = 30,
|
||||||
|
llDetectedName = 31,
|
||||||
|
llDetectedKey = 32,
|
||||||
|
llDetectedOwner = 33,
|
||||||
|
llDetectedType = 34,
|
||||||
|
llDetectedPos = 35,
|
||||||
|
llDetectedVel = 36,
|
||||||
|
llDetectedGrab = 37,
|
||||||
|
llDetectedRot = 38,
|
||||||
|
llDetectedGroup = 39,
|
||||||
|
llDetectedLinkNumber = 40,
|
||||||
|
llDie = 41,
|
||||||
|
llGround = 42,
|
||||||
|
llCloud = 43,
|
||||||
|
llWind = 44,
|
||||||
|
llSetStatus = 45,
|
||||||
|
llGetStatus = 46,
|
||||||
|
llSetScale = 47,
|
||||||
|
llGetScale = 48,
|
||||||
|
llSetColor = 49,
|
||||||
|
llGetAlpha = 50,
|
||||||
|
llSetAlpha = 51,
|
||||||
|
llGetColor = 52,
|
||||||
|
llSetTexture = 53,
|
||||||
|
llScaleTexture = 54,
|
||||||
|
llOffsetTexture = 55,
|
||||||
|
llRotateTexture = 56,
|
||||||
|
llGetTexture = 57,
|
||||||
|
llSetPos = 58,
|
||||||
|
llGetPos = 59,
|
||||||
|
llGetLocalPos = 60,
|
||||||
|
llSetRot = 61,
|
||||||
|
llGetRot = 62,
|
||||||
|
llGetLocalRot = 63,
|
||||||
|
llSetForce = 64,
|
||||||
|
llGetForce = 65,
|
||||||
|
llTarget = 66,
|
||||||
|
llTargetRemove = 67,
|
||||||
|
llRotTarget = 68,
|
||||||
|
llRotTargetRemove = 69,
|
||||||
|
llMoveToTarget = 70,
|
||||||
|
llStopMoveToTarget = 71,
|
||||||
|
llApplyImpulse = 72,
|
||||||
|
llApplyRotationalImpulse = 73,
|
||||||
|
llSetTorque = 74,
|
||||||
|
llGetTorque = 75,
|
||||||
|
llSetForceAndTorque = 76,
|
||||||
|
llGetVel = 77,
|
||||||
|
llGetAccel = 78,
|
||||||
|
llGetOmega = 79,
|
||||||
|
llGetTimeOfDay = 80,
|
||||||
|
llGetWallclock = 81,
|
||||||
|
llGetTime = 82,
|
||||||
|
llResetTime = 83,
|
||||||
|
llGetAndResetTime = 84,
|
||||||
|
llSound = 85,
|
||||||
|
llPlaySound = 86,
|
||||||
|
llLoopSound = 87,
|
||||||
|
llLoopSoundMaster = 88,
|
||||||
|
llLoopSoundSlave = 89,
|
||||||
|
llPlaySoundSlave = 90,
|
||||||
|
llTriggerSound = 91,
|
||||||
|
llStopSound = 92,
|
||||||
|
llPreloadSound = 93,
|
||||||
|
llGetSubString = 94,
|
||||||
|
llDeleteSubString = 95,
|
||||||
|
llInsertString = 96,
|
||||||
|
llToUpper = 97,
|
||||||
|
llToLower = 98,
|
||||||
|
llGiveMoney = 99,
|
||||||
|
llMakeExplosion = 100,
|
||||||
|
llMakeFountain = 101,
|
||||||
|
llMakeSmoke = 102,
|
||||||
|
llMakeFire = 103,
|
||||||
|
llRezObject = 104,
|
||||||
|
llLookAt = 105,
|
||||||
|
llStopLookAt = 106,
|
||||||
|
llSetTimerEvent = 107,
|
||||||
|
llSleep = 108,
|
||||||
|
llGetMass = 109,
|
||||||
|
llCollisionFilter = 110,
|
||||||
|
llTakeControls = 111,
|
||||||
|
llReleaseControls = 112,
|
||||||
|
llAttachToAvatar = 113,
|
||||||
|
llDetachFromAvatar = 114,
|
||||||
|
llTakeCamera = 115,
|
||||||
|
llReleaseCamera = 116,
|
||||||
|
llGetOwner = 117,
|
||||||
|
llInstantMessage = 118,
|
||||||
|
llEmail = 119,
|
||||||
|
llGetNextEmail = 120,
|
||||||
|
llGetKey = 121,
|
||||||
|
llSetBuoyancy = 122,
|
||||||
|
llSetHoverHeight = 123,
|
||||||
|
llStopHover = 124,
|
||||||
|
llMinEventDelay = 125,
|
||||||
|
llSoundPreload = 126,
|
||||||
|
llRotLookAt = 127,
|
||||||
|
llStringLength = 128,
|
||||||
|
llStartAnimation = 129,
|
||||||
|
llStopAnimation = 130,
|
||||||
|
llPointAt = 131,
|
||||||
|
llStopPointAt = 132,
|
||||||
|
llTargetOmega = 133,
|
||||||
|
llGetStartParameter = 134,
|
||||||
|
llGodLikeRezObject = 135,
|
||||||
|
llRequestPermissions = 136,
|
||||||
|
llGetPermissionsKey = 137,
|
||||||
|
llGetPermissions = 138,
|
||||||
|
llGetLinkNumber = 139,
|
||||||
|
llSetLinkColor = 140,
|
||||||
|
llCreateLink = 141,
|
||||||
|
llBreakLink = 142,
|
||||||
|
llBreakAllLinks = 143,
|
||||||
|
llGetLinkKey = 144,
|
||||||
|
llGetLinkName = 145,
|
||||||
|
llGetInventoryNumber = 146,
|
||||||
|
llGetInventoryName = 147,
|
||||||
|
llSetScriptState = 148,
|
||||||
|
llGetEnergy = 149,
|
||||||
|
llGiveInventory = 150,
|
||||||
|
llRemoveInventory = 151,
|
||||||
|
llSetText = 152,
|
||||||
|
llWater = 153,
|
||||||
|
llPassTouches = 154,
|
||||||
|
llRequestAgentData = 155,
|
||||||
|
llRequestInventoryData = 156,
|
||||||
|
llSetDamage = 157,
|
||||||
|
llTeleportAgentHome = 158,
|
||||||
|
llModifyLand = 159,
|
||||||
|
llCollisionSound = 160,
|
||||||
|
llCollisionSprite = 161,
|
||||||
|
llGetAnimation = 162,
|
||||||
|
llResetScript = 163,
|
||||||
|
llMessageLinked = 164,
|
||||||
|
llPushObject = 165,
|
||||||
|
llPassCollisions = 166,
|
||||||
|
llGetScriptName = 167,
|
||||||
|
llGetNumberOfSides = 168,
|
||||||
|
llAxisAngle2Rot = 169,
|
||||||
|
llRot2Axis = 170,
|
||||||
|
llRot2Angle = 171,
|
||||||
|
llAcos = 172,
|
||||||
|
llAsin = 173,
|
||||||
|
llAngleBetween = 174,
|
||||||
|
llGetInventoryKey = 175,
|
||||||
|
llAllowInventoryDrop = 176,
|
||||||
|
llGetSunDirection = 177,
|
||||||
|
llGetTextureOffset = 178,
|
||||||
|
llGetTextureScale = 179,
|
||||||
|
llGetTextureRot = 180,
|
||||||
|
llSubStringIndex = 181,
|
||||||
|
llGetOwnerKey = 182,
|
||||||
|
llGetCenterOfMass = 183,
|
||||||
|
llListSort = 184,
|
||||||
|
llGetListLength = 185,
|
||||||
|
llList2Integer = 186,
|
||||||
|
llList2Float = 187,
|
||||||
|
llList2String = 188,
|
||||||
|
llList2Key = 189,
|
||||||
|
llList2Vector = 190,
|
||||||
|
llList2Rot = 191,
|
||||||
|
llList2List = 192,
|
||||||
|
llDeleteSubList = 193,
|
||||||
|
llGetListEntryType = 194,
|
||||||
|
llList2CSV = 195,
|
||||||
|
llCSV2List = 196,
|
||||||
|
llListRandomize = 197,
|
||||||
|
llList2ListStrided = 198,
|
||||||
|
llGetRegionCorner = 199,
|
||||||
|
llListInsertList = 200,
|
||||||
|
llListFindList = 201,
|
||||||
|
llGetObjectName = 202,
|
||||||
|
llSetObjectName = 203,
|
||||||
|
llGetDate = 204,
|
||||||
|
llEdgeOfWorld = 205,
|
||||||
|
llGetAgentInfo = 206,
|
||||||
|
llAdjustSoundVolume = 207,
|
||||||
|
llSetSoundQueueing = 208,
|
||||||
|
llSetSoundRadius = 209,
|
||||||
|
llKey2Name = 210,
|
||||||
|
llSetTextureAnim = 211,
|
||||||
|
llTriggerSoundLimited = 212,
|
||||||
|
llEjectFromLand = 213,
|
||||||
|
llParseString2List = 214,
|
||||||
|
llOverMyLand = 215,
|
||||||
|
llGetLandOwnerAt = 216,
|
||||||
|
llGetNotecardLine = 217,
|
||||||
|
llGetAgentSize = 218,
|
||||||
|
llSameGroup = 219,
|
||||||
|
llUnSit = 220,
|
||||||
|
llGroundSlope = 221,
|
||||||
|
llGroundNormal = 222,
|
||||||
|
llGroundContour = 223,
|
||||||
|
llGetAttached = 224,
|
||||||
|
llGetFreeMemory = 225,
|
||||||
|
llGetRegionName = 226,
|
||||||
|
llGetRegionTimeDilation = 227,
|
||||||
|
llGetRegionFPS = 228,
|
||||||
|
llParticleSystem = 229,
|
||||||
|
llGroundRepel = 230,
|
||||||
|
llGiveInventoryList = 231,
|
||||||
|
llSetVehicleType = 232,
|
||||||
|
llSetVehicleFloatParam = 233,
|
||||||
|
llSetVehicleVectorParam = 234,
|
||||||
|
llSetVehicleRotationParam = 235,
|
||||||
|
llSetVehicleFlags = 236,
|
||||||
|
llRemoveVehicleFlags = 237,
|
||||||
|
llSitTarget = 238,
|
||||||
|
llAvatarOnSitTarget = 239,
|
||||||
|
llAddToLandPassList = 240,
|
||||||
|
llSetTouchText = 241,
|
||||||
|
llSetSitText = 242,
|
||||||
|
llSetCameraEyeOffset = 243,
|
||||||
|
llSetCameraAtOffset = 244,
|
||||||
|
llDumpList2String = 245,
|
||||||
|
llScriptDanger = 246,
|
||||||
|
llDialog = 247,
|
||||||
|
llVolumeDetect = 248,
|
||||||
|
llResetOtherScript = 249,
|
||||||
|
llGetScriptState = 250,
|
||||||
|
llRemoteLoadScript = 251,
|
||||||
|
llSetRemoteScriptAccessPin = 252,
|
||||||
|
llRemoteLoadScriptPin = 253,
|
||||||
|
llOpenRemoteDataChannel = 254,
|
||||||
|
llSendRemoteData = 255,
|
||||||
|
llRemoteDataReply = 256,
|
||||||
|
llCloseRemoteDataChannel = 257,
|
||||||
|
llMD5String = 258,
|
||||||
|
llSetPrimitiveParams = 259,
|
||||||
|
llStringToBase64 = 260,
|
||||||
|
llBase64ToString = 261,
|
||||||
|
llXorBase64Strings = 262,
|
||||||
|
llRemoteDataSetRegion = 263,
|
||||||
|
llLog10 = 264,
|
||||||
|
llLog = 265,
|
||||||
|
llGetAnimationList = 266,
|
||||||
|
llSetParcelMusicURL = 267,
|
||||||
|
llGetRootPosition = 268,
|
||||||
|
llGetRootRotation = 269,
|
||||||
|
llGetObjectDesc = 270,
|
||||||
|
llSetObjectDesc = 271,
|
||||||
|
llGetCreator = 272,
|
||||||
|
llGetTimestamp = 273,
|
||||||
|
llSetLinkAlpha = 274,
|
||||||
|
llGetNumberOfPrims = 275,
|
||||||
|
llGetNumberOfNotecardLines = 276,
|
||||||
|
llGetBoundingBox = 277,
|
||||||
|
llGetGeometricCenter = 278,
|
||||||
|
llGetPrimitiveParams = 279,
|
||||||
|
llIntegerToBase64 = 280,
|
||||||
|
llBase64ToInteger = 281,
|
||||||
|
llGetGMTclock = 282,
|
||||||
|
llGetSimulatorHostname = 283,
|
||||||
|
llSetLocalRot = 284,
|
||||||
|
llParseStringKeepNulls = 285,
|
||||||
|
llRezAtRoot = 286,
|
||||||
|
llGetObjectPermMask = 287,
|
||||||
|
llSetObjectPermMask = 288,
|
||||||
|
llGetInventoryPermMask = 289,
|
||||||
|
llSetInventoryPermMask = 290,
|
||||||
|
llGetInventoryCreator = 291,
|
||||||
|
llOwnerSay = 292,
|
||||||
|
llRequestSimulatorData = 293,
|
||||||
|
llForceMouselook = 294,
|
||||||
|
llGetObjectMass = 295,
|
||||||
|
llListReplaceList = 296,
|
||||||
|
llLoadURL = 297,
|
||||||
|
llParcelMediaCommandList = 298,
|
||||||
|
llParcelMediaQuery = 299,
|
||||||
|
llModPow = 300,
|
||||||
|
llGetInventoryType = 301,
|
||||||
|
llSetPayPrice = 302,
|
||||||
|
llGetCameraPos = 303,
|
||||||
|
llGetCameraRot = 304,
|
||||||
|
llSetPrimURL = 305,
|
||||||
|
llRefreshPrimURL = 306,
|
||||||
|
llEscapeURL = 307,
|
||||||
|
llUnescapeURL = 308,
|
||||||
|
llMapDestination = 309,
|
||||||
|
llAddToLandBanList = 310,
|
||||||
|
llRemoveFromLandPassList = 311,
|
||||||
|
llRemoveFromLandBanList = 312,
|
||||||
|
llSetCameraParams = 313,
|
||||||
|
llClearCameraParams = 314,
|
||||||
|
llListStatistics = 315,
|
||||||
|
llGetUnixTime = 316,
|
||||||
|
llGetParcelFlags = 317,
|
||||||
|
llGetRegionFlags = 318,
|
||||||
|
llXorBase64StringsCorrect = 319,
|
||||||
|
llHTTPRequest = 320,
|
||||||
|
llResetLandBanList = 321,
|
||||||
|
llResetLandPassList = 322,
|
||||||
|
llGetParcelPrimCount = 323,
|
||||||
|
llGetParcelPrimOwners = 324,
|
||||||
|
llGetObjectPrimCount = 325,
|
||||||
|
llGetParcelMaxPrims = 326,
|
||||||
|
llGetParcelDetails = 327
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,729 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Emit;
|
||||||
|
using System.Text;
|
||||||
|
using OpenSim.Region.ScriptEngine.LSOEngine.LSO;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
internal partial class LSO_Parser
|
||||||
|
{
|
||||||
|
private string FileName;
|
||||||
|
private FileStream fs;
|
||||||
|
private BinaryReader br;
|
||||||
|
internal LSO_Struct.Header myHeader;
|
||||||
|
internal Dictionary<long, LSO_Struct.StaticBlock> StaticBlocks = new Dictionary<long, LSO_Struct.StaticBlock>();
|
||||||
|
//private System.Collections.Hashtable StaticBlocks = new System.Collections.Hashtable();
|
||||||
|
|
||||||
|
private TypeBuilder typeBuilder;
|
||||||
|
private List<string> EventList = new List<string>();
|
||||||
|
|
||||||
|
public LSO_Parser(string _FileName, TypeBuilder _typeBuilder)
|
||||||
|
{
|
||||||
|
FileName = _FileName;
|
||||||
|
typeBuilder = _typeBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void OpenFile()
|
||||||
|
{
|
||||||
|
// Open
|
||||||
|
Common.SendToDebug("Opening filename: " + FileName);
|
||||||
|
fs = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||||
|
br = new BinaryReader(fs, Encoding.BigEndianUnicode);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void CloseFile()
|
||||||
|
{
|
||||||
|
// Close
|
||||||
|
br.Close();
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parse LSO file.
|
||||||
|
/// </summary>
|
||||||
|
public void Parse()
|
||||||
|
{
|
||||||
|
// The LSO Format consist of 6 major blocks: header, statics, functions, states, heap, and stack.
|
||||||
|
|
||||||
|
|
||||||
|
// HEADER BLOCK
|
||||||
|
Common.SendToDebug("Reading HEADER BLOCK at: 0");
|
||||||
|
fs.Seek(0, SeekOrigin.Begin);
|
||||||
|
myHeader = new LSO_Struct.Header();
|
||||||
|
myHeader.TM = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.IP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.VN = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.BP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.SP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.HR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.HP = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.CS = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.NS = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.CE = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.IE = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.ER = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.FR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.SLR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.GVR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.GFR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.PR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.ESR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.SR = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myHeader.NCE = BitConverter.ToUInt64(br_read(8), 0);
|
||||||
|
myHeader.NIE = BitConverter.ToUInt64(br_read(8), 0);
|
||||||
|
myHeader.NER = BitConverter.ToUInt64(br_read(8), 0);
|
||||||
|
|
||||||
|
// Print Header Block to debug
|
||||||
|
Common.SendToDebug("TM - Top of memory (size): " + myHeader.TM);
|
||||||
|
Common.SendToDebug("IP - Instruction Pointer (0=not running): " + myHeader.IP);
|
||||||
|
Common.SendToDebug("VN - Version number: " + myHeader.VN);
|
||||||
|
Common.SendToDebug("BP - Local Frame Pointer: " + myHeader.BP);
|
||||||
|
Common.SendToDebug("SP - Stack Pointer: " + myHeader.SP);
|
||||||
|
Common.SendToDebug("HR - Heap Register: " + myHeader.HR);
|
||||||
|
Common.SendToDebug("HP - Heap Pointer: " + myHeader.HP);
|
||||||
|
Common.SendToDebug("CS - Current State: " + myHeader.CS);
|
||||||
|
Common.SendToDebug("NS - Next State: " + myHeader.NS);
|
||||||
|
Common.SendToDebug("CE - Current Events: " + myHeader.CE);
|
||||||
|
Common.SendToDebug("IE - In Event: " + myHeader.IE);
|
||||||
|
Common.SendToDebug("ER - Event Register: " + myHeader.ER);
|
||||||
|
Common.SendToDebug("FR - Fault Register: " + myHeader.FR);
|
||||||
|
Common.SendToDebug("SLR - Sleep Register: " + myHeader.SLR);
|
||||||
|
Common.SendToDebug("GVR - Global Variable Register: " + myHeader.GVR);
|
||||||
|
Common.SendToDebug("GFR - Global Function Register: " + myHeader.GFR);
|
||||||
|
Common.SendToDebug("PR - Parameter Register: " + myHeader.PR);
|
||||||
|
Common.SendToDebug("ESR - Energy Supply Register: " + myHeader.ESR);
|
||||||
|
Common.SendToDebug("SR - State Register: " + myHeader.SR);
|
||||||
|
Common.SendToDebug("NCE - 64-bit Current Events: " + myHeader.NCE);
|
||||||
|
Common.SendToDebug("NIE - 64-bit In Events: " + myHeader.NIE);
|
||||||
|
Common.SendToDebug("NER - 64-bit Event Register: " + myHeader.NER);
|
||||||
|
Common.SendToDebug("Read position when exiting HEADER BLOCK: " + fs.Position);
|
||||||
|
|
||||||
|
// STATIC BLOCK
|
||||||
|
Common.SendToDebug("Reading STATIC BLOCK at: " + myHeader.GVR);
|
||||||
|
fs.Seek(myHeader.GVR, SeekOrigin.Begin);
|
||||||
|
int StaticBlockCount = 0;
|
||||||
|
// Read function blocks until we hit GFR
|
||||||
|
while (fs.Position < myHeader.GFR)
|
||||||
|
{
|
||||||
|
StaticBlockCount++;
|
||||||
|
long startReadPos = fs.Position;
|
||||||
|
Common.SendToDebug("Reading Static Block " + StaticBlockCount + " at: " + startReadPos);
|
||||||
|
|
||||||
|
//fs.Seek(myHeader.GVR, SeekOrigin.Begin);
|
||||||
|
LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock();
|
||||||
|
myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStaticBlock.ObjectType = br_read(1)[0];
|
||||||
|
Common.SendToDebug("Static Block ObjectType: " +
|
||||||
|
((LSO_Enums.Variable_Type_Codes) myStaticBlock.ObjectType).ToString());
|
||||||
|
myStaticBlock.Unknown = br_read(1)[0];
|
||||||
|
// Size of datatype varies -- what about strings?
|
||||||
|
if (myStaticBlock.ObjectType != 0)
|
||||||
|
myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType));
|
||||||
|
|
||||||
|
StaticBlocks.Add((UInt32) startReadPos, myStaticBlock);
|
||||||
|
}
|
||||||
|
Common.SendToDebug("Number of Static Blocks read: " + StaticBlockCount);
|
||||||
|
|
||||||
|
|
||||||
|
// FUNCTION BLOCK
|
||||||
|
// Always right after STATIC BLOCK
|
||||||
|
LSO_Struct.FunctionBlock myFunctionBlock = new LSO_Struct.FunctionBlock();
|
||||||
|
if (myHeader.GFR == myHeader.SR)
|
||||||
|
{
|
||||||
|
// If GFR and SR are at same position then there is no fuction block
|
||||||
|
Common.SendToDebug("No FUNCTION BLOCK found");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Reading FUNCTION BLOCK at: " + myHeader.GFR);
|
||||||
|
fs.Seek(myHeader.GFR, SeekOrigin.Begin);
|
||||||
|
myFunctionBlock.FunctionCount = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Number of functions in Fuction Block: " + myFunctionBlock.FunctionCount);
|
||||||
|
if (myFunctionBlock.FunctionCount > 0)
|
||||||
|
{
|
||||||
|
myFunctionBlock.CodeChunkPointer = new UInt32[myFunctionBlock.FunctionCount];
|
||||||
|
for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Reading function " + i + " at: " + fs.Position);
|
||||||
|
// TODO: ADD TO FUNCTION LIST (How do we identify it later?)
|
||||||
|
// Note! Absolute position
|
||||||
|
myFunctionBlock.CodeChunkPointer[i] = BitConverter.ToUInt32(br_read(4), 0) + myHeader.GFR;
|
||||||
|
Common.SendToDebug("Fuction " + i + " code chunk position: " +
|
||||||
|
myFunctionBlock.CodeChunkPointer[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// STATE FRAME BLOCK
|
||||||
|
// Always right after FUNCTION BLOCK
|
||||||
|
Common.SendToDebug("Reading STATE BLOCK at: " + myHeader.SR);
|
||||||
|
fs.Seek(myHeader.SR, SeekOrigin.Begin);
|
||||||
|
LSO_Struct.StateFrameBlock myStateFrameBlock = new LSO_Struct.StateFrameBlock();
|
||||||
|
myStateFrameBlock.StateCount = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
if (myStateFrameBlock.StateCount > 0)
|
||||||
|
{
|
||||||
|
// Initialize array
|
||||||
|
myStateFrameBlock.StatePointer = new LSO_Struct.StatePointerBlock[myStateFrameBlock.StateCount];
|
||||||
|
for (int i = 0; i < myStateFrameBlock.StateCount; i++)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Reading STATE POINTER BLOCK " + (i + 1) + " at: " + fs.Position);
|
||||||
|
// Position is relative to state frame
|
||||||
|
myStateFrameBlock.StatePointer[i].Location = myHeader.SR + BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStateFrameBlock.StatePointer[i].EventMask = new BitArray(br_read(8));
|
||||||
|
Common.SendToDebug("Pointer: " + myStateFrameBlock.StatePointer[i].Location);
|
||||||
|
Common.SendToDebug("Total potential EventMask bits: " +
|
||||||
|
myStateFrameBlock.StatePointer[i].EventMask.Count);
|
||||||
|
|
||||||
|
//// Read STATE BLOCK
|
||||||
|
//long CurPos = fs.Position;
|
||||||
|
//fs.Seek(CurPos, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// STATE BLOCK
|
||||||
|
// For each StateFrameBlock there is one StateBlock with multiple event handlers
|
||||||
|
|
||||||
|
if (myStateFrameBlock.StateCount > 0)
|
||||||
|
{
|
||||||
|
// Go through all State Frame Pointers found
|
||||||
|
for (int i = 0; i < myStateFrameBlock.StateCount; i++)
|
||||||
|
{
|
||||||
|
fs.Seek(myStateFrameBlock.StatePointer[i].Location, SeekOrigin.Begin);
|
||||||
|
Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " at: " + fs.Position);
|
||||||
|
|
||||||
|
// READ: STATE BLOCK HEADER
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock = new LSO_Struct.StateBlock();
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StartPos = (UInt32) fs.Position; // Note
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.Unknown = br_read(1)[0];
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.EndPos = (UInt32) fs.Position; // Note
|
||||||
|
Common.SendToDebug("State block Start Pos: " + myStateFrameBlock.StatePointer[i].StateBlock.StartPos);
|
||||||
|
Common.SendToDebug("State block Header Size: " +
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.HeaderSize);
|
||||||
|
Common.SendToDebug("State block Header End Pos: " +
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.EndPos);
|
||||||
|
|
||||||
|
// We need to count number of bits flagged in EventMask?
|
||||||
|
|
||||||
|
|
||||||
|
// for each bit in myStateFrameBlock.StatePointer[i].EventMask
|
||||||
|
|
||||||
|
// ADDING TO ALL RIGHT NOW, SHOULD LIMIT TO ONLY THE ONES IN USE
|
||||||
|
//TODO: Create event hooks
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers =
|
||||||
|
new LSO_Struct.StateBlockHandler[myStateFrameBlock.StatePointer[i].EventMask.Count - 1];
|
||||||
|
for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
|
||||||
|
{
|
||||||
|
if (myStateFrameBlock.StatePointer[i].EventMask.Get(ii) == true)
|
||||||
|
{
|
||||||
|
// We got an event
|
||||||
|
// READ: STATE BLOCK HANDLER
|
||||||
|
Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER matching EVENT MASK " + ii +
|
||||||
|
" (" + ((LSO_Enums.Event_Mask_Values) ii).ToString() + ") at: " +
|
||||||
|
fs.Position);
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer =
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.EndPos +
|
||||||
|
BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CallFrameSize =
|
||||||
|
BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" +
|
||||||
|
((LSO_Enums.Event_Mask_Values) ii).ToString() + ") Code Chunk Pointer: " +
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].
|
||||||
|
CodeChunkPointer);
|
||||||
|
Common.SendToDebug("Reading STATE BLOCK " + (i + 1) + " HANDLER EVENT MASK " + ii + " (" +
|
||||||
|
((LSO_Enums.Event_Mask_Values) ii).ToString() + ") Call Frame Size: " +
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].
|
||||||
|
CallFrameSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//// READ FUNCTION CODE CHUNKS
|
||||||
|
//// Functions + Function start pos (GFR)
|
||||||
|
//// TODO: Somehow be able to identify and reference this
|
||||||
|
//LSO_Struct.CodeChunk[] myFunctionCodeChunk;
|
||||||
|
//if (myFunctionBlock.FunctionCount > 0)
|
||||||
|
//{
|
||||||
|
// myFunctionCodeChunk = new LSO_Struct.CodeChunk[myFunctionBlock.FunctionCount];
|
||||||
|
// for (int i = 0; i < myFunctionBlock.FunctionCount; i++)
|
||||||
|
// {
|
||||||
|
// Common.SendToDebug("Reading Function Code Chunk " + i);
|
||||||
|
// myFunctionCodeChunk[i] = GetCodeChunk((UInt32)myFunctionBlock.CodeChunkPointer[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
//}
|
||||||
|
// READ EVENT CODE CHUNKS
|
||||||
|
LSO_Struct.CodeChunk[] myEventCodeChunk;
|
||||||
|
if (myStateFrameBlock.StateCount > 0)
|
||||||
|
{
|
||||||
|
myEventCodeChunk = new LSO_Struct.CodeChunk[myStateFrameBlock.StateCount];
|
||||||
|
for (int i = 0; i < myStateFrameBlock.StateCount; i++)
|
||||||
|
{
|
||||||
|
// TODO: Somehow organize events and functions so they can be found again,
|
||||||
|
// two level search ain't no good
|
||||||
|
for (int ii = 0; ii < myStateFrameBlock.StatePointer[i].EventMask.Count - 1; ii++)
|
||||||
|
{
|
||||||
|
if (myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer > 0)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Reading Event Code Chunk state " + i + ", event " +
|
||||||
|
(LSO_Enums.Event_Mask_Values) ii);
|
||||||
|
|
||||||
|
|
||||||
|
// Override a Method / Function
|
||||||
|
string eventname = i + "_event_" + (LSO_Enums.Event_Mask_Values) ii;
|
||||||
|
Common.SendToDebug("Event Name: " + eventname);
|
||||||
|
if (Common.IL_ProcessCodeChunks)
|
||||||
|
{
|
||||||
|
EventList.Add(eventname);
|
||||||
|
|
||||||
|
// JUMP TO CODE PROCESSOR
|
||||||
|
ProcessCodeChunk(
|
||||||
|
myStateFrameBlock.StatePointer[i].StateBlock.StateBlockHandlers[ii].CodeChunkPointer,
|
||||||
|
typeBuilder, eventname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Common.IL_CreateFunctionList)
|
||||||
|
IL_INSERT_FUNCTIONLIST();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal LSO_Struct.HeapBlock GetHeap(UInt32 pos)
|
||||||
|
{
|
||||||
|
// HEAP BLOCK
|
||||||
|
// TODO:? Special read for strings/keys (null terminated) and lists (pointers to other HEAP entries)
|
||||||
|
Common.SendToDebug("Reading HEAP BLOCK at: " + pos);
|
||||||
|
fs.Seek(pos, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
LSO_Struct.HeapBlock myHeapBlock = new LSO_Struct.HeapBlock();
|
||||||
|
myHeapBlock.DataBlockSize = BitConverter.ToInt32(br_read(4), 0);
|
||||||
|
myHeapBlock.ObjectType = br_read(1)[0];
|
||||||
|
myHeapBlock.ReferenceCount = BitConverter.ToUInt16(br_read(2), 0);
|
||||||
|
//myHeapBlock.Data = br_read(getObjectSize(myHeapBlock.ObjectType));
|
||||||
|
// Don't read it reversed
|
||||||
|
myHeapBlock.Data = new byte[myHeapBlock.DataBlockSize - 1];
|
||||||
|
br.Read(myHeapBlock.Data, 0, myHeapBlock.DataBlockSize - 1);
|
||||||
|
|
||||||
|
|
||||||
|
Common.SendToDebug("Heap Block Data Block Size: " + myHeapBlock.DataBlockSize);
|
||||||
|
Common.SendToDebug("Heap Block ObjectType: " +
|
||||||
|
((LSO_Enums.Variable_Type_Codes) myHeapBlock.ObjectType).ToString());
|
||||||
|
Common.SendToDebug("Heap Block Reference Count: " + myHeapBlock.ReferenceCount);
|
||||||
|
|
||||||
|
return myHeapBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] br_read(int len)
|
||||||
|
{
|
||||||
|
if (len <= 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[len];
|
||||||
|
for (int i = len - 1; i > -1; i--)
|
||||||
|
bytes[i] = br.ReadByte();
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
catch (Exception e) // NOTLEGIT: No user related exceptions throwable here?
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Exception: " + e.ToString());
|
||||||
|
throw (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//private byte[] br_read_smallendian(int len)
|
||||||
|
//{
|
||||||
|
// byte[] bytes = new byte[len];
|
||||||
|
// br.Read(bytes,0, len);
|
||||||
|
// return bytes;
|
||||||
|
//}
|
||||||
|
private Type getLLObjectType(byte objectCode)
|
||||||
|
{
|
||||||
|
switch ((LSO_Enums.Variable_Type_Codes) objectCode)
|
||||||
|
{
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Void:
|
||||||
|
return typeof (void);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Integer:
|
||||||
|
return typeof (UInt32);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Float:
|
||||||
|
return typeof (float);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.String:
|
||||||
|
return typeof (string);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Key:
|
||||||
|
return typeof (string);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Vector:
|
||||||
|
return typeof (LSO_Enums.Vector);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Rotation:
|
||||||
|
return typeof (LSO_Enums.Rotation);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.List:
|
||||||
|
Common.SendToDebug("TODO: List datatype not implemented yet!");
|
||||||
|
return typeof (ArrayList);
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Null:
|
||||||
|
Common.SendToDebug("TODO: Datatype null is not implemented, using string instead.!");
|
||||||
|
return typeof (string);
|
||||||
|
default:
|
||||||
|
Common.SendToDebug("Lookup of LSL datatype " + objectCode +
|
||||||
|
" to .Net datatype failed: Unknown LSL datatype. Defaulting to object.");
|
||||||
|
return typeof (object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getObjectSize(byte ObjectType)
|
||||||
|
{
|
||||||
|
switch ((LSO_Enums.Variable_Type_Codes) ObjectType)
|
||||||
|
{
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Integer:
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Float:
|
||||||
|
case LSO_Enums.Variable_Type_Codes.String:
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Key:
|
||||||
|
case LSO_Enums.Variable_Type_Codes.List:
|
||||||
|
return 4;
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Vector:
|
||||||
|
return 12;
|
||||||
|
case LSO_Enums.Variable_Type_Codes.Rotation:
|
||||||
|
return 16;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string Read_String()
|
||||||
|
{
|
||||||
|
string ret = String.Empty;
|
||||||
|
byte reader = br_read(1)[0];
|
||||||
|
while (reader != 0x000)
|
||||||
|
{
|
||||||
|
ret += (char) reader;
|
||||||
|
reader = br_read(1)[0];
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a code chunk and creates IL
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pos">Absolute position in file. REMEMBER TO ADD myHeader.GFR!</param>
|
||||||
|
/// <param name="typeBuilder">TypeBuilder for assembly</param>
|
||||||
|
/// <param name="eventname">Name of event (function) to generate</param>
|
||||||
|
private void ProcessCodeChunk(UInt32 pos, TypeBuilder typeBuilder, string eventname)
|
||||||
|
{
|
||||||
|
LSO_Struct.CodeChunk myCodeChunk = new LSO_Struct.CodeChunk();
|
||||||
|
|
||||||
|
Common.SendToDebug("Reading Function Code Chunk at: " + pos);
|
||||||
|
fs.Seek(pos, SeekOrigin.Begin);
|
||||||
|
myCodeChunk.CodeChunkHeaderSize = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
Common.SendToDebug("CodeChunk Header Size: " + myCodeChunk.CodeChunkHeaderSize);
|
||||||
|
// Read until null
|
||||||
|
myCodeChunk.Comment = Read_String();
|
||||||
|
Common.SendToDebug("Function comment: " + myCodeChunk.Comment);
|
||||||
|
myCodeChunk.ReturnTypePos = br_read(1)[0];
|
||||||
|
myCodeChunk.ReturnType = GetStaticBlock((long) myCodeChunk.ReturnTypePos + (long) myHeader.GVR);
|
||||||
|
Common.SendToDebug("Return type #" + myCodeChunk.ReturnType.ObjectType + ": " +
|
||||||
|
((LSO_Enums.Variable_Type_Codes) myCodeChunk.ReturnType.ObjectType).ToString());
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: How to determine number of codechunks -- does this method work?
|
||||||
|
myCodeChunk.CodeChunkArguments = new List<LSO_Struct.CodeChunkArgument>();
|
||||||
|
byte reader = br_read(1)[0];
|
||||||
|
reader = br_read(1)[0];
|
||||||
|
|
||||||
|
// NOTE ON CODE CHUNK ARGUMENTS
|
||||||
|
// This determins type definition
|
||||||
|
int ccount = 0;
|
||||||
|
while (reader != 0x000)
|
||||||
|
{
|
||||||
|
ccount++;
|
||||||
|
Common.SendToDebug("Reading Code Chunk Argument " + ccount);
|
||||||
|
LSO_Struct.CodeChunkArgument CCA = new LSO_Struct.CodeChunkArgument();
|
||||||
|
CCA.FunctionReturnTypePos = reader;
|
||||||
|
reader = br_read(1)[0];
|
||||||
|
CCA.NullString = reader;
|
||||||
|
CCA.FunctionReturnType = GetStaticBlock(CCA.FunctionReturnTypePos + myHeader.GVR);
|
||||||
|
myCodeChunk.CodeChunkArguments.Add(CCA);
|
||||||
|
Common.SendToDebug("Code Chunk Argument " + ccount + " type #" + CCA.FunctionReturnType.ObjectType +
|
||||||
|
": " + (LSO_Enums.Variable_Type_Codes) CCA.FunctionReturnType.ObjectType);
|
||||||
|
}
|
||||||
|
// Create string array
|
||||||
|
Type[] MethodArgs = new Type[myCodeChunk.CodeChunkArguments.Count];
|
||||||
|
for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++)
|
||||||
|
{
|
||||||
|
MethodArgs[_ic] = getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType.ObjectType);
|
||||||
|
Common.SendToDebug("Method argument " + _ic + ": " +
|
||||||
|
getLLObjectType(myCodeChunk.CodeChunkArguments[_ic].FunctionReturnType.ObjectType).
|
||||||
|
ToString());
|
||||||
|
}
|
||||||
|
// End marker is 0x000
|
||||||
|
myCodeChunk.EndMarker = reader;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Emit: START OF METHOD (FUNCTION)
|
||||||
|
//
|
||||||
|
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":MethodBuilder methodBuilder = typeBuilder.DefineMethod...");
|
||||||
|
MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
|
||||||
|
MethodAttributes.Public,
|
||||||
|
typeof (void),
|
||||||
|
new Type[] {typeof (object)});
|
||||||
|
//MethodArgs);
|
||||||
|
//typeof(void), //getLLObjectType(myCodeChunk.ReturnType),
|
||||||
|
// new Type[] { typeof(object) }, //);
|
||||||
|
|
||||||
|
//Common.SendToDebug("CLR:" + eventname + ":typeBuilder.DefineMethodOverride(methodBuilder...");
|
||||||
|
//typeBuilder.DefineMethodOverride(methodBuilder,
|
||||||
|
// typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
|
||||||
|
|
||||||
|
// Create the IL generator
|
||||||
|
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":ILGenerator il = methodBuilder.GetILGenerator();");
|
||||||
|
ILGenerator il = methodBuilder.GetILGenerator();
|
||||||
|
|
||||||
|
|
||||||
|
if (Common.IL_UseTryCatch)
|
||||||
|
IL_INSERT_TRY(il, eventname);
|
||||||
|
|
||||||
|
|
||||||
|
// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
|
||||||
|
//Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
|
||||||
|
//il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
// ("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
//Common.SendToDebug("STARTUP: il.Emit(OpCodes.Ldc_I4_S, 0);");
|
||||||
|
|
||||||
|
//il.Emit(OpCodes.Ldc_I4_S, 0);
|
||||||
|
for (int _ic = 0; _ic < myCodeChunk.CodeChunkArguments.Count; _ic++)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("PARAMS: il.Emit(OpCodes.Ldarg, " + _ic + ");");
|
||||||
|
il.Emit(OpCodes.Ldarg, _ic);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CALLING OPCODE PROCESSOR, one command at the time TO GENERATE IL
|
||||||
|
//
|
||||||
|
bool FoundRet = false;
|
||||||
|
while (FoundRet == false)
|
||||||
|
{
|
||||||
|
FoundRet = LSL_PROCESS_OPCODE(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Common.IL_UseTryCatch)
|
||||||
|
IL_INSERT_END_TRY(il, eventname);
|
||||||
|
|
||||||
|
// Emit: RETURN FROM METHOD
|
||||||
|
il.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_INSERT_FUNCTIONLIST()
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Creating function list");
|
||||||
|
|
||||||
|
|
||||||
|
string eventname = "GetFunctions";
|
||||||
|
|
||||||
|
Common.SendToDebug("Creating IL " + eventname);
|
||||||
|
// Define a private String field.
|
||||||
|
//FieldBuilder myField = myTypeBuilder.DefineField("EventList", typeof(String[]), FieldAttributes.Public);
|
||||||
|
|
||||||
|
|
||||||
|
//FieldBuilder mem = typeBuilder.DefineField("mem", typeof(Array), FieldAttributes.Private);
|
||||||
|
|
||||||
|
|
||||||
|
MethodBuilder methodBuilder = typeBuilder.DefineMethod(eventname,
|
||||||
|
MethodAttributes.Public,
|
||||||
|
typeof (string[]),
|
||||||
|
null);
|
||||||
|
|
||||||
|
//typeBuilder.DefineMethodOverride(methodBuilder,
|
||||||
|
// typeof(LSL_CLRInterface.LSLScript).GetMethod(eventname));
|
||||||
|
|
||||||
|
ILGenerator il = methodBuilder.GetILGenerator();
|
||||||
|
|
||||||
|
|
||||||
|
// IL_INSERT_TRY(il, eventname);
|
||||||
|
|
||||||
|
// // Push string to stack
|
||||||
|
// il.Emit(OpCodes.Ldstr, "Inside " + eventname);
|
||||||
|
|
||||||
|
//// Push Console.WriteLine command to stack ... Console.WriteLine("Hello World!");
|
||||||
|
//il.Emit(OpCodes.Call, typeof(Console).GetMethod
|
||||||
|
// ("WriteLine", new Type[] { typeof(string) }));
|
||||||
|
|
||||||
|
//initIL.Emit(OpCodes.Newobj, typeof(string[]));
|
||||||
|
|
||||||
|
//string[] MyArray = new string[2] { "TestItem1" , "TestItem2" };
|
||||||
|
|
||||||
|
////il.Emit(OpCodes.Ldarg_0);
|
||||||
|
|
||||||
|
il.DeclareLocal(typeof (string[]));
|
||||||
|
|
||||||
|
////il.Emit(OpCodes.Ldarg_0);
|
||||||
|
il.Emit(OpCodes.Ldc_I4, EventList.Count); // Specify array length
|
||||||
|
il.Emit(OpCodes.Newarr, typeof (String)); // create new string array
|
||||||
|
il.Emit(OpCodes.Stloc_0); // Store array as local variable 0 in stack
|
||||||
|
////SetFunctionList
|
||||||
|
|
||||||
|
for (int lv = 0; lv < EventList.Count; lv++)
|
||||||
|
{
|
||||||
|
il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack
|
||||||
|
il.Emit(OpCodes.Ldc_I4, lv); // Push index position
|
||||||
|
il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value
|
||||||
|
il.Emit(OpCodes.Stelem_Ref); // Perform array[index] = value
|
||||||
|
|
||||||
|
//il.Emit(OpCodes.Ldarg_0);
|
||||||
|
//il.Emit(OpCodes.Ldstr, EventList[lv]); // Push value
|
||||||
|
//il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("AddFunction", new Type[] { typeof(string) }));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// IL_INSERT_END_TRY(il, eventname);
|
||||||
|
|
||||||
|
|
||||||
|
il.Emit(OpCodes.Ldloc_0); // Load local variable 0 onto stack
|
||||||
|
// il.Emit(OpCodes.Call, typeof(LSL_BaseClass).GetMethod("SetFunctionList", new Type[] { typeof(Array) }));
|
||||||
|
|
||||||
|
il.Emit(OpCodes.Ret); // Return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void IL_INSERT_TRY(ILGenerator il, string eventname)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* CLR TRY
|
||||||
|
*/
|
||||||
|
//Common.SendToDebug("CLR:" + eventname + ":il.BeginExceptionBlock()");
|
||||||
|
il.BeginExceptionBlock();
|
||||||
|
|
||||||
|
// Push "Hello World!" string to stack
|
||||||
|
//Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
|
||||||
|
//il.Emit(OpCodes.Ldstr, "Starting CLR dynamic execution of: " + eventname);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void IL_INSERT_END_TRY(ILGenerator il, string eventname)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* CATCH
|
||||||
|
*/
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":il.BeginCatchBlock(typeof(Exception));");
|
||||||
|
il.BeginCatchBlock(typeof (Exception));
|
||||||
|
|
||||||
|
// Push "Hello World!" string to stack
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Ldstr...");
|
||||||
|
il.Emit(OpCodes.Ldstr, "Execption executing dynamic CLR function " + eventname + ": ");
|
||||||
|
|
||||||
|
//call void [mscorlib]System.Console::WriteLine(string)
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
|
||||||
|
il.Emit(OpCodes.Call, typeof (Console).GetMethod
|
||||||
|
("Write", new Type[] {typeof (string)}));
|
||||||
|
|
||||||
|
//callvirt instance string [mscorlib]System.Exception::get_Message()
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Callvirt...");
|
||||||
|
il.Emit(OpCodes.Callvirt, typeof (Exception).GetMethod
|
||||||
|
("get_Message"));
|
||||||
|
|
||||||
|
//call void [mscorlib]System.Console::WriteLine(string)
|
||||||
|
Common.SendToDebug("CLR:" + eventname + ":il.Emit(OpCodes.Call...");
|
||||||
|
il.Emit(OpCodes.Call, typeof (Console).GetMethod
|
||||||
|
("WriteLine", new Type[] {typeof (string)}));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CLR END TRY
|
||||||
|
*/
|
||||||
|
//Common.SendToDebug("CLR:" + eventname + ":il.EndExceptionBlock();");
|
||||||
|
il.EndExceptionBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LSO_Struct.StaticBlock GetStaticBlock(long pos)
|
||||||
|
{
|
||||||
|
long FirstPos = fs.Position;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UInt32 position = (UInt32) pos;
|
||||||
|
// STATIC BLOCK
|
||||||
|
Common.SendToDebug("Reading STATIC BLOCK at: " + position);
|
||||||
|
fs.Seek(position, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
if (StaticBlocks.ContainsKey(position) == true)
|
||||||
|
{
|
||||||
|
Common.SendToDebug("Found cached STATIC BLOCK");
|
||||||
|
|
||||||
|
|
||||||
|
return StaticBlocks[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
//int StaticBlockCount = 0;
|
||||||
|
// Read function blocks until we hit GFR
|
||||||
|
//while (fs.Position < myHeader.GFR)
|
||||||
|
//{
|
||||||
|
//StaticBlockCount++;
|
||||||
|
|
||||||
|
//Common.SendToDebug("Reading Static Block at: " + position);
|
||||||
|
|
||||||
|
//fs.Seek(myHeader.GVR, SeekOrigin.Begin);
|
||||||
|
LSO_Struct.StaticBlock myStaticBlock = new LSO_Struct.StaticBlock();
|
||||||
|
myStaticBlock.Static_Chunk_Header_Size = BitConverter.ToUInt32(br_read(4), 0);
|
||||||
|
myStaticBlock.ObjectType = br_read(1)[0];
|
||||||
|
Common.SendToDebug("Static Block ObjectType: " +
|
||||||
|
((LSO_Enums.Variable_Type_Codes) myStaticBlock.ObjectType).ToString());
|
||||||
|
myStaticBlock.Unknown = br_read(1)[0];
|
||||||
|
// Size of datatype varies
|
||||||
|
if (myStaticBlock.ObjectType != 0)
|
||||||
|
myStaticBlock.BlockVariable = br_read(getObjectSize(myStaticBlock.ObjectType));
|
||||||
|
|
||||||
|
StaticBlocks.Add(position, myStaticBlock);
|
||||||
|
//}
|
||||||
|
Common.SendToDebug("Done reading Static Block.");
|
||||||
|
return myStaticBlock;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Go back to original read pos
|
||||||
|
fs.Seek(FirstPos, SeekOrigin.Begin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/* Original code: Tedd Hansen */
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine.LSO
|
||||||
|
{
|
||||||
|
internal static class LSO_Struct
|
||||||
|
{
|
||||||
|
public struct Header
|
||||||
|
{
|
||||||
|
public UInt32 TM;
|
||||||
|
public UInt32 IP;
|
||||||
|
public UInt32 VN;
|
||||||
|
public UInt32 BP;
|
||||||
|
public UInt32 SP;
|
||||||
|
public UInt32 HR;
|
||||||
|
public UInt32 HP;
|
||||||
|
public UInt32 CS;
|
||||||
|
public UInt32 NS;
|
||||||
|
public UInt32 CE;
|
||||||
|
public UInt32 IE;
|
||||||
|
public UInt32 ER;
|
||||||
|
public UInt32 FR;
|
||||||
|
public UInt32 SLR;
|
||||||
|
public UInt32 GVR;
|
||||||
|
public UInt32 GFR;
|
||||||
|
public UInt32 PR;
|
||||||
|
public UInt32 ESR;
|
||||||
|
public UInt32 SR;
|
||||||
|
public UInt64 NCE;
|
||||||
|
public UInt64 NIE;
|
||||||
|
public UInt64 NER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct StaticBlock
|
||||||
|
{
|
||||||
|
public UInt32 Static_Chunk_Header_Size;
|
||||||
|
public byte ObjectType;
|
||||||
|
public byte Unknown;
|
||||||
|
public byte[] BlockVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not actually a structure
|
||||||
|
public struct StaticBlockVariable
|
||||||
|
{
|
||||||
|
public UInt32 Integer1;
|
||||||
|
public UInt32 Float1;
|
||||||
|
public UInt32 HeapPointer_String;
|
||||||
|
public UInt32 HeapPointer_Key;
|
||||||
|
public byte[] Vector_12;
|
||||||
|
public byte[] Rotation_16;
|
||||||
|
public UInt32 Pointer_List_Structure;
|
||||||
|
} */
|
||||||
|
|
||||||
|
public struct HeapBlock
|
||||||
|
{
|
||||||
|
public Int32 DataBlockSize;
|
||||||
|
public byte ObjectType;
|
||||||
|
public UInt16 ReferenceCount;
|
||||||
|
public byte[] Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct StateFrameBlock
|
||||||
|
{
|
||||||
|
public UInt32 StateCount;
|
||||||
|
public StatePointerBlock[] StatePointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct StatePointerBlock
|
||||||
|
{
|
||||||
|
public UInt32 Location;
|
||||||
|
public BitArray EventMask;
|
||||||
|
public StateBlock StateBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct StateBlock
|
||||||
|
{
|
||||||
|
public UInt32 StartPos;
|
||||||
|
public UInt32 EndPos;
|
||||||
|
public UInt32 HeaderSize;
|
||||||
|
public byte Unknown;
|
||||||
|
public StateBlockHandler[] StateBlockHandlers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct StateBlockHandler
|
||||||
|
{
|
||||||
|
public UInt32 CodeChunkPointer;
|
||||||
|
public UInt32 CallFrameSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct FunctionBlock
|
||||||
|
{
|
||||||
|
public UInt32 FunctionCount;
|
||||||
|
public UInt32[] CodeChunkPointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CodeChunk
|
||||||
|
{
|
||||||
|
public UInt32 CodeChunkHeaderSize;
|
||||||
|
public string Comment;
|
||||||
|
public List<CodeChunkArgument> CodeChunkArguments;
|
||||||
|
public byte EndMarker;
|
||||||
|
public byte ReturnTypePos;
|
||||||
|
public StaticBlock ReturnType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CodeChunkArgument
|
||||||
|
{
|
||||||
|
public byte FunctionReturnTypePos;
|
||||||
|
public byte NullString;
|
||||||
|
public StaticBlock FunctionReturnType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,69 +1,50 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AS IS AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
using Rail.Reflect;
|
using System.IO;
|
||||||
using Rail.Transformation;
|
using System.Text;
|
||||||
|
using OpenSim.Region.ScriptEngine.LSOEngine.LSO;
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
|
||||||
{
|
namespace OpenSim.Region.ScriptEngine.LSOEngine
|
||||||
/// <summary>
|
{
|
||||||
/// Tedds Sandbox for RAIL/microtrheading. This class is only for testing purposes!
|
/// <summary>
|
||||||
/// Its offspring will be the actual implementation.
|
/// This class encapsulated an LSO file and contains execution-specific data
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class TempDotNetMicroThreadingCodeInjector
|
public class LSOScript
|
||||||
{
|
{
|
||||||
public static string TestFix(string FileName)
|
private byte[] LSOCode = new byte[1024 * 16]; // Contains the LSO-file
|
||||||
{
|
//private System.IO.MemoryStream LSOCode = new MemoryStream(1024 * 16);
|
||||||
string ret = Path.GetFileNameWithoutExtension(FileName + "_fixed.dll");
|
|
||||||
|
public void Execute(LSO_Enums.Event_Mask_Values Event, params object[] param)
|
||||||
Console.WriteLine("Loading: \"" + FileName + "\"");
|
{
|
||||||
RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly(FileName);
|
|
||||||
|
}
|
||||||
|
}
|
||||||
//Get the type of the method to copy from assembly Teste2.exe to assembly Teste.exe
|
}
|
||||||
RTypeDef type = (RTypeDef) rAssembly.RModuleDef.GetType("SecondLife.Script");
|
|
||||||
|
|
||||||
//Get the methods in the type
|
|
||||||
RMethod[] m = type.GetMethods();
|
|
||||||
|
|
||||||
//Create a MethodPrologueAdder visitor object with the method to add
|
|
||||||
//and with the flag that enables local variable creation set to true
|
|
||||||
MethodPrologueAdder mpa = new MethodPrologueAdder((RMethodDef) m[0], true);
|
|
||||||
|
|
||||||
//Apply the changes to the assembly
|
|
||||||
rAssembly.Accept(mpa);
|
|
||||||
|
|
||||||
//Save the new assembly
|
|
||||||
rAssembly.SaveAssembly(ret);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
|
||||||
|
[assembly: AssemblyTitle("OpenSim.Region.ScriptEngine.LSOEngine")]
|
||||||
|
[assembly : AssemblyDescription("")]
|
||||||
|
[assembly : AssemblyConfiguration("")]
|
||||||
|
[assembly : AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("OpenSim.Region.ScriptEngine.LSOEngine")]
|
||||||
|
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")]
|
||||||
|
[assembly : AssemblyTrademark("")]
|
||||||
|
[assembly : AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
|
||||||
|
[assembly : ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
|
||||||
|
[assembly : Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
|
||||||
|
[assembly : AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly : AssemblyFileVersion("1.0.0.0")]
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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 Nini.Config;
|
||||||
|
using OpenSim.Framework.Console;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
|
||||||
|
using EventManager = OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.EventManager;
|
||||||
|
using ScriptManager=OpenSim.Region.ScriptEngine.LSOEngine.ScriptManager;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class ScriptEngine : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptEngine
|
||||||
|
{
|
||||||
|
// We need to override a few things for our DotNetEngine
|
||||||
|
public override void Initialise(Scene scene, IConfigSource config)
|
||||||
|
{
|
||||||
|
InitializeEngine(scene, config, true, GetScriptManager());
|
||||||
|
}
|
||||||
|
|
||||||
|
public override OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager _GetScriptManager()
|
||||||
|
{
|
||||||
|
return new ScriptManager(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ScriptEngineName
|
||||||
|
{
|
||||||
|
get { return "ScriptEngine.LSOEngine"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenSim 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.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.ScriptEngine.LSOEngine
|
||||||
|
{
|
||||||
|
public class ScriptManager : OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.ScriptManager
|
||||||
|
{
|
||||||
|
public ScriptManager(Common.ScriptEngineBase.ScriptEngine scriptEngine)
|
||||||
|
: base(scriptEngine)
|
||||||
|
{
|
||||||
|
base.m_scriptEngine = scriptEngine;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// KEEP TRACK OF SCRIPTS <int id, whatever script>
|
||||||
|
//internal Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>> Scripts = new Dictionary<uint, Dictionary<LLUUID, LSL_BaseClass>>();
|
||||||
|
// LOAD SCRIPT
|
||||||
|
// UNLOAD SCRIPT
|
||||||
|
// PROVIDE SCRIPT WITH ITS INTERFACE TO OpenSim
|
||||||
|
|
||||||
|
public override void _StartScript(uint localID, LLUUID itemID, string Script)
|
||||||
|
{
|
||||||
|
//IScriptHost root = host.GetRoot();
|
||||||
|
Console.WriteLine("ScriptManager StartScript: localID: " + localID + ", itemID: " + itemID);
|
||||||
|
|
||||||
|
// We will initialize and start the script.
|
||||||
|
// It will be up to the script itself to hook up the correct events.
|
||||||
|
string ScriptSource = String.Empty;
|
||||||
|
|
||||||
|
SceneObjectPart m_host = World.GetSceneObjectPart(localID);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Compile (We assume LSL)
|
||||||
|
//ScriptSource = LSLCompiler.CompileFromLSLText(Script);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
long before;
|
||||||
|
before = GC.GetTotalMemory(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
IScript CompiledScript;
|
||||||
|
CompiledScript = m_scriptEngine.m_AppDomainManager.LoadScript(ScriptSource);
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Console.WriteLine("Script " + itemID + " occupies {0} bytes", GC.GetTotalMemory(true) - before);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CompiledScript.Source = ScriptSource;
|
||||||
|
// Add it to our script memstruct
|
||||||
|
SetScript(localID, itemID, CompiledScript);
|
||||||
|
|
||||||
|
// We need to give (untrusted) assembly a private instance of BuiltIns
|
||||||
|
// this private copy will contain Read-Only FullitemID so that it can bring that on to the server whenever needed.
|
||||||
|
|
||||||
|
|
||||||
|
LSL_BuiltIn_Commands LSLB = new LSL_BuiltIn_Commands(m_scriptEngine, m_host, localID, itemID);
|
||||||
|
|
||||||
|
// Start the script - giving it BuiltIns
|
||||||
|
CompiledScript.Start(LSLB);
|
||||||
|
|
||||||
|
// Fire the first start-event
|
||||||
|
m_scriptEngine.m_EventQueueManager.AddToScriptQueue(localID, itemID, "state_entry", EventQueueManager.llDetectNull, new object[] { });
|
||||||
|
}
|
||||||
|
catch (Exception e) // LEGIT - User Script Compilation
|
||||||
|
{
|
||||||
|
//m_scriptEngine.Log.Error("[ScriptEngine]: Error compiling script: " + e.ToString());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// DISPLAY ERROR INWORLD
|
||||||
|
string text = "Error compiling script:\r\n" + e.Message.ToString();
|
||||||
|
if (text.Length > 1500)
|
||||||
|
text = text.Substring(0, 1500);
|
||||||
|
World.SimChat(Helpers.StringToField(text), ChatTypeEnum.Say, 0, m_host.AbsolutePosition,
|
||||||
|
m_host.Name, m_host.UUID);
|
||||||
|
}
|
||||||
|
catch (Exception e2) // LEGIT - User Scripting
|
||||||
|
{
|
||||||
|
m_scriptEngine.Log.Error("[ScriptEngine]: Error displaying error in-world: " + e2.ToString());
|
||||||
|
m_scriptEngine.Log.Error("[ScriptEngine]: " +
|
||||||
|
"Errormessage: Error compiling script:\r\n" + e.Message.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _StopScript(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
// Stop script
|
||||||
|
Console.WriteLine("Stop script localID: " + localID + " LLUID: " + itemID.ToString());
|
||||||
|
|
||||||
|
// Stop long command on script
|
||||||
|
m_scriptEngine.m_ASYNCLSLCommandManager.RemoveScript(localID, itemID);
|
||||||
|
|
||||||
|
IScript LSLBC = GetScript(localID, itemID);
|
||||||
|
if (LSLBC == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// TEMP: First serialize it
|
||||||
|
//GetSerializedScript(localID, itemID);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get AppDomain
|
||||||
|
AppDomain ad = LSLBC.Exec.GetAppDomain();
|
||||||
|
// Tell script not to accept new requests
|
||||||
|
GetScript(localID, itemID).Exec.StopScript();
|
||||||
|
// Remove from internal structure
|
||||||
|
RemoveScript(localID, itemID);
|
||||||
|
// Tell AppDomain that we have stopped script
|
||||||
|
m_scriptEngine.m_AppDomainManager.StopScript(ad);
|
||||||
|
}
|
||||||
|
catch (Exception e) // LEGIT - Problems caused by User Scripting
|
||||||
|
{
|
||||||
|
Console.WriteLine("Exception stopping script localID: " + localID + " LLUID: " + itemID.ToString() +
|
||||||
|
": " + e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,57 +1,58 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
/* Original code: Tedd Hansen */
|
||||||
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
|
||||||
{
|
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
||||||
public static class Common
|
{
|
||||||
{
|
public static class Common
|
||||||
public static bool debug = true;
|
{
|
||||||
public static ScriptEngine mySE;
|
public static bool debug = true;
|
||||||
|
public static ScriptEngine mySE;
|
||||||
// This class just contains some static log stuff used for debugging.
|
|
||||||
|
// This class just contains some static log stuff used for debugging.
|
||||||
//public delegate void SendToDebugEventDelegate(string Message);
|
|
||||||
//public delegate void SendToLogEventDelegate(string Message);
|
//public delegate void SendToDebugEventDelegate(string Message);
|
||||||
//static public event SendToDebugEventDelegate SendToDebugEvent;
|
//public delegate void SendToLogEventDelegate(string Message);
|
||||||
//static public event SendToLogEventDelegate SendToLogEvent;
|
//static public event SendToDebugEventDelegate SendToDebugEvent;
|
||||||
|
//static public event SendToLogEventDelegate SendToLogEvent;
|
||||||
public static void SendToDebug(string Message)
|
|
||||||
{
|
public static void SendToDebug(string Message)
|
||||||
//if (Debug == true)
|
{
|
||||||
mySE.Log.Verbose("ScriptEngine", "Debug: " + Message);
|
//if (Debug == true)
|
||||||
//SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
mySE.Log.Info("[ScriptEngine]: Debug: " + Message);
|
||||||
}
|
//SendToDebugEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
||||||
|
}
|
||||||
public static void SendToLog(string Message)
|
|
||||||
{
|
public static void SendToLog(string Message)
|
||||||
//if (Debug == true)
|
{
|
||||||
mySE.Log.Verbose("ScriptEngine", "LOG: " + Message);
|
//if (Debug == true)
|
||||||
//SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
mySE.Log.Info("[ScriptEngine]: LOG: " + Message);
|
||||||
}
|
//SendToLogEvent("\r\n" + DateTime.Now.ToString("[HH:mm:ss] ") + Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,242 +1,263 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
/* Original code: Tedd Hansen */
|
||||||
using System;
|
|
||||||
using libsecondlife;
|
using System;
|
||||||
using OpenSim.Framework;
|
using libsecondlife;
|
||||||
using OpenSim.Region.ScriptEngine.Common;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
using OpenSim.Region.ScriptEngine.Common.TRPC;
|
||||||
{
|
|
||||||
/// <summary>
|
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
||||||
/// Handles events from OpenSim. Uses RemoteServer to send commands.
|
{
|
||||||
/// </summary>
|
/// <summary>
|
||||||
[Serializable]
|
/// Handles events from OpenSim. Uses RemoteServer to send commands.
|
||||||
internal class EventManager
|
/// </summary>
|
||||||
{
|
[Serializable]
|
||||||
|
internal class EventManager
|
||||||
System.Collections.Generic.Dictionary<uint, ScriptServerInterfaces.ServerRemotingObject> remoteScript = new System.Collections.Generic.Dictionary<uint, ScriptServerInterfaces.ServerRemotingObject>();
|
{
|
||||||
|
System.Collections.Generic.Dictionary<uint, ScriptServerInterfaces.ServerRemotingObject> remoteScript = new System.Collections.Generic.Dictionary<uint, ScriptServerInterfaces.ServerRemotingObject>();
|
||||||
|
TCPClient m_TCPClient;
|
||||||
private ScriptEngine myScriptEngine;
|
TRPC_Remote RPC;
|
||||||
public EventManager(ScriptEngine _ScriptEngine)
|
int myScriptServerID;
|
||||||
{
|
|
||||||
myScriptEngine = _ScriptEngine;
|
string remoteHost = "127.0.0.1";
|
||||||
|
int remotePort = 8010;
|
||||||
myScriptEngine.Log.Verbose("RemoteEngine", "Hooking up to server events");
|
|
||||||
//myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
|
private ScriptEngine myScriptEngine;
|
||||||
myScriptEngine.World.EventManager.OnRezScript += OnRezScript;
|
public EventManager(ScriptEngine _ScriptEngine)
|
||||||
//myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
|
{
|
||||||
|
myScriptEngine = _ScriptEngine;
|
||||||
|
|
||||||
}
|
m_TCPClient = new TCPClient();
|
||||||
|
RPC = new TRPC_Remote(m_TCPClient);
|
||||||
|
RPC.ReceiveCommand += new TRPC_Remote.ReceiveCommandDelegate(RPC_ReceiveCommand);
|
||||||
public void OnRezScript(uint localID, LLUUID itemID, string script)
|
myScriptServerID = m_TCPClient.ConnectAndReturnID(remoteHost, remotePort);
|
||||||
{
|
|
||||||
// WE ARE CREATING A NEW SCRIPT ... CREATE SCRIPT, GET A REMOTEID THAT WE MAP FROM LOCALID
|
myScriptEngine.Log.Info("[RemoteEngine]: Hooking up to server events");
|
||||||
myScriptEngine.Log.Verbose("RemoteEngine", "Creating new script (with connection)");
|
//myScriptEngine.World.EventManager.OnObjectGrab += touch_start;
|
||||||
ScriptServerInterfaces.ServerRemotingObject obj = myScriptEngine.m_RemoteServer.Connect("localhost", 1234);
|
myScriptEngine.World.EventManager.OnRezScript += OnRezScript;
|
||||||
|
//myScriptEngine.World.EventManager.OnRemoveScript += OnRemoveScript;
|
||||||
remoteScript.Add(localID, obj);
|
}
|
||||||
//remoteScript[localID].Events.OnRezScript(localID, itemID, script);
|
|
||||||
|
void RPC_ReceiveCommand(int ID, string Command, params object[] p)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.Log.Info("[REMOTESERVER]: Received command: '" + Command + "'");
|
||||||
public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
|
if (p != null)
|
||||||
{
|
{
|
||||||
//remoteScript[localID].Events.touch_start(localID, offsetPos, remoteClient);
|
for (int i = 0; i < p.Length; i++)
|
||||||
}
|
{
|
||||||
|
myScriptEngine.Log.Info("[REMOTESERVER]: Param " + i + ": " + p[i].ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
// PLACEHOLDERS -- CODE WILL CHANGE!
|
}
|
||||||
|
|
||||||
|
public void OnRezScript(uint localID, LLUUID itemID, string script)
|
||||||
//public void OnRemoveScript(uint localID, LLUUID itemID)
|
{
|
||||||
//{
|
// WE ARE CREATING A NEW SCRIPT ... CREATE SCRIPT, GET A REMOTEID THAT WE MAP FROM LOCALID
|
||||||
// remoteScript[localID].Events.OnRemoveScript(localID, itemID);
|
myScriptEngine.Log.Info("[RemoteEngine]: Creating new script (with connection)");
|
||||||
//}
|
|
||||||
|
// Temp for now: We have one connection only - this is hardcoded in myScriptServerID
|
||||||
//public void state_exit(uint localID, LLUUID itemID)
|
RPC.SendCommand(myScriptServerID, "OnRezScript", localID, itemID.ToString(), script);
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.state_exit(localID, itemID);
|
//ScriptServerInterfaces.ServerRemotingObject obj = myScriptEngine.m_RemoteServer.Connect("localhost", 1234);
|
||||||
//}
|
//remoteScript.Add(localID, obj);
|
||||||
|
//remoteScript[localID].Events().OnRezScript(localID, itemID, script);
|
||||||
//public void touch(uint localID, LLUUID itemID)
|
}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.touch(localID, itemID);
|
public void touch_start(uint localID, LLVector3 offsetPos, IClientAPI remoteClient)
|
||||||
//}
|
{
|
||||||
|
//remoteScript[localID].Events.touch_start(localID, offsetPos, remoteClient);
|
||||||
//public void touch_end(uint localID, LLUUID itemID)
|
RPC.SendCommand(myScriptServerID, "touch_start", offsetPos, "How to transfer IClientAPI?");
|
||||||
//{
|
}
|
||||||
// remoteScript[localID].Events.touch_end(localID, itemID);
|
|
||||||
//}
|
|
||||||
|
// PLACEHOLDERS -- CODE WILL CHANGE!
|
||||||
//public void collision_start(uint localID, LLUUID itemID)
|
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.collision_start(localID, itemID);
|
//public void OnRemoveScript(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.OnRemoveScript(localID, itemID);
|
||||||
//public void collision(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.collision(localID, itemID);
|
//public void state_exit(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.state_exit(localID, itemID);
|
||||||
//public void collision_end(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.collision_end(localID, itemID);
|
//public void touch(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.touch(localID, itemID);
|
||||||
//public void land_collision_start(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.land_collision_start(localID, itemID);
|
//public void touch_end(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.touch_end(localID, itemID);
|
||||||
//public void land_collision(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.land_collision(localID, itemID);
|
//public void collision_start(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.collision_start(localID, itemID);
|
||||||
//public void land_collision_end(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.land_collision_end(localID, itemID);
|
//public void collision(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.collision(localID, itemID);
|
||||||
//public void timer(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.timer(localID, itemID);
|
//public void collision_end(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.collision_end(localID, itemID);
|
||||||
//public void listen(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.listen(localID, itemID);
|
//public void land_collision_start(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.land_collision_start(localID, itemID);
|
||||||
//public void on_rez(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.on_rez(localID, itemID);
|
//public void land_collision(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.land_collision(localID, itemID);
|
||||||
//public void sensor(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.sensor(localID, itemID);
|
//public void land_collision_end(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.land_collision_end(localID, itemID);
|
||||||
//public void no_sensor(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.no_sensor(localID, itemID);
|
//public void timer(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.timer(localID, itemID);
|
||||||
//public void control(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.control(localID, itemID);
|
//public void listen(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.listen(localID, itemID);
|
||||||
//public void money(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.money(localID, itemID);
|
//public void on_rez(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.on_rez(localID, itemID);
|
||||||
//public void email(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.email(localID, itemID);
|
//public void sensor(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.sensor(localID, itemID);
|
||||||
//public void at_target(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.at_target(localID, itemID);
|
//public void no_sensor(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.no_sensor(localID, itemID);
|
||||||
//public void not_at_target(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.not_at_target(localID, itemID);
|
//public void control(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.control(localID, itemID);
|
||||||
//public void at_rot_target(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.at_rot_target(localID, itemID);
|
//public void money(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.money(localID, itemID);
|
||||||
//public void not_at_rot_target(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.not_at_rot_target(localID, itemID);
|
//public void email(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.email(localID, itemID);
|
||||||
//public void run_time_permissions(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.run_time_permissions(localID, itemID);
|
//public void at_target(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.at_target(localID, itemID);
|
||||||
//public void changed(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.changed(localID, itemID);
|
//public void not_at_target(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.not_at_target(localID, itemID);
|
||||||
//public void attach(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.attach(localID, itemID);
|
//public void at_rot_target(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.at_rot_target(localID, itemID);
|
||||||
//public void dataserver(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.dataserver(localID, itemID);
|
//public void not_at_rot_target(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.not_at_rot_target(localID, itemID);
|
||||||
//public void link_message(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.link_message(localID, itemID);
|
//public void run_time_permissions(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.run_time_permissions(localID, itemID);
|
||||||
//public void moving_start(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.moving_start(localID, itemID);
|
//public void changed(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.changed(localID, itemID);
|
||||||
//public void moving_end(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.moving_end(localID, itemID);
|
//public void attach(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.attach(localID, itemID);
|
||||||
//public void object_rez(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.object_rez(localID, itemID);
|
//public void dataserver(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.dataserver(localID, itemID);
|
||||||
//public void remote_data(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.remote_data(localID, itemID);
|
//public void link_message(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.link_message(localID, itemID);
|
||||||
//public void http_response(uint localID, LLUUID itemID)
|
//}
|
||||||
//{
|
|
||||||
// remoteScript[localID].Events.http_response(localID, itemID);
|
//public void moving_start(uint localID, LLUUID itemID)
|
||||||
//}
|
//{
|
||||||
|
// remoteScript[localID].Events.moving_start(localID, itemID);
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
//public void moving_end(uint localID, LLUUID itemID)
|
||||||
|
//{
|
||||||
|
// remoteScript[localID].Events.moving_end(localID, itemID);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public void object_rez(uint localID, LLUUID itemID)
|
||||||
|
//{
|
||||||
|
// remoteScript[localID].Events.object_rez(localID, itemID);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public void remote_data(uint localID, LLUUID itemID)
|
||||||
|
//{
|
||||||
|
// remoteScript[localID].Events.remote_data(localID, itemID);
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public void http_response(uint localID, LLUUID itemID)
|
||||||
|
//{
|
||||||
|
// remoteScript[localID].Events.http_response(localID, itemID);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,38 +1,66 @@
|
||||||
using System.Reflection;
|
/*
|
||||||
using System.Runtime.InteropServices;
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
// General Information about an assembly is controlled through the following
|
*
|
||||||
// set of attributes. Change these attribute values to modify the information
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// associated with an assembly.
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
[assembly : AssemblyTitle("OpenSim.Region.ScriptEngine.RemoteServer")]
|
* notice, this list of conditions and the following disclaimer.
|
||||||
[assembly : AssemblyDescription("")]
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
[assembly : AssemblyConfiguration("")]
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
[assembly : AssemblyCompany("")]
|
* documentation and/or other materials provided with the distribution.
|
||||||
[assembly : AssemblyProduct("OpenSim.Region.ScriptEngine.RemoteServer")]
|
* * Neither the name of the OpenSim Project nor the
|
||||||
[assembly : AssemblyCopyright("Copyright © 2007")]
|
* names of its contributors may be used to endorse or promote products
|
||||||
[assembly : AssemblyTrademark("")]
|
* derived from this software without specific prior written permission.
|
||||||
[assembly : AssemblyCulture("")]
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
// Setting ComVisible to false makes the types in this assembly not visible
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
// to COM components. If you need to access a type in this assembly from
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
// COM, set the ComVisible attribute to true on that type.
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
[assembly : ComVisible(false)]
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
* 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
|
||||||
[assembly : Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")]
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
// Version information for an assembly consists of the following four values:
|
*/
|
||||||
//
|
|
||||||
// Major Version
|
using System.Reflection;
|
||||||
// Minor Version
|
using System.Runtime.InteropServices;
|
||||||
// Build Number
|
|
||||||
// Revision
|
// General Information about an assembly is controlled through the following
|
||||||
//
|
// set of attributes. Change these attribute values to modify the information
|
||||||
// You can specify all the values or you can default the Revision and Build Numbers
|
// associated with an assembly.
|
||||||
// by using the '*' as shown below:
|
|
||||||
|
[assembly : AssemblyTitle("OpenSim.Region.ScriptEngine.RemoteServer")]
|
||||||
[assembly : AssemblyVersion("1.0.0.0")]
|
[assembly : AssemblyDescription("")]
|
||||||
[assembly : AssemblyFileVersion("1.0.0.0")]
|
[assembly : AssemblyConfiguration("")]
|
||||||
|
[assembly : AssemblyCompany("")]
|
||||||
|
[assembly : AssemblyProduct("OpenSim.Region.ScriptEngine.RemoteServer")]
|
||||||
|
[assembly : AssemblyCopyright("Copyright © OpenSimulator.org Developers 2007-2008")]
|
||||||
|
[assembly : AssemblyTrademark("")]
|
||||||
|
[assembly : AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
|
||||||
|
[assembly : ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
|
||||||
|
[assembly : Guid("2842257e-6fde-4460-9368-4cde57fa9cc4")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
|
||||||
|
[assembly : AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly : AssemblyFileVersion("1.0.0.0")]
|
||||||
|
|
|
@ -1,59 +1,83 @@
|
||||||
using System;
|
/*
|
||||||
using System.Collections.Generic;
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
using System.Text;
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
using System.Runtime.Remoting;
|
*
|
||||||
using System.Runtime.Remoting.Channels;
|
* Redistribution and use in source and binary forms, with or without
|
||||||
using System.Runtime.Remoting.Channels.Tcp;
|
* modification, are permitted provided that the following conditions are met:
|
||||||
using OpenSim.Region.ScriptEngine.Common;
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
{
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
class RemoteServer
|
* documentation and/or other materials provided with the distribution.
|
||||||
{
|
* * Neither the name of the OpenSim Project nor the
|
||||||
// Handles connections to servers
|
* names of its contributors may be used to endorse or promote products
|
||||||
// Create and returns server object
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
public ScriptServerInterfaces.ServerRemotingObject Connect(string hostname, int port)
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
{
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
// Create a channel for communicating w/ the remote object
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
// Notice no port is specified on the client
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
TcpChannel chan = new TcpChannel();
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
try
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
{
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
ChannelServices.RegisterChannel(chan, true);
|
* 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
|
||||||
catch (System.Runtime.Remoting.RemotingException)
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
{
|
*
|
||||||
System.Console.WriteLine("Error: tcp already registered, RemoteServer.cs in OpenSim.Region.ScriptEngine.RemoteServer line 24");
|
*/
|
||||||
}
|
|
||||||
try
|
using System;
|
||||||
{
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
// Create an instance of the remote object
|
using System.Runtime.Remoting;
|
||||||
ScriptServerInterfaces.ServerRemotingObject obj = (ScriptServerInterfaces.ServerRemotingObject)Activator.GetObject(
|
using System.Runtime.Remoting.Channels;
|
||||||
typeof(ScriptServerInterfaces.ServerRemotingObject),
|
using System.Runtime.Remoting.Channels.Tcp;
|
||||||
"tcp://" + hostname + ":" + port + "/DotNetEngine");
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
|
||||||
// Use the object
|
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
||||||
if (obj.Equals(null))
|
{
|
||||||
{
|
class RemoteServer
|
||||||
System.Console.WriteLine("Error: unable to locate server");
|
{
|
||||||
}
|
// Handles connections to servers
|
||||||
else
|
// Create and returns server object
|
||||||
{
|
|
||||||
return obj;
|
public RemoteServer()
|
||||||
}
|
{
|
||||||
}
|
TcpChannel chan = new TcpChannel();
|
||||||
catch (System.Net.Sockets.SocketException)
|
ChannelServices.RegisterChannel(chan, true);
|
||||||
{
|
}
|
||||||
System.Console.WriteLine("Error: unable to connect to server");
|
|
||||||
}
|
public ScriptServerInterfaces.ServerRemotingObject Connect(string hostname, int port)
|
||||||
catch (System.Runtime.Remoting.RemotingException)
|
{
|
||||||
{
|
// Create a channel for communicating w/ the remote object
|
||||||
System.Console.WriteLine("Error: unable to connect to server");
|
// Notice no port is specified on the client
|
||||||
}
|
|
||||||
return null;
|
try
|
||||||
|
{
|
||||||
}
|
// Create an instance of the remote object
|
||||||
}
|
ScriptServerInterfaces.ServerRemotingObject obj = (ScriptServerInterfaces.ServerRemotingObject)Activator.GetObject(
|
||||||
}
|
typeof(ScriptServerInterfaces.ServerRemotingObject),
|
||||||
|
"tcp://" + hostname + ":" + port + "/DotNetEngine");
|
||||||
|
|
||||||
|
// Use the object
|
||||||
|
if (obj.Equals(null))
|
||||||
|
{
|
||||||
|
System.Console.WriteLine("Error: unable to locate server");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Net.Sockets.SocketException)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine("Error: unable to connect to server");
|
||||||
|
}
|
||||||
|
catch (System.Runtime.Remoting.RemotingException)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine("Error: unable to connect to server");
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,106 +1,104 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) Contributors, http://opensimulator.org/
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
* * Redistributions of source code must retain the above copyright
|
* * Redistributions of source code must retain the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer.
|
* notice, this list of conditions and the following disclaimer.
|
||||||
* * Redistributions in binary form must reproduce the above copyright
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* * Neither the name of the OpenSim Project nor the
|
* * Neither the name of the OpenSim Project nor the
|
||||||
* names of its contributors may be used to endorse or promote products
|
* names of its contributors may be used to endorse or promote products
|
||||||
* derived from this software without specific prior written permission.
|
* derived from this software without specific prior written permission.
|
||||||
*
|
*
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/* Original code: Tedd Hansen */
|
/* Original code: Tedd Hansen */
|
||||||
using System;
|
|
||||||
using Nini.Config;
|
using System;
|
||||||
using OpenSim.Framework.Console;
|
using Nini.Config;
|
||||||
using OpenSim.Region.Environment.Interfaces;
|
using OpenSim.Framework.Console;
|
||||||
using OpenSim.Region.Environment.Scenes;
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
|
||||||
{
|
namespace OpenSim.Region.ScriptEngine.RemoteServer
|
||||||
/// <summary>
|
{
|
||||||
/// This is the root object for RemoteServer. Objects access each other trough this class.
|
/// <summary>
|
||||||
/// </summary>
|
/// This is the root object for RemoteServer. Objects access each other trough this class.
|
||||||
///
|
/// </summary>
|
||||||
[Serializable]
|
///
|
||||||
public class ScriptEngine : IRegionModule
|
[Serializable]
|
||||||
{
|
public class ScriptEngine : IRegionModule
|
||||||
internal Scene World;
|
{
|
||||||
internal EventManager m_EventManager; // Handles and queues incoming events from OpenSim
|
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
internal RemoteServer m_RemoteServer; // Handles connections to remote servers
|
|
||||||
|
internal Scene World;
|
||||||
private LogBase m_log;
|
internal EventManager m_EventManager; // Handles and queues incoming events from OpenSim
|
||||||
|
internal RemoteServer m_RemoteServer; // Handles connections to remote servers
|
||||||
public ScriptEngine()
|
|
||||||
{
|
public ScriptEngine()
|
||||||
Common.mySE = this;
|
{
|
||||||
}
|
Common.mySE = this;
|
||||||
|
}
|
||||||
public LogBase Log
|
|
||||||
{
|
public log4net.ILog Log
|
||||||
get { return m_log; }
|
{
|
||||||
}
|
get { return m_log; }
|
||||||
|
}
|
||||||
public void InitializeEngine(Scene Sceneworld, LogBase logger)
|
|
||||||
{
|
public void InitializeEngine(Scene Sceneworld)
|
||||||
World = Sceneworld;
|
{
|
||||||
m_log = logger;
|
World = Sceneworld;
|
||||||
|
|
||||||
Log.Verbose("ScriptEngine", "RemoteEngine (Remote Script Server) initializing");
|
m_log.Info("[ScriptEngine]: RemoteEngine (Remote Script Server) initializing");
|
||||||
// Create all objects we'll be using
|
// Create all objects we'll be using
|
||||||
m_EventManager = new EventManager(this);
|
m_EventManager = new EventManager(this);
|
||||||
m_RemoteServer = new RemoteServer();
|
m_RemoteServer = new RemoteServer();
|
||||||
m_RemoteServer.Connect("localhost", 1234);
|
m_RemoteServer.Connect("localhost", 1234);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown()
|
public void Shutdown()
|
||||||
{
|
{
|
||||||
// We are shutting down
|
// We are shutting down
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region IRegionModule
|
||||||
#region IRegionModule
|
|
||||||
|
public void Initialise(Scene scene, IConfigSource config)
|
||||||
public void Initialise(Scene scene, IConfigSource config)
|
{
|
||||||
{
|
InitializeEngine(scene);
|
||||||
InitializeEngine(scene, MainLog.Instance);
|
}
|
||||||
}
|
|
||||||
|
public void PostInitialise()
|
||||||
public void PostInitialise()
|
{
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public void Close()
|
||||||
public void Close()
|
{
|
||||||
{
|
}
|
||||||
}
|
|
||||||
|
public string Name
|
||||||
public string Name
|
{
|
||||||
{
|
get { return "RemoteServerScriptingModule"; }
|
||||||
get { return "RemoteServerScriptingModule"; }
|
}
|
||||||
}
|
|
||||||
|
public bool IsSharedModule
|
||||||
public bool IsSharedModule
|
{
|
||||||
{
|
get { return false; }
|
||||||
get { return false; }
|
}
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
#endregion
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue