From 8428b25939d39711e732eeb3928e8a8e64aad8a9 Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Mon, 26 Oct 2009 00:10:23 +0100 Subject: Add llRotLookat pt1. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 39 ++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ++++ .../BasicPhysicsPlugin/BasicPhysicsActor.cs | 20 ++++++ .../BulletDotNETPlugin/BulletDotNETCharacter.cs | 6 ++ .../Physics/BulletDotNETPlugin/BulletDotNETPrim.cs | 5 ++ .../Region/Physics/BulletXPlugin/BulletXPlugin.cs | 20 ++++++ OpenSim/Region/Physics/Manager/PhysicsActor.cs | 13 +++- OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 22 ++++++ OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs | 4 +- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 83 ++++++++++++++++------ OpenSim/Region/Physics/POSPlugin/POSCharacter.cs | 21 ++++++ OpenSim/Region/Physics/POSPlugin/POSPrim.cs | 20 ++++++ OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs | 44 ++++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 18 +++-- 14 files changed, 296 insertions(+), 31 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 69b3ded..fff807a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1727,6 +1727,45 @@ namespace OpenSim.Region.Framework.Scenes } } + public void rotLookAt(Quaternion target, float strength, float damping) + { + SceneObjectPart rootpart = m_rootPart; + if (rootpart != null) + { + if (IsAttachment) + { + /* + ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); + if (avatar != null) + { + Rotate the Av? + } */ + } + else + { + if (rootpart.PhysActor != null) + { + rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W); + rootpart.PhysActor.APIDStrength = strength; + rootpart.PhysActor.APIDDamping = damping; + rootpart.PhysActor.APIDActive = true; + } + } + } + } + public void stopLookAt() + { + SceneObjectPart rootpart = m_rootPart; + if (rootpart != null) + { + if (rootpart.PhysActor != null) + { + rootpart.PhysActor.APIDActive = false; + } + } + + } + /// /// Uses a PID to attempt to clamp the object on the Z axis at the given height over tau seconds. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 32171a0..5f46f6f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2187,6 +2187,11 @@ if (m_shape != null) { ParentGroup.HasGroupChanged = true; ScheduleFullUpdate(); } + + public void RotLookAt(Quaternion target, float strength, float damping) + { + m_parentGroup.rotLookAt(target, strength, damping); + } /// /// Schedules this prim for a full update @@ -2662,6 +2667,13 @@ if (m_shape != null) { SetText(text); } + public void StopLookAt() + { + m_parentGroup.stopLookAt(); + + m_parentGroup.ScheduleGroupForTerseUpdate(); + } + public void StopMoveToTarget() { m_parentGroup.stopMoveToTarget(); diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs index 8d8b3fe..2b905b6 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs @@ -307,6 +307,26 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin set { return; } } + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + public override void SubscribeEvents(int ms) { } diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs index 8da9687..d7aed3c 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs @@ -627,6 +627,12 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { set { return; } } + + public override Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + /// /// Adds the force supplied to the Target Velocity diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs index f22ea71..977b463 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs @@ -566,6 +566,11 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } public override float PIDHoverTau { set { m_PIDHoverTau = value; } } + public override Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + public override void AddForce(PhysicsVector force, bool pushforce) { diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index abed8df..14b8f39 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -1236,6 +1236,26 @@ namespace OpenSim.Region.Physics.BulletXPlugin public override PIDHoverType PIDHoverType { set { return; } } public override float PIDHoverTau { set { return; } } + public override OpenMetaverse.Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + public override void SubscribeEvents(int ms) { diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 7603131..566746a 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -230,7 +230,12 @@ namespace OpenSim.Region.Physics.Manager public abstract PIDHoverType PIDHoverType { set;} public abstract float PIDHoverTau { set;} - + // For RotLookAt + public abstract Quaternion APIDTarget { set;} + public abstract bool APIDActive { set;} + public abstract float APIDStrength { set;} + public abstract float APIDDamping { set;} + public abstract void AddForce(PhysicsVector force, bool pushforce); public abstract void AddAngularForce(PhysicsVector force, bool pushforce); public abstract void SetMomentum(PhysicsVector momentum); @@ -463,6 +468,12 @@ namespace OpenSim.Region.Physics.Manager public override bool PIDHoverActive { set { return; } } public override PIDHoverType PIDHoverType { set { return; } } public override float PIDHoverTau { set { return; } } + + public override Quaternion APIDTarget { set { return; } } + public override bool APIDActive { set { return; } } + public override float APIDStrength { set { return; } } + public override float APIDDamping { set { return; } } + public override void SetMomentum(PhysicsVector momentum) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index 71ace16..8272083 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1205,6 +1205,28 @@ namespace OpenSim.Region.Physics.OdePlugin public override bool PIDHoverActive { set { return; } } public override PIDHoverType PIDHoverType { set { return; } } public override float PIDHoverTau { set { return; } } + + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + + public override void SubscribeEvents(int ms) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs index 467eba0..8b57f06 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs @@ -119,7 +119,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. + private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle. // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. @@ -478,7 +478,7 @@ namespace OpenSim.Region.Physics.OdePlugin Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object m_dir *= rotq; // apply obj rotation to velocity vector - // add Gravity andBuoyancy + // add Gravity and Buoyancy // KF: So far I have found no good method to combine a script-requested // .Z velocity and gravity. Therefore only 0g will used script-requested // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index f59f0ae..e1bf996 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1,15 +1,4 @@ /* - * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -34,6 +23,18 @@ * 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. + * + * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. */ using System; using System.Collections.Generic; @@ -82,6 +83,14 @@ namespace OpenSim.Region.Physics.OdePlugin private float PID_D = 35f; private float PID_G = 25f; private bool m_usePID = false; + + private Quaternion m_APIDTarget = new Quaternion(); + private float m_APIDStrength = 0.5f; + private float m_APIDDamping = 0.5f; + + private float APID_D = 35f; + private float APID_G = 25f; + private bool m_useAPID = false; // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), // and are for non-VEHICLES only. @@ -93,7 +102,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_targetHoverHeight = 0f; private float m_groundHeight = 0f; private float m_waterHeight = 0f; - private float m_buoyancy = 0f; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. + private float m_buoyancy = 0f; //Set by llSetBuoyancy(), for non-vehicles. // private float m_tensor = 5f; private int body_autodisable_frames = 20; @@ -1586,21 +1595,18 @@ Console.WriteLine(" JointCreateFixed"); //m_log.Info(m_collisionFlags.ToString()); - //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. - // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ?? + //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle. // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up - // gravityz multiplier = 1 - m_buoyancy - fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; + // NB Prims in ODE are no subject to global gravity + fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass if (m_usePID) { //Console.WriteLine("PID " + m_primName); - // KF - this is for object move? eg. llSetPos() ? + // KF - this is for object MoveToTarget. + //if (!d.BodyIsEnabled(Body)) //d.BodySetForce(Body, 0f, 0f, 0f); - // If we're using the PID controller, then we have no gravity - //fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply... - fz = 0f; // no lock; for now it's only called from within Simulate() @@ -1744,8 +1750,37 @@ Console.WriteLine(" JointCreateFixed"); // We're flying and colliding with something fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); } - } + } // end m_useHoverPID && !m_usePID + + if (m_useAPID) + { + // RotLookAt, apparently overrides all other rotation sources. Inputs: + // Quaternion m_APIDTarget + // float m_APIDStrength // perhaps ratio other forces to lookat force? + // float m_APIDDamping //'seconds to critically damps in'[sic] + // Factors: + // float APID_D + // float APID_G + + // get present body rotation + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); + Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget; + float diff_angle; + Vector3 diff_axis; + rot_diff.GetAxisAngle(out diff_axis, out diff_angle); + diff_axis.Normalize(); + PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); + float RLAservo = timestep / m_APIDDamping; + rotforce = rotforce * RLAservo * m_mass; + d.BodyAddTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); + + // d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); + + + } // end m_useAPID + fx *= m_mass; fy *= m_mass; //fz *= m_mass; @@ -2778,6 +2813,12 @@ Console.WriteLine(" JointCreateFixed"); } public override bool PIDActive { set { m_usePID = value; } } public override float PIDTau { set { m_PIDTau = value; } } + + // For RotLookAt + public override Quaternion APIDTarget { set { m_APIDTarget = value; } } + public override bool APIDActive { set { m_useAPID = value; } } + public override float APIDStrength { set { m_APIDStrength = value; } } + public override float APIDDamping { set { m_APIDDamping = value; } } public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } public override bool PIDHoverActive { set { m_useHoverPID = value; } } diff --git a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs index 35fc616..135f49e 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs @@ -307,6 +307,27 @@ namespace OpenSim.Region.Physics.POSPlugin { set { return; } } + + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + public override void SubscribeEvents(int ms) { diff --git a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs index b50364b..4521dce 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs @@ -302,6 +302,26 @@ namespace OpenSim.Region.Physics.POSPlugin { set { return; } } + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + public override void SubscribeEvents(int ms) { diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs index e7d989c..b3bf70b 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs @@ -500,6 +500,28 @@ namespace OpenSim.Region.Physics.PhysXPlugin public override bool PIDHoverActive { set { return; } } public override PIDHoverType PIDHoverType { set { return; } } public override float PIDHoverTau { set { return; } } + + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + + public override void SubscribeEvents(int ms) { @@ -782,6 +804,28 @@ namespace OpenSim.Region.Physics.PhysXPlugin public override bool PIDHoverActive { set { return; } } public override PIDHoverType PIDHoverType { set { return; } } public override float PIDHoverTau { set { return; } } + + public override Quaternion APIDTarget + { + set { return; } + } + + public override bool APIDActive + { + set { return; } + } + + public override float APIDStrength + { + set { return; } + } + + public override float APIDDamping + { + set { return; } + } + + public override void SubscribeEvents(int ms) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 11f255f..1dc20ff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2694,11 +2694,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Orient the object to the angle calculated llSetRot(rot); } + + public void llRotLookAt(LSL_Rotation target, double strength, double damping) + { + m_host.AddScriptLPS(1); +// NotImplemented("llRotLookAt"); + m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping); + + } + public void llStopLookAt() { m_host.AddScriptLPS(1); - NotImplemented("llStopLookAt"); +// NotImplemented("llStopLookAt"); + m_host.StopLookAt(); } public void llSetTimerEvent(double sec) @@ -3042,12 +3052,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); } - public void llRotLookAt(LSL_Rotation target, double strength, double damping) - { - m_host.AddScriptLPS(1); - NotImplemented("llRotLookAt"); - } - public LSL_Integer llStringLength(string str) { m_host.AddScriptLPS(1); -- cgit v1.1 From a81a16f22f7af6d102f365f69a50c5d201ae8362 Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Tue, 27 Oct 2009 19:56:39 +0100 Subject: llRotLookAt Pt 2 --- OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs | 34 ++++++++------- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 55 +++++++++++++++---------- 2 files changed, 52 insertions(+), 37 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs index 8b57f06..0c168c6 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs @@ -1,16 +1,4 @@ /* - * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. - * * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -35,6 +23,19 @@ * 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. + * + * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + * */ using System; @@ -66,8 +67,8 @@ namespace OpenSim.Region.Physics.OdePlugin // private OdeScene m_parentScene = null; private IntPtr m_body = IntPtr.Zero; - private IntPtr m_jointGroup = IntPtr.Zero; - private IntPtr m_aMotor = IntPtr.Zero; +// private IntPtr m_jointGroup = IntPtr.Zero; +// private IntPtr m_aMotor = IntPtr.Zero; // Vehicle properties @@ -560,6 +561,7 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body */ +//if(frcount == 0) Console.WriteLine("MoveAngular "); // Get what the body is doing, this includes 'external' influences d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); @@ -614,7 +616,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Error is 0 (no error) to +/- 2 (max error) // scale it by VAservo verterr = verterr * VAservo; -//if(frcount == 0) Console.WriteLine("VAerr=" + verterr); +if(frcount == 0) Console.WriteLine("VAerr=" + verterr); // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. @@ -635,7 +637,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Deflection section tba // Sum velocities - m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection + m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index e1bf996..93c9a44 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -87,9 +87,6 @@ namespace OpenSim.Region.Physics.OdePlugin private Quaternion m_APIDTarget = new Quaternion(); private float m_APIDStrength = 0.5f; private float m_APIDDamping = 0.5f; - - private float APID_D = 35f; - private float APID_G = 25f; private bool m_useAPID = false; // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), @@ -192,6 +189,9 @@ namespace OpenSim.Region.Physics.OdePlugin private ODEDynamics m_vehicle; internal int m_material = (int)Material.Wood; + + private int frcount = 0; // Used to limit dynamics debug output to + public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) @@ -1563,9 +1563,14 @@ Console.WriteLine(" JointCreateFixed"); float fy = 0; float fz = 0; + frcount++; // used to limit debug comment output + if (frcount > 100) + frcount = 0; if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. { +if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type + + " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); if (m_vehicle.Type != Vehicle.TYPE_NONE) { // 'VEHICLES' are dealt with in ODEDynamics.cs @@ -1573,7 +1578,6 @@ Console.WriteLine(" JointCreateFixed"); } else { -//Console.WriteLine("Move " + m_primName); if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 // NON-'VEHICLES' are dealt with here if (d.BodyIsEnabled(Body) && !m_angularlock.IsIdentical(PhysicsVector.Zero, 0.003f)) @@ -1602,7 +1606,7 @@ Console.WriteLine(" JointCreateFixed"); if (m_usePID) { -//Console.WriteLine("PID " + m_primName); +//if(frcount == 0) Console.WriteLine("PID " + m_primName); // KF - this is for object MoveToTarget. //if (!d.BodyIsEnabled(Body)) @@ -1741,7 +1745,7 @@ Console.WriteLine(" JointCreateFixed"); d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); d.BodySetLinearVel(Body, vel.X, vel.Y, 0); d.BodyAddForce(Body, 0, 0, fz); - return; + //KF this prevents furthur motions return; } else { @@ -1756,13 +1760,16 @@ Console.WriteLine(" JointCreateFixed"); { // RotLookAt, apparently overrides all other rotation sources. Inputs: // Quaternion m_APIDTarget - // float m_APIDStrength // perhaps ratio other forces to lookat force? - // float m_APIDDamping //'seconds to critically damps in'[sic] + // float m_APIDStrength // From SL experiments, this is the time to get there + // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly + // Also in SL the mass of the object has no effect on time to get there. // Factors: - // float APID_D - // float APID_G - +//if(frcount == 0) Console.WriteLine("APID "); // get present body rotation + float limit = 1.0f; + float scaler = 50f; // adjusts damping time + float RLAservo = 0f; + d.Quaternion rot = d.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget; @@ -1770,15 +1777,21 @@ Console.WriteLine(" JointCreateFixed"); Vector3 diff_axis; rot_diff.GetAxisAngle(out diff_axis, out diff_angle); diff_axis.Normalize(); - PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); - float RLAservo = timestep / m_APIDDamping; - rotforce = rotforce * RLAservo * m_mass; - d.BodyAddTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); - - // d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); - - - + if(diff_angle > 0.01f) // diff_angle is always +ve + { +// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); + Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z); + rotforce = rotforce * rotq; + if(diff_angle > limit) diff_angle = limit; // cap the rotate rate +// RLAservo = timestep / m_APIDStrength * m_mass * scaler; + // rotforce = rotforce * RLAservo * diff_angle ; + // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); + RLAservo = timestep / m_APIDStrength * scaler; + rotforce = rotforce * RLAservo * diff_angle ; + d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); +//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); + } +if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); } // end m_useAPID fx *= m_mass; @@ -2674,7 +2687,7 @@ Console.WriteLine(" JointCreateFixed"); //outofBounds = true; } - float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); +// float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); //Console.WriteLine("Adiff " + m_primName + " = " + Adiff); if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) -- cgit v1.1 From 28aa8010b2b47b73c6b867ff8f6284f98f12f37a Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Nov 2009 21:38:38 +0100 Subject: - Lower TIME_MS_TOLERANCE to 200ms - Allow m_updateFlag to be reset to 0 in the event of a terse update being rejected - Re-add a synchronous SendTo for certain types of packets --- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 24 ++++++++++++++++++++-- .../Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | 18 ++++++++++++++++ .../Region/ClientStack/LindenUDP/OutgoingPacket.cs | 4 +++- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 18 ++++++---------- 4 files changed, 49 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index c773c05..0b05ed9 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -399,6 +399,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Queue or Send OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); + outgoingPacket.Type = type; if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) SendPacketFinal(outgoingPacket); @@ -510,6 +511,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte flags = buffer.Data[0]; bool isResend = (flags & Helpers.MSG_RESENT) != 0; bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; + bool sendSynchronous = false; LLUDPClient udpClient = outgoingPacket.Client; if (!udpClient.IsConnected) @@ -565,9 +567,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (isReliable) Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); - // Put the UDP payload on the wire - AsyncBeginSend(buffer); + //Some packet types need to be sent synchonously. + //Sorry, i know it's not optimal, but until the LL client + //manages packets correctly and re-orders them as required, this is necessary. + + if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate + || outgoingPacket.Type == PacketType.ChatFromSimulator + || outgoingPacket.Type == PacketType.ObjectUpdate + || outgoingPacket.Type == PacketType.LayerData) + { + sendSynchronous = true; + } + // Put the UDP payload on the wire + if (sendSynchronous == true) + { + SyncBeginSend(buffer); + } + else + { + AsyncBeginSend(buffer); + } // Keep track of when this packet was sent out (right now) outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs index d2779ba..63579ac 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs @@ -246,6 +246,24 @@ namespace OpenMetaverse } } + public void SyncBeginSend(UDPPacketBuffer buf) + { + if (!m_shutdownFlag) + { + try + { + m_udpSocket.SendTo( + buf.Data, + 0, + buf.DataLength, + SocketFlags.None, + buf.RemoteEndPoint); + } + catch (SocketException) { } + catch (ObjectDisposedException) { } + } + } + public void AsyncBeginSend(UDPPacketBuffer buf) { if (!m_shutdownFlag) diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs index 1a1a1cb..7dc42d3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs @@ -28,6 +28,7 @@ using System; using OpenSim.Framework; using OpenMetaverse; +using OpenMetaverse.Packets; namespace OpenSim.Region.ClientStack.LindenUDP { @@ -52,7 +53,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public int TickCount; /// Category this packet belongs to public ThrottleOutPacketType Category; - + /// The type of packet so its delivery method can be determined + public PacketType Type; /// /// Default constructor /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 73d0984..c0fd437 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1064,14 +1064,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Clear all pending updates of parts to clients - /// - private void ClearUpdateSchedule() - { - m_updateFlag = 0; - } - private void SendObjectPropertiesToClient(UUID AgentID) { ScenePresence[] avatars = m_parentGroup.Scene.GetScenePresences(); @@ -2387,8 +2379,8 @@ namespace OpenSim.Region.Framework.Scenes { const float ROTATION_TOLERANCE = 0.01f; const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; - const int TIME_MS_TOLERANCE = 3000; + const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary + const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds. if (m_updateFlag == 1) { @@ -2401,7 +2393,7 @@ namespace OpenSim.Region.Framework.Scenes Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) { AddTerseUpdateToAllAvatars(); - ClearUpdateSchedule(); + // This causes the Scene to 'poll' physical objects every couple of frames // bad, so it's been replaced by an event driven method. @@ -2419,13 +2411,15 @@ namespace OpenSim.Region.Framework.Scenes m_lastAngularVelocity = AngularVelocity; m_lastTerseSent = Environment.TickCount; } + //Moved this outside of the if clause so updates don't get blocked.. *sigh* + m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams* } else { if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes { AddFullUpdateToAllAvatars(); - ClearUpdateSchedule(); + m_updateFlag = 0; //Same here } } } -- cgit v1.1 From b7f1fc116eb37a651a80bc09df11fa47540a1df9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 15 Nov 2009 20:21:46 +0000 Subject: Prevent a nullref if a recipient of a group message gas left the scene --- .../Avatar/InstantMessage/OfflineMessageModule.cs | 27 ++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 1614b70..7f9e5af 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -164,19 +164,22 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage Listmsglist = SynchronousRestObjectPoster.BeginPostObject>( "POST", m_RestURL+"/RetrieveMessages/", client.AgentId); - foreach (GridInstantMessage im in msglist) + if (msglist != null) { - // client.SendInstantMessage(im); - - // Send through scene event manager so all modules get a chance - // to look at this message before it gets delivered. - // - // Needed for proper state management for stored group - // invitations - // - Scene s = FindScene(client.AgentId); - if (s != null) - s.EventManager.TriggerIncomingInstantMessage(im); + foreach (GridInstantMessage im in msglist) + { + // client.SendInstantMessage(im); + + // Send through scene event manager so all modules get a chance + // to look at this message before it gets delivered. + // + // Needed for proper state management for stored group + // invitations + // + Scene s = FindScene(client.AgentId); + if (s != null) + s.EventManager.TriggerIncomingInstantMessage(im); + } } } -- cgit v1.1 From a49c524c9e93db1409f1f05d7b881922e178927c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 15 Nov 2009 20:22:15 +0000 Subject: Add the ability to send messages to users ir regions via remote admin --- .../RemoteController/RemoteAdminPlugin.cs | 48 ++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 3149eaa..3bc557d 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -123,6 +123,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController availableMethods["admin_region_query"] = XmlRpcRegionQueryMethod; availableMethods["admin_shutdown"] = XmlRpcShutdownMethod; availableMethods["admin_broadcast"] = XmlRpcAlertMethod; + availableMethods["admin_dialog"] = XmlRpcDialogMethod; availableMethods["admin_restart"] = XmlRpcRestartMethod; availableMethods["admin_load_heightmap"] = XmlRpcLoadHeightmapMethod; // User management @@ -277,6 +278,53 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_log.Info("[RADMIN]: Alert request complete"); return response; } + public XmlRpcResponse XmlRpcDialogMethod(XmlRpcRequest request, IPEndPoint remoteClient) + { + XmlRpcResponse response = new XmlRpcResponse(); + Hashtable responseData = new Hashtable(); + + m_log.Info("[RADMIN]: Dialog request started"); + + try + { + Hashtable requestData = (Hashtable)request.Params[0]; + + checkStringParameters(request, new string[] { "password", "from", "message" }); + + if (m_requiredPassword != String.Empty && + (!requestData.Contains("password") || (string)requestData["password"] != m_requiredPassword)) + throw new Exception("wrong password"); + + string message = (string)requestData["message"]; + string fromuuid = (string)requestData["from"]; + m_log.InfoFormat("[RADMIN]: Broadcasting: {0}", message); + + responseData["accepted"] = true; + responseData["success"] = true; + response.Value = responseData; + + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, fromuuid, message); + }); + } + catch (Exception e) + { + m_log.ErrorFormat("[RADMIN]: Broadcasting: failed: {0}", e.Message); + m_log.DebugFormat("[RADMIN]: Broadcasting: failed: {0}", e.ToString()); + + responseData["accepted"] = false; + responseData["success"] = false; + responseData["error"] = e.Message; + response.Value = responseData; + } + + m_log.Info("[RADMIN]: Alert request complete"); + return response; + } public XmlRpcResponse XmlRpcLoadHeightmapMethod(XmlRpcRequest request, IPEndPoint remoteClient) { -- cgit v1.1 From b9546d12f230f4153b2c6e7e71520aa2d35c762b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 15 Nov 2009 21:20:42 +0000 Subject: Change land packet sending back to what the careminster release used to use, remove the silly spiral stuff. Revert to double packets for improved user experience --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 83 +++++++++------------- 1 file changed, 34 insertions(+), 49 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 7eb829e..49b9378 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -785,6 +785,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public virtual void SendLayerData(float[] map) { Util.FireAndForget(DoSendLayerData, map); + + // Send it sync, and async. It's not that much data + // and it improves user experience just so much! + DoSendLayerData(map); } /// @@ -797,16 +801,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { - //for (int y = 0; y < 16; y++) - //{ - // for (int x = 0; x < 16; x++) - // { - // SendLayerData(x, y, map); - // } - //} - - // Send LayerData in a spiral pattern. Fun! - SendLayerTopRight(map, 0, 0, 15, 15); + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x+=4) + { + SendLayerPacket(x, y, map); + } + } } catch (Exception e) { @@ -814,51 +815,35 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - private void SendLayerTopRight(float[] map, int x1, int y1, int x2, int y2) - { - // Row - for (int i = x1; i <= x2; i++) - SendLayerData(i, y1, map); - - // Column - for (int j = y1 + 1; j <= y2; j++) - SendLayerData(x2, j, map); - - if (x2 - x1 > 0) - SendLayerBottomLeft(map, x1, y1 + 1, x2 - 1, y2); - } - - void SendLayerBottomLeft(float[] map, int x1, int y1, int x2, int y2) - { - // Row in reverse - for (int i = x2; i >= x1; i--) - SendLayerData(i, y2, map); - - // Column in reverse - for (int j = y2 - 1; j >= y1; j--) - SendLayerData(x1, j, map); - - if (x2 - x1 > 0) - SendLayerTopRight(map, x1 + 1, y1, x2, y2 - 1); - } - /// /// Sends a set of four patches (x, x+1, ..., x+3) to the client /// /// heightmap /// X coordinate for patches 0..12 /// Y coordinate for patches 0..15 - // private void SendLayerPacket(float[] map, int y, int x) - // { - // int[] patches = new int[4]; - // patches[0] = x + 0 + y * 16; - // patches[1] = x + 1 + y * 16; - // patches[2] = x + 2 + y * 16; - // patches[3] = x + 3 + y * 16; - - // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); - // OutPacket(layerpack, ThrottleOutPacketType.Land); - // } + private void SendLayerPacket(int x, int y, float[] map) + { + int[] patches = new int[4]; + patches[0] = x + 0 + y * 16; + patches[1] = x + 1 + y * 16; + patches[2] = x + 2 + y * 16; + patches[3] = x + 3 + y * 16; + + float[] heightmap = (map.Length == 65536) ? + map : + LLHeightFieldMoronize(map); + + try + { + Packet layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); + OutPacket(layerpack, ThrottleOutPacketType.Land); + } + catch + { + for (int px = x ; px < x + 4 ; px++) + SendLayerData(px, y, map); + } + } /// /// Sends a specified patch to a client -- cgit v1.1 From 4c10826caa4b2b19200ab3f0272bb1c20c26c53e Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Mon, 16 Nov 2009 02:12:56 +0100 Subject: Fix merge conflicts --- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 6 +++--- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 7 ------- 2 files changed, 3 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 8241e8f..b82586f 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -249,9 +249,9 @@ namespace OpenSim.Region.Physics.Manager public abstract float APIDStrength { set;} public abstract float APIDDamping { set;} - public abstract void AddForce(PhysicsVector force, bool pushforce); - public abstract void AddAngularForce(PhysicsVector force, bool pushforce); - public abstract void SetMomentum(PhysicsVector momentum); + public abstract void AddForce(Vector3 force, bool pushforce); + public abstract void AddAngularForce(Vector3 force, bool pushforce); + public abstract void SetMomentum(Vector3 momentum); public abstract void SubscribeEvents(int ms); public abstract void UnSubscribeEvents(); public abstract bool SubscribedEvents(); diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index b963d65..8f2c801 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -107,17 +107,10 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_PIDHoverTau; private bool m_useHoverPID; private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; -<<<<<<< HEAD:OpenSim/Region/Physics/OdePlugin/ODEPrim.cs - private float m_targetHoverHeight = 0f; - private float m_groundHeight = 0f; - private float m_waterHeight = 0f; - private float m_buoyancy = 0f; //Set by llSetBuoyancy(), for non-vehicles. -======= private float m_targetHoverHeight; private float m_groundHeight; private float m_waterHeight; private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. ->>>>>>> vehicles:OpenSim/Region/Physics/OdePlugin/ODEPrim.cs // private float m_tensor = 5f; private int body_autodisable_frames = 20; -- cgit v1.1 From 7f0f5060ec418533ee7d952bdc0815f3925bda9f Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Thu, 19 Nov 2009 20:13:26 +0100 Subject: Clean up messages in ODE --- OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs | 2 +- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs index 1842eb4..78b15be 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs @@ -629,7 +629,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Error is 0 (no error) to +/- 2 (max error) // scale it by VAservo verterr = verterr * VAservo; -if(frcount == 0) Console.WriteLine("VAerr=" + verterr); +//if(frcount == 0) Console.WriteLine("VAerr=" + verterr); // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 8f2c801..2bf96e4 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -1584,8 +1584,8 @@ Console.WriteLine(" JointCreateFixed"); if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. { -if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type + - " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); +//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type + + // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); if (m_vehicle.Type != Vehicle.TYPE_NONE) { // 'VEHICLES' are dealt with in ODEDynamics.cs @@ -1806,7 +1806,7 @@ if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); //Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); } -if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); +//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); } // end m_useAPID fx *= m_mass; -- cgit v1.1 From 0149265ee83581cf2fb150dcd5d8734c02926261 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sat, 21 Nov 2009 15:36:38 +0100 Subject: Improved avatar responsiveness. --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 4 +- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 24 +++--- .../Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | 89 +++++++++++++++++++--- .../Scenes/Animation/ScenePresenceAnimator.cs | 4 +- OpenSim/Region/Framework/Scenes/Scene.cs | 10 +-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 80 +++++++++++++++---- 6 files changed, 163 insertions(+), 48 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 49b9378..39eb968 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3121,7 +3121,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data); - OutPacket(objupdate, ThrottleOutPacketType.Task); } @@ -3172,8 +3171,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); } - // HACK: Using the task category until the tiered reprioritization code is in - OutPacket(terse, ThrottleOutPacketType.Task); + OutPacket(terse, ThrottleOutPacketType.State); } public void SendCoarseLocationUpdate(List users, List CoarseLocations) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 0b05ed9..4a7bdfe 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -571,23 +571,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP //Sorry, i know it's not optimal, but until the LL client //manages packets correctly and re-orders them as required, this is necessary. - if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate - || outgoingPacket.Type == PacketType.ChatFromSimulator - || outgoingPacket.Type == PacketType.ObjectUpdate - || outgoingPacket.Type == PacketType.LayerData) + + // Put the UDP payload on the wire + if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate) { - sendSynchronous = true; + SyncBeginPrioritySend(buffer, 2); // highest priority } - - // Put the UDP payload on the wire - if (sendSynchronous == true) + else if (outgoingPacket.Type == PacketType.ObjectUpdate + || outgoingPacket.Type == PacketType.ChatFromSimulator + || outgoingPacket.Type == PacketType.LayerData) { - SyncBeginSend(buffer); + SyncBeginPrioritySend(buffer, 1); // medium priority } else { - AsyncBeginSend(buffer); + SyncBeginPrioritySend(buffer, 0); // normal priority } + + //AsyncBeginSend(buffer); + // Keep track of when this packet was sent out (right now) outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; } @@ -862,7 +864,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); - AsyncBeginSend(buffer); + SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends } private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs index 63579ac..45d9170 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs @@ -29,6 +29,7 @@ using System; using System.Net; using System.Net.Sockets; using System.Threading; +using System.Collections.Generic; using log4net; namespace OpenMetaverse @@ -52,12 +53,25 @@ namespace OpenMetaverse /// Local IP address to bind to in server mode protected IPAddress m_localBindAddress; + /// + /// Standard queue for our outgoing SyncBeginPrioritySend + /// + private List m_standardQueue = new List(); + + /// + /// Prioritised queue for our outgoing SyncBeginPrioritySend + /// + private List m_priorityQueue = new List(); + /// UDP socket, used in either client or server mode private Socket m_udpSocket; /// Flag to process packets asynchronously or synchronously private bool m_asyncPacketHandling; + /// Are we currently sending data asynchronously? + private volatile bool m_sendingData = false; + /// The all important shutdown flag private volatile bool m_shutdownFlag = true; @@ -246,25 +260,48 @@ namespace OpenMetaverse } } - public void SyncBeginSend(UDPPacketBuffer buf) + public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority) { if (!m_shutdownFlag) { - try + if (!m_sendingData) { - m_udpSocket.SendTo( - buf.Data, - 0, - buf.DataLength, - SocketFlags.None, - buf.RemoteEndPoint); + m_sendingData = true; + try + { + AsyncBeginSend(buf); + } + catch (SocketException) { } + catch (ObjectDisposedException) { } + } + else + { + if (Priority == 2) + { + lock (m_priorityQueue) + { + m_priorityQueue.Add(buf); + } + } + else + { + lock (m_standardQueue) + { + if (Priority != 0) + { + m_standardQueue.Insert(0, buf); + } + else + { + m_standardQueue.Add(buf); + } + } + } } - catch (SocketException) { } - catch (ObjectDisposedException) { } } } - public void AsyncBeginSend(UDPPacketBuffer buf) + private void AsyncBeginSend(UDPPacketBuffer buf) { if (!m_shutdownFlag) { @@ -288,8 +325,36 @@ namespace OpenMetaverse { try { -// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; m_udpSocket.EndSendTo(result); + + if (m_sendingData) + { + lock (m_priorityQueue) + { + if (m_priorityQueue.Count > 0) + { + UDPPacketBuffer buf = m_priorityQueue[0]; + m_priorityQueue.RemoveAt(0); + AsyncBeginSend(buf); + } + else + { + lock (m_standardQueue) + { + if (m_standardQueue.Count > 0) + { + UDPPacketBuffer buf = m_standardQueue[0]; + m_standardQueue.RemoveAt(0); + AsyncBeginSend(buf); + } + else + { + m_sendingData = false; + } + } + } + } + } } catch (SocketException) { } catch (ObjectDisposedException) { } diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index cbe4118..2230fba 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -156,8 +156,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); // Check control flags - bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS; - bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; + bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS); + bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a430b1e..5058457 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1164,16 +1164,16 @@ namespace OpenSim.Region.Framework.Scenes // Check if any objects have reached their targets CheckAtTargets(); - // Update SceneObjectGroups that have scheduled themselves for updates - // Objects queue their updates onto all scene presences - if (m_frame % m_update_objects == 0) - m_sceneGraph.UpdateObjectGroups(); - // Run through all ScenePresences looking for updates // Presence updates and queued object updates for each presence are sent to clients if (m_frame % m_update_presences == 0) m_sceneGraph.UpdatePresences(); + // Update SceneObjectGroups that have scheduled themselves for updates + // Objects queue their updates onto all scene presences + if (m_frame % m_update_objects == 0) + m_sceneGraph.UpdateObjectGroups(); + int TempPhysicsMS2 = Environment.TickCount; if ((m_frame % m_update_physics == 0) && m_physics_enabled) m_sceneGraph.UpdatePreparePhysics(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 424c25b..99f3141 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes // { // m_log.Debug("[ScenePresence] Destructor called"); // } - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; @@ -144,7 +144,6 @@ namespace OpenSim.Region.Framework.Scenes private int m_perfMonMS; private bool m_setAlwaysRun; - private bool m_forceFly; private bool m_flyDisabled; @@ -166,7 +165,8 @@ namespace OpenSim.Region.Framework.Scenes protected RegionInfo m_regionInfo; protected ulong crossingFromRegion; - private readonly Vector3[] Dir_Vectors = new Vector3[6]; + private readonly Vector3[] Dir_Vectors = new Vector3[9]; + private bool m_isNudging = false; // Position of agent's camera in world (region cordinates) protected Vector3 m_CameraCenter; @@ -230,6 +230,8 @@ namespace OpenSim.Region.Framework.Scenes DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, + DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG } @@ -714,21 +716,41 @@ namespace OpenSim.Region.Framework.Scenes Dir_Vectors[3] = -Vector3.UnitY; //RIGHT Dir_Vectors[4] = Vector3.UnitZ; //UP Dir_Vectors[5] = -Vector3.UnitZ; //DOWN - Dir_Vectors[5] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge + Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE + Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE + Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge } private Vector3[] GetWalkDirectionVectors() { - Vector3[] vector = new Vector3[6]; + Vector3[] vector = new Vector3[9]; vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK vector[2] = Vector3.UnitY; //LEFT vector[3] = -Vector3.UnitY; //RIGHT vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN - vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge + vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE + vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE + vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge return vector; } + + private bool[] GetDirectionIsNudge() + { + bool[] isNudge = new bool[9]; + isNudge[0] = false; //FORWARD + isNudge[1] = false; //BACK + isNudge[2] = false; //LEFT + isNudge[3] = false; //RIGHT + isNudge[4] = false; //UP + isNudge[5] = false; //DOWN + isNudge[6] = true; //FORWARD_NUDGE + isNudge[7] = true; //BACK_NUDGE + isNudge[8] = true; //DOWN_Nudge + return isNudge; + } + #endregion @@ -1147,7 +1169,6 @@ namespace OpenSim.Region.Framework.Scenes // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); // return; //} - m_perfMonMS = Environment.TickCount; ++m_movementUpdateCount; @@ -1229,7 +1250,6 @@ namespace OpenSim.Region.Framework.Scenes m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); } } - lock (scriptedcontrols) { if (scriptedcontrols.Count > 0) @@ -1261,7 +1281,6 @@ namespace OpenSim.Region.Framework.Scenes { return; } - if (m_allowMovement) { int i = 0; @@ -1289,6 +1308,11 @@ namespace OpenSim.Region.Framework.Scenes update_rotation = true; } + //guilty until proven innocent.. + bool Nudging = true; + //Basically, if there is at least one non-nudge control then we don't need + //to worry about stopping the avatar + if (m_parentID == 0) { bool bAllowUpdateMoveToPosition = false; @@ -1303,6 +1327,12 @@ namespace OpenSim.Region.Framework.Scenes else dirVectors = Dir_Vectors; + bool[] isNudge = GetDirectionIsNudge(); + + + + + foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) { if (((uint)flags & (uint)DCF) != 0) @@ -1312,6 +1342,10 @@ namespace OpenSim.Region.Framework.Scenes try { agent_control_v3 += dirVectors[i]; + if (isNudge[i] == false) + { + Nudging = false; + } } catch (IndexOutOfRangeException) { @@ -1373,6 +1407,9 @@ namespace OpenSim.Region.Framework.Scenes // Ignore z component of vector Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); LocalVectorToTarget2D.Normalize(); + + //We're not nudging + Nudging = false; agent_control_v3 += LocalVectorToTarget2D; // update avatar movement flags. the avatar coordinate system is as follows: @@ -1450,7 +1487,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.DebugFormat( // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); - AddNewMovement(agent_control_v3, q); + AddNewMovement(agent_control_v3, q, Nudging); if (update_movementflag) Animator.UpdateMovementAnimations(); @@ -1886,7 +1923,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// The vector in which to move. This is relative to the rotation argument /// The direction in which this avatar should now face. - public void AddNewMovement(Vector3 vec, Quaternion rotation) + public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) { if (m_isChildAgent) { @@ -1960,7 +1997,7 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Add the force instead of only setting it to support multiple forces per frame? m_forceToApply = direc; - + m_isNudging = Nudging; m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); } @@ -1975,7 +2012,7 @@ namespace OpenSim.Region.Framework.Scenes const float POSITION_TOLERANCE = 0.05f; //const int TIME_MS_TOLERANCE = 3000; - SendPrimUpdates(); + if (m_newCoarseLocations) { @@ -2011,6 +2048,9 @@ namespace OpenSim.Region.Framework.Scenes CheckForBorderCrossing(); CheckForSignificantMovement(); // sends update to the modules. } + + //Sending prim updates AFTER the avatar terse updates are sent + SendPrimUpdates(); } #endregion @@ -2864,14 +2904,24 @@ namespace OpenSim.Region.Framework.Scenes { if (m_forceToApply.HasValue) { - Vector3 force = m_forceToApply.Value; + Vector3 force = m_forceToApply.Value; m_updateflag = true; -// movementvector = force; Velocity = force; m_forceToApply = null; } + else + { + if (m_isNudging) + { + Vector3 force = Vector3.Zero; + + m_updateflag = true; + Velocity = force; + m_isNudging = false; + } + } } public override void SetText(string text, Vector3 color, double alpha) -- cgit v1.1 From 4a29a7f92cc5264dfcb4a4376a61506d29dd9d8d Mon Sep 17 00:00:00 2001 From: CasperW Date: Sat, 21 Nov 2009 18:50:52 +0100 Subject: Minor packet ordering fix --- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 1 - .../Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | 40 ++++++++++++++++------ 2 files changed, 30 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 4a7bdfe..98bb4f7 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -578,7 +578,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP SyncBeginPrioritySend(buffer, 2); // highest priority } else if (outgoingPacket.Type == PacketType.ObjectUpdate - || outgoingPacket.Type == PacketType.ChatFromSimulator || outgoingPacket.Type == PacketType.LayerData) { SyncBeginPrioritySend(buffer, 1); // medium priority diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs index 45d9170..de2cd24 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs @@ -57,7 +57,12 @@ namespace OpenMetaverse /// Standard queue for our outgoing SyncBeginPrioritySend /// private List m_standardQueue = new List(); - + + /// + /// Medium priority queue for our outgoing SyncBeginPrioritySend + /// + private List m_mediumPriorityQueue = new List(); + /// /// Prioritised queue for our outgoing SyncBeginPrioritySend /// @@ -285,13 +290,16 @@ namespace OpenMetaverse } else { - lock (m_standardQueue) + if (Priority != 0) { - if (Priority != 0) + lock (m_mediumPriorityQueue) { - m_standardQueue.Insert(0, buf); + m_mediumPriorityQueue.Add(buf); } - else + } + else + { + lock (m_standardQueue) { m_standardQueue.Add(buf); } @@ -339,17 +347,29 @@ namespace OpenMetaverse } else { - lock (m_standardQueue) + lock (m_mediumPriorityQueue) { - if (m_standardQueue.Count > 0) + if (m_mediumPriorityQueue.Count > 0) { - UDPPacketBuffer buf = m_standardQueue[0]; - m_standardQueue.RemoveAt(0); + UDPPacketBuffer buf = m_mediumPriorityQueue[0]; + m_mediumPriorityQueue.RemoveAt(0); AsyncBeginSend(buf); } else { - m_sendingData = false; + lock (m_standardQueue) + { + if (m_standardQueue.Count > 0) + { + UDPPacketBuffer buf = m_standardQueue[0]; + m_standardQueue.RemoveAt(0); + AsyncBeginSend(buf); + } + else + { + m_sendingData = false; + } + } } } } -- cgit v1.1 From f1522e62042d11604ad70a39b26dc94953e9db7d Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Sun, 22 Nov 2009 08:31:35 +0100 Subject: Add non-scripted sit, fix scripted sit. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 99 +++++++++++++++++------- 1 file changed, 69 insertions(+), 30 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1dedcf1..aa538dc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -89,7 +89,8 @@ namespace OpenSim.Region.Framework.Scenes /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis /// issue #1716 /// - private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); +// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); + private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); public UUID currentParcelUUID = UUID.Zero; @@ -113,7 +114,8 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 lastKnownAllowedPosition; public bool sentMessageAboutRestrictedParcelFlyingDown; public Vector4 CollisionPlane = Vector4.UnitW; - + + private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; @@ -1531,7 +1533,7 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; SendFullUpdateToAllClients(); - //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); + HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? } //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); m_requestedSitTargetUUID = UUID.Zero; @@ -1644,7 +1646,7 @@ namespace OpenSim.Region.Framework.Scenes bool SitTargetisSet = (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); - + // this test is probably failing if (SitTargetisSet && SitTargetUnOccupied) { //switch the target to this prim @@ -1671,26 +1673,37 @@ namespace OpenSim.Region.Framework.Scenes { // TODO: determine position to sit at based on scene geometry; don't trust offset from client // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - + + // part is the prim to sit on + // offset is the vector distance from that prim center to the click-spot + // UUID is the UUID of the Avatar doing the clicking + + m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation + // Is a sit target available? Vector3 avSitOffSet = part.SitTargetPosition; Quaternion avSitOrientation = part.SitTargetOrientation; UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); - bool SitTargetisSet = - (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && - avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); +// bool SitTargetisSet = +// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && +// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); + bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation)); + +//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied + +// " TargSet=" + SitTargetisSet); + if (SitTargetisSet && SitTargetUnOccupied) { part.SetAvatarOnSitTarget(UUID); offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); sitOrientation = avSitOrientation; - autopilot = false; + autopilot = false; // Jump direct to scripted llSitPos() } - pos = part.AbsolutePosition + offset; + pos = part.AbsolutePosition + offset; // Region position where clicked //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) //{ // offset = pos; @@ -1703,17 +1716,17 @@ namespace OpenSim.Region.Framework.Scenes m_sitAvatarHeight = m_physicsActor.Size.Z; if (autopilot) - { + { // its not a scripted sit if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) { - autopilot = false; + autopilot = false; // close enough RemoveFromPhysicalScene(); - AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); - } + AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim + } // else the autopilot will get us close } else - { + { // its a scripted sit RemoveFromPhysicalScene(); } } @@ -1816,26 +1829,41 @@ namespace OpenSim.Region.Framework.Scenes { if (part.GetAvatarOnSitTarget() == UUID) { + // Scripted sit Vector3 sitTargetPos = part.SitTargetPosition; Quaternion sitTargetOrient = part.SitTargetOrientation; - - //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); - //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); - - //Quaternion result = (sitTargetOrient * vq) * nq; - m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); m_pos += SIT_TARGET_ADJUSTMENT; m_bodyRot = sitTargetOrient; - //Rotation = sitTargetOrient; m_parentPosition = part.AbsolutePosition; - - //SendTerseUpdateToAllClients(); } else { - m_pos -= part.AbsolutePosition; + // Non-scripted sit by Kitto Flora 21Nov09 + // Calculate angle of line from prim to Av + float y_diff = (m_avInitialPos.Y - part.AbsolutePosition.Y); + float x_diff = ( m_avInitialPos.X - part.AbsolutePosition.X); + if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 + if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 + float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); + Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. + // Av sits at world euler <0,0, z>, translated by part rotation + m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click + m_pos = new Vector3(0f, 0f, 0.05f) + + (new Vector3(0.0f, 0f, 0.625f) * partIRot) + + (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); // sit at center of prim m_parentPosition = part.AbsolutePosition; + //Set up raytrace to find top surface of prim + Vector3 size = part.Scale; + float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); + Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); + Vector3 down = new Vector3(0f, 0f, -1f); + m_scene.PhysicsScene.RaycastWorld( + start, // Vector3 position, + down, // Vector3 direction, + mag, // float length, + SitAltitudeCallback); // retMethod } } else @@ -1850,11 +1878,22 @@ namespace OpenSim.Region.Framework.Scenes Animator.TrySetMovementAnimation(sitAnimation); SendFullUpdateToAllClients(); - // This may seem stupid, but Our Full updates don't send avatar rotation :P - // So we're also sending a terse update (which has avatar rotation) - // [Update] We do now. - //SendTerseUpdateToAllClients(); } + + public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) + { +// Console.WriteLine("[RAYCASTRESULT]: Hit={0}, Point={1}, ID={2}, Dist={3}", hitYN, collisionPoint, localid, distance); + if(hitYN) + { + // m_pos = Av offset from prim center to make look like on center + // m_parentPosition = Actual center pos of prim + // collisionPoint = spot on prim where we want to sit + SceneObjectPart part = m_scene.GetSceneObjectPart(localid); + Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset); + m_pos += offset; +// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit); + } + } /// /// Event handler for the 'Always run' setting on the client @@ -3578,4 +3617,4 @@ namespace OpenSim.Region.Framework.Scenes } } } -} \ No newline at end of file +} -- cgit v1.1 From 889ce36afa67c521f3e50e4833a894ffd39af490 Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 23 Nov 2009 16:02:05 +0100 Subject: Added some [DebuggerNonUserCode] modifiers to functions that throw EventAbortException() to ease debugging on Visual Studio --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++++ OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs | 2 ++ OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs | 2 ++ OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 5 ++++- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 3 +++ 5 files changed, 15 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 50b2fb5..b549b5c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; //for [DebuggerNonUserCode] using System.Runtime.Remoting.Lifetime; using System.Text; using System.Threading; @@ -151,6 +152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api get { return m_ScriptEngine.World; } } + [DebuggerNonUserCode] public void state(string newState) { m_ScriptEngine.SetState(m_itemID, newState); @@ -160,6 +162,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Reset the named script. The script must be present /// in the same prim. /// + [DebuggerNonUserCode] public void llResetScript() { m_host.AddScriptLPS(1); @@ -3755,6 +3758,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(3000); } + [DebuggerNonUserCode] public void llRemoveInventory(string name) { m_host.AddScriptLPS(1); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs index 7f67599..15e0408 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; //for [DebuggerNonUserCode] using System.Reflection; using System.Runtime.Remoting.Lifetime; using OpenSim.Region.ScriptEngine.Shared; @@ -131,6 +132,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return (eventFlags); } + [DebuggerNonUserCode] public void ExecuteEvent(string state, string FunctionName, object[] args) { // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs index 121159c..a44abb0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs @@ -33,6 +33,7 @@ using System.Threading; using System.Reflection; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; //for [DebuggerNonUserCode] using OpenSim.Region.ScriptEngine.Interfaces; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; @@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return (int)m_Executor.GetStateEventFlags(state); } + [DebuggerNonUserCode] public void ExecuteEvent(string state, string FunctionName, object[] args) { m_Executor.ExecuteEvent(state, FunctionName, args); diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 41b5d49..ed3fdbe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -27,6 +27,7 @@ using System; using System.IO; +using System.Diagnostics; //for [DebuggerNonUserCode] using System.Runtime.Remoting; using System.Runtime.Remoting.Lifetime; using System.Threading; @@ -544,6 +545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance return true; } + [DebuggerNonUserCode] //Prevents the debugger from farting in this function public void SetState(string state) { if (state == State) @@ -555,7 +557,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance new DetectParams[0])); PostEvent(new EventParams("state_entry", new Object[0], new DetectParams[0])); - + throw new EventAbortException(); } @@ -824,6 +826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance new Object[0], new DetectParams[0])); } + [DebuggerNonUserCode] //Stops the VS debugger from farting in this function public void ApiResetScript() { // bool running = Running; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index a60c0ba..8b94f28 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -30,6 +30,7 @@ using System.IO; using System.Threading; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; //for [DebuggerNonUserCode] using System.Security; using System.Security.Policy; using System.Reflection; @@ -1119,6 +1120,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine return false; } + [DebuggerNonUserCode] public void ApiResetScript(UUID itemID) { IScriptInstance instance = GetInstance(itemID); @@ -1170,6 +1172,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine return UUID.Zero; } + [DebuggerNonUserCode] public void SetState(UUID itemID, string newState) { IScriptInstance instance = GetInstance(itemID); -- cgit v1.1 From 73c2162ff60850d96761aa07a1950dbbb2ec3e80 Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 23 Nov 2009 19:51:40 +0100 Subject: Fixed nullrefs --- .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 42 ++++++++++++---------- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 8 +++-- 2 files changed, 29 insertions(+), 21 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index cd59bdb..5c24f03 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -266,25 +266,29 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat } // m_log.DebugFormat("[CHAT] Broadcast: fromID {0} fromName {1}, cType {2}, sType {3}", fromID, fromName, cType, sourceType); - - ((Scene)c.Scene).ForEachScenePresence( - delegate(ScenePresence presence) - { - // ignore chat from child agents - if (presence.IsChildAgent) return; - - IClientAPI client = presence.ControllingClient; - - // don't forward SayOwner chat from objects to - // non-owner agents - if ((c.Type == ChatTypeEnum.Owner) && - (null != c.SenderObject) && - (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) - return; - - client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, - (byte)sourceType, (byte)ChatAudibleLevel.Fully); - }); + if (c.Scene != null) + { + ((Scene)c.Scene).ForEachScenePresence + ( + delegate(ScenePresence presence) + { + // ignore chat from child agents + if (presence.IsChildAgent) return; + + IClientAPI client = presence.ControllingClient; + + // don't forward SayOwner chat from objects to + // non-owner agents + if ((c.Type == ChatTypeEnum.Owner) && + (null != c.SenderObject) && + (((SceneObjectPart)c.SenderObject).OwnerID != client.AgentId)) + return; + + client.SendChatMessage(c.Message, (byte)cType, CenterOfRegion, fromName, fromID, + (byte)sourceType, (byte)ChatAudibleLevel.Fully); + } + ); + } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 66fb918..83208e9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -840,8 +840,12 @@ namespace OpenSim.Region.Framework.Scenes public void RemoveTaskInventory(IClientAPI remoteClient, UUID itemID, uint localID) { SceneObjectPart part = GetSceneObjectPart(localID); - SceneObjectGroup group = part.ParentGroup; - if (group != null) + SceneObjectGroup group = null; + if (part != null) + { + group = part.ParentGroup; + } + if (part != null && group != null) { TaskInventoryItem item = group.GetInventoryItem(localID, itemID); if (item == null) -- cgit v1.1 From 247c66b3fe792692468ede6a516d85c6c9852d23 Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 23 Nov 2009 20:25:53 +0100 Subject: Swap the locking of m_EventQueue and m_Script to ease locks on script inventory operations --- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 234 +++++++++++---------- 1 file changed, 119 insertions(+), 115 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index ed3fdbe..063d50f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -640,154 +640,158 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance /// public object EventProcessor() { + + EventParams data = null; + + lock (m_EventQueue) + { lock (m_Script) { - EventParams data = null; - - lock (m_EventQueue) + data = (EventParams) m_EventQueue.Dequeue(); + if (data == null) // Shouldn't happen { - data = (EventParams) m_EventQueue.Dequeue(); - if (data == null) // Shouldn't happen + if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { - if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) - { - m_CurrentResult = m_Engine.QueueEventHandler(this); - } - else - { - m_CurrentResult = null; - } - return 0; + m_CurrentResult = m_Engine.QueueEventHandler(this); } - - if (data.EventName == "timer") - m_TimerQueued = false; - if (data.EventName == "control") + else { - if (m_ControlEventsInQueue > 0) - m_ControlEventsInQueue--; + m_CurrentResult = null; } - if (data.EventName == "collision") - m_CollisionInQueue = false; + return 0; } - - //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); - m_DetectParams = data.DetectParams; - - if (data.EventName == "state") // Hardcoded state change + if (data.EventName == "timer") + m_TimerQueued = false; + if (data.EventName == "control") { - // m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", - // m_PrimName, m_ScriptName, data.Params[0].ToString()); - m_State=data.Params[0].ToString(); - AsyncCommandManager.RemoveScript(m_Engine, - m_LocalID, m_ItemID); + if (m_ControlEventsInQueue > 0) + m_ControlEventsInQueue--; + } + if (data.EventName == "collision") + m_CollisionInQueue = false; + } + } + lock(m_Script) + { + + //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); - SceneObjectPart part = m_Engine.World.GetSceneObjectPart( - m_LocalID); - if (part != null) - { - part.SetScriptEvents(m_ItemID, - (int)m_Script.GetStateEventFlags(State)); - } + m_DetectParams = data.DetectParams; + + if (data.EventName == "state") // Hardcoded state change + { +// m_log.DebugFormat("[Script] Script {0}.{1} state set to {2}", +// m_PrimName, m_ScriptName, data.Params[0].ToString()); + m_State=data.Params[0].ToString(); + AsyncCommandManager.RemoveScript(m_Engine, + m_LocalID, m_ItemID); + + SceneObjectPart part = m_Engine.World.GetSceneObjectPart( + m_LocalID); + if (part != null) + { + part.SetScriptEvents(m_ItemID, + (int)m_Script.GetStateEventFlags(State)); } - else + } + else + { + if (m_Engine.World.PipeEventsForScript(m_LocalID) || + data.EventName == "control") // Don't freeze avies! { - if (m_Engine.World.PipeEventsForScript(m_LocalID) || - data.EventName == "control") // Don't freeze avies! - { - SceneObjectPart part = m_Engine.World.GetSceneObjectPart( - m_LocalID); - // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", - // m_PrimName, m_ScriptName, data.EventName, m_State); + SceneObjectPart part = m_Engine.World.GetSceneObjectPart( + m_LocalID); + // m_log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}", + // m_PrimName, m_ScriptName, data.EventName, m_State); - try - { - m_CurrentEvent = data.EventName; - m_EventStart = DateTime.Now; - m_InEvent = true; + try + { + m_CurrentEvent = data.EventName; + m_EventStart = DateTime.Now; + m_InEvent = true; - m_Script.ExecuteEvent(State, data.EventName, data.Params); + m_Script.ExecuteEvent(State, data.EventName, data.Params); - m_InEvent = false; - m_CurrentEvent = String.Empty; + m_InEvent = false; + m_CurrentEvent = String.Empty; - if (m_SaveState) - { - // This will be the very first event we deliver - // (state_entry) in default state - // + if (m_SaveState) + { + // This will be the very first event we deliver + // (state_entry) in default state + // - SaveState(m_Assembly); + SaveState(m_Assembly); - m_SaveState = false; - } + m_SaveState = false; } - catch (Exception e) - { - // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); - m_InEvent = false; - m_CurrentEvent = String.Empty; + } + catch (Exception e) + { + // m_log.DebugFormat("[SCRIPT] Exception: {0}", e.Message); + m_InEvent = false; + m_CurrentEvent = String.Empty; - if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) - { - try - { - // DISPLAY ERROR INWORLD - string text = FormatException(e); - - if (text.Length > 1000) - text = text.Substring(0, 1000); - m_Engine.World.SimChat(Utils.StringToBytes(text), - ChatTypeEnum.DebugChannel, 2147483647, - part.AbsolutePosition, - part.Name, part.UUID, false); - } - catch (Exception) - { - } - // catch (Exception e2) // LEGIT: User Scripting - // { - // m_log.Error("[SCRIPT]: "+ - // "Error displaying error in-world: " + - // e2.ToString()); - // m_log.Error("[SCRIPT]: " + - // "Errormessage: Error compiling script:\r\n" + - // e.ToString()); - // } - } - else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) + if ((!(e is TargetInvocationException) || (!(e.InnerException is SelfDeleteException) && !(e.InnerException is ScriptDeleteException))) && !(e is ThreadAbortException)) + { + try { - m_InSelfDelete = true; - if (part != null && part.ParentGroup != null) - m_Engine.World.DeleteSceneObject(part.ParentGroup, false); + // DISPLAY ERROR INWORLD + string text = FormatException(e); + + if (text.Length > 1000) + text = text.Substring(0, 1000); + m_Engine.World.SimChat(Utils.StringToBytes(text), + ChatTypeEnum.DebugChannel, 2147483647, + part.AbsolutePosition, + part.Name, part.UUID, false); } - else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) + catch (Exception) { - m_InSelfDelete = true; - if (part != null && part.ParentGroup != null) - part.Inventory.RemoveInventoryItem(m_ItemID); } + // catch (Exception e2) // LEGIT: User Scripting + // { + // m_log.Error("[SCRIPT]: "+ + // "Error displaying error in-world: " + + // e2.ToString()); + // m_log.Error("[SCRIPT]: " + + // "Errormessage: Error compiling script:\r\n" + + // e.ToString()); + // } + } + else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) + { + m_InSelfDelete = true; + if (part != null && part.ParentGroup != null) + m_Engine.World.DeleteSceneObject(part.ParentGroup, false); + } + else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) + { + m_InSelfDelete = true; + if (part != null && part.ParentGroup != null) + part.Inventory.RemoveInventoryItem(m_ItemID); } } } + } - lock (m_EventQueue) + lock (m_EventQueue) + { + if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) { - if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) - { - m_CurrentResult = m_Engine.QueueEventHandler(this); - } - else - { - m_CurrentResult = null; - } + m_CurrentResult = m_Engine.QueueEventHandler(this); + } + else + { + m_CurrentResult = null; } + } - m_DetectParams = null; + m_DetectParams = null; - return 0; - } + return 0; + } } public int EventTime() -- cgit v1.1 From d1147136946daf14724183b3191119be44ff8b16 Mon Sep 17 00:00:00 2001 From: CasperW Date: Tue, 24 Nov 2009 18:02:12 +0100 Subject: Drop all locking of part.TaskInventory in favour of a ReaderWriterLockSlim lock handler. This gives us: - Faster prim inventory actions. Multiple threads can read at once. - Fixes the known prim inventory thread locks - In the event of a thread lock occurring, it will usually self heal after sixty seconds with an error message in the console --- OpenSim/Framework/TaskInventoryDictionary.cs | 111 ++++- .../World/Archiver/ArchiveReadRequest.cs | 21 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 38 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 390 ++++++++------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 16 +- .../Shared/Api/Implementation/LSL_Api.cs | 532 ++++++++++++--------- .../Shared/Api/Implementation/OSSL_Api.cs | 36 +- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 22 +- 8 files changed, 685 insertions(+), 481 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 25ae6b0..efe5f0c 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -27,9 +27,12 @@ using System; using System.Collections.Generic; +using System.Threading; +using System.Reflection; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; +using log4net; using OpenMetaverse; namespace OpenSim.Framework @@ -45,6 +48,105 @@ namespace OpenSim.Framework // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Thread LockedByThread; + /// + /// An advanced lock for inventory data + /// + private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim(); + + /// + /// Are we readlocked by the calling thread? + /// + public bool IsReadLockedByMe() + { + if (m_itemLock.RecursiveReadCount > 0) + { + return true; + } + else + { + return false; + } + } + + /// + /// Lock our inventory list for reading (many can read, one can write) + /// + public void LockItemsForRead(bool locked) + { + if (locked) + { + if (m_itemLock.IsWriteLockHeld && LockedByThread != null) + { + if (!LockedByThread.IsAlive) + { + //Locked by dead thread, reset. + m_itemLock = new System.Threading.ReaderWriterLockSlim(); + } + } + + if (m_itemLock.RecursiveReadCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_itemLock.ExitReadLock(); + } + if (m_itemLock.RecursiveWriteCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); + m_itemLock.ExitWriteLock(); + } + + while (!m_itemLock.TryEnterReadLock(60000)) + { + m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + if (m_itemLock.IsWriteLockHeld) + { + m_itemLock = new System.Threading.ReaderWriterLockSlim(); + } + } + } + else + { + m_itemLock.ExitReadLock(); + } + } + + /// + /// Lock our inventory list for writing (many can read, one can write) + /// + public void LockItemsForWrite(bool locked) + { + if (locked) + { + //Enter a write lock, wait indefinately for one to open. + if (m_itemLock.RecursiveReadCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_itemLock.ExitReadLock(); + } + if (m_itemLock.RecursiveWriteCount > 0) + { + m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); + m_itemLock.ExitWriteLock(); + } + while (!m_itemLock.TryEnterWriteLock(60000)) + { + m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + if (m_itemLock.IsWriteLockHeld) + { + m_itemLock = new System.Threading.ReaderWriterLockSlim(); + } + } + + LockedByThread = Thread.CurrentThread; + } + else + { + m_itemLock.ExitWriteLock(); + } + } #region ICloneable Members @@ -52,13 +154,12 @@ namespace OpenSim.Framework { TaskInventoryDictionary clone = new TaskInventoryDictionary(); - lock (this) + m_itemLock.EnterReadLock(); + foreach (UUID uuid in Keys) { - foreach (UUID uuid in Keys) - { - clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); - } + clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); } + m_itemLock.ExitReadLock(); return clone; } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs index 70a225e..f204faf 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveReadRequest.cs @@ -246,21 +246,20 @@ namespace OpenSim.Region.CoreModules.World.Archiver // Fix ownership/creator of inventory items // Not doing so results in inventory items // being no copy/no mod for everyone - lock (part.TaskInventory) + part.TaskInventory.LockItemsForRead(true); + TaskInventoryDictionary inv = part.TaskInventory; + foreach (KeyValuePair kvp in inv) { - TaskInventoryDictionary inv = part.TaskInventory; - foreach (KeyValuePair kvp in inv) + if (!ResolveUserUuid(kvp.Value.OwnerID)) { - if (!ResolveUserUuid(kvp.Value.OwnerID)) - { - kvp.Value.OwnerID = masterAvatarId; - } - if (!ResolveUserUuid(kvp.Value.CreatorID)) - { - kvp.Value.CreatorID = masterAvatarId; - } + kvp.Value.OwnerID = masterAvatarId; + } + if (!ResolveUserUuid(kvp.Value.CreatorID)) + { + kvp.Value.CreatorID = masterAvatarId; } } + part.TaskInventory.LockItemsForRead(false); } if (m_scene.AddRestoredSceneObject(sceneObject, true, false)) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index cdec135..bbece2f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -389,12 +389,16 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes + /// Get the inventory list /// public TaskInventoryDictionary TaskInventory { - get { return m_inventory.Items; } - set { m_inventory.Items = value; } + get { + return m_inventory.Items; + } + set { + m_inventory.Items = value; + } } public uint ObjectFlags @@ -2101,17 +2105,18 @@ namespace OpenSim.Region.Framework.Scenes //Trys to fetch sound id from prim's inventory. //Prim's inventory doesn't support non script items yet - lock (TaskInventory) + TaskInventory.LockItemsForRead(true); + + foreach (KeyValuePair item in TaskInventory) { - foreach (KeyValuePair item in TaskInventory) + if (item.Value.Name == sound) { - if (item.Value.Name == sound) - { - soundID = item.Value.ItemID; - break; - } + soundID = item.Value.ItemID; + break; } } + + TaskInventory.LockItemsForRead(false); } List avatarts = m_parentGroup.Scene.GetAvatars(); @@ -2457,17 +2462,16 @@ namespace OpenSim.Region.Framework.Scenes if (!UUID.TryParse(sound, out soundID)) { // search sound file from inventory - lock (TaskInventory) + TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair item in TaskInventory) { - foreach (KeyValuePair item in TaskInventory) + if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) { - if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) - { - soundID = item.Value.ItemID; - break; - } + soundID = item.Value.ItemID; + break; } } + TaskInventory.LockItemsForRead(false); } if (soundID == UUID.Zero) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index f4ca877..4dc709e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -80,7 +80,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal TaskInventoryDictionary Items { - get { return m_items; } + get { + return m_items; + } set { m_items = value; @@ -116,22 +118,25 @@ namespace OpenSim.Region.Framework.Scenes /// Link number for the part public void ResetInventoryIDs() { - lock (Items) + m_items.LockItemsForWrite(true); + + if (0 == Items.Count) { - if (0 == Items.Count) - return; + m_items.LockItemsForWrite(false); + return; + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - Items.Clear(); + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + IList items = new List(Items.Values); + Items.Clear(); - foreach (TaskInventoryItem item in items) - { - item.ResetIDs(m_part.UUID); - Items.Add(item.ItemID, item); - } + foreach (TaskInventoryItem item in items) + { + item.ResetIDs(m_part.UUID); + Items.Add(item.ItemID, item); } + m_items.LockItemsForWrite(false); } /// @@ -140,25 +145,25 @@ namespace OpenSim.Region.Framework.Scenes /// public void ChangeInventoryOwner(UUID ownerId) { - lock (Items) + m_items.LockItemsForWrite(true); + if (0 == Items.Count) { - if (0 == Items.Count) - { - return; - } + m_items.LockItemsForWrite(false); + return; + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + IList items = new List(Items.Values); + foreach (TaskInventoryItem item in items) + { + if (ownerId != item.OwnerID) { - if (ownerId != item.OwnerID) - { - item.LastOwnerID = item.OwnerID; - item.OwnerID = ownerId; - } + item.LastOwnerID = item.OwnerID; + item.OwnerID = ownerId; } } + m_items.LockItemsForWrite(false); } /// @@ -167,24 +172,24 @@ namespace OpenSim.Region.Framework.Scenes /// public void ChangeInventoryGroup(UUID groupID) { - lock (Items) + m_items.LockItemsForWrite(true); + if (0 == Items.Count) { - if (0 == Items.Count) - { - return; - } + m_items.LockItemsForWrite(false); + return; + } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; - IList items = new List(Items.Values); - foreach (TaskInventoryItem item in items) + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + IList items = new List(Items.Values); + foreach (TaskInventoryItem item in items) + { + if (groupID != item.GroupID) { - if (groupID != item.GroupID) - { - item.GroupID = groupID; - } + item.GroupID = groupID; } } + m_items.LockItemsForWrite(false); } /// @@ -192,14 +197,14 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) { - lock (m_items) + Items.LockItemsForRead(true); + IList items = new List(Items.Values); + Items.LockItemsForRead(false); + foreach (TaskInventoryItem item in items) { - foreach (TaskInventoryItem item in Items.Values) + if ((int)InventoryType.LSL == item.InvType) { - if ((int)InventoryType.LSL == item.InvType) - { - CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); - } + CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); } } } @@ -209,17 +214,20 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveScriptInstances() { - lock (Items) + Items.LockItemsForRead(true); + IList items = new List(Items.Values); + Items.LockItemsForRead(false); + + foreach (TaskInventoryItem item in items) { - foreach (TaskInventoryItem item in Items.Values) + if ((int)InventoryType.LSL == item.InvType) { - if ((int)InventoryType.LSL == item.InvType) - { - RemoveScriptInstance(item.ItemID); - m_part.RemoveScriptEvents(item.ItemID); - } + RemoveScriptInstance(item.ItemID); + m_part.RemoveScriptEvents(item.ItemID); } } + + } /// @@ -244,8 +252,10 @@ namespace OpenSim.Region.Framework.Scenes if (stateSource == 1 && // Prim crossing m_part.ParentGroup.Scene.m_trustBinaries) { + m_items.LockItemsForWrite(true); m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; + m_items.LockItemsForWrite(false); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); @@ -266,8 +276,10 @@ namespace OpenSim.Region.Framework.Scenes { if (m_part.ParentGroup.m_savedScriptState != null) RestoreSavedScriptState(item.OldItemID, item.ItemID); + m_items.LockItemsForWrite(true); m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; + m_items.LockItemsForWrite(false); string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); @@ -302,20 +314,22 @@ namespace OpenSim.Region.Framework.Scenes /// public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) { - lock (m_items) + m_items.LockItemsForRead(true); + if (m_items.ContainsKey(itemId)) { - if (m_items.ContainsKey(itemId)) - { - CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}", - itemId, m_part.Name, m_part.UUID); - } + TaskInventoryItem item = m_items[itemId]; + m_items.LockItemsForRead(false); + CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); } + else + { + m_items.LockItemsForRead(false); + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}", + itemId, m_part.Name, m_part.UUID); + } + } /// @@ -346,11 +360,16 @@ namespace OpenSim.Region.Framework.Scenes /// private bool InventoryContainsName(string name) { - foreach (TaskInventoryItem item in Items.Values) + m_items.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_items.Values) { if (item.Name == name) + { + m_items.LockItemsForRead(false); return true; + } } + m_items.LockItemsForRead(false); return false; } @@ -392,7 +411,9 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) { + m_items.LockItemsForRead(true); List il = new List(m_items.Values); + m_items.LockItemsForRead(false); foreach (TaskInventoryItem i in il) { if (i.Name == item.Name) @@ -429,15 +450,14 @@ namespace OpenSim.Region.Framework.Scenes item.ParentPartID = m_part.UUID; item.Name = name; - lock (m_items) - { - m_items.Add(item.ItemID, item); - + m_items.LockItemsForWrite(true); + m_items.Add(item.ItemID, item); + m_items.LockItemsForWrite(false); if (allowedDrop) m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); else m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - } + m_inventorySerial++; //m_inventorySerial += 2; @@ -454,14 +474,13 @@ namespace OpenSim.Region.Framework.Scenes /// public void RestoreInventoryItems(ICollection items) { - lock (m_items) + m_items.LockItemsForWrite(true); + foreach (TaskInventoryItem item in items) { - foreach (TaskInventoryItem item in items) - { - m_items.Add(item.ItemID, item); - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - } + m_items.Add(item.ItemID, item); + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); } + m_items.LockItemsForWrite(false); m_inventorySerial++; } @@ -474,8 +493,9 @@ namespace OpenSim.Region.Framework.Scenes public TaskInventoryItem GetInventoryItem(UUID itemId) { TaskInventoryItem item; + m_items.LockItemsForRead(true); m_items.TryGetValue(itemId, out item); - + m_items.LockItemsForRead(false); return item; } @@ -487,45 +507,45 @@ namespace OpenSim.Region.Framework.Scenes /// false if the item did not exist, true if the update occurred successfully public bool UpdateInventoryItem(TaskInventoryItem item) { - lock (m_items) + m_items.LockItemsForWrite(true); + + if (m_items.ContainsKey(item.ItemID)) { - if (m_items.ContainsKey(item.ItemID)) + item.ParentID = m_part.UUID; + item.ParentPartID = m_part.UUID; + item.Flags = m_items[item.ItemID].Flags; + if (item.AssetID == UUID.Zero) { - item.ParentID = m_part.UUID; - item.ParentPartID = m_part.UUID; - item.Flags = m_items[item.ItemID].Flags; - if (item.AssetID == UUID.Zero) - { - item.AssetID = m_items[item.ItemID].AssetID; - } - else if ((InventoryType)item.Type == InventoryType.Notecard) - { - ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); + item.AssetID = m_items[item.ItemID].AssetID; + } + else if ((InventoryType)item.Type == InventoryType.Notecard) + { + ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); - if (presence != null) - { - presence.ControllingClient.SendAgentAlertMessage( - "Notecard saved", false); - } + if (presence != null) + { + presence.ControllingClient.SendAgentAlertMessage( + "Notecard saved", false); } + } - m_items[item.ItemID] = item; - m_inventorySerial++; - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; + m_items[item.ItemID] = item; + m_inventorySerial++; + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - return true; - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", - item.ItemID, m_part.Name, m_part.UUID); - } + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + m_items.LockItemsForWrite(false); + return true; + } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", + item.ItemID, m_part.Name, m_part.UUID); } + m_items.LockItemsForWrite(false); return false; } @@ -538,51 +558,54 @@ namespace OpenSim.Region.Framework.Scenes /// in this prim's inventory. public int RemoveInventoryItem(UUID itemID) { - lock (m_items) + m_items.LockItemsForRead(true); + + if (m_items.ContainsKey(itemID)) { - if (m_items.ContainsKey(itemID)) + int type = m_items[itemID].InvType; + m_items.LockItemsForRead(false); + if (type == 10) // Script { - int type = m_items[itemID].InvType; - if (type == 10) // Script - { - m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); - } - m_items.Remove(itemID); - m_inventorySerial++; - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; + m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); + } + m_items.LockItemsForWrite(true); + m_items.Remove(itemID); + m_items.LockItemsForWrite(false); + m_inventorySerial++; + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - int scriptcount = 0; - lock (m_items) - { - foreach (TaskInventoryItem item in m_items.Values) - { - if (item.Type == 10) - { - scriptcount++; - } - } - } + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; - if (scriptcount <= 0) + int scriptcount = 0; + m_items.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.Type == 10) { - m_part.RemFlag(PrimFlags.Scripted); + scriptcount++; } - - m_part.ScheduleFullUpdate(); - - return type; } - else + m_items.LockItemsForRead(false); + + + if (scriptcount <= 0) { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", - itemID, m_part.Name, m_part.UUID); + m_part.RemFlag(PrimFlags.Scripted); } + + m_part.ScheduleFullUpdate(); + + return type; + } + else + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", + itemID, m_part.Name, m_part.UUID); } + m_items.LockItemsForWrite(false); return -1; } @@ -635,52 +658,53 @@ namespace OpenSim.Region.Framework.Scenes // isn't available (such as drag from prim inventory to agent inventory) InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - lock (m_items) + m_items.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) - { - UUID ownerID = item.OwnerID; - uint everyoneMask = 0; - uint baseMask = item.BasePermissions; - uint ownerMask = item.CurrentPermissions; + UUID ownerID = item.OwnerID; + uint everyoneMask = 0; + uint baseMask = item.BasePermissions; + uint ownerMask = item.CurrentPermissions; - invString.AddItemStart(); - invString.AddNameValueLine("item_id", item.ItemID.ToString()); - invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); + invString.AddItemStart(); + invString.AddNameValueLine("item_id", item.ItemID.ToString()); + invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); - invString.AddPermissionsStart(); + invString.AddPermissionsStart(); - invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); - invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); - invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); - invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); - invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); + invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); + invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); + invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); + invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); + invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); - invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); - invString.AddNameValueLine("owner_id", ownerID.ToString()); + invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); + invString.AddNameValueLine("owner_id", ownerID.ToString()); - invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); + invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); - invString.AddNameValueLine("group_id", item.GroupID.ToString()); - invString.AddSectionEnd(); + invString.AddNameValueLine("group_id", item.GroupID.ToString()); + invString.AddSectionEnd(); - invString.AddNameValueLine("asset_id", item.AssetID.ToString()); - invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); - invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); - invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); + invString.AddNameValueLine("asset_id", item.AssetID.ToString()); + invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); + invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); + invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); - invString.AddSaleStart(); - invString.AddNameValueLine("sale_type", "not"); - invString.AddNameValueLine("sale_price", "0"); - invString.AddSectionEnd(); + invString.AddSaleStart(); + invString.AddNameValueLine("sale_type", "not"); + invString.AddNameValueLine("sale_price", "0"); + invString.AddSectionEnd(); - invString.AddNameValueLine("name", item.Name + "|"); - invString.AddNameValueLine("desc", item.Description + "|"); + invString.AddNameValueLine("name", item.Name + "|"); + invString.AddNameValueLine("desc", item.Description + "|"); - invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); - invString.AddSectionEnd(); - } + invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); + invString.AddSectionEnd(); } + int count = m_items.Count; + m_items.LockItemsForRead(false); fileData = Utils.StringToBytes(invString.BuildString); @@ -689,6 +713,7 @@ namespace OpenSim.Region.Framework.Scenes if (fileData.Length > 2) { + m_log.Debug("Sending task inventory list of " + count.ToString() + " items to client " + client.AgentId.ToString()); xferManager.AddNewFile(m_inventoryFileName, fileData); } } @@ -701,10 +726,9 @@ namespace OpenSim.Region.Framework.Scenes { if (HasInventoryChanged) { - lock (Items) - { - datastore.StorePrimInventory(m_part.UUID, Items.Values); - } + Items.LockItemsForRead(true); + datastore.StorePrimInventory(m_part.UUID, Items.Values); + Items.LockItemsForRead(false); HasInventoryChanged = false; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4e5fee1..4c8c94f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1615,21 +1615,19 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); if (part != null) { + part.TaskInventory.LockItemsForRead(true); TaskInventoryDictionary taskIDict = part.TaskInventory; if (taskIDict != null) { - lock (taskIDict) + foreach (UUID taskID in taskIDict.Keys) { - foreach (UUID taskID in taskIDict.Keys) - { - UnRegisterControlEventsToScript(LocalId, taskID); - taskIDict[taskID].PermsMask &= ~( - 2048 | //PERMISSION_CONTROL_CAMERA - 4); // PERMISSION_TAKE_CONTROLS - } + UnRegisterControlEventsToScript(LocalId, taskID); + taskIDict[taskID].PermsMask &= ~( + 2048 | //PERMISSION_CONTROL_CAMERA + 4); // PERMISSION_TAKE_CONTROLS } - } + part.TaskInventory.LockItemsForRead(false); // Reset sit target. if (part.GetAvatarOnSitTarget() == UUID) part.SetAvatarOnSitTarget(UUID.Zero); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b549b5c..a94cd46 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -275,40 +275,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID InventorySelf() { UUID invItemID = new UUID(); - - lock (m_host.TaskInventory) + bool unlock = false; + if (!m_host.TaskInventory.IsReadLockedByMe()) + { + m_host.TaskInventory.LockItemsForRead(true); + unlock = true; + } + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) { - if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) - { - invItemID = inv.Key; - break; - } + invItemID = inv.Key; + break; } } - + if (unlock) + { + m_host.TaskInventory.LockItemsForRead(false); + } return invItemID; } protected UUID InventoryKey(string name, int type) { m_host.AddScriptLPS(1); - - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) + m_host.TaskInventory.LockItemsForRead(false); + + if (inv.Value.Type != type) { - if (inv.Value.Type != type) - return UUID.Zero; - - return inv.Value.AssetID; + return UUID.Zero; } + + return inv.Value.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero; } @@ -316,17 +324,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + + m_host.TaskInventory.LockItemsForRead(true); + + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) - { - return inv.Value.AssetID; - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); + + return UUID.Zero; } @@ -2537,12 +2549,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); + m_host.TaskInventory.LockItemsForRead(true); TaskInventoryItem item = m_host.TaskInventory[invItemID]; - - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[invItemID]; - } + m_host.TaskInventory.LockItemsForRead(false); if (item.PermsGranter == UUID.Zero) return 0; @@ -2617,6 +2626,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (dist > m_ScriptDistanceFactor * 10.0f) return; + //Clone is thread-safe TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); foreach (KeyValuePair inv in partInventory) @@ -2750,13 +2760,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else + { + item = m_host.TaskInventory[InventorySelf()]; } + m_host.TaskInventory.LockItemsForRead(false); if (item.PermsGranter != UUID.Zero) { @@ -2778,13 +2792,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { TaskInventoryItem item; + m_host.TaskInventory.LockItemsForRead(true); lock (m_host.TaskInventory) { + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) + { + m_host.TaskInventory.LockItemsForRead(false); return; + } else + { item = m_host.TaskInventory[InventorySelf()]; + } } + m_host.TaskInventory.LockItemsForRead(false); m_host.AddScriptLPS(1); @@ -2821,14 +2843,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else + { + item = m_host.TaskInventory[InventorySelf()]; } + m_host.TaskInventory.LockItemsForRead(false); + if (item.PermsGranter != m_host.OwnerID) return; @@ -2853,13 +2881,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else + { + item = m_host.TaskInventory[InventorySelf()]; } + m_host.TaskInventory.LockItemsForRead(false); + if (item.PermsGranter != m_host.OwnerID) return; @@ -3083,14 +3117,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; } - + else + { + item = m_host.TaskInventory[InventorySelf()]; + } + m_host.TaskInventory.LockItemsForRead(false); if (item.PermsGranter == UUID.Zero) return; @@ -3120,13 +3157,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(InventorySelf())) { - if (!m_host.TaskInventory.ContainsKey(InventorySelf())) - return; - else - item = m_host.TaskInventory[InventorySelf()]; + m_host.TaskInventory.LockItemsForRead(false); + return; } + else + { + item = m_host.TaskInventory[InventorySelf()]; + } + m_host.TaskInventory.LockItemsForRead(false); + if (item.PermsGranter == UUID.Zero) return; @@ -3199,10 +3241,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api TaskInventoryItem item; - lock (m_host.TaskInventory) + + m_host.TaskInventory.LockItemsForRead(true); + if (!m_host.TaskInventory.ContainsKey(invItemID)) + { + m_host.TaskInventory.LockItemsForRead(false); + return; + } + else { item = m_host.TaskInventory[invItemID]; } + m_host.TaskInventory.LockItemsForRead(false); if (agentID == UUID.Zero || perm == 0) // Releasing permissions { @@ -3234,11 +3284,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms { - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = perm; - } + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsGranter = agentID; + m_host.TaskInventory[invItemID].PermsMask = perm; + m_host.TaskInventory.LockItemsForWrite(false); m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { @@ -3258,11 +3307,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms { - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = perm; - } + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsGranter = agentID; + m_host.TaskInventory[invItemID].PermsMask = perm; + m_host.TaskInventory.LockItemsForWrite(false); m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { @@ -3283,11 +3331,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!m_waitingForScriptAnswer) { - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsGranter = agentID; - m_host.TaskInventory[invItemID].PermsMask = 0; - } + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsGranter = agentID; + m_host.TaskInventory[invItemID].PermsMask = 0; + m_host.TaskInventory.LockItemsForWrite(false); presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; m_waitingForScriptAnswer=true; @@ -3322,10 +3369,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) llReleaseControls(); - lock (m_host.TaskInventory) - { - m_host.TaskInventory[invItemID].PermsMask = answer; - } + + m_host.TaskInventory.LockItemsForWrite(true); + m_host.TaskInventory[invItemID].PermsMask = answer; + m_host.TaskInventory.LockItemsForWrite(false); + m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( "run_time_permissions", new Object[] { @@ -3337,16 +3385,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.ItemID == m_itemID) { - if (item.Type == 10 && item.ItemID == m_itemID) - { - return item.PermsGranter.ToString(); - } + m_host.TaskInventory.LockItemsForRead(false); + return item.PermsGranter.ToString(); } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero.ToString(); } @@ -3355,19 +3404,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.ItemID == m_itemID) { - if (item.Type == 10 && item.ItemID == m_itemID) - { - int perms = item.PermsMask; - if (m_automaticLinkPermission) - perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; - return perms; - } + int perms = item.PermsMask; + if (m_automaticLinkPermission) + perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; + m_host.TaskInventory.LockItemsForRead(false); + return perms; } } + m_host.TaskInventory.LockItemsForRead(false); return 0; } @@ -3400,11 +3450,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID invItemID = InventorySelf(); TaskInventoryItem item; - lock (m_host.TaskInventory) - { - item = m_host.TaskInventory[invItemID]; - } - + m_host.TaskInventory.LockItemsForRead(true); + item = m_host.TaskInventory[invItemID]; + m_host.TaskInventory.LockItemsForRead(false); + if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { @@ -3457,16 +3506,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID invItemID = InventorySelf(); - lock (m_host.TaskInventory) - { + m_host.TaskInventory.LockItemsForRead(true); if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 && !m_automaticLinkPermission) { ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); + m_host.TaskInventory.LockItemsForRead(false); return; } - } - + m_host.TaskInventory.LockItemsForRead(false); + if (linknum < ScriptBaseClass.LINK_THIS) return; @@ -3635,17 +3684,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); int count = 0; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Type == type || type == -1) { - if (inv.Value.Type == type || type == -1) - { - count = count + 1; - } + count = count + 1; } } - + + m_host.TaskInventory.LockItemsForRead(false); return count; } @@ -3654,16 +3702,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); ArrayList keys = new ArrayList(); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Type == type || type == -1) { - if (inv.Value.Type == type || type == -1) - { - keys.Add(inv.Value.Name); - } + keys.Add(inv.Value.Name); } } + m_host.TaskInventory.LockItemsForRead(false); if (keys.Count == 0) { @@ -3700,20 +3747,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // move the first object found with this inventory name - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == inventory) { - if (inv.Value.Name == inventory) - { - found = true; - objId = inv.Key; - assetType = inv.Value.Type; - objName = inv.Value.Name; - break; - } + found = true; + objId = inv.Key; + assetType = inv.Value.Type; + objName = inv.Value.Name; + break; } } + m_host.TaskInventory.LockItemsForRead(false); if (!found) { @@ -3763,20 +3809,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Name == name) { - if (item.Name == name) - { - if (item.ItemID == m_itemID) - throw new ScriptDeleteException(); - else - m_host.Inventory.RemoveInventoryItem(item.ItemID); - return; - } + if (item.ItemID == m_itemID) + throw new ScriptDeleteException(); + else + m_host.Inventory.RemoveInventoryItem(item.ItemID); + + m_host.TaskInventory.LockItemsForRead(false); + return; } } + m_host.TaskInventory.LockItemsForRead(false); } public void llSetText(string text, LSL_Vector color, double alpha) @@ -3865,6 +3912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + //Clone is thread safe TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); foreach (TaskInventoryItem item in itemDictionary.Values) @@ -3955,17 +4003,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID soundId = UUID.Zero; if (!UUID.TryParse(impact_sound, out soundId)) { - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) { - if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) - { - soundId = item.AssetID; - break; - } + soundId = item.AssetID; + break; } } + m_host.TaskInventory.LockItemsForRead(false); } m_host.CollisionSound = soundId; m_host.CollisionSoundVolume = (float)impact_volume; @@ -4011,6 +4058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID partItemID; foreach (SceneObjectPart part in parts) { + //Clone is thread safe TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); foreach (TaskInventoryItem item in itemsDictionary.Values) @@ -4218,17 +4266,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.ItemID == m_itemID) { - if (item.Type == 10 && item.ItemID == m_itemID) - { - result = item.Name!=null?item.Name:String.Empty; - break; - } + result = item.Name!=null?item.Name:String.Empty; + break; } } + m_host.TaskInventory.LockItemsForRead(false); return result; } @@ -4486,23 +4533,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) + if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) { - if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) - { - return inv.Value.AssetID.ToString(); - } - else - { - return UUID.Zero.ToString(); - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.AssetID.ToString(); + } + else + { + m_host.TaskInventory.LockItemsForRead(false); + return UUID.Zero.ToString(); } } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero.ToString(); } @@ -5997,14 +6045,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID GetTaskInventoryItem(string name) { - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) - return inv.Key; + m_host.TaskInventory.LockItemsForRead(false); + return inv.Key; } } + m_host.TaskInventory.LockItemsForRead(false); return UUID.Zero; } @@ -6315,22 +6365,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // copy the first script found with this inventory name - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) + // make sure the object is a script + if (10 == inv.Value.Type) { - // make sure the object is a script - if (10 == inv.Value.Type) - { - found = true; - srcId = inv.Key; - break; - } + found = true; + srcId = inv.Key; + break; } } } + m_host.TaskInventory.LockItemsForRead(false); if (!found) { @@ -8133,28 +8182,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == item) { - if (inv.Value.Name == item) + m_host.TaskInventory.LockItemsForRead(false); + switch (mask) { - switch (mask) - { - case 0: - return (int)inv.Value.BasePermissions; - case 1: - return (int)inv.Value.CurrentPermissions; - case 2: - return (int)inv.Value.GroupPermissions; - case 3: - return (int)inv.Value.EveryonePermissions; - case 4: - return (int)inv.Value.NextPermissions; - } + case 0: + return (int)inv.Value.BasePermissions; + case 1: + return (int)inv.Value.CurrentPermissions; + case 2: + return (int)inv.Value.GroupPermissions; + case 3: + return (int)inv.Value.EveryonePermissions; + case 4: + return (int)inv.Value.NextPermissions; } } } + m_host.TaskInventory.LockItemsForRead(false); return -1; } @@ -8169,16 +8218,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == item) { - if (inv.Value.Name == item) - { - return inv.Value.CreatorID.ToString(); - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.CreatorID.ToString(); } } + m_host.TaskInventory.LockItemsForRead(false); llSay(0, "No item name '" + item + "'"); @@ -8702,16 +8751,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == name) { - if (inv.Value.Name == name) - { - return inv.Value.Type; - } + m_host.TaskInventory.LockItemsForRead(false); + return inv.Value.Type; } } + m_host.TaskInventory.LockItemsForRead(false); return -1; } @@ -8742,17 +8791,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (invItemID == UUID.Zero) return new LSL_Vector(); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) { - if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) - return new LSL_Vector(); + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Vector(); + } - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) - { - ShoutError("No permissions to track the camera"); - return new LSL_Vector(); - } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + ShoutError("No permissions to track the camera"); + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Vector(); } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(m_host.OwnerID); if (presence != null) @@ -8770,17 +8822,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (invItemID == UUID.Zero) return new LSL_Rotation(); - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) { - if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) - return new LSL_Rotation(); - - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) - { - ShoutError("No permissions to track the camera"); - return new LSL_Rotation(); - } + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Rotation(); } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) + { + ShoutError("No permissions to track the camera"); + m_host.TaskInventory.LockItemsForRead(false); + return new LSL_Rotation(); + } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(m_host.OwnerID); if (presence != null) @@ -8930,14 +8984,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (objectID == UUID.Zero) return; UUID agentID; - lock (m_host.TaskInventory) - { - // we need the permission first, to know which avatar we want to set the camera for - agentID = m_host.TaskInventory[invItemID].PermsGranter; + m_host.TaskInventory.LockItemsForRead(true); + // we need the permission first, to know which avatar we want to set the camera for + agentID = m_host.TaskInventory[invItemID].PermsGranter; - if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; + if (agentID == UUID.Zero) + { + m_host.TaskInventory.LockItemsForRead(false); + return; + } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + { + m_host.TaskInventory.LockItemsForRead(false); + return; } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(agentID); @@ -8987,12 +9048,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // we need the permission first, to know which avatar we want to clear the camera for UUID agentID; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + agentID = m_host.TaskInventory[invItemID].PermsGranter; + if (agentID == UUID.Zero) { - agentID = m_host.TaskInventory[invItemID].PermsGranter; - if (agentID == UUID.Zero) return; - if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; + m_host.TaskInventory.LockItemsForRead(false); + return; } + if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) + { + m_host.TaskInventory.LockItemsForRead(false); + return; + } + m_host.TaskInventory.LockItemsForRead(false); ScenePresence presence = World.GetScenePresence(agentID); @@ -9449,15 +9517,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal UUID ScriptByName(string name) { - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + if (item.Type == 10 && item.Name == name) { - if (item.Type == 10 && item.Name == name) - return item.ItemID; + m_host.TaskInventory.LockItemsForRead(false); + return item.ItemID; } } + m_host.TaskInventory.LockItemsForRead(false); + return UUID.Zero; } @@ -9498,6 +9570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + //Clone is thread safe TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); UUID assetID = UUID.Zero; @@ -9560,6 +9633,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + //Clone is thread safe TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); UUID assetID = UUID.Zero; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7fdbac8..83322eb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -728,18 +728,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (target != null) { UUID animID=UUID.Zero; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == animation) { - if (inv.Value.Name == animation) - { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; - } + if (inv.Value.Type == (int)AssetType.Animation) + animID = inv.Value.AssetID; + continue; } } + m_host.TaskInventory.LockItemsForRead(false); if (animID == UUID.Zero) target.Animator.AddAnimation(animation, m_host.UUID); else @@ -761,18 +760,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (target != null) { UUID animID=UUID.Zero; - lock (m_host.TaskInventory) + m_host.TaskInventory.LockItemsForRead(true); + foreach (KeyValuePair inv in m_host.TaskInventory) { - foreach (KeyValuePair inv in m_host.TaskInventory) + if (inv.Value.Name == animation) { - if (inv.Value.Name == animation) - { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; - } + if (inv.Value.Type == (int)AssetType.Animation) + animID = inv.Value.AssetID; + continue; } } + m_host.TaskInventory.LockItemsForRead(false); if (animID == UUID.Zero) target.Animator.RemoveAnimation(animation); @@ -1541,6 +1539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(name, out assetID)) { + m_host.TaskInventory.LockItemsForRead(true); foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { if (item.Type == 7 && item.Name == name) @@ -1548,6 +1547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api assetID = item.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); } if (assetID == UUID.Zero) @@ -1594,6 +1594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(name, out assetID)) { + m_host.TaskInventory.LockItemsForRead(true); foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { if (item.Type == 7 && item.Name == name) @@ -1601,6 +1602,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api assetID = item.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); } if (assetID == UUID.Zero) @@ -1651,6 +1653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!UUID.TryParse(name, out assetID)) { + m_host.TaskInventory.LockItemsForRead(true); foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { if (item.Type == 7 && item.Name == name) @@ -1658,6 +1661,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api assetID = item.AssetID; } } + m_host.TaskInventory.LockItemsForRead(false); } if (assetID == UUID.Zero) diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index 063d50f..0f4a9ad 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -238,13 +238,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance if (part != null) { - lock (part.TaskInventory) + part.TaskInventory.LockItemsForRead(true); + if (part.TaskInventory.ContainsKey(m_ItemID)) { - if (part.TaskInventory.ContainsKey(m_ItemID)) - { - m_thisScriptTask = part.TaskInventory[m_ItemID]; - } + m_thisScriptTask = part.TaskInventory[m_ItemID]; } + part.TaskInventory.LockItemsForRead(false); } ApiManager am = new ApiManager(); @@ -429,14 +428,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { int permsMask; UUID permsGranter; - lock (part.TaskInventory) + part.TaskInventory.LockItemsForRead(true); + if (!part.TaskInventory.ContainsKey(m_ItemID)) { - if (!part.TaskInventory.ContainsKey(m_ItemID)) - return; - - permsGranter = part.TaskInventory[m_ItemID].PermsGranter; - permsMask = part.TaskInventory[m_ItemID].PermsMask; + part.TaskInventory.LockItemsForRead(false); + return; } + permsGranter = part.TaskInventory[m_ItemID].PermsGranter; + permsMask = part.TaskInventory[m_ItemID].PermsMask; + part.TaskInventory.LockItemsForRead(false); if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) { -- cgit v1.1 From 8383bde76880fc94a6644422d45baa28252b0231 Mon Sep 17 00:00:00 2001 From: CasperW Date: Tue, 24 Nov 2009 18:18:19 +0100 Subject: Removed some extra debug chatter --- .../CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index d9a021f..b60b32b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -389,7 +389,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer { // Check if this is ours to handle // - m_log.Info("OnFridInstantMessage"); + //m_log.Info("OnFridInstantMessage"); if (msg.dialog != (byte) InstantMessageDialog.InventoryOffered) return; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4dc709e..abb04cd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -713,7 +713,6 @@ namespace OpenSim.Region.Framework.Scenes if (fileData.Length > 2) { - m_log.Debug("Sending task inventory list of " + count.ToString() + " items to client " + client.AgentId.ToString()); xferManager.AddNewFile(m_inventoryFileName, fileData); } } -- cgit v1.1 From d5aceb6d95779b19d13eef9f2427c79233166a63 Mon Sep 17 00:00:00 2001 From: CasperW Date: Tue, 24 Nov 2009 23:33:12 +0100 Subject: Append a prefix to the god avatar names appearing in chat whilst in god mode (disabled by default, config entry admin_prefix) --- OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 5c24f03..1e63e3e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat private int m_shoutdistance = 100; private int m_whisperdistance = 10; private List m_scenes = new List(); - + private string m_adminPrefix = ""; internal object m_syncy = new object(); internal IConfig m_config; @@ -76,6 +76,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); + m_adminPrefix = config.Configs["Chat"].GetString("admin_prefix", ""); } public virtual void AddRegion(Scene scene) @@ -185,6 +186,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat protected virtual void DeliverChatToAvatars(ChatSourceType sourceType, OSChatMessage c) { string fromName = c.From; + string fromNamePrefix = ""; UUID fromID = UUID.Zero; string message = c.Message; IScene scene = c.Scene; @@ -207,7 +209,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat fromPos = avatar.AbsolutePosition; fromName = avatar.Name; fromID = c.Sender.AgentId; - + if (avatar.GodLevel > 200) + { + fromNamePrefix = m_adminPrefix; + } break; case ChatSourceType.Object: @@ -227,7 +232,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat s.ForEachScenePresence( delegate(ScenePresence presence) { - TrySendChatMessage(presence, fromPos, regionPos, fromID, fromName, c.Type, message, sourceType); + TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType); } ); } -- cgit v1.1 From 32c464ad1f43cbee9492108c1bec7f874a20cd47 Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Wed, 25 Nov 2009 08:03:09 +0100 Subject: Fixed animation sequencing: SitHere, Falling, Stand/Walk etc. Login Init Av Animation at Stand. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 15 ++++++---- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 34 +++++++++++++++------- 2 files changed, 33 insertions(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 30a95ce..2d41342 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -53,8 +53,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation { get { return m_movementAnimation; } } - protected string m_movementAnimation = "DEFAULT"; - + // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist! + protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init. private int m_animTickFall; private int m_animTickJump; @@ -123,17 +123,22 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public void TrySetMovementAnimation(string anim) { - //m_log.DebugFormat("Updating movement animation to {0}", anim); +//Console.WriteLine("Updating movement animation to {0}", anim); if (!m_scenePresence.IsChildAgent) { if (m_animations.TrySetDefaultAnimation( anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero)) { +//Console.WriteLine("TSMA {0} success.", anim); // 16384 is CHANGED_ANIMATION m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); SendAnimPack(); } + else + { +//Console.WriteLine("TSMA {0} fail.", anim); + } } } @@ -313,7 +318,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void UpdateMovementAnimations() { m_movementAnimation = GetMovementAnimation(); - +//Console.WriteLine("UMA got {0}", m_movementAnimation); if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) { // This was the previous behavior before PREJUMP @@ -445,4 +450,4 @@ namespace OpenSim.Region.Framework.Scenes.Animation SendAnimPack(animIDs, sequenceNums, objectIDs); } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4e5fee1..a65b84b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -90,6 +90,7 @@ namespace OpenSim.Region.Framework.Scenes /// issue #1716 /// // private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); + // Value revised by KF 091121 by comparison with SL. private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); public UUID currentParcelUUID = UUID.Zero; @@ -205,6 +206,9 @@ namespace OpenSim.Region.Framework.Scenes private bool m_followCamAuto; private int m_movementUpdateCount; + private int m_lastColCount = -1; //KF: Look for Collision chnages + private int m_updateCount = 0; //KF: Update Anims for a while + private static readonly int UPDATE_COUNT = 10; // how many frames to update for private const int NumMovementsBetweenRayCast = 5; @@ -662,9 +666,7 @@ namespace OpenSim.Region.Framework.Scenes AdjustKnownSeeds(); - // TODO: I think, this won't send anything, as we are still a child here... - Animator.TrySetMovementAnimation("STAND"); - + Animator.TrySetMovementAnimation("STAND"); // we created a new ScenePresence (a new child agent) in a fresh region. // Request info about all the (root) agents in this region // Note: This won't send data *to* other clients in that region (children don't send) @@ -1018,7 +1020,9 @@ namespace OpenSim.Region.Framework.Scenes { AbsolutePosition = AbsolutePosition + new Vector3(0f, 0f, (1.56f / 6f)); } - + + m_updateCount = UPDATE_COUNT; //KF: Trigger Anim updates to catch falling anim. + ControllingClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_rootRegionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, AbsolutePosition, Velocity, Vector3.Zero, m_bodyRot, new Vector4(0,0,1,AbsolutePosition.Z - 0.5f), m_uuid, null, GetUpdatePriority(ControllingClient))); } @@ -1266,9 +1270,7 @@ namespace OpenSim.Region.Framework.Scenes if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) { - // TODO: This doesn't prevent the user from walking yet. - // Setting parent ID would fix this, if we knew what value - // to use. Or we could add a m_isSitting variable. + m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); } @@ -1926,7 +1928,6 @@ namespace OpenSim.Region.Framework.Scenes public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) { -// Console.WriteLine("[RAYCASTRESULT]: Hit={0}, Point={1}, ID={2}, Dist={3}", hitYN, collisionPoint, localid, distance); if(hitYN) { // m_pos = Av offset from prim center to make look like on center @@ -2964,6 +2965,7 @@ namespace OpenSim.Region.Framework.Scenes m_updateflag = true; Velocity = force; m_isNudging = false; + m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" } } } @@ -3015,19 +3017,29 @@ namespace OpenSim.Region.Framework.Scenes // Event called by the physics plugin to tell the avatar about a collision. private void PhysicsCollisionUpdate(EventArgs e) { + if (m_updateCount > 0) //KF: Update Anims for a short period. Many Anim + { // changes are very asynchronous. + Animator.UpdateMovementAnimations(); + m_updateCount--; + } + if (e == null) return; - //if ((Math.Abs(Velocity.X) > 0.1e-9f) || (Math.Abs(Velocity.Y) > 0.1e-9f)) // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( // as of this comment the interval is set in AddToPhysicalScene - Animator.UpdateMovementAnimations(); - + CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary coldata = collisionData.m_objCollisionList; CollisionPlane = Vector4.UnitW; + if (m_lastColCount != coldata.Count) + { + m_updateCount = 10; + m_lastColCount = coldata.Count; + } + if (coldata.Count != 0) { switch (Animator.CurrentMovementAnimation) -- cgit v1.1 From c81f37cf82c3a9d2aae92d5f44734fc5098c5b75 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 25 Nov 2009 17:01:41 +0000 Subject: Change osTeleportAgent parameters from long to int. That numerical range is not even supported by the underlying type, so there is no need to ask for a type the script can not even supply. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 4 ++-- OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 83322eb..10165d3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -636,13 +636,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // Teleport functions - public void osTeleportAgent(string agent, uint regionX, uint regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) + public void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat) { // High because there is no security check. High griefer potential // CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); - ulong regionHandle = Util.UIntsToLong((regionX * (uint)Constants.RegionSize), (regionY * (uint)Constants.RegionSize)); + ulong regionHandle = Util.UIntsToLong(((uint)regionX * (uint)Constants.RegionSize), ((uint)regionY * (uint)Constants.RegionSize)); m_host.AddScriptLPS(1); UUID agentId = new UUID(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 2a403bf..470946a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces // Teleport commands void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); - void osTeleportAgent(string agent, uint regionX, uint regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); + void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); // Animation commands diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 4928e90..6b88834 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -201,9 +201,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_OSSL_Functions.osTeleportAgent(agent, regionName, position, lookat); } - public void osTeleportAgent(string agent, long regionX, long regionY, vector position, vector lookat) + public void osTeleportAgent(string agent, int regionX, int regionY, vector position, vector lookat) { - m_OSSL_Functions.osTeleportAgent(agent, (uint) regionX, (uint) regionY, position, lookat); + m_OSSL_Functions.osTeleportAgent(agent, regionX, regionY, position, lookat); } public void osTeleportAgent(string agent, vector position, vector lookat) -- cgit v1.1 From de927adf2709f50d0fe85a1c59e7677d862d0d72 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 25 Nov 2009 20:01:21 +0000 Subject: Add the dummy "Size" property to the list type --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 3f38bb6..1fc31c5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -429,6 +429,11 @@ namespace OpenSim.Region.ScriptEngine.Shared } } + public int Size + { + get { return 0; } + } + public object[] Data { get { -- cgit v1.1 From b9d22aa8213b62eb0c368b345ccfc105367c1aba Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 26 Nov 2009 01:59:08 +0100 Subject: Add nudge right and left to avatar movement (faster reaction times when stepping left or right.) --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4c8c94f..9b04422 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -169,7 +169,7 @@ namespace OpenSim.Region.Framework.Scenes protected RegionInfo m_regionInfo; protected ulong crossingFromRegion; - private readonly Vector3[] Dir_Vectors = new Vector3[9]; + private readonly Vector3[] Dir_Vectors = new Vector3[11]; private bool m_isNudging = false; // Position of agent's camera in world (region cordinates) @@ -236,6 +236,8 @@ namespace OpenSim.Region.Framework.Scenes DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, + DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG } @@ -722,12 +724,14 @@ namespace OpenSim.Region.Framework.Scenes Dir_Vectors[5] = -Vector3.UnitZ; //DOWN Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE - Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge + Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE + Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE + Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge } private Vector3[] GetWalkDirectionVectors() { - Vector3[] vector = new Vector3[9]; + Vector3[] vector = new Vector3[11]; vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK vector[2] = Vector3.UnitY; //LEFT @@ -736,13 +740,15 @@ namespace OpenSim.Region.Framework.Scenes vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE - vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge + vector[8] = Vector3.UnitY; //LEFT_NUDGE + vector[9] = -Vector3.UnitY; //RIGHT_NUDGE + vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge return vector; } private bool[] GetDirectionIsNudge() { - bool[] isNudge = new bool[9]; + bool[] isNudge = new bool[11]; isNudge[0] = false; //FORWARD isNudge[1] = false; //BACK isNudge[2] = false; //LEFT @@ -751,7 +757,9 @@ namespace OpenSim.Region.Framework.Scenes isNudge[5] = false; //DOWN isNudge[6] = true; //FORWARD_NUDGE isNudge[7] = true; //BACK_NUDGE - isNudge[8] = true; //DOWN_Nudge + isNudge[8] = true; //LEFT_NUDGE + isNudge[9] = true; //RIGHT_NUDGE + isNudge[10] = true; //DOWN_Nudge return isNudge; } -- cgit v1.1 From 63b6b9cdce6382e2285b1a9d76e68a0ac10602ef Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 26 Nov 2009 02:35:27 +0100 Subject: Added animation support for my last commit --- OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs | 4 ++-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 30a95ce..2c4a4b0 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -158,8 +158,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation // Check control flags bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS); bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); - bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; - bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; + bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); + bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG); //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9b04422..a1bb244 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -742,7 +742,7 @@ namespace OpenSim.Region.Framework.Scenes vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE vector[8] = Vector3.UnitY; //LEFT_NUDGE vector[9] = -Vector3.UnitY; //RIGHT_NUDGE - vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge + vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE return vector; } -- cgit v1.1 From ac2fcbe224d4877dccc4d73e9c58771e40a4ae1c Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 26 Nov 2009 15:17:44 +0100 Subject: Improvements to rAdmin admin_shutdown and admin_restart. Both methods can now accept a parameter of noticetype = dialog in order to display a blue persistant dropdown instead of a short notice. Added an optional and configurable delay to the restart method, defaulting at 30 seconds as before. Both methods can also accept a noticetype = none dialog in order to act silently. --- .../RemoteController/RemoteAdminPlugin.cs | 74 +++++++++++++++++++++- OpenSim/Region/Framework/Scenes/Scene.cs | 16 ++++- 2 files changed, 86 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 3bc557d..325816d 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -213,9 +213,59 @@ namespace OpenSim.ApplicationPlugins.RemoteController if (!m_app.SceneManager.TryGetScene(regionID, out rebootedScene)) throw new Exception("region not found"); + int timeout = 30000; + string message; + + if (requestData.ContainsKey("restart") + && ((string)requestData["restart"] == "delayed") + && requestData.ContainsKey("milliseconds")) + { + timeout = Int32.Parse(requestData["milliseconds"].ToString()); + + if (timeout < 15000) + { + //It must be at least 15 seconds or we'll cancel the reboot request + timeout = 15000; + } + + message + = "Region is restarting in " + ((int)(timeout / 1000)).ToString() + + " second(s). Please save what you are doing and log out."; + } + else + { + message = "Region is restarting in 30 second(s). Please save what you are doing and log out."; + } + + if (requestData.ContainsKey("noticetype") + && ((string)requestData["noticetype"] == "dialog")) + { + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); + }); + } + else + { + if (!requestData.ContainsKey("noticetype") + || ((string)requestData["noticetype"] != "none")) + { + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) + dialogModule.SendGeneralAlert(message); + }); + } + } + responseData["rebooting"] = true; response.Value = responseData; - rebootedScene.Restart(30); + rebootedScene.Restart(timeout / 1000,false); } catch (Exception e) { @@ -419,13 +469,33 @@ namespace OpenSim.ApplicationPlugins.RemoteController message = "Region is going down now."; } - m_app.SceneManager.ForEachScene( + if (requestData.ContainsKey("noticetype") + && ((string) requestData["noticetype"] == "dialog")) + { + m_app.SceneManager.ForEachScene( delegate(Scene scene) { IDialogModule dialogModule = scene.RequestModuleInterface(); if (dialogModule != null) + dialogModule.SendNotificationToUsersInRegion(UUID.Zero, "System", message); + }); + } + else + { + if (!requestData.ContainsKey("noticetype") + || ((string)requestData["noticetype"] != "none")) + { + m_app.SceneManager.ForEachScene( + delegate(Scene scene) + { + IDialogModule dialogModule = scene.RequestModuleInterface(); + if (dialogModule != null) dialogModule.SendGeneralAlert(message); }); + } + } + + // Perform shutdown System.Timers.Timer shutdownTimer = new System.Timers.Timer(timeout); // Wait before firing diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4ffa1a2..be1d4bf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -873,6 +873,15 @@ namespace OpenSim.Region.Framework.Scenes /// float indicating duration before restart. public virtual void Restart(float seconds) { + Restart(seconds, true); + } + + /// + /// Given float seconds, this will restart the region. showDialog will optionally alert the users. + /// + /// float indicating duration before restart. + public virtual void Restart(float seconds, bool showDialog) + { // notifications are done in 15 second increments // so .. if the number of seconds is less then 15 seconds, it's not really a restart request // It's a 'Cancel restart' request. @@ -893,8 +902,11 @@ namespace OpenSim.Region.Framework.Scenes m_restartTimer.Elapsed += new ElapsedEventHandler(RestartTimer_Elapsed); m_log.Info("[REGION]: Restarting Region in " + (seconds / 60) + " minutes"); m_restartTimer.Start(); - m_dialogModule.SendNotificationToUsersInRegion( - UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in 2 Minutes"); + if (showDialog) + { + m_dialogModule.SendNotificationToUsersInRegion( + UUID.Random(), String.Empty, RegionInfo.RegionName + ": Restarting in " + (seconds / 60).ToString() + " Minutes"); + } } } -- cgit v1.1 From 22c325aa5ae06b897e5eb10404c0aa3727f8237b Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 26 Nov 2009 12:08:20 +0000 Subject: Remove GetAssemblyName and friends from the SE interface. It's now handled internally --- .../Framework/Interfaces/IEntityInventory.cs | 6 -- .../Region/Framework/Interfaces/IScriptModule.cs | 1 - .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 93 ++------------------- .../Framework/Scenes/SceneObjectPartInventory.cs | 30 ------- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 95 ++++++++++++++++++++-- 5 files changed, 91 insertions(+), 134 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 2c906a2..2998f45 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -185,12 +185,6 @@ namespace OpenSim.Region.Framework.Interfaces List GetInventoryList(); /// - /// Get the names of the assemblies associated with scripts in this inventory. - /// - /// - string[] GetScriptAssemblies(); - - /// /// Get the xml representing the saved states of scripts in this inventory. /// /// diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 10835b9..72bb0f0 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -34,7 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces { string ScriptEngineName { get; } - string GetAssemblyName(UUID itemID); string GetXMLState(UUID itemID); bool CanBeDeleted(UUID itemID); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 3cec77f..9a6f2b8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -309,26 +309,15 @@ namespace OpenSim.Region.Framework.Scenes public string GetStateSnapshot() { - //m_log.Debug(" >>> GetStateSnapshot <<<"); - - List assemblies = new List(); Dictionary states = new Dictionary(); foreach (SceneObjectPart part in m_parts.Values) { - foreach (string a in part.Inventory.GetScriptAssemblies()) - { - if (a != "" && !assemblies.Contains(a)) - assemblies.Add(a); - } - foreach (KeyValuePair s in part.Inventory.GetScriptStates()) - { states[s.Key] = s.Value; - } } - if (states.Count < 1 || assemblies.Count < 1) + if (states.Count < 1) return ""; XmlDocument xmldoc = new XmlDocument(); @@ -342,94 +331,21 @@ namespace OpenSim.Region.Framework.Scenes xmldoc.AppendChild(rootElement); - XmlElement wrapper = xmldoc.CreateElement("", "Assemblies", - ""); - rootElement.AppendChild(wrapper); - - foreach (string assembly in assemblies) - { - string fn = Path.GetFileName(assembly); - if (fn == String.Empty) - continue; - - String filedata = String.Empty; - - if (File.Exists(assembly+".text")) - { - FileInfo tfi = new FileInfo(assembly+".text"); - - if (tfi == null) - continue; - - Byte[] tdata = new Byte[tfi.Length]; - - try - { - FileStream tfs = File.Open(assembly+".text", FileMode.Open, FileAccess.Read); - tfs.Read(tdata, 0, tdata.Length); - tfs.Close(); - } - catch (Exception e) - { - m_log.DebugFormat("[SOG]: Unable to open script textfile {0}, reason: {1}", assembly+".text", e.Message); - } - - filedata = new System.Text.ASCIIEncoding().GetString(tdata); - } - else - { - FileInfo fi = new FileInfo(assembly); - - if (fi == null) - continue; - - Byte[] data = new Byte[fi.Length]; - - try - { - FileStream fs = File.Open(assembly, FileMode.Open, FileAccess.Read); - fs.Read(data, 0, data.Length); - fs.Close(); - } - catch (Exception e) - { - m_log.DebugFormat("[SOG]: Unable to open script assembly {0}, reason: {1}", assembly, e.Message); - } - - filedata = System.Convert.ToBase64String(data); - } - XmlElement assemblyData = xmldoc.CreateElement("", "Assembly", ""); - XmlAttribute assemblyName = xmldoc.CreateAttribute("", "Filename", ""); - assemblyName.Value = fn; - assemblyData.Attributes.Append(assemblyName); - - assemblyData.InnerText = filedata; - - wrapper.AppendChild(assemblyData); - } - - wrapper = xmldoc.CreateElement("", "ScriptStates", + XmlElement wrapper = xmldoc.CreateElement("", "ScriptStates", ""); rootElement.AppendChild(wrapper); foreach (KeyValuePair state in states) { - XmlElement stateData = xmldoc.CreateElement("", "State", ""); - - XmlAttribute stateID = xmldoc.CreateAttribute("", "UUID", ""); - stateID.Value = state.Key.ToString(); - stateData.Attributes.Append(stateID); - XmlDocument sdoc = new XmlDocument(); sdoc.LoadXml(state.Value); - XmlNodeList rootL = sdoc.GetElementsByTagName("ScriptState"); + XmlNodeList rootL = sdoc.GetElementsByTagName("State"); XmlNode rootNode = rootL[0]; XmlNode newNode = xmldoc.ImportNode(rootNode, true); - stateData.AppendChild(newNode); - wrapper.AppendChild(stateData); + wrapper.AppendChild(newNode); } return xmldoc.InnerXml; @@ -437,6 +353,7 @@ namespace OpenSim.Region.Framework.Scenes public void SetState(string objXMLData, UUID RegionID) { +m_log.Debug("SetState called with " + objXMLData); if (objXMLData == String.Empty) return; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index abb04cd..2ef8258 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -880,36 +880,6 @@ namespace OpenSim.Region.Framework.Scenes return ret; } - public string[] GetScriptAssemblies() - { - IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); - - List ret = new List(); - if (engines == null) // No engine at all - return new string[0]; - - foreach (TaskInventoryItem item in m_items.Values) - { - if (item.InvType == (int)InventoryType.LSL) - { - foreach (IScriptModule e in engines) - { - if (e != null) - { - string n = e.GetAssemblyName(item.ItemID); - if (n != String.Empty) - { - if (!ret.Contains(n)) - ret.Add(n); - break; - } - } - } - } - } - return ret.ToArray(); - } - public Dictionary GetScriptStates() { IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 8b94f28..4dc6cb8 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1248,20 +1248,97 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - public string GetAssemblyName(UUID itemID) - { - IScriptInstance instance = GetInstance(itemID); - if (instance == null) - return ""; - return instance.GetAssemblyName(); - } - public string GetXMLState(UUID itemID) { IScriptInstance instance = GetInstance(itemID); if (instance == null) return ""; - return instance.GetXMLState(); + string xml = instance.GetXMLState(); + + XmlDocument sdoc = new XmlDocument(); + sdoc.LoadXml(xml); + XmlNodeList rootL = sdoc.GetElementsByTagName("ScriptState"); + XmlNode rootNode = rootL[0]; + + // Create + XmlDocument doc = new XmlDocument(); + XmlElement stateData = doc.CreateElement("", "State", ""); + XmlAttribute stateID = doc.CreateAttribute("", "UUID", ""); + stateID.Value = itemID.ToString(); + stateData.Attributes.Append(stateID); + XmlAttribute assetID = doc.CreateAttribute("", "Asset", ""); + assetID.Value = instance.AssetID.ToString(); + stateData.Attributes.Append(assetID); + doc.AppendChild(stateData); + + // Add ... + XmlNode xmlstate = doc.ImportNode(rootNode, true); + stateData.AppendChild(xmlstate); + + string assemName = instance.GetAssemblyName(); + + string fn = Path.GetFileName(assemName); + + string assem = String.Empty; + + if (File.Exists(assemName + ".text")) + { + FileInfo tfi = new FileInfo(assemName + ".text"); + + if (tfi != null) + { + Byte[] tdata = new Byte[tfi.Length]; + + try + { + FileStream tfs = File.Open(assemName + ".text", + FileMode.Open, FileAccess.Read); + tfs.Read(tdata, 0, tdata.Length); + tfs.Close(); + + assem = new System.Text.ASCIIEncoding().GetString(tdata); + } + catch (Exception e) + { + m_log.DebugFormat("[XEngine]: Unable to open script textfile {0}, reason: {1}", assemName+".text", e.Message); + } + } + } + else + { + FileInfo fi = new FileInfo(assemName); + + if (fi != null) + { + Byte[] data = new Byte[fi.Length]; + + try + { + FileStream fs = File.Open(assemName, FileMode.Open, FileAccess.Read); + fs.Read(data, 0, data.Length); + fs.Close(); + + assem = System.Convert.ToBase64String(data); + } + catch (Exception e) + { + m_log.DebugFormat("[XEngine]: Unable to open script assembly {0}, reason: {1}", assemName, e.Message); + } + + } + } + + XmlElement assemblyData = doc.CreateElement("", "Assembly", ""); + XmlAttribute assemblyName = doc.CreateAttribute("", "Filename", ""); + + assemblyName.Value = fn; + assemblyData.Attributes.Append(assemblyName); + + assemblyData.InnerText = assem; + + stateData.AppendChild(assemblyData); + + return doc.InnerXml; } public bool CanBeDeleted(UUID itemID) -- cgit v1.1 From a27d33cb634c78425eaa34cb5efd113e131baa51 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 26 Nov 2009 12:16:42 +0000 Subject: Remove the old remoting-type interregion code for prim/script crossing --- OpenSim/Framework/IRegionCommsListener.cs | 2 - OpenSim/Framework/RegionCommsListener.cs | 25 ------ OpenSim/Region/Framework/Scenes/Scene.cs | 99 ---------------------- .../Framework/Scenes/SceneCommunicationService.cs | 72 ---------------- 4 files changed, 198 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/IRegionCommsListener.cs b/OpenSim/Framework/IRegionCommsListener.cs index 307c6bc..cd59c63 100644 --- a/OpenSim/Framework/IRegionCommsListener.cs +++ b/OpenSim/Framework/IRegionCommsListener.cs @@ -32,7 +32,6 @@ namespace OpenSim.Framework { public delegate void ExpectUserDelegate(AgentCircuitData agent); - public delegate bool ExpectPrimDelegate(UUID primID, string objData, int XMLMethod); public delegate void UpdateNeighbours(List neighbours); @@ -55,7 +54,6 @@ namespace OpenSim.Framework public interface IRegionCommsListener { event ExpectUserDelegate OnExpectUser; - event ExpectPrimDelegate OnExpectPrim; event GenericCall2 OnExpectChildAgent; event AgentCrossing OnAvatarCrossingIntoRegion; event PrimCrossing OnPrimCrossingIntoRegion; diff --git a/OpenSim/Framework/RegionCommsListener.cs b/OpenSim/Framework/RegionCommsListener.cs index 90200d6..718a556 100644 --- a/OpenSim/Framework/RegionCommsListener.cs +++ b/OpenSim/Framework/RegionCommsListener.cs @@ -43,7 +43,6 @@ namespace OpenSim.Framework private ChildAgentUpdate handlerChildAgentUpdate = null; // OnChildAgentUpdate; private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; private GenericCall2 handlerExpectChildAgent = null; // OnExpectChildAgent; - private ExpectPrimDelegate handlerExpectPrim = null; // OnExpectPrim; private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser private UpdateNeighbours handlerNeighboursUpdate = null; // OnNeighboursUpdate; private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; @@ -53,7 +52,6 @@ namespace OpenSim.Framework #region IRegionCommsListener Members public event ExpectUserDelegate OnExpectUser; - public event ExpectPrimDelegate OnExpectPrim; public event GenericCall2 OnExpectChildAgent; public event AgentCrossing OnAvatarCrossingIntoRegion; public event PrimCrossing OnPrimCrossingIntoRegion; @@ -95,17 +93,6 @@ namespace OpenSim.Framework } - public virtual bool TriggerExpectPrim(UUID primID, string objData, int XMLMethod) - { - handlerExpectPrim = OnExpectPrim; - if (handlerExpectPrim != null) - { - handlerExpectPrim(primID, objData, XMLMethod); - return true; - } - return false; - } - public virtual bool TriggerChildAgentUpdate(ChildAgentDataUpdate cAgentData) { handlerChildAgentUpdate = OnChildAgentUpdate; @@ -128,18 +115,6 @@ namespace OpenSim.Framework return false; } - public virtual bool TriggerExpectPrimCrossing(UUID primID, Vector3 position, - bool isPhysical) - { - handlerPrimCrossingIntoRegion = OnPrimCrossingIntoRegion; - if (handlerPrimCrossingIntoRegion != null) - { - handlerPrimCrossingIntoRegion(primID, position, isPhysical); - return true; - } - return false; - } - public virtual bool TriggerAcknowledgeAgentCrossed(UUID agentID) { handlerAcknowledgeAgentCrossed = OnAcknowledgeAgentCrossed; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index be1d4bf..f932659 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2393,103 +2393,6 @@ namespace OpenSim.Region.Framework.Scenes return successYN; } - /// - /// Handle a scene object that is crossing into this region from another. - /// NOTE: Unused as of 2009-02-09. Soon to be deleted. - /// - /// - /// - /// - /// - /// - public bool IncomingInterRegionPrimGroup(UUID primID, string objXMLData, int XMLMethod) - { - if (XMLMethod == 0) - { - m_log.DebugFormat("[INTERREGION]: A new prim {0} arrived from a neighbor", primID); - SceneObjectGroup sceneObject = m_serialiser.DeserializeGroupFromXml2(objXMLData); - if (sceneObject.IsAttachment) - sceneObject.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom; - - return AddSceneObject(sceneObject); - } - else if ((XMLMethod == 100) && m_allowScriptCrossings) - { - m_log.Warn("[INTERREGION]: Prim state data arrived from a neighbor"); - - XmlDocument doc = new XmlDocument(); - doc.LoadXml(objXMLData); - - XmlNodeList rootL = doc.GetElementsByTagName("ScriptData"); - if (rootL.Count == 1) - { - XmlNode rootNode = rootL[0]; - if (rootNode != null) - { - XmlNodeList partL = rootNode.ChildNodes; - - foreach (XmlNode part in partL) - { - XmlNodeList nodeL = part.ChildNodes; - - switch (part.Name) - { - case "Assemblies": - foreach (XmlNode asm in nodeL) - { - string fn = asm.Attributes.GetNamedItem("Filename").Value; - - Byte[] filedata = Convert.FromBase64String(asm.InnerText); - string path = Path.Combine("ScriptEngines", RegionInfo.RegionID.ToString()); - path = Path.Combine(path, fn); - - if (!File.Exists(path)) - { - FileStream fs = File.Create(path); - fs.Write(filedata, 0, filedata.Length); - fs.Close(); - } - } - break; - case "ScriptStates": - foreach (XmlNode st in nodeL) - { - string id = st.Attributes.GetNamedItem("UUID").Value; - UUID uuid = new UUID(id); - XmlNode state = st.ChildNodes[0]; - - XmlDocument sdoc = new XmlDocument(); - XmlNode sxmlnode = sdoc.CreateNode( - XmlNodeType.XmlDeclaration, - "", ""); - sdoc.AppendChild(sxmlnode); - - XmlNode newnode = sdoc.ImportNode(state, true); - sdoc.AppendChild(newnode); - - string spath = Path.Combine("ScriptEngines", RegionInfo.RegionID.ToString()); - spath = Path.Combine(spath, uuid.ToString()); - FileStream sfs = File.Create(spath + ".state"); - ASCIIEncoding enc = new ASCIIEncoding(); - Byte[] buf = enc.GetBytes(sdoc.InnerXml); - sfs.Write(buf, 0, buf.Length); - sfs.Close(); - } - break; - } - } - } - } - - SceneObjectPart RootPrim = GetSceneObjectPart(primID); - RootPrim.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1); - - return true; - } - - return true; - } - public bool IncomingCreateObject(ISceneObject sog) { //m_log.Debug(" >>> IncomingCreateObject <<< " + ((SceneObjectGroup)sog).AbsolutePosition + " deleted? " + ((SceneObjectGroup)sog).IsDeleted); @@ -3362,7 +3265,6 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService.OnCloseAgentConnection += IncomingCloseAgent; //m_eventManager.OnRegionUp += OtherRegionUp; //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; - m_sceneGridService.OnExpectPrim += IncomingInterRegionPrimGroup; //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; m_sceneGridService.KiPrimitive += SendKillObject; @@ -3386,7 +3288,6 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService.KiPrimitive -= SendKillObject; m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; - m_sceneGridService.OnExpectPrim -= IncomingInterRegionPrimGroup; //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; //m_eventManager.OnRegionUp -= OtherRegionUp; m_sceneGridService.OnExpectUser -= HandleNewUserConnection; diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 76c6cab..3892769 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -85,7 +85,6 @@ namespace OpenSim.Region.Framework.Scenes /// /// A Prim will arrive shortly /// - public event ExpectPrimDelegate OnExpectPrim; public event CloseAgentConnection OnCloseAgentConnection; /// @@ -116,7 +115,6 @@ namespace OpenSim.Region.Framework.Scenes private AgentCrossing handlerAvatarCrossingIntoRegion = null; // OnAvatarCrossingIntoRegion; private ExpectUserDelegate handlerExpectUser = null; // OnExpectUser; - private ExpectPrimDelegate handlerExpectPrim = null; // OnExpectPrim; private CloseAgentConnection handlerCloseAgentConnection = null; // OnCloseAgentConnection; private PrimCrossing handlerPrimCrossingIntoRegion = null; // OnPrimCrossingIntoRegion; //private RegionUp handlerRegionUp = null; // OnRegionUp; @@ -147,30 +145,6 @@ namespace OpenSim.Region.Framework.Scenes /// Thrown if region registration fails. public void RegisterRegion(IInterregionCommsOut comms_out, RegionInfo regionInfos) { - //m_interregionCommsOut = comms_out; - - //m_regionInfo = regionInfos; - //m_commsProvider.GridService.gdebugRegionName = regionInfos.RegionName; - //regionCommsHost = m_commsProvider.GridService.RegisterRegion(m_regionInfo); - - //if (regionCommsHost != null) - //{ - // //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: registered with gridservice and got" + regionCommsHost.ToString()); - - // regionCommsHost.debugRegionName = regionInfos.RegionName; - // regionCommsHost.OnExpectPrim += IncomingPrimCrossing; - // regionCommsHost.OnExpectUser += NewUserConnection; - // regionCommsHost.OnAvatarCrossingIntoRegion += AgentCrossing; - // regionCommsHost.OnCloseAgentConnection += CloseConnection; - // regionCommsHost.OnRegionUp += newRegionUp; - // regionCommsHost.OnChildAgentUpdate += ChildAgentUpdate; - // regionCommsHost.OnLogOffUser += GridLogOffUser; - // regionCommsHost.OnGetLandData += FetchLandData; - //} - //else - //{ - // //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: registered with gridservice and got null"); - //} } /// @@ -179,31 +153,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void Close() { - - //if (regionCommsHost != null) - //{ - // regionCommsHost.OnLogOffUser -= GridLogOffUser; - // regionCommsHost.OnChildAgentUpdate -= ChildAgentUpdate; - // regionCommsHost.OnRegionUp -= newRegionUp; - // regionCommsHost.OnExpectUser -= NewUserConnection; - // regionCommsHost.OnExpectPrim -= IncomingPrimCrossing; - // regionCommsHost.OnAvatarCrossingIntoRegion -= AgentCrossing; - // regionCommsHost.OnCloseAgentConnection -= CloseConnection; - // regionCommsHost.OnGetLandData -= FetchLandData; - - // try - // { - // m_commsProvider.GridService.DeregisterRegion(m_regionInfo); - // } - // catch (Exception e) - // { - // m_log.ErrorFormat( - // "[GRID]: Deregistration of region {0} from the grid failed - {1}. Continuing", - // m_regionInfo.RegionName, e); - // } - - // regionCommsHost = null; - //} } #region CommsManager Event handlers @@ -263,27 +212,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// We have a new prim from a neighbor - /// - /// unique ID for the primative - /// XML2 encoded data of the primative - /// An Int that represents the version of the XMLMethod - /// True if the prim was accepted, false if it was not - protected bool IncomingPrimCrossing(UUID primID, String objXMLData, int XMLMethod) - { - handlerExpectPrim = OnExpectPrim; - if (handlerExpectPrim != null) - { - return handlerExpectPrim(primID, objXMLData, XMLMethod); - } - else - { - return false; - } - - } - protected void PrimCrossing(UUID primID, Vector3 position, bool isPhysical) { handlerPrimCrossingIntoRegion = OnPrimCrossingIntoRegion; -- cgit v1.1 From bd3b9f79c2ac25c39d531c3d0c390eacab8ab958 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 26 Nov 2009 17:59:28 +0000 Subject: Update CM version --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index ec94b2d..0d4215b 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.9"; + private const string VERSION_NUMBER = "0.6.9-CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour -- cgit v1.1 From ad2f0a1290b9260393a27291fdd8a1592222c368 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 26 Nov 2009 18:04:58 +0000 Subject: Remove OS version crap from about dialog --- OpenSim/Framework/Util.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 87ba5a8..c052745 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -990,19 +990,19 @@ namespace OpenSim.Framework { string os = String.Empty; - if (Environment.OSVersion.Platform != PlatformID.Unix) - { - os = Environment.OSVersion.ToString(); - } - else - { - os = ReadEtcIssue(); - } - - if (os.Length > 45) - { - os = os.Substring(0, 45); - } +// if (Environment.OSVersion.Platform != PlatformID.Unix) +// { +// os = Environment.OSVersion.ToString(); +// } +// else +// { +// os = ReadEtcIssue(); +// } +// +// if (os.Length > 45) +// { +// os = os.Substring(0, 45); +// } return os; } -- cgit v1.1 From 5dedacca3c9692948f29f5198dd444efe7c8526d Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Thu, 26 Nov 2009 20:37:08 +0100 Subject: First attempt at mult-sit on large single prims. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 91 +++++++++++++++--------- 1 file changed, 58 insertions(+), 33 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a65b84b..e677cfd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -117,6 +117,7 @@ namespace OpenSim.Region.Framework.Scenes public Vector4 CollisionPlane = Vector4.UnitW; private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation + private Vector3 m_avUnscriptedSitPos; // for non-scripted prims private Vector3 m_lastPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; @@ -1644,9 +1645,9 @@ namespace OpenSim.Region.Framework.Scenes { AddToPhysicalScene(false); } - m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); m_parentPosition = Vector3.Zero; +//Console.WriteLine("Stand Pos {0}", m_pos); m_parentID = 0; SendFullUpdateToAllClients(); @@ -1740,21 +1741,37 @@ namespace OpenSim.Region.Framework.Scenes //Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied + // " TargSet=" + SitTargetisSet); - - if (SitTargetisSet && SitTargetUnOccupied) - { - part.SetAvatarOnSitTarget(UUID); - offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); - sitOrientation = avSitOrientation; - autopilot = false; // Jump direct to scripted llSitPos() - } + // Sit analysis rewritten by KF 091125 + if (SitTargetisSet) // scipted sit + { + if (SitTargetUnOccupied) + { + part.SetAvatarOnSitTarget(UUID); // set that Av will be on it + offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one + sitOrientation = avSitOrientation; // Change rotatione to the scripted one + autopilot = false; // Jump direct to scripted llSitPos() + } + else return; + } + else // Not Scripted + { + if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) // large prim + { + Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + m_avUnscriptedSitPos = offset * partIRot; // sit where clicked + pos = part.AbsolutePosition + (offset * partIRot); + } + else // small prim + { + if (SitTargetUnOccupied) + { + m_avUnscriptedSitPos = Vector3.Zero; // Sit on unoccupied small prim center + pos = part.AbsolutePosition; + } + else return; // occupied small + } // end large/small + } // end Scripted/not - pos = part.AbsolutePosition + offset; // Region position where clicked - //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) - //{ - // offset = pos; - //autopilot = false; - //} if (m_physicsActor != null) { // If we're not using the client autopilot, we're immediately warping the avatar to the location @@ -1887,8 +1904,9 @@ namespace OpenSim.Region.Framework.Scenes { // Non-scripted sit by Kitto Flora 21Nov09 // Calculate angle of line from prim to Av - float y_diff = (m_avInitialPos.Y - part.AbsolutePosition.Y); - float x_diff = ( m_avInitialPos.X - part.AbsolutePosition.X); + Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; + float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); + float x_diff = ( m_avInitialPos.X - sitTargetPos.X); if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); @@ -1896,23 +1914,30 @@ namespace OpenSim.Region.Framework.Scenes // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. // Av sits at world euler <0,0, z>, translated by part rotation m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click - m_pos = new Vector3(0f, 0f, 0.05f) + - (new Vector3(0.0f, 0f, 0.625f) * partIRot) + - (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); // sit at center of prim m_parentPosition = part.AbsolutePosition; - //Set up raytrace to find top surface of prim - Vector3 size = part.Scale; - float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); - Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); - Vector3 down = new Vector3(0f, 0f, -1f); - m_scene.PhysicsScene.RaycastWorld( - start, // Vector3 position, - down, // Vector3 direction, - mag, // float length, - SitAltitudeCallback); // retMethod - } - } - else + if(m_avUnscriptedSitPos != Vector3.Zero) + { // sit where clicked on big prim + m_pos = m_avUnscriptedSitPos + (new Vector3(0.0f, 0f, 0.625f) * partIRot); + } + else + { // sit at center of small prim + m_pos = new Vector3(0f, 0f, 0.05f) + + (new Vector3(0.0f, 0f, 0.625f) * partIRot) + + (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); + //Set up raytrace to find top surface of prim + Vector3 size = part.Scale; + float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); + Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); + Vector3 down = new Vector3(0f, 0f, -1f); + m_scene.PhysicsScene.RaycastWorld( + start, // Vector3 position, + down, // Vector3 direction, + mag, // float length, + SitAltitudeCallback); // retMethod + } // end small/big + } // end scripted/not + } + else // no Av { return; } -- cgit v1.1 From aa695e92f7d3b56e6e3371be021d9e6acf91077c Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 27 Nov 2009 08:58:26 +0000 Subject: Reset update flag when a SOG is deleted. This fixes llDie(); --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f36ff1d..26a843e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1199,6 +1199,7 @@ namespace OpenSim.Region.Framework.Scenes if (!silent) { + part.UpdateFlag = 0; if (part == m_rootPart) avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); } -- cgit v1.1 From 9888f95068373f1bfdb289e85560a7d873d22696 Mon Sep 17 00:00:00 2001 From: CasperW Date: Fri, 27 Nov 2009 18:29:03 +0100 Subject: Convert multiple lock()s which directly hinder script performance in linksets to ReaderWriterLockSlim. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 400 ++++++++++++++------ .../Shared/Api/Implementation/LSL_Api.cs | 11 +- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 415 ++++++++++++--------- 3 files changed, 531 insertions(+), 295 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 26a843e..fb34ddc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -98,6 +98,66 @@ namespace OpenSim.Region.Framework.Scenes private bool m_hasGroupChanged = false; private long timeFirstChanged; private long timeLastChanged; + private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); + + public void lockPartsForRead(bool locked) + { + if (locked) + { + if (m_partsLock.RecursiveReadCount > 0) + { + m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_partsLock.ExitReadLock(); + } + if (m_partsLock.RecursiveWriteCount > 0) + { + m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed."); + m_partsLock.ExitWriteLock(); + } + + while (!m_partsLock.TryEnterReadLock(60000)) + { + m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire READ lock of m_parts in SceneObjectGroup. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + if (m_partsLock.IsWriteLockHeld) + { + m_partsLock = new System.Threading.ReaderWriterLockSlim(); + } + } + } + else + { + m_partsLock.ExitReadLock(); + } + } + public void lockPartsForWrite(bool locked) + { + if (locked) + { + if (m_partsLock.RecursiveReadCount > 0) + { + m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_partsLock.ExitReadLock(); + } + if (m_partsLock.RecursiveWriteCount > 0) + { + m_log.Error("[SceneObjectGroup.m_parts] Recursive write lock requested. This should not happen and means something needs to be fixed."); + m_partsLock.ExitWriteLock(); + } + + while (!m_partsLock.TryEnterWriteLock(60000)) + { + m_log.Error("[SceneObjectGroup.m_parts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + if (m_partsLock.IsWriteLockHeld) + { + m_partsLock = new System.Threading.ReaderWriterLockSlim(); + } + } + } + else + { + m_partsLock.ExitWriteLock(); + } + } public bool HasGroupChanged { @@ -243,13 +303,16 @@ namespace OpenSim.Region.Framework.Scenes set { m_regionHandle = value; - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.RegionHandle = m_regionHandle; + } } + lockPartsForRead(false); } } @@ -275,13 +338,16 @@ namespace OpenSim.Region.Framework.Scenes m_scene.CrossPrimGroupIntoNewRegion(val, this, true); } - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.GroupPosition = val; + } } + lockPartsForRead(false); //if (m_rootPart.PhysActor != null) //{ @@ -432,13 +498,16 @@ namespace OpenSim.Region.Framework.Scenes public void SetFromItemID(UUID AssetId) { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.FromItemID = AssetId; + } } + lockPartsForRead(false); } public UUID GetFromItemID() @@ -505,10 +574,11 @@ namespace OpenSim.Region.Framework.Scenes Vector3 maxScale = Vector3.Zero; Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + Vector3 partscale = part.Scale; Vector3 partoffset = part.OffsetPosition; @@ -519,8 +589,11 @@ namespace OpenSim.Region.Framework.Scenes maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; + } } + lockPartsForRead(false); + finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; @@ -536,10 +609,11 @@ namespace OpenSim.Region.Framework.Scenes EntityIntersection result = new EntityIntersection(); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + // Temporary commented to stop compiler warning //Vector3 partPosition = // new Vector3(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); @@ -567,8 +641,10 @@ namespace OpenSim.Region.Framework.Scenes result.distance = inter.distance; } } + } } + lockPartsForRead(false); return result; } @@ -581,10 +657,11 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) { float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + Vector3 worldPos = part.GetWorldPosition(); Vector3 offset = worldPos - AbsolutePosition; Quaternion worldRot; @@ -643,6 +720,8 @@ namespace OpenSim.Region.Framework.Scenes backBottomRight.Y = orig.Y + (part.Scale.Y / 2); backBottomRight.Z = orig.Z - (part.Scale.Z / 2); + + //m_log.InfoFormat("pre corner 1 is {0} {1} {2}", frontTopLeft.X, frontTopLeft.Y, frontTopLeft.Z); //m_log.InfoFormat("pre corner 2 is {0} {1} {2}", frontTopRight.X, frontTopRight.Y, frontTopRight.Z); //m_log.InfoFormat("pre corner 3 is {0} {1} {2}", frontBottomRight.X, frontBottomRight.Y, frontBottomRight.Z); @@ -814,6 +893,7 @@ namespace OpenSim.Region.Framework.Scenes minZ = backBottomLeft.Z; } } + lockPartsForRead(false); Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); @@ -842,17 +922,20 @@ namespace OpenSim.Region.Framework.Scenes Dictionary states = new Dictionary(); // Capture script state while holding the lock - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + Dictionary pstates = part.Inventory.GetScriptStates(); foreach (UUID itemid in pstates.Keys) { states.Add(itemid, pstates[itemid]); } + } } + lockPartsForRead(false); if (states.Count > 0) { @@ -1014,13 +1097,16 @@ namespace OpenSim.Region.Framework.Scenes public override void UpdateMovement() { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.UpdateMovement(); + } } + lockPartsForRead(false); } public ushort GetTimeDilation() @@ -1064,7 +1150,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddPart(SceneObjectPart part) { - lock (m_parts) + lockPartsForWrite(true); { part.SetParent(this); m_parts.Add(part.UUID, part); @@ -1074,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.LinkNum == 2 && RootPart != null) RootPart.LinkNum = 1; } + lockPartsForWrite(false); } /// @@ -1081,28 +1168,33 @@ namespace OpenSim.Region.Framework.Scenes /// private void UpdateParentIDs() { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + if (part.UUID != m_rootPart.UUID) { part.ParentID = m_rootPart.LocalId; } + } } + lockPartsForRead(false); } public void RegenerateFullIDs() { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.UUID = UUID.Random(); - + } } + lockPartsForRead(false); } // helper provided for parts. @@ -1183,29 +1275,33 @@ namespace OpenSim.Region.Framework.Scenes DetachFromBackup(); - lock (m_parts) + lockPartsForRead(true); + List values = new List(m_parts.Values); + lockPartsForRead(false); + + foreach (SceneObjectPart part in values) { - foreach (SceneObjectPart part in m_parts.Values) - { // part.Inventory.RemoveScriptInstances(); - - ScenePresence[] avatars = Scene.GetScenePresences(); - for (int i = 0; i < avatars.Length; i++) + + ScenePresence[] avatars = Scene.GetScenePresences(); + for (int i = 0; i < avatars.Length; i++) + { + if (avatars[i].ParentID == LocalId) { - if (avatars[i].ParentID == LocalId) - { - avatars[i].StandUp(); - } + avatars[i].StandUp(); + } - if (!silent) - { - part.UpdateFlag = 0; - if (part == m_rootPart) - avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); - } + if (!silent) + { + part.UpdateFlag = 0; + if (part == m_rootPart) + avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); } } + } + + } public void AddScriptLPS(int count) @@ -1230,17 +1326,20 @@ namespace OpenSim.Region.Framework.Scenes scriptEvents aggregateScriptEvents=0; - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + if (part == null) continue; if (part != RootPart) part.ObjectFlags = objectflagupdate; aggregateScriptEvents |= part.AggregateScriptEvents; + } } + lockPartsForRead(false); m_scriptListens_atTarget = ((aggregateScriptEvents & scriptEvents.at_target) != 0); m_scriptListens_notAtTarget = ((aggregateScriptEvents & scriptEvents.not_at_target) != 0); @@ -1273,42 +1372,52 @@ namespace OpenSim.Region.Framework.Scenes /// public void ApplyPhysics(bool m_physicalPrim) { - lock (m_parts) + lockPartsForRead(true); + + if (m_parts.Count > 1) { - if (m_parts.Count > 1) + List values = new List(m_parts.Values); + lockPartsForRead(false); + m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); + foreach (SceneObjectPart part in values) { - m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); - foreach (SceneObjectPart part in m_parts.Values) + + if (part.LocalId != m_rootPart.LocalId) { - if (part.LocalId != m_rootPart.LocalId) - { - part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); - } + part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, m_physicalPrim); } - // Hack to get the physics scene geometries in the right spot - ResetChildPrimPhysicsPositions(); - } - else - { - m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); } + // Hack to get the physics scene geometries in the right spot + ResetChildPrimPhysicsPositions(); + } + else + { + lockPartsForRead(false); + m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_physicalPrim); } } public void SetOwnerId(UUID userId) { - ForEachPart(delegate(SceneObjectPart part) { part.OwnerID = userId; }); + ForEachPart(delegate(SceneObjectPart part) + { + + part.OwnerID = userId; + + }); } public void ForEachPart(Action whatToDo) { - lock (m_parts) + lockPartsForRead(true); + List values = new List(m_parts.Values); + lockPartsForRead(false); + foreach (SceneObjectPart part in values) { - foreach (SceneObjectPart part in m_parts.Values) - { - whatToDo(part); - } + + whatToDo(part); + } } @@ -1407,14 +1516,17 @@ namespace OpenSim.Region.Framework.Scenes { SendPartFullUpdate(remoteClient, RootPart, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, RootPart.UUID)); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + if (part != RootPart) SendPartFullUpdate(remoteClient, part, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); + } } + lockPartsForRead(false); } /// @@ -1509,10 +1621,11 @@ namespace OpenSim.Region.Framework.Scenes List partList; - lock (m_parts) - { - partList = new List(m_parts.Values); - } + lockPartsForRead(true); + + partList = new List(m_parts.Values); + + lockPartsForRead(false); partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) { @@ -1835,10 +1948,11 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart newPart = part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed); newPart.SetParent(this); - lock (m_parts) + lockPartsForWrite(true); { m_parts.Add(newPart.UUID, newPart); } + lockPartsForWrite(false); SetPartAsNonRoot(newPart); @@ -1901,7 +2015,7 @@ namespace OpenSim.Region.Framework.Scenes //if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) // return; - lock (m_parts) + lockPartsForRead(true); { bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); @@ -1919,34 +2033,43 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in m_parts.Values) { + part.SendScheduledUpdates(); + } } + lockPartsForRead(false); } public void ScheduleFullUpdateToAvatar(ScenePresence presence) { RootPart.AddFullUpdateToAvatar(presence); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + if (part != RootPart) part.AddFullUpdateToAvatar(presence); + } } + lockPartsForRead(false); } public void ScheduleTerseUpdateToAvatar(ScenePresence presence) { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.AddTerseUpdateToAvatar(presence); + } } + lockPartsForRead(false); } /// @@ -1957,14 +2080,17 @@ namespace OpenSim.Region.Framework.Scenes checkAtTargets(); RootPart.ScheduleFullUpdate(); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + if (part != RootPart) part.ScheduleFullUpdate(); + } } + lockPartsForRead(false); } /// @@ -1972,13 +2098,16 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForTerseUpdate() { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + part.ScheduleTerseUpdate(); + } } + lockPartsForRead(false); } /// @@ -1991,14 +2120,17 @@ namespace OpenSim.Region.Framework.Scenes RootPart.SendFullUpdateToAllClients(); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { + if (part != RootPart) part.SendFullUpdateToAllClients(); + } } + lockPartsForRead(false); } /// @@ -2029,14 +2161,15 @@ namespace OpenSim.Region.Framework.Scenes { if (IsDeleted) return; - - lock (m_parts) + + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { part.SendTerseUpdateToAllClients(); } } + lockPartsForRead(false); } #endregion @@ -2050,16 +2183,18 @@ namespace OpenSim.Region.Framework.Scenes /// null if no child part with that linknum or child part public SceneObjectPart GetLinkNumPart(int linknum) { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { if (part.LinkNum == linknum) { + lockPartsForRead(false); return part; } } } + lockPartsForRead(false); return null; } @@ -2087,17 +2222,19 @@ namespace OpenSim.Region.Framework.Scenes public SceneObjectPart GetChildPart(uint localID) { //m_log.DebugFormat("Entered looking for {0}", localID); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { //m_log.DebugFormat("Found {0}", part.LocalId); if (part.LocalId == localID) { + lockPartsForRead(false); return part; } } } + lockPartsForRead(false); return null; } @@ -2127,17 +2264,19 @@ namespace OpenSim.Region.Framework.Scenes public bool HasChildPrim(uint localID) { //m_log.DebugFormat("Entered HasChildPrim looking for {0}", localID); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { //m_log.DebugFormat("Found {0}", part.LocalId); if (part.LocalId == localID) { + lockPartsForRead(false); return true; } } } + lockPartsForRead(false); return false; } @@ -2187,53 +2326,57 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.LinkNum == 0) m_rootPart.LinkNum = 1; - lock (m_parts) - { - m_parts.Add(linkPart.UUID, linkPart); + lockPartsForWrite(true); + + m_parts.Add(linkPart.UUID, linkPart); + + lockPartsForWrite(false); - // Insert in terms of link numbers, the new links - // before the current ones (with the exception of - // the root prim. Shuffle the old ones up - foreach (KeyValuePair kvp in m_parts) + // Insert in terms of link numbers, the new links + // before the current ones (with the exception of + // the root prim. Shuffle the old ones up + lockPartsForRead(true); + foreach (KeyValuePair kvp in m_parts) + { + if (kvp.Value.LinkNum != 1) { - if (kvp.Value.LinkNum != 1) - { - // Don't update root prim link number - kvp.Value.LinkNum += objectGroup.PrimCount; - } + // Don't update root prim link number + kvp.Value.LinkNum += objectGroup.PrimCount; } + } + lockPartsForRead(false); - linkPart.LinkNum = 2; + linkPart.LinkNum = 2; - linkPart.SetParent(this); - linkPart.AddFlag(PrimFlags.CreateSelected); + linkPart.SetParent(this); + linkPart.AddFlag(PrimFlags.CreateSelected); - //if (linkPart.PhysActor != null) - //{ - // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); - - //linkPart.PhysActor = null; - //} + //if (linkPart.PhysActor != null) + //{ + // m_scene.PhysicsScene.RemovePrim(linkPart.PhysActor); + + //linkPart.PhysActor = null; + //} - //TODO: rest of parts - int linkNum = 3; - foreach (SceneObjectPart part in objectGroup.Children.Values) + //TODO: rest of parts + int linkNum = 3; + foreach (SceneObjectPart part in objectGroup.Children.Values) + { + if (part.UUID != objectGroup.m_rootPart.UUID) { - if (part.UUID != objectGroup.m_rootPart.UUID) - { - LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); - } - part.ClearUndoState(); + LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); } + part.ClearUndoState(); } m_scene.UnlinkSceneObject(objectGroup.UUID, true); objectGroup.m_isDeleted = true; + + objectGroup.lockPartsForWrite(true); - lock (objectGroup.m_parts) - { - objectGroup.m_parts.Clear(); - } + objectGroup.m_parts.Clear(); + + objectGroup.lockPartsForWrite(false); // Can't do this yet since backup still makes use of the root part without any synchronization // objectGroup.m_rootPart = null; @@ -2292,11 +2435,12 @@ namespace OpenSim.Region.Framework.Scenes Quaternion worldRot = linkPart.GetWorldRotation(); // Remove the part from this object - lock (m_parts) + lockPartsForWrite(true); { m_parts.Remove(linkPart.UUID); } - + lockPartsForWrite(false); + lockPartsForRead(true); if (m_parts.Count == 1 && RootPart != null) //Single prim is left RootPart.LinkNum = 0; else @@ -2307,6 +2451,7 @@ namespace OpenSim.Region.Framework.Scenes p.LinkNum--; } } + lockPartsForRead(false); linkPart.ParentID = 0; linkPart.LinkNum = 0; @@ -2624,22 +2769,23 @@ namespace OpenSim.Region.Framework.Scenes if (selectionPart != null) { - lock (m_parts) + lockPartsForRead(true); + List parts = new List(m_parts.Values); + lockPartsForRead(false); + foreach (SceneObjectPart part in parts) { - foreach (SceneObjectPart part in m_parts.Values) + if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) { - if (part.Scale.X > 10.0 || part.Scale.Y > 10.0 || part.Scale.Z > 10.0) - { - UsePhysics = false; // Reset physics - break; - } + UsePhysics = false; // Reset physics + break; } + } - foreach (SceneObjectPart part in m_parts.Values) - { - part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); - } + foreach (SceneObjectPart part in parts) + { + part.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); } + } } @@ -2863,7 +3009,7 @@ namespace OpenSim.Region.Framework.Scenes prevScale.Z *= z; part.Resize(prevScale); - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart obPart in m_parts.Values) { @@ -2882,6 +3028,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + lockPartsForRead(false); if (part.PhysActor != null) { @@ -2962,7 +3109,7 @@ namespace OpenSim.Region.Framework.Scenes axDiff *= Quaternion.Inverse(partRotation); diff = axDiff; - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart obPart in m_parts.Values) { @@ -2972,6 +3119,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + lockPartsForRead(false); AbsolutePosition = newPos; @@ -3089,7 +3237,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); } - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart prim in m_parts.Values) { @@ -3107,6 +3255,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + lockPartsForRead(false); m_rootPart.ScheduleTerseUpdate(); } @@ -3205,7 +3354,7 @@ namespace OpenSim.Region.Framework.Scenes if (atTargets.Count > 0) { uint[] localids = new uint[0]; - lock (m_parts) + lockPartsForRead(true); { localids = new uint[m_parts.Count]; int cntr = 0; @@ -3215,6 +3364,7 @@ namespace OpenSim.Region.Framework.Scenes cntr++; } } + lockPartsForRead(false); for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3233,7 +3383,7 @@ namespace OpenSim.Region.Framework.Scenes { //trigger not_at_target uint[] localids = new uint[0]; - lock (m_parts) + lockPartsForRead(true); { localids = new uint[m_parts.Count]; int cntr = 0; @@ -3243,7 +3393,8 @@ namespace OpenSim.Region.Framework.Scenes cntr++; } } - + lockPartsForRead(false); + for (int ctr = 0; ctr < localids.Length; ctr++) { m_scene.EventManager.TriggerNotAtTargetEvent(localids[ctr]); @@ -3256,19 +3407,20 @@ namespace OpenSim.Region.Framework.Scenes public float GetMass() { float retmass = 0f; - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { retmass += part.GetMass(); } } + lockPartsForRead(false); return retmass; } public void CheckSculptAndLoad() { - lock (m_parts) + lockPartsForRead(true); { if (!IsDeleted) { @@ -3293,6 +3445,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + lockPartsForRead(false); } protected void AssetReceived(string id, Object sender, AssetBase asset) @@ -3313,7 +3466,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetGroup(UUID GroupID, IClientAPI client) { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) { @@ -3323,7 +3476,7 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChanged = true; } - + lockPartsForRead(false); ScheduleGroupForFullUpdate(); } @@ -3342,11 +3495,12 @@ namespace OpenSim.Region.Framework.Scenes public void SetAttachmentPoint(byte point) { - lock (m_parts) + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) part.SetAttachmentPoint(point); } + lockPartsForRead(false); } #region ISceneObject diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ec771e3..267928b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2950,8 +2950,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_host.OwnerID.ToString(); } + [DebuggerNonUserCode] public void llInstantMessage(string user, string message) { + UUID result; + if (!UUID.TryParse(user, out result)) + { + throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user)); + return; + } + + m_host.AddScriptLPS(1); // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. @@ -2966,7 +2975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID friendTransactionID = UUID.Random(); //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); - + GridInstantMessage msg = new GridInstantMessage(); msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; msg.toAgentID = new Guid(user); // toAgentID.Guid; diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index d997ea3..49c69ab 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -101,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine private Dictionary m_Scripts = new Dictionary(); + private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); + // Maps the asset ID to the assembly private Dictionary m_Assemblies = @@ -122,6 +124,65 @@ namespace OpenSim.Region.ScriptEngine.XEngine private ScriptCompileQueue m_CompileQueue = new ScriptCompileQueue(); IWorkItemResult m_CurrentCompile = null; + private void lockScriptsForRead(bool locked) + { + if (locked) + { + if (m_scriptsLock.RecursiveReadCount > 0) + { + m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_scriptsLock.ExitReadLock(); + } + if (m_scriptsLock.RecursiveWriteCount > 0) + { + m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); + m_scriptsLock.ExitWriteLock(); + } + + while (!m_scriptsLock.TryEnterReadLock(60000)) + { + m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + if (m_scriptsLock.IsWriteLockHeld) + { + m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); + } + } + } + else + { + m_scriptsLock.ExitReadLock(); + } + } + private void lockScriptsForWrite(bool locked) + { + if (locked) + { + if (m_scriptsLock.RecursiveReadCount > 0) + { + m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + m_scriptsLock.ExitReadLock(); + } + if (m_scriptsLock.RecursiveWriteCount > 0) + { + m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed."); + m_scriptsLock.ExitWriteLock(); + } + + while (!m_scriptsLock.TryEnterWriteLock(60000)) + { + m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + if (m_scriptsLock.IsWriteLockHeld) + { + m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim(); + } + } + } + else + { + m_scriptsLock.ExitWriteLock(); + } + } + public string ScriptEngineName { get { return "XEngine"; } @@ -261,43 +322,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine public void RemoveRegion(Scene scene) { - lock (m_Scripts) + lockScriptsForRead(true); + foreach (IScriptInstance instance in m_Scripts.Values) { - foreach (IScriptInstance instance in m_Scripts.Values) + // Force a final state save + // + if (m_Assemblies.ContainsKey(instance.AssetID)) { - // Force a final state save - // - if (m_Assemblies.ContainsKey(instance.AssetID)) - { - string assembly = m_Assemblies[instance.AssetID]; - instance.SaveState(assembly); - } + string assembly = m_Assemblies[instance.AssetID]; + instance.SaveState(assembly); + } - // Clear the event queue and abort the instance thread - // - instance.ClearQueue(); - instance.Stop(0); + // Clear the event queue and abort the instance thread + // + instance.ClearQueue(); + instance.Stop(0); - // Release events, timer, etc - // - instance.DestroyScriptInstance(); + // Release events, timer, etc + // + instance.DestroyScriptInstance(); - // Unload scripts and app domains - // Must be done explicitly because they have infinite - // lifetime - // - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); - if (m_DomainScripts[instance.AppDomain].Count == 0) - { - m_DomainScripts.Remove(instance.AppDomain); - UnloadAppDomain(instance.AppDomain); - } + // Unload scripts and app domains + // Must be done explicitly because they have infinite + // lifetime + // + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + if (m_DomainScripts[instance.AppDomain].Count == 0) + { + m_DomainScripts.Remove(instance.AppDomain); + UnloadAppDomain(instance.AppDomain); } - m_Scripts.Clear(); - m_PrimObjects.Clear(); - m_Assemblies.Clear(); - m_DomainScripts.Clear(); } + lockScriptsForRead(false); + lockScriptsForWrite(true); + m_Scripts.Clear(); + lockScriptsForWrite(false); + m_PrimObjects.Clear(); + m_Assemblies.Clear(); + m_DomainScripts.Clear(); + lock (m_ScriptEngines) { m_ScriptEngines.Remove(this); @@ -356,22 +419,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine List instances = new List(); - lock (m_Scripts) - { - foreach (IScriptInstance instance in m_Scripts.Values) + lockScriptsForRead(true); + foreach (IScriptInstance instance in m_Scripts.Values) instances.Add(instance); - } + lockScriptsForRead(false); foreach (IScriptInstance i in instances) { string assembly = String.Empty; - lock (m_Scripts) - { + if (!m_Assemblies.ContainsKey(i.AssetID)) continue; assembly = m_Assemblies[i.AssetID]; - } + i.SaveState(assembly); } @@ -673,172 +734,183 @@ namespace OpenSim.Region.ScriptEngine.XEngine return false; } - lock (m_Scripts) + + + ScriptInstance instance = null; + // Create the object record + lockScriptsForRead(true); + if ((!m_Scripts.ContainsKey(itemID)) || + (m_Scripts[itemID].AssetID != assetID)) { - ScriptInstance instance = null; - // Create the object record + lockScriptsForRead(false); - if ((!m_Scripts.ContainsKey(itemID)) || - (m_Scripts[itemID].AssetID != assetID)) - { - UUID appDomain = assetID; + UUID appDomain = assetID; - if (part.ParentGroup.IsAttachment) - appDomain = part.ParentGroup.RootPart.UUID; + if (part.ParentGroup.IsAttachment) + appDomain = part.ParentGroup.RootPart.UUID; - if (!m_AppDomains.ContainsKey(appDomain)) + if (!m_AppDomains.ContainsKey(appDomain)) + { + try { - try - { - AppDomainSetup appSetup = new AppDomainSetup(); -// appSetup.ApplicationBase = Path.Combine( -// "ScriptEngines", -// m_Scene.RegionInfo.RegionID.ToString()); - - Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; - Evidence evidence = new Evidence(baseEvidence); - - AppDomain sandbox; - if (m_AppDomainLoading) - sandbox = AppDomain.CreateDomain( - m_Scene.RegionInfo.RegionID.ToString(), - evidence, appSetup); - else - sandbox = AppDomain.CurrentDomain; - - //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); - //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); - //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); - //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); - //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); - //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; - //sandbox.SetAppDomainPolicy(sandboxPolicy); - - m_AppDomains[appDomain] = sandbox; - - m_AppDomains[appDomain].AssemblyResolve += - new ResolveEventHandler( - AssemblyResolver.OnAssemblyResolve); - m_DomainScripts[appDomain] = new List(); - } - catch (Exception e) - { - m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); - m_ScriptErrorMessage += "Exception creating app domain:\n"; - m_ScriptFailCount++; - lock (m_AddingAssemblies) - { - m_AddingAssemblies[assembly]--; - } - return false; - } + AppDomainSetup appSetup = new AppDomainSetup(); + // appSetup.ApplicationBase = Path.Combine( + // "ScriptEngines", + // m_Scene.RegionInfo.RegionID.ToString()); + + Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; + Evidence evidence = new Evidence(baseEvidence); + + AppDomain sandbox; + if (m_AppDomainLoading) + sandbox = AppDomain.CreateDomain( + m_Scene.RegionInfo.RegionID.ToString(), + evidence, appSetup); + else + sandbox = AppDomain.CurrentDomain; + + //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); + //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); + //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); + //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); + //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); + //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; + //sandbox.SetAppDomainPolicy(sandboxPolicy); + + m_AppDomains[appDomain] = sandbox; + + m_AppDomains[appDomain].AssemblyResolve += + new ResolveEventHandler( + AssemblyResolver.OnAssemblyResolve); + m_DomainScripts[appDomain] = new List(); } - m_DomainScripts[appDomain].Add(itemID); - - instance = new ScriptInstance(this, part, - itemID, assetID, assembly, - m_AppDomains[appDomain], - part.ParentGroup.RootPart.Name, - item.Name, startParam, postOnRez, - stateSource, m_MaxScriptQueue); - - m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}", - part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString()); - - if (presence != null) + catch (Exception e) { - ShowScriptSaveResponse(item.OwnerID, - assetID, "Compile successful", true); + m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); + m_ScriptErrorMessage += "Exception creating app domain:\n"; + m_ScriptFailCount++; + lock (m_AddingAssemblies) + { + m_AddingAssemblies[assembly]--; + } + return false; } + } + m_DomainScripts[appDomain].Add(itemID); - instance.AppDomain = appDomain; - instance.LineMap = linemap; + instance = new ScriptInstance(this, part, + itemID, assetID, assembly, + m_AppDomains[appDomain], + part.ParentGroup.RootPart.Name, + item.Name, startParam, postOnRez, + stateSource, m_MaxScriptQueue); - m_Scripts[itemID] = instance; - } + m_log.DebugFormat("[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}", + part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, part.ParentGroup.RootPart.AbsolutePosition.ToString()); - lock (m_PrimObjects) + if (presence != null) { - if (!m_PrimObjects.ContainsKey(localID)) - m_PrimObjects[localID] = new List(); + ShowScriptSaveResponse(item.OwnerID, + assetID, "Compile successful", true); + } - if (!m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Add(itemID); + instance.AppDomain = appDomain; + instance.LineMap = linemap; + lockScriptsForWrite(true); + m_Scripts[itemID] = instance; + lockScriptsForWrite(false); + } + else + { + lockScriptsForRead(false); + } + lock (m_PrimObjects) + { + if (!m_PrimObjects.ContainsKey(localID)) + m_PrimObjects[localID] = new List(); - } + if (!m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Add(itemID); - if (!m_Assemblies.ContainsKey(assetID)) - m_Assemblies[assetID] = assembly; + } - lock (m_AddingAssemblies) - { - m_AddingAssemblies[assembly]--; - } + if (!m_Assemblies.ContainsKey(assetID)) + m_Assemblies[assetID] = assembly; - if (instance!=null) - instance.Init(); + lock (m_AddingAssemblies) + { + m_AddingAssemblies[assembly]--; } + + if (instance!=null) + instance.Init(); + return true; } public void OnRemoveScript(uint localID, UUID itemID) { - lock (m_Scripts) + lockScriptsForRead(true); + // Do we even have it? + if (!m_Scripts.ContainsKey(itemID)) { - // Do we even have it? - if (!m_Scripts.ContainsKey(itemID)) - return; + lockScriptsForRead(false); + return; + } + - IScriptInstance instance=m_Scripts[itemID]; - m_Scripts.Remove(itemID); + IScriptInstance instance=m_Scripts[itemID]; + lockScriptsForRead(false); + lockScriptsForWrite(true); + m_Scripts.Remove(itemID); + lockScriptsForWrite(false); + instance.ClearQueue(); + instance.Stop(0); - instance.ClearQueue(); - instance.Stop(0); + SceneObjectPart part = + m_Scene.GetSceneObjectPart(localID); - SceneObjectPart part = - m_Scene.GetSceneObjectPart(localID); - - if (part != null) - part.RemoveScriptEvents(itemID); + if (part != null) + part.RemoveScriptEvents(itemID); // bool objectRemoved = false; - lock (m_PrimObjects) + lock (m_PrimObjects) + { + // Remove the script from it's prim + if (m_PrimObjects.ContainsKey(localID)) { - // Remove the script from it's prim - if (m_PrimObjects.ContainsKey(localID)) - { - // Remove inventory item record - if (m_PrimObjects[localID].Contains(itemID)) - m_PrimObjects[localID].Remove(itemID); + // Remove inventory item record + if (m_PrimObjects[localID].Contains(itemID)) + m_PrimObjects[localID].Remove(itemID); - // If there are no more scripts, remove prim - if (m_PrimObjects[localID].Count == 0) - { - m_PrimObjects.Remove(localID); + // If there are no more scripts, remove prim + if (m_PrimObjects[localID].Count == 0) + { + m_PrimObjects.Remove(localID); // objectRemoved = true; - } } } + } - instance.RemoveState(); - instance.DestroyScriptInstance(); + instance.RemoveState(); + instance.DestroyScriptInstance(); - m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); - if (m_DomainScripts[instance.AppDomain].Count == 0) - { - m_DomainScripts.Remove(instance.AppDomain); - UnloadAppDomain(instance.AppDomain); - } + m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); + if (m_DomainScripts[instance.AppDomain].Count == 0) + { + m_DomainScripts.Remove(instance.AppDomain); + UnloadAppDomain(instance.AppDomain); + } - instance = null; + instance = null; - ObjectRemoved handlerObjectRemoved = OnObjectRemoved; - if (handlerObjectRemoved != null) - handlerObjectRemoved(part.UUID); + ObjectRemoved handlerObjectRemoved = OnObjectRemoved; + if (handlerObjectRemoved != null) + handlerObjectRemoved(part.UUID); - CleanAssemblies(); - } + CleanAssemblies(); + ScriptRemoved handlerScriptRemoved = OnScriptRemoved; if (handlerScriptRemoved != null) @@ -1091,12 +1163,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine private IScriptInstance GetInstance(UUID itemID) { IScriptInstance instance; - lock (m_Scripts) + lockScriptsForRead(true); + if (!m_Scripts.ContainsKey(itemID)) { - if (!m_Scripts.ContainsKey(itemID)) - return null; - instance = m_Scripts[itemID]; + lockScriptsForRead(false); + return null; } + instance = m_Scripts[itemID]; + lockScriptsForRead(false); return instance; } @@ -1200,11 +1274,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine { List instances = new List(); - lock (m_Scripts) - { - foreach (IScriptInstance instance in m_Scripts.Values) + lockScriptsForRead(true); + foreach (IScriptInstance instance in m_Scripts.Values) instances.Add(instance); - } + lockScriptsForRead(false); foreach (IScriptInstance i in instances) { -- cgit v1.1 From 2e6dce434f1fd20664a60e464e589798287dcfe3 Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 30 Nov 2009 21:52:55 +0100 Subject: Enforce physical prim max size on single prims. Also convert a lock() to ReaderWriterLockSlim that i missed in the last commit --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 119 ++++++++++----------- 1 file changed, 58 insertions(+), 61 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fb34ddc..42481ff 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2871,11 +2871,9 @@ namespace OpenSim.Region.Framework.Scenes scale.Y = m_scene.m_maxNonphys; if (scale.Z > m_scene.m_maxNonphys) scale.Z = m_scene.m_maxNonphys; - SceneObjectPart part = GetChildPart(localID); if (part != null) { - part.Resize(scale); if (part.PhysActor != null) { if (part.PhysActor.IsPhysical) @@ -2890,7 +2888,7 @@ namespace OpenSim.Region.Framework.Scenes part.PhysActor.Size = scale; m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); } - //if (part.UUID != m_rootPart.UUID) + part.Resize(scale); HasGroupChanged = true; ScheduleGroupForFullUpdate(); @@ -2931,77 +2929,76 @@ namespace OpenSim.Region.Framework.Scenes float y = (scale.Y / part.Scale.Y); float z = (scale.Z / part.Scale.Z); - lock (m_parts) + lockPartsForRead(true); + if (x > 1.0f || y > 1.0f || z > 1.0f) { - if (x > 1.0f || y > 1.0f || z > 1.0f) + foreach (SceneObjectPart obPart in m_parts.Values) { - foreach (SceneObjectPart obPart in m_parts.Values) + if (obPart.UUID != m_rootPart.UUID) { - if (obPart.UUID != m_rootPart.UUID) - { - Vector3 oldSize = new Vector3(obPart.Scale); + Vector3 oldSize = new Vector3(obPart.Scale); - float f = 1.0f; - float a = 1.0f; + float f = 1.0f; + float a = 1.0f; - if (part.PhysActor != null && part.PhysActor.IsPhysical) + if (part.PhysActor != null && part.PhysActor.IsPhysical) + { + if (oldSize.X*x > m_scene.m_maxPhys) { - if (oldSize.X*x > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.X; - a = f / x; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Y*y > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.Y; - a = f / y; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Z*z > m_scene.m_maxPhys) - { - f = m_scene.m_maxPhys / oldSize.Z; - a = f / z; - x *= a; - y *= a; - z *= a; - } + f = m_scene.m_maxPhys / oldSize.X; + a = f / x; + x *= a; + y *= a; + z *= a; } - else + if (oldSize.Y*y > m_scene.m_maxPhys) + { + f = m_scene.m_maxPhys / oldSize.Y; + a = f / y; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Z*z > m_scene.m_maxPhys) + { + f = m_scene.m_maxPhys / oldSize.Z; + a = f / z; + x *= a; + y *= a; + z *= a; + } + } + else + { + if (oldSize.X*x > m_scene.m_maxNonphys) { - if (oldSize.X*x > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.X; - a = f / x; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Y*y > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.Y; - a = f / y; - x *= a; - y *= a; - z *= a; - } - if (oldSize.Z*z > m_scene.m_maxNonphys) - { - f = m_scene.m_maxNonphys / oldSize.Z; - a = f / z; - x *= a; - y *= a; - z *= a; - } + f = m_scene.m_maxNonphys / oldSize.X; + a = f / x; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Y*y > m_scene.m_maxNonphys) + { + f = m_scene.m_maxNonphys / oldSize.Y; + a = f / y; + x *= a; + y *= a; + z *= a; + } + if (oldSize.Z*z > m_scene.m_maxNonphys) + { + f = m_scene.m_maxNonphys / oldSize.Z; + a = f / z; + x *= a; + y *= a; + z *= a; } } } } } + lockPartsForRead(false); Vector3 prevScale = part.Scale; prevScale.X *= x; -- cgit v1.1 From cc8246206d5044aff0b306a4bcaf4b321fb826c9 Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Sat, 5 Dec 2009 09:03:02 +0100 Subject: Secnond revision of Sit and Stand for unscripted prims; Comment out spammy debug messages in Interregion.... --- OpenSim/Framework/Servers/VersionInfo.cs | 8 +- .../Interregion/RESTInterregionComms.cs | 9 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 + OpenSim/Region/Framework/Scenes/ScenePresence.cs | 253 ++++++++++++--------- 4 files changed, 156 insertions(+), 122 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 0d4215b..f5be1e6 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,9 +29,8 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.9-CM"; - private const Flavour VERSION_FLAVOUR = Flavour.Dev; - + private const string VERSION_NUMBER = "112609s"; + private const Flavour VERSION_FLAVOUR = Flavour.BetaM7; public enum Flavour { Unknown, @@ -39,7 +38,8 @@ namespace OpenSim RC1, RC2, Release, - Post_Fixes + Post_Fixes, + BetaM7 } public static string Version diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs index 710e3ca..39e2413 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs @@ -331,12 +331,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion { //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); - m_log.Debug("---------------------------"); +/* m_log.Debug("---------------------------"); m_log.Debug(" >> uri=" + request["uri"]); m_log.Debug(" >> content-type=" + request["content-type"]); m_log.Debug(" >> http-method=" + request["http-method"]); - m_log.Debug("---------------------------\n"); - + m_log.Debug("---------------------------\n"); */ Hashtable responsedata = new Hashtable(); responsedata["content_type"] = "text/html"; responsedata["keepalive"] = false; @@ -576,11 +575,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion { m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); - m_log.Debug("---------------------------"); + /* m_log.Debug("---------------------------"); m_log.Debug(" >> uri=" + request["uri"]); m_log.Debug(" >> content-type=" + request["content-type"]); m_log.Debug(" >> http-method=" + request["http-method"]); - m_log.Debug("---------------------------\n"); + m_log.Debug("---------------------------\n"); */ Hashtable responsedata = new Hashtable(); responsedata["content_type"] = "text/html"; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 19e3023..9f2c3db 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -212,6 +212,7 @@ namespace OpenSim.Region.Framework.Scenes private Quaternion m_sitTargetOrientation = Quaternion.Identity; private Vector3 m_sitTargetPosition; private string m_sitAnimation = "SIT"; + private bool m_occupied; // KF if any av is sitting on this prim private string m_text = String.Empty; private string m_touchName = String.Empty; private readonly UndoStack m_undo = new UndoStack(5); @@ -993,6 +994,13 @@ namespace OpenSim.Region.Framework.Scenes get { return _flags; } set { _flags = value; } } + + [XmlIgnore] + public bool IsOccupied // KF If an av is sittingon this prim + { + get { return m_occupied; } + set { m_occupied = value; } + } [XmlIgnore] public UUID SitTargetAvatar diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cebd108..817b9df 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -197,6 +197,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_autopilotMoving; private Vector3 m_autoPilotTarget; private bool m_sitAtAutoTarget; + private Vector3 m_initialSitTarget; //KF: First estimate of where to sit private string m_nextSitAnimation = String.Empty; @@ -1524,7 +1525,6 @@ namespace OpenSim.Region.Framework.Scenes m_sitAtAutoTarget = false; PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; //proxy.PCode = (byte)PCode.ParticleSystem; - proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); proxyObjectGroup.AttachToScene(m_scene); @@ -1566,7 +1566,7 @@ namespace OpenSim.Region.Framework.Scenes } m_moveToPositionInProgress = true; m_moveToPositionTarget = new Vector3(locx, locy, locz); - } + } catch (Exception ex) { //Why did I get this error? @@ -1646,16 +1646,22 @@ namespace OpenSim.Region.Framework.Scenes m_parentPosition = part.GetWorldPosition(); ControllingClient.SendClearFollowCamProperties(part.ParentUUID); } + // part.GetWorldRotation() is the rotation of the object being sat on + // Rotation is the sittiing Av's rotation + + Quaternion wr = Quaternion.Inverse(Quaternion.Inverse(Rotation) * Quaternion.Inverse(part.GetWorldRotation())); // world or. of the av + Vector3 so = new Vector3(1.0f, 0f, 0f) * wr; // 1M infront of av + Vector3 wso = so + part.GetWorldPosition() + ( m_pos * part.GetWorldRotation()); // + av sit offset! if (m_physicsActor == null) { AddToPhysicalScene(false); } - m_pos += m_parentPosition + new Vector3(0.0f, 0.0f, 2.0f*m_sitAvatarHeight); + AbsolutePosition = wso; //KF: Fix stand up. m_parentPosition = Vector3.Zero; -//Console.WriteLine("Stand Pos {0}", m_pos); - - m_parentID = 0; + + m_parentID = 0; + part.IsOccupied = false; SendFullUpdateToAllClients(); m_requestedSitTargetID = 0; if ((m_physicsActor != null) && (m_avHeight > 0)) @@ -1694,13 +1700,9 @@ namespace OpenSim.Region.Framework.Scenes Vector3 avSitOffSet = part.SitTargetPosition; Quaternion avSitOrientation = part.SitTargetOrientation; UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); - - bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); - bool SitTargetisSet = - (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 1f && - avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f)); - // this test is probably failing - if (SitTargetisSet && SitTargetUnOccupied) + bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); + bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. + if (SitTargetisSet && !SitTargetOccupied) { //switch the target to this prim return part; @@ -1714,7 +1716,7 @@ namespace OpenSim.Region.Framework.Scenes private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset) { bool autopilot = true; - Vector3 pos = new Vector3(); + Vector3 autopilotTarget = new Vector3(); Quaternion sitOrientation = Quaternion.Identity; Vector3 cameraEyeOffset = Vector3.Zero; Vector3 cameraAtOffset = Vector3.Zero; @@ -1722,98 +1724,104 @@ namespace OpenSim.Region.Framework.Scenes //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part != null) - { - // TODO: determine position to sit at based on scene geometry; don't trust offset from client - // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it + if (part == null) return; + + // TODO: determine position to sit at based on scene geometry; don't trust offset from client + // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - // part is the prim to sit on - // offset is the vector distance from that prim center to the click-spot - // UUID is the UUID of the Avatar doing the clicking - - m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation + // part is the prim to sit on + // offset is the world-ref vector distance from that prim center to the click-spot + // UUID is the UUID of the Avatar doing the clicking - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); - - bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); -// bool SitTargetisSet = -// (!(avSitOffSet.X == 0f && avSitOffSet.Y == 0f && avSitOffSet.Z == 0f && avSitOrientation.W == 0f && -// avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f)); - - bool SitTargetisSet = ((Vector3.Zero != avSitOffSet) || (Quaternion.Identity != avSitOrientation)); - -//Console.WriteLine("SendSitResponse offset=" + offset + " UnOccup=" + SitTargetUnOccupied + -// " TargSet=" + SitTargetisSet); - // Sit analysis rewritten by KF 091125 - if (SitTargetisSet) // scipted sit - { - if (SitTargetUnOccupied) - { - part.SetAvatarOnSitTarget(UUID); // set that Av will be on it - offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one - sitOrientation = avSitOrientation; // Change rotatione to the scripted one - autopilot = false; // Jump direct to scripted llSitPos() - } - else return; + m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation + + // Is a sit target available? + Vector3 avSitOffSet = part.SitTargetPosition; + Quaternion avSitOrientation = part.SitTargetOrientation; + + bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. + Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + +//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); + // Sit analysis rewritten by KF 091125 + if (SitTargetisSet) // scipted sit + { + if (!part.IsOccupied) + { +//Console.WriteLine("Scripted, unoccupied"); + part.SetAvatarOnSitTarget(UUID); // set that Av will be on it + offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one + sitOrientation = avSitOrientation; // Change rotatione to the scripted one + autopilot = false; // Jump direct to scripted llSitPos() } - else // Not Scripted - { - if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) // large prim - { - Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); - m_avUnscriptedSitPos = offset * partIRot; // sit where clicked - pos = part.AbsolutePosition + (offset * partIRot); - } - else // small prim - { - if (SitTargetUnOccupied) - { - m_avUnscriptedSitPos = Vector3.Zero; // Sit on unoccupied small prim center - pos = part.AbsolutePosition; - } - else return; // occupied small - } // end large/small - } // end Scripted/not - - if (m_physicsActor != null) - { - // If we're not using the client autopilot, we're immediately warping the avatar to the location - // We can remove the physicsActor until they stand up. - m_sitAvatarHeight = m_physicsActor.Size.Z; - - if (autopilot) - { // its not a scripted sit - if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) - { - autopilot = false; // close enough + else + { +//Console.WriteLine("Scripted, occupied"); + return; + } + } + else // Not Scripted + { + if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) + { + // large prim & offset, ignore if other Avs sitting +// offset.Z -= 0.05f; + m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked + autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point + +//Console.WriteLine(" offset ={0}", offset); +//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); +//Console.WriteLine(" autopilotTarget={0}", autopilotTarget); + + } + else // small offset + { +//Console.WriteLine("Small offset"); + if (!part.IsOccupied) + { + m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center + autopilotTarget = part.AbsolutePosition; + } + else return; // occupied small + } // end large/small + } // end Scripted/not + cameraAtOffset = part.GetCameraAtOffset(); + cameraEyeOffset = part.GetCameraEyeOffset(); + forceMouselook = part.GetForceMouselook(); - RemoveFromPhysicalScene(); - AbsolutePosition = pos + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to Prim - } // else the autopilot will get us close - } - else - { // its a scripted sit + if (m_physicsActor != null) + { + // If we're not using the client autopilot, we're immediately warping the avatar to the location + // We can remove the physicsActor until they stand up. + m_sitAvatarHeight = m_physicsActor.Size.Z; + if (autopilot) + { // its not a scripted sit +// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) + if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) + { + autopilot = false; // close enough RemoveFromPhysicalScene(); - } + AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target + } // else the autopilot will get us close + } + else + { // its a scripted sit + RemoveFromPhysicalScene(); } - - cameraAtOffset = part.GetCameraAtOffset(); - cameraEyeOffset = part.GetCameraEyeOffset(); - forceMouselook = part.GetForceMouselook(); } + else return; // physactor is null! - ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); - m_requestedSitTargetUUID = targetID; + Vector3 offsetr = offset * partIRot; + ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target // This calls HandleAgentSit twice, once from here, and the client calls // HandleAgentSit itself after it gets to the location // It doesn't get to the location until we've moved them there though // which happens in HandleAgentSit :P m_autopilotMoving = autopilot; - m_autoPilotTarget = pos; + m_autoPilotTarget = autopilotTarget; m_sitAtAutoTarget = autopilot; + m_initialSitTarget = autopilotTarget; if (!autopilot) HandleAgentSit(remoteClient, UUID); } @@ -1898,6 +1906,7 @@ namespace OpenSim.Region.Framework.Scenes { if (part.GetAvatarOnSitTarget() == UUID) { +//Console.WriteLine("Scripted Sit"); // Scripted sit Vector3 sitTargetPos = part.SitTargetPosition; Quaternion sitTargetOrient = part.SitTargetOrientation; @@ -1905,42 +1914,44 @@ namespace OpenSim.Region.Framework.Scenes m_pos += SIT_TARGET_ADJUSTMENT; m_bodyRot = sitTargetOrient; m_parentPosition = part.AbsolutePosition; + part.IsOccupied = true; } else { +//Console.WriteLine("NON Scripted Sit"); + // if m_avUnscriptedSitPos is zero then Av sits above center + // Else Av sits at m_avUnscriptedSitPos + // Non-scripted sit by Kitto Flora 21Nov09 // Calculate angle of line from prim to Av + Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); float x_diff = ( m_avInitialPos.X - sitTargetPos.X); if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); - Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. // Av sits at world euler <0,0, z>, translated by part rotation m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click + m_parentPosition = part.AbsolutePosition; - if(m_avUnscriptedSitPos != Vector3.Zero) - { // sit where clicked on big prim - m_pos = m_avUnscriptedSitPos + (new Vector3(0.0f, 0f, 0.625f) * partIRot); - } - else - { // sit at center of small prim - m_pos = new Vector3(0f, 0f, 0.05f) + - (new Vector3(0.0f, 0f, 0.625f) * partIRot) + - (new Vector3(0.25f, 0f, 0.0f) * m_bodyRot); - //Set up raytrace to find top surface of prim - Vector3 size = part.Scale; - float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); - Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); - Vector3 down = new Vector3(0f, 0f, -1f); - m_scene.PhysicsScene.RaycastWorld( + part.IsOccupied = true; + m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation + (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center + (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + + m_avUnscriptedSitPos; // adds click offset, if any + //Set up raytrace to find top surface of prim + Vector3 size = part.Scale; + float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); + Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); + Vector3 down = new Vector3(0f, 0f, -1f); +//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); + m_scene.PhysicsScene.RaycastWorld( start, // Vector3 position, down, // Vector3 direction, mag, // float length, SitAltitudeCallback); // retMethod - } // end small/big } // end scripted/not } else // no Av @@ -1957,19 +1968,24 @@ namespace OpenSim.Region.Framework.Scenes SendFullUpdateToAllClients(); } - public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) + public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) // KF: Nov 2009 { + // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer + // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. if(hitYN) { // m_pos = Av offset from prim center to make look like on center // m_parentPosition = Actual center pos of prim // collisionPoint = spot on prim where we want to sit + // collisionPoint.Z = global sit surface height SceneObjectPart part = m_scene.GetSceneObjectPart(localid); - Vector3 offset = (collisionPoint - m_parentPosition) * Quaternion.Inverse(part.RotationOffset); + Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + float offZ = collisionPoint.Z - m_initialSitTarget.Z; + Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction +//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); m_pos += offset; -// Console.WriteLine("m_pos={0}, offset={1} newsit={2}", m_pos, offset, newsit); } - } + } // End SitAltitudeCallback KF. /// /// Event handler for the 'Always run' setting on the client @@ -3716,5 +3732,16 @@ namespace OpenSim.Region.Framework.Scenes m_reprioritization_called = false; } } + + private Vector3 Quat2Euler(Quaternion rot){ + float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , + (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); + float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); + float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , + (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); + return(new Vector3(x,y,z)); + } + + } } -- cgit v1.1 From 129de260329791529904c02c3515d40879d7d214 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 5 Dec 2009 23:25:30 +0000 Subject: Cause better packing of ObjectProperties --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 106 +++++++++++++++------ 1 file changed, 79 insertions(+), 27 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index e812945..71f9b90 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -352,6 +352,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP private IHyperAssetService m_hyperAssets; private const bool m_checkPackets = true; + private Timer m_propertiesPacketTimer; + private List m_propertiesBlocks = new List(); + #endregion Class Members #region Properties @@ -433,6 +436,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_udpClient.OnQueueEmpty += HandleQueueEmpty; m_udpClient.OnPacketStats += PopulateStats; + m_propertiesPacketTimer = new Timer(100); + m_propertiesPacketTimer.Elapsed += ProcessObjectPropertiesPacket; + RegisterLocalPacketHandlers(); } @@ -3562,42 +3568,88 @@ namespace OpenSim.Region.ClientStack.LindenUDP string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice) { - ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); // TODO: don't create new blocks if recycling an old packet - proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; - proper.ObjectData[0] = new ObjectPropertiesPacket.ObjectDataBlock(); - proper.ObjectData[0].ItemID = ItemID; - proper.ObjectData[0].CreationDate = CreationDate; - proper.ObjectData[0].CreatorID = CreatorUUID; - proper.ObjectData[0].FolderID = FolderUUID; - proper.ObjectData[0].FromTaskID = FromTaskUUID; - proper.ObjectData[0].GroupID = GroupUUID; - proper.ObjectData[0].InventorySerial = InventorySerial; - - proper.ObjectData[0].LastOwnerID = LastOwnerUUID; + ObjectPropertiesPacket.ObjectDataBlock block = + new ObjectPropertiesPacket.ObjectDataBlock(); + + block.ItemID = ItemID; + block.CreationDate = CreationDate; + block.CreatorID = CreatorUUID; + block.FolderID = FolderUUID; + block.FromTaskID = FromTaskUUID; + block.GroupID = GroupUUID; + block.InventorySerial = InventorySerial; + + block.LastOwnerID = LastOwnerUUID; // proper.ObjectData[0].LastOwnerID = UUID.Zero; - proper.ObjectData[0].ObjectID = ObjectUUID; + block.ObjectID = ObjectUUID; if (OwnerUUID == GroupUUID) - proper.ObjectData[0].OwnerID = UUID.Zero; + block.OwnerID = UUID.Zero; else - proper.ObjectData[0].OwnerID = OwnerUUID; - proper.ObjectData[0].TouchName = Util.StringToBytes256(TouchTitle); - proper.ObjectData[0].TextureID = TextureID; - proper.ObjectData[0].SitName = Util.StringToBytes256(SitTitle); - proper.ObjectData[0].Name = Util.StringToBytes256(ItemName); - proper.ObjectData[0].Description = Util.StringToBytes256(ItemDescription); - proper.ObjectData[0].OwnerMask = OwnerMask; - proper.ObjectData[0].NextOwnerMask = NextOwnerMask; - proper.ObjectData[0].GroupMask = GroupMask; - proper.ObjectData[0].EveryoneMask = EveryoneMask; - proper.ObjectData[0].BaseMask = BaseMask; + block.OwnerID = OwnerUUID; + block.TouchName = Util.StringToBytes256(TouchTitle); + block.TextureID = TextureID; + block.SitName = Util.StringToBytes256(SitTitle); + block.Name = Util.StringToBytes256(ItemName); + block.Description = Util.StringToBytes256(ItemDescription); + block.OwnerMask = OwnerMask; + block.NextOwnerMask = NextOwnerMask; + block.GroupMask = GroupMask; + block.EveryoneMask = EveryoneMask; + block.BaseMask = BaseMask; // proper.ObjectData[0].AggregatePerms = 53; // proper.ObjectData[0].AggregatePermTextures = 0; // proper.ObjectData[0].AggregatePermTexturesOwner = 0; - proper.ObjectData[0].SaleType = saleType; - proper.ObjectData[0].SalePrice = salePrice; + block.SaleType = saleType; + block.SalePrice = salePrice; + + lock (m_propertiesPacketTimer) + { + m_propertiesBlocks.Add(block); + + int length = 0; + foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + { + length += b.Length; + } + if (length > 1100) // FIXME: use real MTU + { + ProcessObjectPropertiesPacket(null, null); + m_propertiesPacketTimer.Stop(); + return; + } + + m_propertiesPacketTimer.Stop(); + m_propertiesPacketTimer.Start(); + } + + //proper.Header.Zerocoded = true; + //OutPacket(proper, ThrottleOutPacketType.Task); + } + + private void ProcessObjectPropertiesPacket(Object sender, ElapsedEventArgs e) + { + ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); + + lock (m_propertiesPacketTimer) + { + m_propertiesPacketTimer.Stop(); + + proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; + + int index = 0; + + foreach (ObjectPropertiesPacket.ObjectDataBlock b in m_propertiesBlocks) + { + proper.ObjectData[index++] = b; + } + + m_propertiesBlocks.Clear(); + } + proper.Header.Zerocoded = true; OutPacket(proper, ThrottleOutPacketType.Task); } -- cgit v1.1 From ceccfe02d0e25c234560b6ef25306b8db4cd9875 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 00:02:24 +0000 Subject: Eliminate multiple updates on link/unlink --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 ++ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 ++++---- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 ++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 2fdb48d..d87e814 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1593,6 +1593,8 @@ namespace OpenSim.Region.Framework.Scenes // occur on link to invoke this elsewhere (such as object selection) parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); parentGroup.TriggerScriptChangedEvent(Changed.LINK); + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); if (client != null) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ecda80c..fa2e3ce 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2389,8 +2389,8 @@ namespace OpenSim.Region.Framework.Scenes // unmoved prims! ResetChildPrimPhysicsPositions(); - HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + //HasGroupChanged = true; + //ScheduleGroupForFullUpdate(); } /// @@ -2483,8 +2483,8 @@ namespace OpenSim.Region.Framework.Scenes linkPart.Rezzed = RootPart.Rezzed; - HasGroupChanged = true; - ScheduleGroupForFullUpdate(); + //HasGroupChanged = true; + //ScheduleGroupForFullUpdate(); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 267928b..e694f15 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3588,6 +3588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { parentPrim.DelinkFromGroup(part.LocalId, true); } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); if (parts.Count > 0) @@ -3599,6 +3601,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.UpdateFlag = 0; newRoot.ParentGroup.LinkToGroup(part.ParentGroup); } + newRoot.ParentGroup.HasGroupChanged = true; + newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } } else @@ -3607,6 +3611,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return; parentPrim.DelinkFromGroup(childPrim.LocalId, true); + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } } @@ -3626,6 +3632,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parentPrim.DelinkFromGroup(part.LocalId, true); parentPrim.TriggerScriptChangedEvent(Changed.LINK); } + parentPrim.HasGroupChanged = true; + parentPrim.ScheduleGroupForFullUpdate(); } public LSL_String llGetLinkKey(int linknum) -- cgit v1.1 From fbefa8273be70d90404b37230c168fd031288e31 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 00:25:04 +0000 Subject: Lock updates out while linking and unlinking --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 255 ++++++++++++++------------ 1 file changed, 134 insertions(+), 121 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d87e814..5efe188 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -26,6 +26,7 @@ */ using System; +using System.Threading; using System.Collections.Generic; using System.Reflection; using OpenMetaverse; @@ -96,6 +97,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); private readonly Object m_dictionary_lock = new Object(); + private Object m_updateLock = new Object(); + #endregion protected internal SceneGraph(Scene parent, RegionInfo regInfo) @@ -369,6 +372,9 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void UpdateObjectGroups() { + if (!Monitor.TryEnter(m_updateLock)) + return; + List updates; // Some updates add more updates to the updateList. @@ -395,6 +401,7 @@ namespace OpenSim.Region.Framework.Scenes "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); } } + Monitor.Exit(m_updateLock); } protected internal void AddPhysicalPrim(int number) @@ -1555,56 +1562,59 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) { - SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); - - List childGroups = new List(); - if (parentGroup != null) + lock (m_updateLock) { - // We do this in reverse to get the link order of the prims correct - for (int i = childPrimIds.Count - 1; i >= 0; i--) + SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); + + List childGroups = new List(); + if (parentGroup != null) { - SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); - if (child != null) + // We do this in reverse to get the link order of the prims correct + for (int i = childPrimIds.Count - 1; i >= 0; i--) { - // Make sure no child prim is set for sale - // So that, on delink, no prims are unwittingly - // left for sale and sold off - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; - childGroups.Add(child); + SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); + if (child != null) + { + // Make sure no child prim is set for sale + // So that, on delink, no prims are unwittingly + // left for sale and sold off + child.RootPart.ObjectSaleType = 0; + child.RootPart.SalePrice = 10; + childGroups.Add(child); + } } } - } - else - { - return; // parent is null so not in this region - } + else + { + return; // parent is null so not in this region + } - foreach (SceneObjectGroup child in childGroups) - { - parentGroup.LinkToGroup(child); + foreach (SceneObjectGroup child in childGroups) + { + parentGroup.LinkToGroup(child); - // this is here so physics gets updated! - // Don't remove! Bad juju! Stay away! or fix physics! - child.AbsolutePosition = child.AbsolutePosition; - } + // this is here so physics gets updated! + // Don't remove! Bad juju! Stay away! or fix physics! + child.AbsolutePosition = child.AbsolutePosition; + } - // We need to explicitly resend the newly link prim's object properties since no other actions - // occur on link to invoke this elsewhere (such as object selection) - parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); - parentGroup.TriggerScriptChangedEvent(Changed.LINK); - parentGroup.HasGroupChanged = true; - parentGroup.ScheduleGroupForFullUpdate(); - - if (client != null) - { - parentGroup.GetProperties(client); - } - else - { - foreach (ScenePresence p in GetScenePresences()) + // We need to explicitly resend the newly link prim's object properties since no other actions + // occur on link to invoke this elsewhere (such as object selection) + parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); + parentGroup.TriggerScriptChangedEvent(Changed.LINK); + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); + + if (client != null) { - parentGroup.GetProperties(p.ControllingClient); + parentGroup.GetProperties(client); + } + else + { + foreach (ScenePresence p in GetScenePresences()) + { + parentGroup.GetProperties(p.ControllingClient); + } } } } @@ -1620,109 +1630,112 @@ namespace OpenSim.Region.Framework.Scenes protected internal void DelinkObjects(List primIds, bool sendEvents) { - List childParts = new List(); - List rootParts = new List(); - List affectedGroups = new List(); - // Look them all up in one go, since that is comparatively expensive - // - foreach (uint primID in primIds) + lock (m_updateLock) { - SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); - if (part != null) + List childParts = new List(); + List rootParts = new List(); + List affectedGroups = new List(); + // Look them all up in one go, since that is comparatively expensive + // + foreach (uint primID in primIds) { - if (part.LinkNum < 2) // Root or single - rootParts.Add(part); + SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); + if (part != null) + { + if (part.LinkNum < 2) // Root or single + rootParts.Add(part); + else + childParts.Add(part); + + SceneObjectGroup group = part.ParentGroup; + if (!affectedGroups.Contains(group)) + affectedGroups.Add(group); + } else - childParts.Add(part); - - SceneObjectGroup group = part.ParentGroup; - if (!affectedGroups.Contains(group)) - affectedGroups.Add(group); + { + m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); + } } - else + + foreach (SceneObjectPart child in childParts) { - m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); + // Unlink all child parts from their groups + // + child.ParentGroup.DelinkFromGroup(child, sendEvents); } - } - foreach (SceneObjectPart child in childParts) - { - // Unlink all child parts from their groups - // - child.ParentGroup.DelinkFromGroup(child, sendEvents); - } - - foreach (SceneObjectPart root in rootParts) - { - // In most cases, this will run only one time, and the prim - // will be a solo prim - // However, editing linked parts and unlinking may be different - // - SceneObjectGroup group = root.ParentGroup; - List newSet = new List(group.Children.Values); - int numChildren = group.Children.Count; - - // If there are prims left in a link set, but the root is - // slated for unlink, we need to do this - // - if (numChildren != 1) + foreach (SceneObjectPart root in rootParts) { - // Unlink the remaining set + // In most cases, this will run only one time, and the prim + // will be a solo prim + // However, editing linked parts and unlinking may be different // - bool sendEventsToRemainder = true; - if (numChildren > 1) - sendEventsToRemainder = false; - - foreach (SceneObjectPart p in newSet) - { - if (p != group.RootPart) - group.DelinkFromGroup(p, sendEventsToRemainder); - } + SceneObjectGroup group = root.ParentGroup; + List newSet = new List(group.Children.Values); + int numChildren = group.Children.Count; - // If there is more than one prim remaining, we - // need to re-link + // If there are prims left in a link set, but the root is + // slated for unlink, we need to do this // - if (numChildren > 2) + if (numChildren != 1) { - // Remove old root + // Unlink the remaining set // - if (newSet.Contains(root)) - newSet.Remove(root); + bool sendEventsToRemainder = true; + if (numChildren > 1) + sendEventsToRemainder = false; - // Preserve link ordering - // - newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) + foreach (SceneObjectPart p in newSet) { - return a.LinkNum.CompareTo(b.LinkNum); - }); + if (p != group.RootPart) + group.DelinkFromGroup(p, sendEventsToRemainder); + } - // Determine new root + // If there is more than one prim remaining, we + // need to re-link // - SceneObjectPart newRoot = newSet[0]; - newSet.RemoveAt(0); + if (numChildren > 2) + { + // Remove old root + // + if (newSet.Contains(root)) + newSet.Remove(root); + + // Preserve link ordering + // + newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) + { + return a.LinkNum.CompareTo(b.LinkNum); + }); - List linkIDs = new List(); + // Determine new root + // + SceneObjectPart newRoot = newSet[0]; + newSet.RemoveAt(0); - foreach (SceneObjectPart newChild in newSet) - { - newChild.UpdateFlag = 0; - linkIDs.Add(newChild.LocalId); - } + List linkIDs = new List(); + + foreach (SceneObjectPart newChild in newSet) + { + newChild.UpdateFlag = 0; + linkIDs.Add(newChild.LocalId); + } - LinkObjects(null, newRoot.LocalId, linkIDs); - if (!affectedGroups.Contains(newRoot.ParentGroup)) - affectedGroups.Add(newRoot.ParentGroup); + LinkObjects(null, newRoot.LocalId, linkIDs); + if (!affectedGroups.Contains(newRoot.ParentGroup)) + affectedGroups.Add(newRoot.ParentGroup); + } } } - } - // Finally, trigger events in the roots - // - foreach (SceneObjectGroup g in affectedGroups) - { - g.TriggerScriptChangedEvent(Changed.LINK); - g.HasGroupChanged = true; // Persist - g.ScheduleGroupForFullUpdate(); + // Finally, trigger events in the roots + // + foreach (SceneObjectGroup g in affectedGroups) + { + g.TriggerScriptChangedEvent(Changed.LINK); + g.HasGroupChanged = true; // Persist + g.ScheduleGroupForFullUpdate(); + } } } -- cgit v1.1 From f2891e77383f70d807f4ef1ceefbf9a0f2bf6a84 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 00:50:28 +0000 Subject: Remove extra forced updates. They're not needed for each prim. Really. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index fa2e3ce..93888f1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2292,14 +2292,14 @@ namespace OpenSim.Region.Framework.Scenes public void LinkToGroup(SceneObjectGroup objectGroup) { // Make sure we have sent any pending unlinks or stuff. - if (objectGroup.RootPart.UpdateFlag > 0) - { - m_log.WarnFormat( - "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", - objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); + //if (objectGroup.RootPart.UpdateFlag > 0) + //{ + // m_log.WarnFormat( + // "[SCENE OBJECT GROUP]: Forcing send of linkset {0}, {1} to {2}, {3} as its still waiting.", + // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); - objectGroup.RootPart.SendScheduledUpdates(); - } + // objectGroup.RootPart.SendScheduledUpdates(); + //} // m_log.DebugFormat( // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", -- cgit v1.1 From da414fd509a6adfa0499b71172e1c789b3cf7ca4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 01:20:39 +0000 Subject: Change locking to not mix explicit Monitor.* calls with lock() --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5efe188..4bdc52c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1562,7 +1562,8 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) { - lock (m_updateLock) + Monitor.Enter(m_updateLock); + try { SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); @@ -1617,6 +1618,10 @@ namespace OpenSim.Region.Framework.Scenes } } } + finally + { + Monitor.Exit(m_updateLock); + } } /// @@ -1630,7 +1635,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal void DelinkObjects(List primIds, bool sendEvents) { - lock (m_updateLock) + Monitor.Enter(m_updateLock); + try { List childParts = new List(); List rootParts = new List(); @@ -1737,6 +1743,10 @@ namespace OpenSim.Region.Framework.Scenes g.ScheduleGroupForFullUpdate(); } } + finally + { + Monitor.Exit(m_updateLock); + } } protected internal void MakeObjectSearchable(IClientAPI remoteClient, bool IncludeInSearch, uint localID) -- cgit v1.1 From 2fe75a62bec2f06155bf5f05b6f558d028f6b12c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 02:00:32 +0000 Subject: Skip single prims in unlink selections --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 4bdc52c..18e7b79 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1648,14 +1648,17 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); if (part != null) { - if (part.LinkNum < 2) // Root or single - rootParts.Add(part); - else - childParts.Add(part); - - SceneObjectGroup group = part.ParentGroup; - if (!affectedGroups.Contains(group)) - affectedGroups.Add(group); + if (part.ParentGroup.Children.Count != 1) // Skip single + { + if (part.LinkNum < 2) // Root + rootParts.Add(part); + else + childParts.Add(part); + + SceneObjectGroup group = part.ParentGroup; + if (!affectedGroups.Contains(group)) + affectedGroups.Add(group); + } } else { -- cgit v1.1 From 79511ecce240a864dc02575acd3399fb244a8d82 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 02:15:52 +0000 Subject: Experimental: Remove explicit property sends --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 18e7b79..f74fd5d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1606,17 +1606,17 @@ namespace OpenSim.Region.Framework.Scenes parentGroup.HasGroupChanged = true; parentGroup.ScheduleGroupForFullUpdate(); - if (client != null) - { - parentGroup.GetProperties(client); - } - else - { - foreach (ScenePresence p in GetScenePresences()) - { - parentGroup.GetProperties(p.ControllingClient); - } - } +// if (client != null) +// { +// parentGroup.GetProperties(client); +// } +// else +// { +// foreach (ScenePresence p in GetScenePresences()) +// { +// parentGroup.GetProperties(p.ControllingClient); +// } +// } } finally { -- cgit v1.1 From f9ae9afaacc82ee0284b1f7dc88ad880aabe23af Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 03:10:34 +0000 Subject: Fix build break from conflicted merge --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3d4490a..f6bcb59 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1972,7 +1972,7 @@ namespace OpenSim.Region.Framework.Scenes SendFullUpdateToAllClients(); } - public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance) + public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) { if(hitYN) { -- cgit v1.1 From 1e222d52e6219db4ad32338b952a94eebb0f7799 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 6 Dec 2009 03:56:15 +0000 Subject: Change EntityManager to use RWlocks --- OpenSim/Region/Framework/Scenes/EntityManager.cs | 79 ++++++++++++++++++++---- 1 file changed, 67 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/EntityManager.cs b/OpenSim/Region/Framework/Scenes/EntityManager.cs index 099fcce..c246e32 100644 --- a/OpenSim/Region/Framework/Scenes/EntityManager.cs +++ b/OpenSim/Region/Framework/Scenes/EntityManager.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes private readonly Dictionary m_eb_uuid = new Dictionary(); private readonly Dictionary m_eb_localID = new Dictionary(); //private readonly Dictionary m_pres_uuid = new Dictionary(); - private readonly Object m_lock = new Object(); + private System.Threading.ReaderWriterLockSlim m_lock = new System.Threading.ReaderWriterLockSlim(); [Obsolete("Use Add() instead.")] public void Add(UUID id, EntityBase eb) @@ -50,7 +50,8 @@ namespace OpenSim.Region.Framework.Scenes public void Add(EntityBase entity) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -62,11 +63,16 @@ namespace OpenSim.Region.Framework.Scenes m_log.ErrorFormat("Add Entity failed: {0}", e.Message); } } + finally + { + m_lock.ExitWriteLock(); + } } public void InsertOrReplace(EntityBase entity) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -78,15 +84,24 @@ namespace OpenSim.Region.Framework.Scenes m_log.ErrorFormat("Insert or Replace Entity failed: {0}", e.Message); } } + finally + { + m_lock.ExitWriteLock(); + } } public void Clear() { - lock (m_lock) + m_lock.EnterWriteLock(); + try { m_eb_uuid.Clear(); m_eb_localID.Clear(); } + finally + { + m_lock.ExitWriteLock(); + } } public int Count @@ -123,7 +138,8 @@ namespace OpenSim.Region.Framework.Scenes public bool Remove(uint localID) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -141,11 +157,16 @@ namespace OpenSim.Region.Framework.Scenes return false; } } + finally + { + m_lock.ExitWriteLock(); + } } public bool Remove(UUID id) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { try { @@ -163,13 +184,18 @@ namespace OpenSim.Region.Framework.Scenes return false; } } + finally + { + m_lock.ExitWriteLock(); + } } public List GetAllByType() { List tmp = new List(); - lock (m_lock) + m_lock.EnterReadLock(); + try { try { @@ -187,23 +213,33 @@ namespace OpenSim.Region.Framework.Scenes tmp = null; } } + finally + { + m_lock.ExitReadLock(); + } return tmp; } public List GetEntities() { - lock (m_lock) + m_lock.EnterReadLock(); + try { return new List(m_eb_uuid.Values); } + finally + { + m_lock.ExitReadLock(); + } } public EntityBase this[UUID id] { get { - lock (m_lock) + m_lock.EnterReadLock(); + try { EntityBase entity; if (m_eb_uuid.TryGetValue(id, out entity)) @@ -211,6 +247,10 @@ namespace OpenSim.Region.Framework.Scenes else return null; } + finally + { + m_lock.ExitReadLock(); + } } set { @@ -222,7 +262,8 @@ namespace OpenSim.Region.Framework.Scenes { get { - lock (m_lock) + m_lock.EnterReadLock(); + try { EntityBase entity; if (m_eb_localID.TryGetValue(localID, out entity)) @@ -230,6 +271,10 @@ namespace OpenSim.Region.Framework.Scenes else return null; } + finally + { + m_lock.ExitReadLock(); + } } set { @@ -239,18 +284,28 @@ namespace OpenSim.Region.Framework.Scenes public bool TryGetValue(UUID key, out EntityBase obj) { - lock (m_lock) + m_lock.EnterReadLock(); + try { return m_eb_uuid.TryGetValue(key, out obj); } + finally + { + m_lock.ExitReadLock(); + } } public bool TryGetValue(uint key, out EntityBase obj) { - lock (m_lock) + m_lock.EnterReadLock(); + try { return m_eb_localID.TryGetValue(key, out obj); } + finally + { + m_lock.ExitReadLock(); + } } /// -- cgit v1.1 From 172e2f4e7609c278d02ad83ca207fd79624db587 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sun, 6 Dec 2009 17:23:07 +0100 Subject: Fix to existing ReaderWriterLockSlim implementations --- OpenSim/Framework/TaskInventoryDictionary.cs | 10 ++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 ++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 3 ++- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 10 ++++++++-- 4 files changed, 26 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index efe5f0c..4b9a509 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -109,7 +109,10 @@ namespace OpenSim.Framework } else { - m_itemLock.ExitReadLock(); + if (m_itemLock.RecursiveReadCount>0) + { + m_itemLock.ExitReadLock(); + } } } @@ -144,7 +147,10 @@ namespace OpenSim.Framework } else { - m_itemLock.ExitWriteLock(); + if (m_itemLock.RecursiveWriteCount > 0) + { + m_itemLock.ExitWriteLock(); + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 93888f1..eacd219 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -126,7 +126,10 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_partsLock.ExitReadLock(); + if (m_partsLock.RecursiveReadCount > 0) + { + m_partsLock.ExitReadLock(); + } } } public void lockPartsForWrite(bool locked) @@ -155,7 +158,10 @@ namespace OpenSim.Region.Framework.Scenes } else { - m_partsLock.ExitWriteLock(); + if (m_partsLock.RecursiveWriteCount > 0) + { + m_partsLock.ExitWriteLock(); + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4780ff2..b57d912 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -320,17 +320,18 @@ namespace OpenSim.Region.Framework.Scenes { if (m_items.ContainsKey(itemId)) { + m_items.LockItemsForRead(false); CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); } else { + m_items.LockItemsForRead(false); m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", itemId, m_part.Name, m_part.UUID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } - m_items.LockItemsForRead(false); } else { diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 49c69ab..184af19 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -150,7 +150,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - m_scriptsLock.ExitReadLock(); + if (m_scriptsLock.RecursiveReadCount > 0) + { + m_scriptsLock.ExitReadLock(); + } } } private void lockScriptsForWrite(bool locked) @@ -179,7 +182,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine } else { - m_scriptsLock.ExitWriteLock(); + if (m_scriptsLock.RecursiveWriteCount > 0) + { + m_scriptsLock.ExitWriteLock(); + } } } -- cgit v1.1 From 0d1d437bd3bf608448d71ea7de8e4f7cfb0371f0 Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Sun, 6 Dec 2009 21:11:59 +0100 Subject: Fix linked physical daughter prim position update. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 17 ++++++++++++++--- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 -- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 9f2c3db..a6382ee 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -513,9 +513,16 @@ namespace OpenSim.Region.Framework.Scenes { // If this is a linkset, we don't want the physics engine mucking up our group position here. PhysicsActor actor = PhysActor; - if (actor != null && _parentID == 0) + if (actor != null) { - m_groupPosition = actor.Position; + if (_parentID == 0) + { + m_groupPosition = actor.Position; + } + else + { + m_groupPosition = ParentGroup.AbsolutePosition; // KF+Casper Update Child prims too! + } } if (IsAttachment) @@ -1743,9 +1750,13 @@ namespace OpenSim.Region.Framework.Scenes Quaternion parentRot = ParentGroup.RootPart.RotationOffset; Vector3 axPos = OffsetPosition; - axPos *= parentRot; Vector3 translationOffsetPosition = axPos; + + int tx = (int)GroupPosition.X; + int ty = (int)GroupPosition.Y; + int tz = (int)GroupPosition.Z; + return GroupPosition + translationOffsetPosition; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 817b9df..5d0218f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1642,7 +1642,6 @@ namespace OpenSim.Region.Framework.Scenes // Reset sit target. if (part.GetAvatarOnSitTarget() == UUID) part.SetAvatarOnSitTarget(UUID.Zero); - m_parentPosition = part.GetWorldPosition(); ControllingClient.SendClearFollowCamProperties(part.ParentUUID); } @@ -1659,7 +1658,6 @@ namespace OpenSim.Region.Framework.Scenes } AbsolutePosition = wso; //KF: Fix stand up. m_parentPosition = Vector3.Zero; - m_parentID = 0; part.IsOccupied = false; SendFullUpdateToAllClients(); -- cgit v1.1 From c2d3afdeee1b1b8b9b4ef0c6588777536adc15db Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 7 Dec 2009 14:31:20 +0000 Subject: Same for the remote auth connector --- .../Authorization/RemoteAuthorizationServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs index fca2df2..68499f3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization IConfig authorizationConfig = source.Configs["AuthorizationService"]; if (authorizationConfig == null) { - m_log.Error("[REMOTE AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); + m_log.Info("[REMOTE AUTHORIZATION CONNECTOR]: AuthorizationService missing from OpenSim.ini"); return; } -- cgit v1.1 From 29a740ec8c78bfc3c1ab5b41b302ae2205c6e9aa Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 7 Dec 2009 18:03:53 +0100 Subject: Initial windlight codebase commit --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 2 +- .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 2 +- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 9 +- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 192 +++++++++++++++++++++ OpenSim/Data/Null/NullDataStore.cs | 7 +- OpenSim/Data/SQLite/SQLiteRegionData.cs | 7 +- OpenSim/Framework/IClientAPI.cs | 2 +- OpenSim/Framework/RegionInfo.cs | 69 +++++++- .../Region/ClientStack/LindenUDP/LLClientView.cs | 6 +- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- .../Framework/Interfaces/IRegionDataStore.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 2 + .../Region/Framework/Scenes/Tests/SceneTests.cs | 7 +- .../Server/IRCClientView.cs | 2 +- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- OpenSim/Tests/Common/Mock/TestClient.cs | 2 +- 16 files changed, 297 insertions(+), 17 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 0cae3dd..9f9d151 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -902,7 +902,7 @@ namespace OpenSim.Client.MXP.ClientStack // Need to translate to MXP somehow } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { // Need to translate to MXP somehow } diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index fb87c15..533475f 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -483,7 +483,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { throw new System.NotImplementedException(); } diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index 6371307..678b251 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -671,7 +671,12 @@ VALUES cmd.ExecuteNonQuery(); } } - + public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + { + //This connector doesn't support the windlight module yet + //Return default LL windlight settings + return new RegionMeta7WindlightData(); + } /// /// Loads the settings of a region. /// @@ -696,7 +701,7 @@ VALUES } } - //If comes here then there is now region setting for that region + //If we reach this point then there are new region settings for that region regionSettings = new RegionSettings(); regionSettings.RegionUUID = regionUUID; regionSettings.OnSave += StoreRegionSettings; diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index c49153f..e47d2a5 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -691,6 +691,97 @@ namespace OpenSim.Data.MySQL } } + public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + { + RegionMeta7WindlightData nWP = new RegionMeta7WindlightData(); + nWP.OnSave += StoreRegionWindlightSettings; + lock (m_Connection) + { + + string command = "select * from `regionwindlight` where region_id = ?regionID"; + + MySqlCommand cmd = new MySqlCommand(command); + + cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); + + IDataReader result = ExecuteReader(cmd); + if (!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; + StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + UUID.TryParse(result["region_id"].ToString(), out nWP.regionID); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + } + } + return nWP; + } + public RegionSettings LoadRegionSettings(UUID regionUUID) { RegionSettings rs = null; @@ -724,6 +815,107 @@ namespace OpenSim.Data.MySQL return rs; } + public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + { + lock (m_Connection) + { + using (MySqlCommand cmd = m_Connection.CreateCommand()) + { + cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; + cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; + cmd.CommandText += "`reflection_wavelet_scale_1`, `reflection_wavelet_scale_2`, `reflection_wavelet_scale_3`, "; + cmd.CommandText += "`fresnel_scale`, `fresnel_offset`, `refract_scale_above`, `refract_scale_below`, "; + cmd.CommandText += "`blur_multiplier`, `big_wave_direction_x`, `big_wave_direction_y`, `little_wave_direction_x`, "; + cmd.CommandText += "`little_wave_direction_y`, `normal_map_texture`, `horizon_r`, `horizon_g`, `horizon_b`, "; + cmd.CommandText += "`horizon_i`, `haze_horizon`, `blue_density_r`, `blue_density_g`, `blue_density_b`, "; + cmd.CommandText += "`blue_density_i`, `haze_density`, `density_multiplier`, `distance_multiplier`, `max_altitude`, "; + cmd.CommandText += "`sun_moon_color_r`, `sun_moon_color_g`, `sun_moon_color_b`, `sun_moon_color_i`, `sun_moon_position`, "; + cmd.CommandText += "`ambient_r`, `ambient_g`, `ambient_b`, `ambient_i`, `east_angle`, `sun_glow_focus`, `sun_glow_size`, "; + cmd.CommandText += "`scene_gamma`, `star_brightness`, `cloud_color_r`, `cloud_color_g`, `cloud_color_b`, `cloud_color_i`, "; + cmd.CommandText += "`cloud_x`, `cloud_y`, `cloud_density`, `cloud_coverage`, `cloud_scale`, `cloud_detail_x`, "; + cmd.CommandText += "`cloud_detail_y`, `cloud_detail_density`, `cloud_scroll_x`, `cloud_scroll_x_lock`, `cloud_scroll_y`, "; + cmd.CommandText += "`cloud_scroll_y_lock`, `draw_classic_clouds`) VALUES (?region_id, ?water_color_r, "; + cmd.CommandText += "?water_color_g, ?water_color_b, ?water_fog_density_exponent, ?underwater_fog_modifier, ?reflection_wavelet_scale_1, "; + cmd.CommandText += "?reflection_wavelet_scale_2, ?reflection_wavelet_scale_3, ?fresnel_scale, ?fresnel_offset, ?refract_scale_above, "; + cmd.CommandText += "?refract_scale_below, ?blur_multiplier, ?big_wave_direction_x, ?big_wave_direction_y, ?little_wave_direction_x, "; + cmd.CommandText += "?little_wave_direction_y, ?normal_map_texture, ?horizon_r, ?horizon_g, ?horizon_b, ?horizon_i, ?haze_horizon, "; + cmd.CommandText += "?blue_density_r, ?blue_density_g, ?blue_density_b, ?blue_density_i, ?haze_density, ?density_multiplier, "; + cmd.CommandText += "?distance_multiplier, ?max_altitude, ?sun_moon_color_r, ?sun_moon_color_g, ?sun_moon_color_b, "; + cmd.CommandText += "?sun_moon_color_i, ?sun_moon_position, ?ambient_r, ?ambient_g, ?ambient_b, ?ambient_i, ?east_angle, "; + cmd.CommandText += "?sun_glow_focus, ?sun_glow_size, ?scene_gamma, ?star_brightness, ?cloud_color_r, ?cloud_color_g, "; + cmd.CommandText += "?cloud_color_b, ?cloud_color_i, ?cloud_x, ?cloud_y, ?cloud_density, ?cloud_coverage, ?cloud_scale, "; + cmd.CommandText += "?cloud_detail_x, ?cloud_detail_y, ?cloud_detail_density, ?cloud_scroll_x, ?cloud_scroll_x_lock, "; + cmd.CommandText += "?cloud_scroll_y, ?cloud_scroll_y_lock, ?draw_classic_clouds)"; + + cmd.Parameters.AddWithValue("region_id", wl.regionID); + cmd.Parameters.AddWithValue("water_color_r", wl.waterColor.X); + cmd.Parameters.AddWithValue("water_color_g", wl.waterColor.Y); + cmd.Parameters.AddWithValue("water_color_b", wl.waterColor.Z); + cmd.Parameters.AddWithValue("water_fog_density_exponent", wl.waterFogDensityExponent); + cmd.Parameters.AddWithValue("underwater_fog_modifier", wl.underwaterFogModifier); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_1", wl.reflectionWaveletScale.X); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_2", wl.reflectionWaveletScale.Y); + cmd.Parameters.AddWithValue("reflection_wavelet_scale_3", wl.reflectionWaveletScale.Z); + cmd.Parameters.AddWithValue("fresnel_scale", wl.fresnelScale); + cmd.Parameters.AddWithValue("fresnel_offset", wl.fresnelOffset); + cmd.Parameters.AddWithValue("refract_scale_above", wl.refractScaleAbove); + cmd.Parameters.AddWithValue("refract_scale_below", wl.refractScaleBelow); + cmd.Parameters.AddWithValue("blur_multiplier", wl.blurMultiplier); + cmd.Parameters.AddWithValue("big_wave_direction_x", wl.bigWaveDirection.X); + cmd.Parameters.AddWithValue("big_wave_direction_y", wl.bigWaveDirection.Y); + cmd.Parameters.AddWithValue("little_wave_direction_x", wl.littleWaveDirection.X); + cmd.Parameters.AddWithValue("little_wave_direction_y", wl.littleWaveDirection.Y); + cmd.Parameters.AddWithValue("normal_map_texture", wl.normalMapTexture); + cmd.Parameters.AddWithValue("horizon_r", wl.horizon.X); + cmd.Parameters.AddWithValue("horizon_g", wl.horizon.Y); + cmd.Parameters.AddWithValue("horizon_b", wl.horizon.Z); + cmd.Parameters.AddWithValue("horizon_i", wl.horizon.W); + cmd.Parameters.AddWithValue("haze_horizon", wl.hazeHorizon); + cmd.Parameters.AddWithValue("blue_density_r", wl.blueDensity.X); + cmd.Parameters.AddWithValue("blue_density_g", wl.blueDensity.Y); + cmd.Parameters.AddWithValue("blue_density_b", wl.blueDensity.Z); + cmd.Parameters.AddWithValue("blue_density_i", wl.blueDensity.W); + cmd.Parameters.AddWithValue("haze_density", wl.hazeDensity); + cmd.Parameters.AddWithValue("density_multiplier", wl.densityMultiplier); + cmd.Parameters.AddWithValue("distance_multiplier", wl.distanceMultiplier); + cmd.Parameters.AddWithValue("max_altitude", wl.maxAltitude); + cmd.Parameters.AddWithValue("sun_moon_color_r", wl.sunMoonColor.X); + cmd.Parameters.AddWithValue("sun_moon_color_g", wl.sunMoonColor.Y); + cmd.Parameters.AddWithValue("sun_moon_color_b", wl.sunMoonColor.Z); + cmd.Parameters.AddWithValue("sun_moon_color_i", wl.sunMoonColor.W); + cmd.Parameters.AddWithValue("sun_moon_position", wl.sunMoonPosition); + cmd.Parameters.AddWithValue("ambient_r", wl.ambient.X); + cmd.Parameters.AddWithValue("ambient_g", wl.ambient.Y); + cmd.Parameters.AddWithValue("ambient_b", wl.ambient.Z); + cmd.Parameters.AddWithValue("ambient_i", wl.ambient.W); + cmd.Parameters.AddWithValue("east_angle", wl.eastAngle); + cmd.Parameters.AddWithValue("sun_glow_focus", wl.sunGlowFocus); + cmd.Parameters.AddWithValue("sun_glow_size", wl.sunGlowSize); + cmd.Parameters.AddWithValue("scene_gamma", wl.sceneGamma); + cmd.Parameters.AddWithValue("star_brightness", wl.starBrightness); + cmd.Parameters.AddWithValue("cloud_color_r", wl.cloudColor.X); + cmd.Parameters.AddWithValue("cloud_color_g", wl.cloudColor.Y); + cmd.Parameters.AddWithValue("cloud_color_b", wl.cloudColor.Z); + cmd.Parameters.AddWithValue("cloud_color_i", wl.cloudColor.W); + cmd.Parameters.AddWithValue("cloud_x", wl.cloudXYDensity.X); + cmd.Parameters.AddWithValue("cloud_y", wl.cloudXYDensity.Y); + cmd.Parameters.AddWithValue("cloud_density", wl.cloudXYDensity.Z); + cmd.Parameters.AddWithValue("cloud_coverage", wl.cloudCoverage); + cmd.Parameters.AddWithValue("cloud_scale", wl.cloudScale); + cmd.Parameters.AddWithValue("cloud_detail_x", wl.cloudDetailXYDensity.X); + cmd.Parameters.AddWithValue("cloud_detail_y", wl.cloudDetailXYDensity.Y); + cmd.Parameters.AddWithValue("cloud_detail_density", wl.cloudDetailXYDensity.Z); + cmd.Parameters.AddWithValue("cloud_scroll_x", wl.cloudScrollX); + cmd.Parameters.AddWithValue("cloud_scroll_x_lock", wl.cloudScrollXLock); + cmd.Parameters.AddWithValue("cloud_scroll_y", wl.cloudScrollY); + cmd.Parameters.AddWithValue("cloud_scroll_y_lock", wl.cloudScrollYLock); + cmd.Parameters.AddWithValue("draw_classic_clouds", wl.drawClassicClouds); + + ExecuteNonQuery(cmd); + } + } + } + public void StoreRegionSettings(RegionSettings rs) { lock (m_Connection) diff --git a/OpenSim/Data/Null/NullDataStore.cs b/OpenSim/Data/Null/NullDataStore.cs index 427fa0a..39ca8f9 100644 --- a/OpenSim/Data/Null/NullDataStore.cs +++ b/OpenSim/Data/Null/NullDataStore.cs @@ -50,7 +50,12 @@ namespace OpenSim.Data.Null public void StoreRegionSettings(RegionSettings rs) { } - + public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + { + //This connector doesn't support the windlight module yet + //Return default LL windlight settings + return new RegionMeta7WindlightData(); + } public RegionSettings LoadRegionSettings(UUID regionUUID) { return null; diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index b68de1a..53b806c 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -272,7 +272,12 @@ namespace OpenSim.Data.SQLite Commit(); } } - + public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + { + //This connector doesn't support the windlight module yet + //Return default LL windlight settings + return new RegionMeta7WindlightData(); + } public RegionSettings LoadRegionSettings(UUID regionUUID) { lock (ds) diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 04ba9c6..cb136e2 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1077,7 +1077,7 @@ namespace OpenSim.Framework void SendInstantMessage(GridInstantMessage im); - void SendGenericMessage(string method, List message); + void SendGenericMessage(string method, List message); void SendLayerData(float[] map); void SendLayerData(int px, int py, float[] map); diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 721233d..c39cc03 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -36,8 +36,59 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework.Console; + namespace OpenSim.Framework { + public class RegionMeta7WindlightData + { + public UUID regionID = UUID.Zero; + public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f); + public float waterFogDensityExponent = 4.0f; + public float underwaterFogModifier = 0.25f; + public Vector3 reflectionWaveletScale = new Vector3(2.0f,2.0f,2.0f); + public float fresnelScale = 0.40f; + public float fresnelOffset = 0.50f; + public float refractScaleAbove = 0.03f; + public float refractScaleBelow = 0.20f; + public float blurMultiplier = 0.040f; + public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f); + public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f); + public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); + public Vector4 horizon = new Vector4(0.26f, 0.24f, 0.34f, 0.33f); + public float hazeHorizon = 0.19f; + public Vector4 blueDensity = new Vector4(0.10f, 0.93f, 0.02f, 0.93f); + public float hazeDensity = 0.70f; + public float densityMultiplier = 0.18f; + public float distanceMultiplier = 0.8f; + public UInt16 maxAltitude = 1605; + public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f); + public float sunMoonPosition = 0.335f; + public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f); + public float eastAngle = 0.0f; + public float sunGlowFocus = 0.10f; + public float sunGlowSize = 0.10f; + public float sceneGamma = 1.0f; + public float starBrightness = 0.0f; + public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f); + public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f); + public float cloudCoverage = 0.27f; + public float cloudScale = 0.42f; + public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f); + public float cloudScrollX = 0.20f; + public bool cloudScrollXLock = false; + public float cloudScrollY = 0.01f; + public bool cloudScrollYLock = false; + public bool drawClassicClouds = false; + + public delegate void SaveDelegate(RegionMeta7WindlightData wl); + public event SaveDelegate OnSave; + public void Save() + { + if (OnSave != null) + OnSave(this); + } + } + [Serializable] public class SimpleRegionInfo { @@ -304,8 +355,7 @@ namespace OpenSim.Framework private bool m_clampPrimSize = false; private int m_objectCapacity = 0; private string m_regionType = String.Empty; - - + private RegionMeta7WindlightData m_windlight = new RegionMeta7WindlightData(); // Apparently, we're applying the same estatesettings regardless of whether it's local or remote. // MT: Yes. Estates can't span trust boundaries. Therefore, it can be @@ -454,6 +504,21 @@ namespace OpenSim.Framework set { m_regionSettings = value; } } + public RegionMeta7WindlightData WindlightSettings + { + get + { + if (m_windlight == null) + { + m_windlight = new RegionMeta7WindlightData(); + } + + return m_windlight; + } + + set { m_windlight = value; } + } + public int NonphysPrimMax { get { return m_nonphysPrimMax; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index b588a2e..6cbf1a6 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -764,16 +764,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { GenericMessagePacket gmp = new GenericMessagePacket(); gmp.MethodData.Method = Util.StringToBytes256(method); gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; int i = 0; - foreach (string val in message) + foreach (byte[] val in message) { gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); - gmp.ParamList[i++].Parameter = Util.StringToBytes256(val); + gmp.ParamList[i++].Parameter = val; } OutPacket(gmp, ThrottleOutPacketType.Task); } diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 9754da3..816060f 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -433,7 +433,7 @@ namespace OpenSim.Region.Examples.SimpleModule } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { } diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs index 78bd622..225cc9a 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs @@ -103,6 +103,7 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionSettings(RegionSettings rs); RegionSettings LoadRegionSettings(UUID regionUUID); + RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID); void Shutdown(); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f5a1e74..f70af27 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -539,6 +539,8 @@ namespace OpenSim.Region.Framework.Scenes // Load region settings m_regInfo.RegionSettings = m_storageManager.DataStore.LoadRegionSettings(m_regInfo.RegionID); + m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(m_regInfo.RegionID); + if (m_storageManager.EstateDataStore != null) { m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID); diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 8a27b7b..e8cda60 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -101,7 +101,12 @@ namespace OpenSim.Region.Framework.Scenes.Tests { throw new NotImplementedException(); } - + public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + { + //This connector doesn't support the windlight module yet + //Return default LL windlight settings + return new RegionMeta7WindlightData(); + } public RegionSettings LoadRegionSettings(UUID regionUUID) { return null; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 6c3e7eb..bdf1574 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -936,7 +936,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server // TODO } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index cf36d08..975033a 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -522,7 +522,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 27025d9..5f172c4 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -491,7 +491,7 @@ namespace OpenSim.Tests.Common.Mock } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { } -- cgit v1.1 From ee9d46c8255840473ed62c3b37270b35af1a9027 Mon Sep 17 00:00:00 2001 From: KittoFlora Date: Tue, 8 Dec 2009 05:49:05 +0100 Subject: Correct AbsolutePosition calculation --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a6382ee..a23c11e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -849,7 +849,8 @@ namespace OpenSim.Region.Framework.Scenes if (IsAttachment) return GroupPosition; - return m_offsetPosition + m_groupPosition; } +// return m_offsetPosition + m_groupPosition; } + return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored! } public SceneObjectGroup ParentGroup -- cgit v1.1 From e3f229225c5a1506090bfcffcce6d423a566f1fe Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Dec 2009 01:34:26 +0100 Subject: Enable scripting interface for windlight --- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 4 + OpenSim/Data/Null/NullDataStore.cs | 4 + OpenSim/Data/SQLite/SQLiteRegionData.cs | 4 + .../Framework/Interfaces/IRegionDataStore.cs | 1 + OpenSim/Region/Framework/Scenes/EventManager.cs | 12 + OpenSim/Region/Framework/Scenes/Scene.cs | 7 + .../Region/Framework/Scenes/Tests/SceneTests.cs | 4 + .../Shared/Api/Implementation/OSSL_Api.cs | 333 +++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 7 +- .../Shared/Api/Runtime/LSL_Constants.cs | 38 +++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 10 + 11 files changed, 423 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index 678b251..0b430c7 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -677,6 +677,10 @@ VALUES //Return default LL windlight settings return new RegionMeta7WindlightData(); } + public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + { + //This connector doesn't support the windlight module yet + } /// /// Loads the settings of a region. /// diff --git a/OpenSim/Data/Null/NullDataStore.cs b/OpenSim/Data/Null/NullDataStore.cs index 39ca8f9..4b6d0f3 100644 --- a/OpenSim/Data/Null/NullDataStore.cs +++ b/OpenSim/Data/Null/NullDataStore.cs @@ -56,6 +56,10 @@ namespace OpenSim.Data.Null //Return default LL windlight settings return new RegionMeta7WindlightData(); } + public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + { + //This connector doesn't support the windlight module yet + } public RegionSettings LoadRegionSettings(UUID regionUUID) { return null; diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 53b806c..f1c1f78 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -278,6 +278,10 @@ namespace OpenSim.Data.SQLite //Return default LL windlight settings return new RegionMeta7WindlightData(); } + public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + { + //This connector doesn't support the windlight module yet + } public RegionSettings LoadRegionSettings(UUID regionUUID) { lock (ds) diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs index 225cc9a..7312799 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs @@ -104,6 +104,7 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionSettings(RegionSettings rs); RegionSettings LoadRegionSettings(UUID regionUUID); RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID); + void StoreRegionWindlightSettings(RegionMeta7WindlightData wl); void Shutdown(); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 753344d..a86e263 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -193,7 +193,9 @@ namespace OpenSim.Region.Framework.Scenes public event OnMakeChildAgentDelegate OnMakeChildAgent; public delegate void OnMakeRootAgentDelegate(ScenePresence presence); + public delegate void OnSaveNewWindlightProfileDelegate(); public event OnMakeRootAgentDelegate OnMakeRootAgent; + public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile; public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); @@ -411,6 +413,7 @@ namespace OpenSim.Region.Framework.Scenes private IncomingInstantMessage handlerUnhandledInstantMessage = null; //OnUnhandledInstantMessage; private ClientClosed handlerClientClosed = null; //OnClientClosed; private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; + private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile; private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; @@ -772,6 +775,15 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerOnSaveNewWindlightProfile() + { + handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile; + if (handlerSaveNewWindlightProfile != null) + { + handlerSaveNewWindlightProfile(); + } + } + public void TriggerOnMakeRootAgent(ScenePresence presence) { handlerMakeRootAgent = OnMakeRootAgent; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8d91d65..475d775 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1505,6 +1505,13 @@ namespace OpenSim.Region.Framework.Scenes m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); } + public void StoreWindlightProfile(RegionMeta7WindlightData wl) + { + m_regInfo.WindlightSettings = wl; + m_storageManager.DataStore.StoreRegionWindlightSettings(wl); + m_eventManager.TriggerOnSaveNewWindlightProfile(); + } + /// /// Loads the World heightmap /// diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index e8cda60..5abbb82 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -107,6 +107,10 @@ namespace OpenSim.Region.Framework.Scenes.Tests //Return default LL windlight settings return new RegionMeta7WindlightData(); } + public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + { + //This connector doesn't support the windlight module yet + } public RegionSettings LoadRegionSettings(UUID regionUUID) { return null; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 7f739b1..33c67d5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -42,6 +42,7 @@ using OpenSim.Region.CoreModules.Avatar.NPC; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Hypergrid; +using OpenSim.Region.CoreModules.World.Meta7Windlight; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; @@ -1974,5 +1975,337 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ret; } + /// + /// Get the current Windlight scene + /// + /// List of windlight parameters + public LSL_List osGetWindlightScene(LSL_List rules) + { + CheckThreatLevel(ThreatLevel.Low, "osGetWindlightScene"); + m_host.AddScriptLPS(1); + RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_List toadd = new LSL_List(); + + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + toadd.Add(new LSL_Float(wl.blurMultiplier)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + toadd.Add(new LSL_Float(wl.cloudCoverage)); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + toadd.Add(new LSL_Float(wl.cloudScale)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + toadd.Add(new LSL_Float(wl.cloudScrollX)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + toadd.Add(new LSL_Float(wl.cloudScrollY)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + toadd.Add(new LSL_Float(wl.densityMultiplier)); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + toadd.Add(new LSL_Float(wl.distanceMultiplier)); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + toadd.Add(new LSL_Float(wl.eastAngle)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + toadd.Add(new LSL_Float(wl.fresnelOffset)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + toadd.Add(new LSL_Float(wl.fresnelScale)); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + toadd.Add(new LSL_Float(wl.hazeDensity)); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + toadd.Add(new LSL_Float(wl.hazeHorizon)); + break; + case (int)ScriptBaseClass.WL_HORIZON: + toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + toadd.Add(new LSL_Integer(wl.maxAltitude)); + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + toadd.Add(new LSL_Float(wl.refractScaleAbove)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + toadd.Add(new LSL_Float(wl.refractScaleBelow)); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + toadd.Add(new LSL_Float(wl.sceneGamma)); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + toadd.Add(new LSL_Float(wl.starBrightness)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + toadd.Add(new LSL_Float(wl.sunGlowFocus)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + toadd.Add(new LSL_Float(wl.sunGlowSize)); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + toadd.Add(new LSL_Float(wl.underwaterFogModifier)); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); + break; + } + + if (toadd.Length > 0) + { + values.Add(rule); + values.Add(toadd.Data[0]); + } + idx++; + } + + + return values; + + } + + /// + /// Set the current Windlight scene + /// + /// + /// success: true or false + public int osSetWindlightScene(LSL_List rules) + { + CheckThreatLevel(ThreatLevel.High, "osSetWindlightScene"); + int success = 0; + m_host.AddScriptLPS(1); + if (Meta7WindlightModule.EnableWindlight) + { + RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + LSL_List values = new LSL_List(); + int idx = 0; + success = 1; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_Types.Quaternion iQ; + LSL_Types.Vector3 iV; + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + idx++; + wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + idx++; + wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + idx++; + wl.cloudScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + idx++; + wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + idx++; + wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + idx++; + wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + idx++; + wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + idx++; + wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + idx++; + wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + idx++; + wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + idx++; + wl.eastAngle = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + idx++; + wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + idx++; + wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + idx++; + wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + idx++; + wl.hazeHorizon= (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HORIZON: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + idx++; + wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + idx++; + wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + idx++; + iV = rules.GetVector3Item(idx); + wl.reflectionWaveletScale= new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + idx++; + wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + idx++; + wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + idx++; + wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + idx++; + wl.starBrightness= (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + idx++; + wl.sunGlowFocus= (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + idx++; + wl.sunGlowSize= (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + idx++; + wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + idx++; + iV = rules.GetVector3Item(idx); + wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + idx++; + wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); + break; + default: + success = 0; + break; + } + idx++; + } + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + + } + return success; + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 0b0dc00..dd2869b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces // Avatar Info Commands string osGetAgentIP(string agent); LSL_List osGetAgents(); - + // Teleport commands void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); @@ -163,5 +163,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces key osGetMapTexture(); key osGetRegionMapTexture(string regionName); LSL_List osGetRegionStats(); + + // Windlight Functions + LSL_List osGetWindlightScene(LSL_List rules); + int osSetWindlightScene(LSL_List rules); + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index acff8fb..4956c28 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -539,5 +539,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int STATS_ACTIVE_SCRIPTS = 19; public const int STATS_SCRIPT_LPS = 20; + // Constants for osWindlight* + public const int WL_WATER_COLOR = 0; + public const int WL_WATER_FOG_DENSITY_EXPONENT = 1; + public const int WL_UNDERWATER_FOG_MODIFIER = 2; + public const int WL_REFLECTION_WAVELET_SCALE = 3; + public const int WL_FRESNEL_SCALE = 4; + public const int WL_FRESNEL_OFFSET = 5; + public const int WL_REFRACT_SCALE_ABOVE = 6; + public const int WL_REFRACT_SCALE_BELOW = 7; + public const int WL_BLUR_MULTIPLIER = 8; + public const int WL_BIG_WAVE_DIRECTION = 9; + public const int WL_LITTLE_WAVE_DIRECTION = 10; + public const int WL_NORMAL_MAP_TEXTURE = 11; + public const int WL_HORIZON = 12; + public const int WL_HAZE_HORIZON = 13; + public const int WL_BLUE_DENSITY = 14; + public const int WL_HAZE_DENSITY = 15; + public const int WL_DENSITY_MULTIPLIER = 16; + public const int WL_DISTANCE_MULTIPLIER = 17; + public const int WL_MAX_ALTITUDE = 18; + public const int WL_SUN_MOON_COLOR = 19; + public const int WL_AMBIENT = 20; + public const int WL_EAST_ANGLE = 21; + public const int WL_SUN_GLOW_FOCUS = 22; + public const int WL_SUN_GLOW_SIZE = 23; + public const int WL_SCENE_GAMMA = 24; + public const int WL_STAR_BRIGHTNESS = 25; + public const int WL_CLOUD_COLOR = 26; + public const int WL_CLOUD_XY_DENSITY = 27; + public const int WL_CLOUD_COVERAGE = 28; + public const int WL_CLOUD_SCALE = 29; + public const int WL_CLOUD_DETAIL_XY_DENSITY = 30; + public const int WL_CLOUD_SCROLL_X = 31; + public const int WL_CLOUD_SCROLL_Y = 32; + public const int WL_CLOUD_SCROLL_Y_LOCK = 33; + public const int WL_CLOUD_SCROLL_X_LOCK = 34; + public const int WL_DRAW_CLASSIC_CLOUDS = 35; + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 519463e..1480b8b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -637,5 +637,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osGetRegionStats(); } + + public LSL_List osGetWindlightScene(LSL_List rules) + { + return m_OSSL_Functions.osGetWindlightScene(rules); + } + + public int osSetWindlightScene(LSL_List rules) + { + return m_OSSL_Functions.osSetWindlightScene(rules); + } } } -- cgit v1.1 From d092977f4a933baa990cb239d91c1bec860698e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 9 Dec 2009 01:53:41 +0100 Subject: Windlight configuration option in ini, and migration --- OpenSim/Data/MySQL/Resources/032_RegionStore.sql | 70 ++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 OpenSim/Data/MySQL/Resources/032_RegionStore.sql (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/Resources/032_RegionStore.sql b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql new file mode 100644 index 0000000..0545ee1 --- /dev/null +++ b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql @@ -0,0 +1,70 @@ +BEGIN; + +CREATE TABLE `regionwindlight` ( + `region_id` varchar(36) NOT NULL DEFAULT '000000-0000-0000-0000-000000000000', + `water_color_r` float(9,6) unsigned NOT NULL DEFAULT '4.000000', + `water_color_g` float(9,6) unsigned NOT NULL DEFAULT '38.000000', + `water_color_b` float(9,6) unsigned NOT NULL DEFAULT '64.000000', + `water_fog_density_exponent` float(3,1) unsigned NOT NULL DEFAULT '4.0', + `underwater_fog_modifier` float(3,2) unsigned NOT NULL DEFAULT '0.25', + `reflection_wavelet_scale_1` float(3,1) unsigned NOT NULL DEFAULT '2.0', + `reflection_wavelet_scale_2` float(3,1) unsigned NOT NULL DEFAULT '2.0', + `reflection_wavelet_scale_3` float(3,1) unsigned NOT NULL DEFAULT '2.0', + `fresnel_scale` float(3,2) unsigned NOT NULL DEFAULT '0.40', + `fresnel_offset` float(3,2) unsigned NOT NULL DEFAULT '0.50', + `refract_scale_above` float(3,2) unsigned NOT NULL DEFAULT '0.03', + `refract_scale_below` float(3,2) unsigned NOT NULL DEFAULT '0.20', + `blur_multiplier` float(4,3) unsigned NOT NULL DEFAULT '0.040', + `big_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.05', + `big_wave_direction_y` float(3,2) NOT NULL DEFAULT '-0.42', + `little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11', + `little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16', + `normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4', + `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.26', + `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.24', + `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.33', + `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.33', + `haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19', + `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.10', + `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.93', + `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.02', + `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.93', + `haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70', + `density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18', + `distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8', + `max_altitude` int(4) unsigned NOT NULL DEFAULT '1605', + `sun_moon_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.24', + `sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26', + `sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30', + `sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30', + `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.335', + `ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35', + `ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35', + `ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35', + `ambient_i` float(3,2) unsigned NOT NULL DEFAULT '0.35', + `east_angle` float(3,2) unsigned NOT NULL DEFAULT '0.00', + `sun_glow_focus` float(3,2) unsigned NOT NULL DEFAULT '0.10', + `sun_glow_size` float(3,2) unsigned NOT NULL DEFAULT '1.75', + `scene_gamma` float(4,2) unsigned NOT NULL DEFAULT '1.00', + `star_brightness` float(3,2) unsigned NOT NULL DEFAULT '0.00', + `cloud_color_r` float(3,2) unsigned NOT NULL DEFAULT '0.41', + `cloud_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.41', + `cloud_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.41', + `cloud_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.41', + `cloud_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', + `cloud_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', + `cloud_density` float(3,2) unsigned NOT NULL DEFAULT '1.00', + `cloud_coverage` float(3,2) unsigned NOT NULL DEFAULT '0.27', + `cloud_scale` float(3,2) unsigned NOT NULL DEFAULT '0.42', + `cloud_detail_x` float(3,2) unsigned NOT NULL DEFAULT '1.00', + `cloud_detail_y` float(3,2) unsigned NOT NULL DEFAULT '0.53', + `cloud_detail_density` float(3,2) unsigned NOT NULL DEFAULT '0.12', + `cloud_scroll_x` float(3,2) unsigned NOT NULL DEFAULT '0.20', + `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', + `cloud_scroll_y` float(3,2) unsigned NOT NULL DEFAULT '0.01', + `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', + `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`region_id`) +); + +COMMIT; \ No newline at end of file -- cgit v1.1 From 2a6dbd068ef48c7605f44153dcfea6b215749bed Mon Sep 17 00:00:00 2001 From: CasperW Date: Wed, 9 Dec 2009 03:58:56 +0100 Subject: Last bits and bobs to clean up the Meta7WindlightModule --- .../World/Meta7Windlight/Meta7WindlightModule.cs | 245 +++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 8 +- 2 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs new file mode 100644 index 0000000..f180b47 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs @@ -0,0 +1,245 @@ +/* + * Copyright (c) Thomas Grimshaw and Magne Metaverse Research + * + * This module is not open source. All rights reserved. + * Unauthorised copying, distribution or public display is prohibited. + * + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using OpenMetaverse; +using log4net; +using Nini.Config; +using OpenSim.Data; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.Framework.InterfaceCommander; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + + +namespace OpenSim.Region.CoreModules.World.Meta7Windlight +{ + public class Meta7WindlightModule : IRegionModule, ICommandableModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private readonly Commander m_commander = new Commander("windlight"); + private Scene m_scene; + private static bool m_enableWindlight; + + #region ICommandableModule Members + + public ICommander CommandInterface + { + get { return m_commander; } + } + + #endregion + + #region IRegionModule Members + + public static bool EnableWindlight + { + get + { + return m_enableWindlight; + } + set + { + } + } + + public void Initialise(Scene scene, IConfigSource config) + { + m_scene = scene; + m_scene.RegisterModuleInterface(this); + m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; + + // ini file settings + try + { + m_enableWindlight = config.Configs["Meta7Windlight"].GetBoolean("enable_windlight", false); + } + catch (Exception) + { + m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default"); + } + + if (m_enableWindlight) + { + m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent; + m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile; + } + + InstallCommands(); + + m_log.Debug("[WINDLIGHT]: Initialised windlight module"); + } + public void SendProfileToClient(ScenePresence presence) + { + if (m_enableWindlight) + { + if (presence.IsChildAgent == false) + { + IClientAPI client = presence.ControllingClient; + RegionMeta7WindlightData wl = m_scene.RegionInfo.WindlightSettings; + byte[] mBlock = new Byte[249]; + int pos = 0; + + wl.waterColor.ToBytes(mBlock, 0); pos += 12; + Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4; + wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4; + wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8; + wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8; + wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16; + wl.horizon.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4; + wl.blueDensity.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4; + wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4; + wl.ambient.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4; + wl.cloudColor.ToBytes(mBlock, pos); pos += 16; + wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4; + wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4; + Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2; + mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++; + mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++; + mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++; + List param = new List(); + param.Add(mBlock); + + client.SendGenericMessage("Windlight", param); + } + } + else + { + //We probably don't want to spam chat with this.. probably + //m_log.Debug("[WINDLIGHT]: Module disabled"); + } + } + private void EventManager_OnMakeRootAgent(ScenePresence presence) + { + m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client"); + SendProfileToClient(presence); + } + + private void EventManager_OnSaveNewWindlightProfile() + { + m_scene.ForEachScenePresence(SendProfileToClient); + } + + public void PostInitialise() + { + + } + + public void Close() + { + } + + public string Name + { + get { return "Meta7WindlightModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + + #endregion + + #region events + + #endregion + + #region ICommandableModule Members + + private void InstallCommands() + { + Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast"); + Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin"); + Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Enable the windlight plugin"); + + m_commander.RegisterCommand("load", wlload); + m_commander.RegisterCommand("enable", wlenable); + m_commander.RegisterCommand("disable", wldisable); + + m_scene.RegisterModuleCommander(m_commander); + } + + private void HandleLoad(Object[] args) + { + if (!m_enableWindlight) + { + m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first."); + } + else + { + m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database"); + m_scene.LoadWindlightProfile(); + m_log.InfoFormat("[WINDLIGHT]: Load complete"); + } + } + + private void HandleDisable(Object[] args) + { + m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled"); + m_enableWindlight=false; + } + + private void HandleEnable(Object[] args) + { + m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled"); + m_enableWindlight = true; + } + + /// + /// Processes commandline input. Do not call directly. + /// + /// Commandline arguments + private void EventManager_OnPluginConsole(string[] args) + { + if (args[0] == "windlight") + { + if (args.Length == 1) + { + m_commander.ProcessConsoleCommand("add", new string[0]); + return; + } + + string[] tmpArgs = new string[args.Length - 2]; + int i; + for (i = 2; i < args.Length; i++) + { + tmpArgs[i - 2] = args[i]; + } + + m_commander.ProcessConsoleCommand(args[1], tmpArgs); + } + } + #endregion + + } +} + diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 475d775..1b275b0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1504,7 +1504,7 @@ namespace OpenSim.Region.Framework.Scenes { m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); } - + public void StoreWindlightProfile(RegionMeta7WindlightData wl) { m_regInfo.WindlightSettings = wl; @@ -1512,6 +1512,12 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnSaveNewWindlightProfile(); } + public void LoadWindlightProfile() + { + m_regInfo.WindlightSettings = m_storageManager.DataStore.LoadRegionWindlightSettings(RegionInfo.RegionID); + m_eventManager.TriggerOnSaveNewWindlightProfile(); + } + /// /// Loads the World heightmap /// -- cgit v1.1 From a6a6bf007a2fb0e33daefc0ea7c4ad968a85d08e Mon Sep 17 00:00:00 2001 From: CasperW Date: Wed, 9 Dec 2009 22:57:35 +0100 Subject: Move osFunctions into a new Careminster script interface --- .../Shared/Api/Implementation/CM_Api.cs | 430 +++++++++++++++++++++ .../Shared/Api/Implementation/OSSL_Api.cs | 334 ---------------- .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 20 + .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 5 - .../Shared/Api/Runtime/CM_Constants.cs | 76 ++++ .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 71 ++++ .../Shared/Api/Runtime/LSL_Constants.cs | 38 -- .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 10 - 8 files changed, 597 insertions(+), 387 deletions(-) create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs new file mode 100644 index 0000000..4cc2f0a --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -0,0 +1,430 @@ +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Lifetime; +using OpenMetaverse; +using Nini.Config; +using OpenSim; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.World.Meta7Windlight; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Shared.Api +{ + [Serializable] + public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi + { + internal IScriptEngine m_ScriptEngine; + internal SceneObjectPart m_host; + internal uint m_localID; + internal UUID m_itemID; + internal bool m_CMFunctionsEnabled = false; + internal IScriptModuleComms m_comms = null; + + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + { + m_ScriptEngine = ScriptEngine; + m_host = host; + m_localID = localID; + m_itemID = itemID; + + if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) + m_CMFunctionsEnabled = true; + + m_comms = m_ScriptEngine.World.RequestModuleInterface(); + if (m_comms == null) + m_CMFunctionsEnabled = false; + } + + public override Object InitializeLifetimeService() + { + ILease lease = (ILease)base.InitializeLifetimeService(); + + if (lease.CurrentState == LeaseState.Initial) + { + lease.InitialLeaseTime = TimeSpan.FromMinutes(0); + // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); + // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); + } + return lease; + } + + public Scene World + { + get { return m_ScriptEngine.World; } + } + + // + //Dumps an error message on the debug console. + // + + internal void CMShoutError(string message) + { + if (message.Length > 1023) + message = message.Substring(0, 1023); + + World.SimChat(Utils.StringToBytes(message), + ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); + + IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); + wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); + } + + /// + /// Get the current Windlight scene + /// + /// List of windlight parameters + public LSL_List cmGetWindlightScene(LSL_List rules) + { + if (!m_CMFunctionsEnabled) + { + CMShoutError("Careminster functions are not enabled."); + return new LSL_List(); + } + m_host.AddScriptLPS(1); + RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_List toadd = new LSL_List(); + + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + toadd.Add(new LSL_Float(wl.blurMultiplier)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + toadd.Add(new LSL_Float(wl.cloudCoverage)); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + toadd.Add(new LSL_Float(wl.cloudScale)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + toadd.Add(new LSL_Float(wl.cloudScrollX)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + toadd.Add(new LSL_Float(wl.cloudScrollY)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + toadd.Add(new LSL_Float(wl.densityMultiplier)); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + toadd.Add(new LSL_Float(wl.distanceMultiplier)); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + toadd.Add(new LSL_Float(wl.eastAngle)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + toadd.Add(new LSL_Float(wl.fresnelOffset)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + toadd.Add(new LSL_Float(wl.fresnelScale)); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + toadd.Add(new LSL_Float(wl.hazeDensity)); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + toadd.Add(new LSL_Float(wl.hazeHorizon)); + break; + case (int)ScriptBaseClass.WL_HORIZON: + toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + toadd.Add(new LSL_Integer(wl.maxAltitude)); + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + toadd.Add(new LSL_Float(wl.refractScaleAbove)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + toadd.Add(new LSL_Float(wl.refractScaleBelow)); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + toadd.Add(new LSL_Float(wl.sceneGamma)); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + toadd.Add(new LSL_Float(wl.starBrightness)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + toadd.Add(new LSL_Float(wl.sunGlowFocus)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + toadd.Add(new LSL_Float(wl.sunGlowSize)); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + toadd.Add(new LSL_Float(wl.underwaterFogModifier)); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); + break; + } + + if (toadd.Length > 0) + { + values.Add(rule); + values.Add(toadd.Data[0]); + } + idx++; + } + + + return values; + + } + + /// + /// Set the current Windlight scene + /// + /// + /// success: true or false + public int cmSetWindlightScene(LSL_List rules) + { + if (!m_CMFunctionsEnabled) + { + CMShoutError("Careminster functions are not enabled."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (Meta7WindlightModule.EnableWindlight) + { + RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + LSL_List values = new LSL_List(); + int idx = 0; + success = 1; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_Types.Quaternion iQ; + LSL_Types.Vector3 iV; + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + idx++; + wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + idx++; + wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + idx++; + wl.cloudScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + idx++; + wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + idx++; + wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + idx++; + wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + idx++; + wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + idx++; + wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + idx++; + wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + idx++; + wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + idx++; + wl.eastAngle = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + idx++; + wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + idx++; + wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + idx++; + wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + idx++; + wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HORIZON: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + idx++; + wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + idx++; + wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + idx++; + iV = rules.GetVector3Item(idx); + wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + idx++; + wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + idx++; + wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + idx++; + wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + idx++; + wl.starBrightness = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + idx++; + wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + idx++; + wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + idx++; + wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + idx++; + iV = rules.GetVector3Item(idx); + wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + idx++; + wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); + break; + default: + success = 0; + break; + } + idx++; + } + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + + } + return success; + } + + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 33c67d5..836f276 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -42,7 +42,6 @@ using OpenSim.Region.CoreModules.Avatar.NPC; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes.Hypergrid; -using OpenSim.Region.CoreModules.World.Meta7Windlight; using OpenSim.Region.ScriptEngine.Shared; using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; using OpenSim.Region.ScriptEngine.Shared.ScriptBase; @@ -1974,338 +1973,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } return ret; } - - /// - /// Get the current Windlight scene - /// - /// List of windlight parameters - public LSL_List osGetWindlightScene(LSL_List rules) - { - CheckThreatLevel(ThreatLevel.Low, "osGetWindlightScene"); - m_host.AddScriptLPS(1); - RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_List toadd = new LSL_List(); - - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - toadd.Add(new LSL_Float(wl.blurMultiplier)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - toadd.Add(new LSL_Float(wl.cloudCoverage)); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - toadd.Add(new LSL_Float(wl.cloudScale)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - toadd.Add(new LSL_Float(wl.cloudScrollX)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - toadd.Add(new LSL_Float(wl.cloudScrollY)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - toadd.Add(new LSL_Float(wl.densityMultiplier)); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - toadd.Add(new LSL_Float(wl.distanceMultiplier)); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - toadd.Add(new LSL_Float(wl.eastAngle)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - toadd.Add(new LSL_Float(wl.fresnelOffset)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - toadd.Add(new LSL_Float(wl.fresnelScale)); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - toadd.Add(new LSL_Float(wl.hazeDensity)); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - toadd.Add(new LSL_Float(wl.hazeHorizon)); - break; - case (int)ScriptBaseClass.WL_HORIZON: - toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - toadd.Add(new LSL_Integer(wl.maxAltitude)); - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - toadd.Add(new LSL_Float(wl.refractScaleAbove)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - toadd.Add(new LSL_Float(wl.refractScaleBelow)); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - toadd.Add(new LSL_Float(wl.sceneGamma)); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - toadd.Add(new LSL_Float(wl.starBrightness)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - toadd.Add(new LSL_Float(wl.sunGlowFocus)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - toadd.Add(new LSL_Float(wl.sunGlowSize)); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - toadd.Add(new LSL_Float(wl.underwaterFogModifier)); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); - break; - } - - if (toadd.Length > 0) - { - values.Add(rule); - values.Add(toadd.Data[0]); - } - idx++; - } - - - return values; - - } - - /// - /// Set the current Windlight scene - /// - /// - /// success: true or false - public int osSetWindlightScene(LSL_List rules) - { - CheckThreatLevel(ThreatLevel.High, "osSetWindlightScene"); - int success = 0; - m_host.AddScriptLPS(1); - if (Meta7WindlightModule.EnableWindlight) - { - RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - success = 1; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_Types.Quaternion iQ; - LSL_Types.Vector3 iV; - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - idx++; - wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - idx++; - wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - idx++; - wl.cloudScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - idx++; - wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - idx++; - wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - idx++; - wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - idx++; - wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - idx++; - wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - idx++; - wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - idx++; - wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - idx++; - wl.eastAngle = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - idx++; - wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - idx++; - wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - idx++; - wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - idx++; - wl.hazeHorizon= (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HORIZON: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - idx++; - wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - idx++; - wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - idx++; - iV = rules.GetVector3Item(idx); - wl.reflectionWaveletScale= new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - idx++; - wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - idx++; - wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - idx++; - wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - idx++; - wl.starBrightness= (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - idx++; - wl.sunGlowFocus= (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - idx++; - wl.sunGlowSize= (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - idx++; - wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - idx++; - iV = rules.GetVector3Item(idx); - wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - idx++; - wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); - break; - default: - success = 0; - break; - } - idx++; - } - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - - } - return success; - } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs new file mode 100644 index 0000000..9dd0b73 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs @@ -0,0 +1,20 @@ +using System.Collections; +using OpenSim.Region.ScriptEngine.Interfaces; + +using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; + +namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces +{ + public interface ICM_Api + { + // Windlight Functions + LSL_List cmGetWindlightScene(LSL_List rules); + int cmSetWindlightScene(LSL_List rules); + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index dd2869b..c3bf7d2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -163,10 +163,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces key osGetMapTexture(); key osGetRegionMapTexture(string regionName); LSL_List osGetRegionStats(); - - // Windlight Functions - LSL_List osGetWindlightScene(LSL_List rules); - int osSetWindlightScene(LSL_List rules); - } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs new file mode 100644 index 0000000..7b67fa3 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs @@ -0,0 +1,76 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSLInteger = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; + +namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase +{ + public partial class ScriptBaseClass + { + // Constants for cmWindlight* + public const int WL_WATER_COLOR = 0; + public const int WL_WATER_FOG_DENSITY_EXPONENT = 1; + public const int WL_UNDERWATER_FOG_MODIFIER = 2; + public const int WL_REFLECTION_WAVELET_SCALE = 3; + public const int WL_FRESNEL_SCALE = 4; + public const int WL_FRESNEL_OFFSET = 5; + public const int WL_REFRACT_SCALE_ABOVE = 6; + public const int WL_REFRACT_SCALE_BELOW = 7; + public const int WL_BLUR_MULTIPLIER = 8; + public const int WL_BIG_WAVE_DIRECTION = 9; + public const int WL_LITTLE_WAVE_DIRECTION = 10; + public const int WL_NORMAL_MAP_TEXTURE = 11; + public const int WL_HORIZON = 12; + public const int WL_HAZE_HORIZON = 13; + public const int WL_BLUE_DENSITY = 14; + public const int WL_HAZE_DENSITY = 15; + public const int WL_DENSITY_MULTIPLIER = 16; + public const int WL_DISTANCE_MULTIPLIER = 17; + public const int WL_MAX_ALTITUDE = 18; + public const int WL_SUN_MOON_COLOR = 19; + public const int WL_AMBIENT = 20; + public const int WL_EAST_ANGLE = 21; + public const int WL_SUN_GLOW_FOCUS = 22; + public const int WL_SUN_GLOW_SIZE = 23; + public const int WL_SCENE_GAMMA = 24; + public const int WL_STAR_BRIGHTNESS = 25; + public const int WL_CLOUD_COLOR = 26; + public const int WL_CLOUD_XY_DENSITY = 27; + public const int WL_CLOUD_COVERAGE = 28; + public const int WL_CLOUD_SCALE = 29; + public const int WL_CLOUD_DETAIL_XY_DENSITY = 30; + public const int WL_CLOUD_SCROLL_X = 31; + public const int WL_CLOUD_SCROLL_Y = 32; + public const int WL_CLOUD_SCROLL_Y_LOCK = 33; + public const int WL_CLOUD_SCROLL_X_LOCK = 34; + public const int WL_DRAW_CLASSIC_CLOUDS = 35; + + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs new file mode 100644 index 0000000..e85d41e --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Runtime.Remoting.Lifetime; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; +using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; + +namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase +{ + public partial class ScriptBaseClass : MarshalByRefObject + { + public ICM_Api m_CM_Functions; + + public void ApiTypeCM(IScriptApi api) + { + if (!(api is ICM_Api)) + return; + + m_CM_Functions = (ICM_Api)api; + } + + public LSL_List cmGetWindlightScene(LSL_List rules) + { + return m_CM_Functions.cmGetWindlightScene(rules); + } + + public int cmSetWindlightScene(LSL_List rules) + { + return m_CM_Functions.cmSetWindlightScene(rules); + } + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 4956c28..acff8fb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -539,43 +539,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int STATS_ACTIVE_SCRIPTS = 19; public const int STATS_SCRIPT_LPS = 20; - // Constants for osWindlight* - public const int WL_WATER_COLOR = 0; - public const int WL_WATER_FOG_DENSITY_EXPONENT = 1; - public const int WL_UNDERWATER_FOG_MODIFIER = 2; - public const int WL_REFLECTION_WAVELET_SCALE = 3; - public const int WL_FRESNEL_SCALE = 4; - public const int WL_FRESNEL_OFFSET = 5; - public const int WL_REFRACT_SCALE_ABOVE = 6; - public const int WL_REFRACT_SCALE_BELOW = 7; - public const int WL_BLUR_MULTIPLIER = 8; - public const int WL_BIG_WAVE_DIRECTION = 9; - public const int WL_LITTLE_WAVE_DIRECTION = 10; - public const int WL_NORMAL_MAP_TEXTURE = 11; - public const int WL_HORIZON = 12; - public const int WL_HAZE_HORIZON = 13; - public const int WL_BLUE_DENSITY = 14; - public const int WL_HAZE_DENSITY = 15; - public const int WL_DENSITY_MULTIPLIER = 16; - public const int WL_DISTANCE_MULTIPLIER = 17; - public const int WL_MAX_ALTITUDE = 18; - public const int WL_SUN_MOON_COLOR = 19; - public const int WL_AMBIENT = 20; - public const int WL_EAST_ANGLE = 21; - public const int WL_SUN_GLOW_FOCUS = 22; - public const int WL_SUN_GLOW_SIZE = 23; - public const int WL_SCENE_GAMMA = 24; - public const int WL_STAR_BRIGHTNESS = 25; - public const int WL_CLOUD_COLOR = 26; - public const int WL_CLOUD_XY_DENSITY = 27; - public const int WL_CLOUD_COVERAGE = 28; - public const int WL_CLOUD_SCALE = 29; - public const int WL_CLOUD_DETAIL_XY_DENSITY = 30; - public const int WL_CLOUD_SCROLL_X = 31; - public const int WL_CLOUD_SCROLL_Y = 32; - public const int WL_CLOUD_SCROLL_Y_LOCK = 33; - public const int WL_CLOUD_SCROLL_X_LOCK = 34; - public const int WL_DRAW_CLASSIC_CLOUDS = 35; - } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 1480b8b..519463e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -637,15 +637,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_OSSL_Functions.osGetRegionStats(); } - - public LSL_List osGetWindlightScene(LSL_List rules) - { - return m_OSSL_Functions.osGetWindlightScene(rules); - } - - public int osSetWindlightScene(LSL_List rules) - { - return m_OSSL_Functions.osSetWindlightScene(rules); - } } } -- cgit v1.1 From 0889b5aef1b93909cb7ae5c29beb5e23bd566c47 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 10 Dec 2009 18:20:40 +0000 Subject: Fix version number --- OpenSim/Framework/Servers/VersionInfo.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index f5be1e6..d348c90 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,8 +29,8 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "112609s"; - private const Flavour VERSION_FLAVOUR = Flavour.BetaM7; + private const string VERSION_NUMBER = "0.6.9CM"; + private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour { Unknown, @@ -38,8 +38,7 @@ namespace OpenSim RC1, RC2, Release, - Post_Fixes, - BetaM7 + Post_Fixes } public static string Version -- cgit v1.1 From 5ffd59e7b870acb74ad7c6be4a1f49b62b013f21 Mon Sep 17 00:00:00 2001 From: grid Date: Thu, 10 Dec 2009 22:09:16 -0500 Subject: Kill a NRE caused by an error message trying to print unavailable data --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index e2a5406..17977f1 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -480,8 +480,8 @@ namespace OpenSim.Data.MySQL else { m_log.WarnFormat( - "[REGION DB]: Database contains an orphan child prim {0} {1} at {2} in region {3} pointing to missing parent {4}. This prim will not be loaded.", - prim.Name, prim.UUID, prim.AbsolutePosition, regionID, prim.ParentUUID); + "[REGION DB]: Database contains an orphan child prim {0} {1} in region {3} pointing to missing parent {4}. This prim will not be loaded.", + prim.Name, prim.UUID, regionID, prim.ParentUUID); } } } -- cgit v1.1 From f6b1344722908f0d14d6e30c4b01b2f712c584f2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 11 Dec 2009 02:40:33 +0000 Subject: Refix the fix --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index 17977f1..e57e929 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -480,7 +480,7 @@ namespace OpenSim.Data.MySQL else { m_log.WarnFormat( - "[REGION DB]: Database contains an orphan child prim {0} {1} in region {3} pointing to missing parent {4}. This prim will not be loaded.", + "[REGION DB]: Database contains an orphan child prim {0} {1} in region {2} pointing to missing parent {3}. This prim will not be loaded.", prim.Name, prim.UUID, regionID, prim.ParentUUID); } } -- cgit v1.1 From b9cd66d510f9229952aec5594d512faf7b60c899 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Dec 2009 13:33:45 +0000 Subject: test commit --- OpenSim/Framework/Servers/VersionInfo.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index d348c90..75e4a5d 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,6 +29,7 @@ namespace OpenSim { public class VersionInfo { + private const string VERSION_NUMBER = "0.6.9CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour -- cgit v1.1 From fbafd2212402619ec5efa66797fd42d59da1333b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Dec 2009 13:43:49 +0000 Subject: Reverse text commit whitespace change --- OpenSim/Framework/Servers/VersionInfo.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 75e4a5d..d348c90 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,6 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.9CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour -- cgit v1.1 From 794419852b793cd0be96bafb945305fadbb95b6c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Dec 2009 14:23:20 +0000 Subject: Another test --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index d348c90..714a592 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -24,7 +24,7 @@ * (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 { public class VersionInfo -- cgit v1.1 From c00158b238c863d27f1b883f2cd4e573f7036dda Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Dec 2009 14:35:12 +0000 Subject: Reverse test commit (again) --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 714a592..d348c90 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -24,7 +24,7 @@ * (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 { public class VersionInfo -- cgit v1.1 From b056c243e46daa3370f8d330b70a37b5f856e9ec Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Sat, 12 Dec 2009 10:12:59 -0500 Subject: Commit partial work because of repo change --- OpenSim/Data/SQLite/SQLiteRegionData.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 83 ++++++++++++++++++++---- 2 files changed, 73 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index f1c1f78..83fd775 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -329,7 +329,7 @@ namespace OpenSim.Data.SQLite { foreach (SceneObjectPart prim in obj.Children.Values) { - m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); +// m_log.Info("[REGION DB]: Adding obj: " + obj.UUID + " to region: " + regionUUID); addPrim(prim, obj.UUID, regionUUID); } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c553ca0..d0c20ff 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1660,16 +1660,27 @@ namespace OpenSim.Region.Framework.Scenes } // part.GetWorldRotation() is the rotation of the object being sat on // Rotation is the sittiing Av's rotation - - Quaternion wr = Quaternion.Inverse(Quaternion.Inverse(Rotation) * Quaternion.Inverse(part.GetWorldRotation())); // world or. of the av - Vector3 so = new Vector3(1.0f, 0f, 0f) * wr; // 1M infront of av - Vector3 wso = so + part.GetWorldPosition() + ( m_pos * part.GetWorldRotation()); // + av sit offset! + + Quaternion partRot; + if (part.LinkNum == 1) + { // Root prim of linkset + partRot = part.ParentGroup.RootPart.RotationOffset; + } + else + { // single or child prim + partRot = part.GetWorldRotation(); + } + Quaternion partIRot = Quaternion.Inverse(partRot); + + Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av + Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ( m_pos * partRot); // + av sit offset! if (m_physicsActor == null) { AddToPhysicalScene(false); } - AbsolutePosition = wso; //KF: Fix stand up. + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. m_parentPosition = Vector3.Zero; m_parentID = 0; part.IsOccupied = false; @@ -1752,8 +1763,17 @@ namespace OpenSim.Region.Framework.Scenes Quaternion avSitOrientation = part.SitTargetOrientation; bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. - Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); - + // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + Quaternion partRot; + if (part.LinkNum == 1) + { // Root prim of linkset + partRot = part.ParentGroup.RootPart.RotationOffset; + } + else + { // single or child prim + partRot = part.GetWorldRotation(); + } + Quaternion partIRot = Quaternion.Inverse(partRot); //Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); // Sit analysis rewritten by KF 091125 if (SitTargetisSet) // scipted sit @@ -1800,6 +1820,8 @@ namespace OpenSim.Region.Framework.Scenes cameraAtOffset = part.GetCameraAtOffset(); cameraEyeOffset = part.GetCameraEyeOffset(); forceMouselook = part.GetForceMouselook(); + if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // + if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // if (m_physicsActor != null) { @@ -1823,7 +1845,29 @@ namespace OpenSim.Region.Framework.Scenes } else return; // physactor is null! - Vector3 offsetr = offset * partIRot; + Vector3 offsetr; // = offset * partIRot; + // KF: In a linkset, offsetr needs to be relative to the group root! 091208 + // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); + if (part.LinkNum < 2) + { // Single, or Root prim of linkset, target is ClickOffset * RootRot + offsetr = offset * partIRot; + } + else + { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) + offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + + (offset * partRot); + } + +Console.WriteLine(" "); +Console.WriteLine("link number ={0}", part.LinkNum); +Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); +Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); +Console.WriteLine("Click offst ={0}", offset); +Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); +Console.WriteLine("offsetr ={0}", offsetr); +Console.WriteLine("Camera At ={0}", cameraAtOffset); +Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); + ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target // This calls HandleAgentSit twice, once from here, and the client calls @@ -2142,13 +2186,20 @@ namespace OpenSim.Region.Framework.Scenes } else { -//Console.WriteLine("NON Scripted Sit"); // if m_avUnscriptedSitPos is zero then Av sits above center // Else Av sits at m_avUnscriptedSitPos // Non-scripted sit by Kitto Flora 21Nov09 // Calculate angle of line from prim to Av - Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + Quaternion partIRot; + if (part.LinkNum == 1) + { // Root prim of linkset + partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); + } + else + { // single or child prim + partIRot = Quaternion.Inverse(part.GetWorldRotation()); + } Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); float x_diff = ( m_avInitialPos.X - sitTargetPos.X); @@ -2203,11 +2254,21 @@ namespace OpenSim.Region.Framework.Scenes // collisionPoint = spot on prim where we want to sit // collisionPoint.Z = global sit surface height SceneObjectPart part = m_scene.GetSceneObjectPart(localid); - Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + Quaternion partIRot; + if (part.LinkNum == 1) + { // Root prim of linkset + partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); + } + else + { // single or child prim + partIRot = Quaternion.Inverse(part.GetWorldRotation()); + } float offZ = collisionPoint.Z - m_initialSitTarget.Z; Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); m_pos += offset; + ControllingClient.SendClearFollowCamProperties(part.UUID); + } } // End SitAltitudeCallback KF. -- cgit v1.1 From 9904700dfdb7c6a111d9464eb23566fff73dc6b1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Dec 2009 16:00:44 +0000 Subject: Another whitespace test commit --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index d348c90..714a592 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -24,7 +24,7 @@ * (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 { public class VersionInfo -- cgit v1.1 From 30d64444a090148e5c07f27adc19ac2925533a19 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Dec 2009 16:01:53 +0000 Subject: And reverse --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 714a592..d348c90 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -24,7 +24,7 @@ * (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 { public class VersionInfo -- cgit v1.1 From b8b4517211d332f76c022075f81cfefd41877d14 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 15 Dec 2009 01:49:23 -0500 Subject: Removed excessive call to UpdateMovementAnimations which prevented GroundSit; Corrected cause of 'sit on roof'. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 48 ++++++++++++------------ 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d0c20ff..c67463a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -670,8 +670,7 @@ namespace OpenSim.Region.Framework.Scenes AdjustKnownSeeds(); - - Animator.TrySetMovementAnimation("STAND"); + Animator.TrySetMovementAnimation("STAND"); // we created a new ScenePresence (a new child agent) in a fresh region. // Request info about all the (root) agents in this region // Note: This won't send data *to* other clients in that region (children don't send) @@ -1691,7 +1690,6 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_avHeight); } } - Animator.TrySetMovementAnimation("STAND"); } @@ -1858,15 +1856,15 @@ namespace OpenSim.Region.Framework.Scenes (offset * partRot); } -Console.WriteLine(" "); -Console.WriteLine("link number ={0}", part.LinkNum); -Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); -Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); -Console.WriteLine("Click offst ={0}", offset); -Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); -Console.WriteLine("offsetr ={0}", offsetr); -Console.WriteLine("Camera At ={0}", cameraAtOffset); -Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); +//Console.WriteLine(" "); +//Console.WriteLine("link number ={0}", part.LinkNum); +//Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); +//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); +//Console.WriteLine("Click offst ={0}", offset); +//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); +//Console.WriteLine("offsetr ={0}", offsetr); +//Console.WriteLine("Camera At ={0}", cameraAtOffset); +//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target @@ -2218,7 +2216,7 @@ Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); m_avUnscriptedSitPos; // adds click offset, if any //Set up raytrace to find top surface of prim Vector3 size = part.Scale; - float mag = 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); + float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); Vector3 down = new Vector3(0f, 0f, -1f); //Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); @@ -2267,7 +2265,7 @@ Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); m_pos += offset; - ControllingClient.SendClearFollowCamProperties(part.UUID); +// ControllingClient.SendClearFollowCamProperties(part.UUID); } } // End SitAltitudeCallback KF. @@ -3297,7 +3295,7 @@ Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); m_updateflag = true; Velocity = force; m_isNudging = false; - m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" + m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" } } } @@ -3349,19 +3347,19 @@ Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); // Event called by the physics plugin to tell the avatar about a collision. private void PhysicsCollisionUpdate(EventArgs e) { - if (m_updateCount > 0) //KF: Update Anims for a short period. Many Anim - { // changes are very asynchronous. - Animator.UpdateMovementAnimations(); - m_updateCount--; - } - if (e == null) return; - - // The Physics Scene will send updates every 500 ms grep: m_physicsActor.SubscribeEvents( + + // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( // as of this comment the interval is set in AddToPhysicalScene if (Animator!=null) - Animator.UpdateMovementAnimations(); + { + if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, + { // else its will lock out other animation changes, like ground sit. + Animator.UpdateMovementAnimations(); + m_updateCount--; + } + } CollisionEventUpdate collisionData = (CollisionEventUpdate)e; Dictionary coldata = collisionData.m_objCollisionList; @@ -3370,7 +3368,7 @@ Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); if (m_lastColCount != coldata.Count) { - m_updateCount = 10; + m_updateCount = UPDATE_COUNT; m_lastColCount = coldata.Count; } -- cgit v1.1 From 7cd44c1a818615ca0e267f64c74593ad0361350b Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 15 Dec 2009 20:04:53 -0500 Subject: Fix prim linking bug, Manis #14 --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a23c11e..778e384 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -513,18 +513,24 @@ namespace OpenSim.Region.Framework.Scenes { // If this is a linkset, we don't want the physics engine mucking up our group position here. PhysicsActor actor = PhysActor; + + if (actor != null && _parentID == 0) + { + m_groupPosition = actor.Position; + } +/* if (actor != null) { if (_parentID == 0) { - m_groupPosition = actor.Position; + m_groupPosition = actor.Position; } else { m_groupPosition = ParentGroup.AbsolutePosition; // KF+Casper Update Child prims too! } } - +*/ if (IsAttachment) { ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); -- cgit v1.1 From 6483470ec5e9000fb6a85bbdfe5b79be6f336a74 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 17 Dec 2009 02:54:02 -0500 Subject: Fix GetWorldRotation(), and a host of related Sit fixes. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 73 +++++++++++----------- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 6 +- 3 files changed, 43 insertions(+), 38 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 778e384..4495eda 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1775,7 +1775,7 @@ namespace OpenSim.Region.Framework.Scenes { Quaternion newRot; - if (this.LinkNum == 0) + if (this.LinkNum < 2) //KF Single or root prim { newRot = RotationOffset; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c67463a..865f649 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1661,14 +1661,14 @@ namespace OpenSim.Region.Framework.Scenes // Rotation is the sittiing Av's rotation Quaternion partRot; - if (part.LinkNum == 1) - { // Root prim of linkset - partRot = part.ParentGroup.RootPart.RotationOffset; - } - else - { // single or child prim +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partRot = part.ParentGroup.RootPart.RotationOffset; +// } +// else +// { // single or child prim partRot = part.GetWorldRotation(); - } +// } Quaternion partIRot = Quaternion.Inverse(partRot); Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av @@ -1763,14 +1763,14 @@ namespace OpenSim.Region.Framework.Scenes bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); Quaternion partRot; - if (part.LinkNum == 1) - { // Root prim of linkset - partRot = part.ParentGroup.RootPart.RotationOffset; - } - else - { // single or child prim +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partRot = part.ParentGroup.RootPart.RotationOffset; +// } +// else +// { // single or child prim partRot = part.GetWorldRotation(); - } +// } Quaternion partIRot = Quaternion.Inverse(partRot); //Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); // Sit analysis rewritten by KF 091125 @@ -1846,15 +1846,15 @@ namespace OpenSim.Region.Framework.Scenes Vector3 offsetr; // = offset * partIRot; // KF: In a linkset, offsetr needs to be relative to the group root! 091208 // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); - if (part.LinkNum < 2) - { // Single, or Root prim of linkset, target is ClickOffset * RootRot + // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. + // { // Single, or Root prim of linkset, target is ClickOffset * RootRot offsetr = offset * partIRot; - } - else - { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) - offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + - (offset * partRot); - } +// + // else + // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) + // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + + // (offset * partRot); + // } //Console.WriteLine(" "); //Console.WriteLine("link number ={0}", part.LinkNum); @@ -2170,6 +2170,7 @@ namespace OpenSim.Region.Framework.Scenes { if (part != null) { +//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); if (part.GetAvatarOnSitTarget() == UUID) { //Console.WriteLine("Scripted Sit"); @@ -2190,14 +2191,14 @@ namespace OpenSim.Region.Framework.Scenes // Non-scripted sit by Kitto Flora 21Nov09 // Calculate angle of line from prim to Av Quaternion partIRot; - if (part.LinkNum == 1) - { // Root prim of linkset - partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); - } - else - { // single or child prim +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); +// } +// else +// { // single or child prim partIRot = Quaternion.Inverse(part.GetWorldRotation()); - } +// } Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); float x_diff = ( m_avInitialPos.X - sitTargetPos.X); @@ -2253,14 +2254,14 @@ namespace OpenSim.Region.Framework.Scenes // collisionPoint.Z = global sit surface height SceneObjectPart part = m_scene.GetSceneObjectPart(localid); Quaternion partIRot; - if (part.LinkNum == 1) - { // Root prim of linkset - partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); - } - else - { // single or child prim +// if (part.LinkNum == 1) +/// { // Root prim of linkset +// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); +// } +// else +// { // single or child prim partIRot = Quaternion.Inverse(part.GetWorldRotation()); - } +// } float offZ = collisionPoint.Z - m_initialSitTarget.Z; Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index c27c420..688be83 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2673,7 +2673,7 @@ Console.WriteLine(" JointCreateFixed"); m_lastposition = _position; m_lastorientation = _orientation; - + l_position.X = vec.X; l_position.Y = vec.Y; l_position.Z = vec.Z; @@ -2681,6 +2681,10 @@ Console.WriteLine(" JointCreateFixed"); l_orientation.Y = ori.Y; l_orientation.Z = ori.Z; l_orientation.W = ori.W; + +// if(l_position.Y != m_lastposition.Y){ +// Console.WriteLine("UP&V {0} {1}", m_primName, l_position); +// } if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) { -- cgit v1.1 From 6dbe25360ec3dc3c998378da8b422751d3e032a9 Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 17 Dec 2009 18:40:34 +0100 Subject: Add cmSetWindlightSceneTargeted. Add restrictions on windlight script use. --- OpenSim/Data/MySQL/Resources/032_RegionStore.sql | 20 +- OpenSim/Framework/RegionInfo.cs | 21 +- .../World/Meta7Windlight/Meta7WindlightModule.cs | 127 ++++--- OpenSim/Region/Framework/Scenes/EventManager.cs | 12 + OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- .../Shared/Api/Implementation/CM_Api.cs | 401 ++++++++++++--------- .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 3 +- .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 5 + 8 files changed, 344 insertions(+), 249 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/Resources/032_RegionStore.sql b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql index 0545ee1..b10ffcf 100644 --- a/OpenSim/Data/MySQL/Resources/032_RegionStore.sql +++ b/OpenSim/Data/MySQL/Resources/032_RegionStore.sql @@ -20,15 +20,15 @@ CREATE TABLE `regionwindlight` ( `little_wave_direction_x` float(3,2) NOT NULL DEFAULT '1.11', `little_wave_direction_y` float(3,2) NOT NULL DEFAULT '-1.16', `normal_map_texture` varchar(36) NOT NULL DEFAULT '822ded49-9a6c-f61c-cb89-6df54f42cdf4', - `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.26', - `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.24', - `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.33', - `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.33', + `horizon_r` float(3,2) unsigned NOT NULL DEFAULT '0.25', + `horizon_g` float(3,2) unsigned NOT NULL DEFAULT '0.25', + `horizon_b` float(3,2) unsigned NOT NULL DEFAULT '0.32', + `horizon_i` float(3,2) unsigned NOT NULL DEFAULT '0.32', `haze_horizon` float(3,2) unsigned NOT NULL DEFAULT '0.19', - `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.10', - `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.93', - `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.02', - `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.93', + `blue_density_r` float(3,2) unsigned NOT NULL DEFAULT '0.12', + `blue_density_g` float(3,2) unsigned NOT NULL DEFAULT '0.22', + `blue_density_b` float(3,2) unsigned NOT NULL DEFAULT '0.38', + `blue_density_i` float(3,2) unsigned NOT NULL DEFAULT '0.38', `haze_density` float(3,2) unsigned NOT NULL DEFAULT '0.70', `density_multiplier` float(3,2) unsigned NOT NULL DEFAULT '0.18', `distance_multiplier` float(4,1) unsigned NOT NULL DEFAULT '0.8', @@ -37,7 +37,7 @@ CREATE TABLE `regionwindlight` ( `sun_moon_color_g` float(3,2) unsigned NOT NULL DEFAULT '0.26', `sun_moon_color_b` float(3,2) unsigned NOT NULL DEFAULT '0.30', `sun_moon_color_i` float(3,2) unsigned NOT NULL DEFAULT '0.30', - `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.335', + `sun_moon_position` float(4,3) unsigned NOT NULL DEFAULT '0.317', `ambient_r` float(3,2) unsigned NOT NULL DEFAULT '0.35', `ambient_g` float(3,2) unsigned NOT NULL DEFAULT '0.35', `ambient_b` float(3,2) unsigned NOT NULL DEFAULT '0.35', @@ -63,7 +63,7 @@ CREATE TABLE `regionwindlight` ( `cloud_scroll_x_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', `cloud_scroll_y` float(3,2) unsigned NOT NULL DEFAULT '0.01', `cloud_scroll_y_lock` tinyint(1) unsigned NOT NULL DEFAULT '0', - `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '0', + `draw_classic_clouds` tinyint(1) unsigned NOT NULL DEFAULT '1', PRIMARY KEY (`region_id`) ); diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 9e00528..1ea08f9 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -38,8 +38,8 @@ using OpenSim.Framework.Console; namespace OpenSim.Framework -{ - public class RegionMeta7WindlightData +{ + public class RegionMeta7WindlightData : ICloneable { public UUID regionID = UUID.Zero; public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f); @@ -54,19 +54,19 @@ namespace OpenSim.Framework public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f); public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f); public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); - public Vector4 horizon = new Vector4(0.26f, 0.24f, 0.34f, 0.33f); + public Vector4 horizon = new Vector4(0.25f, 0.25f, 0.32f, 0.32f); public float hazeHorizon = 0.19f; - public Vector4 blueDensity = new Vector4(0.10f, 0.93f, 0.02f, 0.93f); + public Vector4 blueDensity = new Vector4(0.12f, 0.22f, 0.38f, 0.38f); public float hazeDensity = 0.70f; public float densityMultiplier = 0.18f; public float distanceMultiplier = 0.8f; public UInt16 maxAltitude = 1605; public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f); - public float sunMoonPosition = 0.335f; + public float sunMoonPosition = 0.317f; public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f); public float eastAngle = 0.0f; public float sunGlowFocus = 0.10f; - public float sunGlowSize = 0.10f; + public float sunGlowSize = 1.75f; public float sceneGamma = 1.0f; public float starBrightness = 0.0f; public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f); @@ -78,7 +78,7 @@ namespace OpenSim.Framework public bool cloudScrollXLock = false; public float cloudScrollY = 0.01f; public bool cloudScrollYLock = false; - public bool drawClassicClouds = false; + public bool drawClassicClouds = true; public delegate void SaveDelegate(RegionMeta7WindlightData wl); public event SaveDelegate OnSave; @@ -86,7 +86,12 @@ namespace OpenSim.Framework { if (OnSave != null) OnSave(this); - } + } + public object Clone() + { + return this.MemberwiseClone(); // call clone method + } + } [Serializable] diff --git a/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs index f180b47..72b0b38 100644 --- a/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs +++ b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs @@ -70,64 +70,69 @@ namespace OpenSim.Region.CoreModules.World.Meta7Windlight if (m_enableWindlight) { m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent; - m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile; + m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile; + m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted; } InstallCommands(); m_log.Debug("[WINDLIGHT]: Initialised windlight module"); + } + + private List compileWindlightSettings(RegionMeta7WindlightData wl) + { + byte[] mBlock = new Byte[249]; + int pos = 0; + + wl.waterColor.ToBytes(mBlock, 0); pos += 12; + Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4; + wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4; + wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8; + wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8; + wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16; + wl.horizon.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4; + wl.blueDensity.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4; + wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4; + wl.ambient.ToBytes(mBlock, pos); pos += 16; + Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4; + wl.cloudColor.ToBytes(mBlock, pos); pos += 16; + wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4; + wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12; + Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4; + Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4; + Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2; + mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++; + mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++; + mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++; + List param = new List(); + param.Add(mBlock); + return param; } public void SendProfileToClient(ScenePresence presence) - { + { + IClientAPI client = presence.ControllingClient; if (m_enableWindlight) { if (presence.IsChildAgent == false) - { - IClientAPI client = presence.ControllingClient; - RegionMeta7WindlightData wl = m_scene.RegionInfo.WindlightSettings; - byte[] mBlock = new Byte[249]; - int pos = 0; - - wl.waterColor.ToBytes(mBlock, 0); pos += 12; - Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4; - wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4; - wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8; - wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8; - wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16; - wl.horizon.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4; - wl.blueDensity.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4; - wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4; - wl.ambient.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4; - wl.cloudColor.ToBytes(mBlock, pos); pos += 16; - wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4; - wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4; - Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2; - mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++; - mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++; - mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++; - List param = new List(); - param.Add(mBlock); - + { + List param = compileWindlightSettings(m_scene.RegionInfo.WindlightSettings); client.SendGenericMessage("Windlight", param); } } @@ -136,13 +141,37 @@ namespace OpenSim.Region.CoreModules.World.Meta7Windlight //We probably don't want to spam chat with this.. probably //m_log.Debug("[WINDLIGHT]: Module disabled"); } + } + public void SendProfileToClient(ScenePresence presence, RegionMeta7WindlightData wl) + { + IClientAPI client = presence.ControllingClient; + if (m_enableWindlight) + { + if (presence.IsChildAgent == false) + { + List param = compileWindlightSettings(wl); + client.SendGenericMessage("Windlight", param); + } + } + else + { + //We probably don't want to spam chat with this.. probably + //m_log.Debug("[WINDLIGHT]: Module disabled"); + } } private void EventManager_OnMakeRootAgent(ScenePresence presence) { m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client"); SendProfileToClient(presence); + } + private void EventManager_OnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID pUUID) + { + ScenePresence Sc; + if (m_scene.TryGetAvatar(pUUID,out Sc)) + { + SendProfileToClient(Sc,wl); + } } - private void EventManager_OnSaveNewWindlightProfile() { m_scene.ForEachScenePresence(SendProfileToClient); diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index a86e263..68e73b1 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -194,7 +194,9 @@ namespace OpenSim.Region.Framework.Scenes public delegate void OnMakeRootAgentDelegate(ScenePresence presence); public delegate void OnSaveNewWindlightProfileDelegate(); + public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user); public event OnMakeRootAgentDelegate OnMakeRootAgent; + public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted; public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile; public delegate void NewInventoryItemUploadComplete(UUID avatarID, UUID assetID, string name, int userlevel); @@ -414,6 +416,7 @@ namespace OpenSim.Region.Framework.Scenes private ClientClosed handlerClientClosed = null; //OnClientClosed; private OnMakeChildAgentDelegate handlerMakeChildAgent = null; //OnMakeChildAgent; private OnSaveNewWindlightProfileDelegate handlerSaveNewWindlightProfile = null; //OnSaveNewWindlightProfile; + private OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = null; //OnSendNewWindlightProfileTargeted; private OnMakeRootAgentDelegate handlerMakeRootAgent = null; //OnMakeRootAgent; private OnTerrainTickDelegate handlerTerrainTick = null; // OnTerainTick; private RegisterCapsEvent handlerRegisterCaps = null; // OnRegisterCaps; @@ -775,6 +778,15 @@ namespace OpenSim.Region.Framework.Scenes } } + public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user) + { + handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted; + if (handlerSendNewWindlightProfileTargeted != null) + { + handlerSendNewWindlightProfileTargeted(wl, user); + } + } + public void TriggerOnSaveNewWindlightProfile() { handlerSaveNewWindlightProfile = OnSaveNewWindlightProfile; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 104d22b..20cae5d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1519,8 +1519,8 @@ namespace OpenSim.Region.Framework.Scenes public void SaveTerrain() { m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); - } - + } + public void StoreWindlightProfile(RegionMeta7WindlightData wl) { m_regInfo.WindlightSettings = wl; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 4cc2f0a..d4250c1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -229,8 +229,181 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return values; - } + } + + private RegionMeta7WindlightData getWindlightProfileFromRules(LSL_List rules) + { + RegionMeta7WindlightData wl = (RegionMeta7WindlightData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_Types.Quaternion iQ; + LSL_Types.Vector3 iV; + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + idx++; + wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + idx++; + wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + idx++; + wl.cloudScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + idx++; + wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + idx++; + wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + idx++; + wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + idx++; + wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + idx++; + wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + idx++; + wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + idx++; + wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + idx++; + wl.eastAngle = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + idx++; + wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + idx++; + wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + idx++; + wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + idx++; + wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HORIZON: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + idx++; + wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + idx++; + wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + idx++; + iV = rules.GetVector3Item(idx); + wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + idx++; + wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + idx++; + wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + idx++; + wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + idx++; + wl.starBrightness = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + idx++; + wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + idx++; + wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + idx++; + wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + idx++; + iV = rules.GetVector3Item(idx); + wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + idx++; + wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); + break; + } + idx++; + } + return wl; + } /// /// Set the current Windlight scene /// @@ -242,188 +415,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CMShoutError("Careminster functions are not enabled."); return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + CMShoutError("cmSetWindlightScene can only be used by estate managers or owners."); + return 0; } int success = 0; - m_host.AddScriptLPS(1); - if (Meta7WindlightModule.EnableWindlight) - { - RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - success = 1; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_Types.Quaternion iQ; - LSL_Types.Vector3 iV; - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - idx++; - wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - idx++; - wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - idx++; - wl.cloudScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - idx++; - wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - idx++; - wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - idx++; - wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - idx++; - wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - idx++; - wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - idx++; - wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - idx++; - wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - idx++; - wl.eastAngle = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - idx++; - wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - idx++; - wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - idx++; - wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - idx++; - wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HORIZON: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - idx++; - wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - idx++; - wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - idx++; - iV = rules.GetVector3Item(idx); - wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - idx++; - wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - idx++; - wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - idx++; - wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - idx++; - wl.starBrightness = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - idx++; - wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - idx++; - wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - idx++; - wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - idx++; - iV = rules.GetVector3Item(idx); - wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - idx++; - wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); - break; - default: - success = 0; - break; - } - idx++; - } - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - + m_host.AddScriptLPS(1); + if (Meta7WindlightModule.EnableWindlight) + { + RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + success = 1; + } + else + { + CMShoutError("Windlight module is disabled"); + return 0; } return success; + } + /// + /// Set the current Windlight scene to a target avatar + /// + /// + /// success: true or false + public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) + { + if (!m_CMFunctionsEnabled) + { + CMShoutError("Careminster functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (Meta7WindlightModule.EnableWindlight) + { + RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); + World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); + success = 1; + } + else + { + CMShoutError("Windlight module is disabled"); + return 0; + } + return success; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs index 9dd0b73..ef990a1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs @@ -15,6 +15,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { // Windlight Functions LSL_List cmGetWindlightScene(LSL_List rules); - int cmSetWindlightScene(LSL_List rules); + int cmSetWindlightScene(LSL_List rules); + int cmSetWindlightSceneTargeted(LSL_List rules, key target); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs index e85d41e..5bc3a88 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs @@ -66,6 +66,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public int cmSetWindlightScene(LSL_List rules) { return m_CM_Functions.cmSetWindlightScene(rules); + } + + public int cmSetWindlightSceneTargeted(LSL_List rules, key target) + { + return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target); } } } -- cgit v1.1 From e38e8ae98759e403175016260edd27772b5c9e4c Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Sat, 19 Dec 2009 19:54:44 -0500 Subject: Fix mantis #10 & #14 --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 33 +++++++--------------- 2 files changed, 11 insertions(+), 24 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index d348c90..a7d34f5 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.9CM"; + private const string VERSION_NUMBER = "0.6.91CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 778e384..0eddbfd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -513,24 +513,11 @@ namespace OpenSim.Region.Framework.Scenes { // If this is a linkset, we don't want the physics engine mucking up our group position here. PhysicsActor actor = PhysActor; - if (actor != null && _parentID == 0) { m_groupPosition = actor.Position; - } -/* - if (actor != null) - { - if (_parentID == 0) - { - m_groupPosition = actor.Position; - } - else - { - m_groupPosition = ParentGroup.AbsolutePosition; // KF+Casper Update Child prims too! - } } -*/ + if (IsAttachment) { ScenePresence sp = m_parentGroup.Scene.GetScenePresence(AttachedAvatar); @@ -545,7 +532,6 @@ namespace OpenSim.Region.Framework.Scenes StoreUndoState(); m_groupPosition = value; - PhysicsActor actor = PhysActor; if (actor != null) { @@ -1755,16 +1741,17 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 GetWorldPosition() { Quaternion parentRot = ParentGroup.RootPart.RotationOffset; - Vector3 axPos = OffsetPosition; axPos *= parentRot; Vector3 translationOffsetPosition = axPos; - - int tx = (int)GroupPosition.X; - int ty = (int)GroupPosition.Y; - int tz = (int)GroupPosition.Z; - - return GroupPosition + translationOffsetPosition; + if(_parentID == 0) + { + return GroupPosition; + } + else + { + return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position + } } /// @@ -1775,7 +1762,7 @@ namespace OpenSim.Region.Framework.Scenes { Quaternion newRot; - if (this.LinkNum == 0) + if (this.LinkNum < 2) //KF Single or root prim { newRot = RotationOffset; } -- cgit v1.1 From 31bf25d05e09395416c0427e783f8685a9e69889 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sun, 20 Dec 2009 16:18:43 +0100 Subject: Reverted my changes to jhurliman's packet stack since it currently causes more problems than it resolves. The stack DOES need a rework particularly with regards to priorities, but this is not it. --- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 27 +----- .../Region/ClientStack/LindenUDP/OpenSimUDPBase.cs | 107 +-------------------- .../Region/ClientStack/LindenUDP/OutgoingPacket.cs | 4 +- 3 files changed, 6 insertions(+), 132 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 4d9f58f..3c4fa72 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -402,7 +402,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Queue or Send OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category); - outgoingPacket.Type = type; if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket)) SendPacketFinal(outgoingPacket); @@ -514,7 +513,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP byte flags = buffer.Data[0]; bool isResend = (flags & Helpers.MSG_RESENT) != 0; bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0; - bool sendSynchronous = false; LLUDPClient udpClient = outgoingPacket.Client; if (!udpClient.IsConnected) @@ -570,28 +568,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (isReliable) Interlocked.Add(ref udpClient.UnackedBytes, outgoingPacket.Buffer.DataLength); - //Some packet types need to be sent synchonously. - //Sorry, i know it's not optimal, but until the LL client - //manages packets correctly and re-orders them as required, this is necessary. - - // Put the UDP payload on the wire - if (outgoingPacket.Type == PacketType.ImprovedTerseObjectUpdate) - { - SyncBeginPrioritySend(buffer, 2); // highest priority - } - else if (outgoingPacket.Type == PacketType.ObjectUpdate - || outgoingPacket.Type == PacketType.LayerData) - { - SyncBeginPrioritySend(buffer, 1); // medium priority - } - else - { - SyncBeginPrioritySend(buffer, 0); // normal priority - } - - //AsyncBeginSend(buffer); - + AsyncBeginSend(buffer); + // Keep track of when this packet was sent out (right now) outgoingPacket.TickCount = Environment.TickCount & Int32.MaxValue; } @@ -872,7 +851,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length); - SyncBeginPrioritySend(buffer, 1); //Setting this to a medium priority should help minimise resends + AsyncBeginSend(buffer); } private bool IsClientAuthorized(UseCircuitCodePacket useCircuitCode, out AuthenticateResponse sessionInfo) diff --git a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs index de2cd24..d2779ba 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OpenSimUDPBase.cs @@ -29,7 +29,6 @@ using System; using System.Net; using System.Net.Sockets; using System.Threading; -using System.Collections.Generic; using log4net; namespace OpenMetaverse @@ -53,30 +52,12 @@ namespace OpenMetaverse /// Local IP address to bind to in server mode protected IPAddress m_localBindAddress; - /// - /// Standard queue for our outgoing SyncBeginPrioritySend - /// - private List m_standardQueue = new List(); - - /// - /// Medium priority queue for our outgoing SyncBeginPrioritySend - /// - private List m_mediumPriorityQueue = new List(); - - /// - /// Prioritised queue for our outgoing SyncBeginPrioritySend - /// - private List m_priorityQueue = new List(); - /// UDP socket, used in either client or server mode private Socket m_udpSocket; /// Flag to process packets asynchronously or synchronously private bool m_asyncPacketHandling; - /// Are we currently sending data asynchronously? - private volatile bool m_sendingData = false; - /// The all important shutdown flag private volatile bool m_shutdownFlag = true; @@ -265,51 +246,7 @@ namespace OpenMetaverse } } - public void SyncBeginPrioritySend(UDPPacketBuffer buf, int Priority) - { - if (!m_shutdownFlag) - { - if (!m_sendingData) - { - m_sendingData = true; - try - { - AsyncBeginSend(buf); - } - catch (SocketException) { } - catch (ObjectDisposedException) { } - } - else - { - if (Priority == 2) - { - lock (m_priorityQueue) - { - m_priorityQueue.Add(buf); - } - } - else - { - if (Priority != 0) - { - lock (m_mediumPriorityQueue) - { - m_mediumPriorityQueue.Add(buf); - } - } - else - { - lock (m_standardQueue) - { - m_standardQueue.Add(buf); - } - } - } - } - } - } - - private void AsyncBeginSend(UDPPacketBuffer buf) + public void AsyncBeginSend(UDPPacketBuffer buf) { if (!m_shutdownFlag) { @@ -333,48 +270,8 @@ namespace OpenMetaverse { try { +// UDPPacketBuffer buf = (UDPPacketBuffer)result.AsyncState; m_udpSocket.EndSendTo(result); - - if (m_sendingData) - { - lock (m_priorityQueue) - { - if (m_priorityQueue.Count > 0) - { - UDPPacketBuffer buf = m_priorityQueue[0]; - m_priorityQueue.RemoveAt(0); - AsyncBeginSend(buf); - } - else - { - lock (m_mediumPriorityQueue) - { - if (m_mediumPriorityQueue.Count > 0) - { - UDPPacketBuffer buf = m_mediumPriorityQueue[0]; - m_mediumPriorityQueue.RemoveAt(0); - AsyncBeginSend(buf); - } - else - { - lock (m_standardQueue) - { - if (m_standardQueue.Count > 0) - { - UDPPacketBuffer buf = m_standardQueue[0]; - m_standardQueue.RemoveAt(0); - AsyncBeginSend(buf); - } - else - { - m_sendingData = false; - } - } - } - } - } - } - } } catch (SocketException) { } catch (ObjectDisposedException) { } diff --git a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs index 7dc42d3..1a1a1cb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/OutgoingPacket.cs @@ -28,7 +28,6 @@ using System; using OpenSim.Framework; using OpenMetaverse; -using OpenMetaverse.Packets; namespace OpenSim.Region.ClientStack.LindenUDP { @@ -53,8 +52,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public int TickCount; /// Category this packet belongs to public ThrottleOutPacketType Category; - /// The type of packet so its delivery method can be determined - public PacketType Type; + /// /// Default constructor /// -- cgit v1.1 From e3c14660478bdd3af8c792b4b6b48ffffbbe19f9 Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 21 Dec 2009 13:22:52 +0100 Subject: Fixed a nasty crash in StandUp() that occurred when the part got killed with an avatar sitting on it. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 54 ++++++++++++++++++------ 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 865f649..abdd1a0 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -118,7 +118,8 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; + private Vector3 m_lastPosition; + private Vector3 m_lastWorldPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; //private int m_lastTerseSent; @@ -1667,24 +1668,45 @@ namespace OpenSim.Region.Framework.Scenes // } // else // { // single or child prim - partRot = part.GetWorldRotation(); -// } + +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); + } + Quaternion partIRot = Quaternion.Inverse(partRot); Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ( m_pos * partRot); // + av sit offset! - if (m_physicsActor == null) - { - AddToPhysicalScene(false); + + if (m_physicsActor == null) + { + AddToPhysicalScene(false); + } + //CW: If the part isn't null then we can set the current position + if (part != null) + { + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. + part.IsOccupied = false; + } + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; } - AbsolutePosition = avWorldStandUp; //KF: Fix stand up. - m_parentPosition = Vector3.Zero; + + m_parentPosition = Vector3.Zero; m_parentID = 0; - part.IsOccupied = false; SendFullUpdateToAllClients(); m_requestedSitTargetID = 0; + if ((m_physicsActor != null) && (m_avHeight > 0)) { SetHeight(m_avHeight); @@ -1778,7 +1800,7 @@ namespace OpenSim.Region.Framework.Scenes { if (!part.IsOccupied) { -//Console.WriteLine("Scripted, unoccupied"); +//Console.WriteLine("Scripted, unoccupied"); part.SetAvatarOnSitTarget(UUID); // set that Av will be on it offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one sitOrientation = avSitOrientation; // Change rotatione to the scripted one @@ -1831,13 +1853,19 @@ namespace OpenSim.Region.Framework.Scenes // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) { - autopilot = false; // close enough + autopilot = false; // close enough + m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. + Not using the part's position because returning the AV to the last known standing + position is likely to be more friendly, isn't it? */ RemoveFromPhysicalScene(); AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target } // else the autopilot will get us close } else - { // its a scripted sit + { // its a scripted sit + m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. + I *am* using the part's position this time because we have no real idea how far away + the avatar is from the sit target. */ RemoveFromPhysicalScene(); } } -- cgit v1.1 From 69b551c51686bca58c478f517f6ccfa561ad9730 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Dec 2009 03:22:33 +0100 Subject: Allow 100ms for scripts to run attach(NULL_KEY) on detach --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f74fd5d..e875525 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -542,6 +542,18 @@ namespace OpenSim.Region.Framework.Scenes if (group.GetFromItemID() == itemID) { m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); + bool hasScripts = false; + foreach (SceneObjectPart part in group.Children) + { + if (part..Inventory.ContainsScripts()) + { + hasScripts = true; + break; + } + } + + if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event + System.Threading.Thread.Sleep(100); group.DetachToInventoryPrep(); m_log.Debug("[DETACH]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); -- cgit v1.1 From 46fea747265574bb056b8d1ffa189ec3725a7abc Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Dec 2009 03:25:09 +0100 Subject: Jumped the gun... --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index e875525..fadeaf4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -545,7 +545,7 @@ namespace OpenSim.Region.Framework.Scenes bool hasScripts = false; foreach (SceneObjectPart part in group.Children) { - if (part..Inventory.ContainsScripts()) + if (part.Inventory.ContainsScripts()) { hasScripts = true; break; -- cgit v1.1 From 49fbe0ddb429b8625682255bf0cafa9ea93d274a Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Dec 2009 03:26:47 +0100 Subject: Should not commit without compiling --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index fadeaf4..b0fb8b3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -543,7 +543,7 @@ namespace OpenSim.Region.Framework.Scenes { m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero); bool hasScripts = false; - foreach (SceneObjectPart part in group.Children) + foreach (SceneObjectPart part in group.Children.Values) { if (part.Inventory.ContainsScripts()) { -- cgit v1.1 From 0a29842caf5dbe711490b9b323ae922c418c6c30 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 22 Dec 2009 00:20:04 -0500 Subject: Include ChOdePlugin --- OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs | 58 + OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 1353 +++++++ .../Physics/ChOdePlugin/ODEDynamics.c_comments | 630 ++++ OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 673 ++++ OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 3271 +++++++++++++++++ .../ChOdePlugin/ODERayCastRequestManager.cs | 375 ++ .../Region/Physics/ChOdePlugin/OdePhysicsJoint.cs | 48 + OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 3865 ++++++++++++++++++++ .../Physics/ChOdePlugin/Tests/ODETestClass.cs | 122 + OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs | 98 + OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 21 +- OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs | 20 +- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 108 +- 13 files changed, 10524 insertions(+), 118 deletions(-) create mode 100644 OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments create mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODERayCastRequestManager.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/OdePhysicsJoint.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/Tests/ODETestClass.cs create mode 100644 OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs new file mode 100644 index 0000000..d65929a --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/AssemblyInfo.cs @@ -0,0 +1,58 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Reflection; +using System.Runtime.InteropServices; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly : AssemblyTitle("OdePlugin")] +[assembly : AssemblyDescription("")] +[assembly : AssemblyConfiguration("")] +[assembly : AssemblyCompany("http://opensimulator.org")] +[assembly : AssemblyProduct("OdePlugin")] +[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")] +[assembly : AssemblyTrademark("")] +[assembly : AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. + +[assembly : ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly : AssemblyVersion("0.6.5.*")] diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs new file mode 100644 index 0000000..aa0acb7 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -0,0 +1,1353 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using OpenMetaverse; +using Ode.NET; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using log4net; + +namespace OpenSim.Region.Physics.OdePlugin +{ + /// + /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves. + /// + + public enum dParam : int + { + LowStop = 0, + HiStop = 1, + Vel = 2, + FMax = 3, + FudgeFactor = 4, + Bounce = 5, + CFM = 6, + StopERP = 7, + StopCFM = 8, + LoStop2 = 256, + HiStop2 = 257, + Vel2 = 258, + FMax2 = 259, + StopERP2 = 7 + 256, + StopCFM2 = 8 + 256, + LoStop3 = 512, + HiStop3 = 513, + Vel3 = 514, + FMax3 = 515, + StopERP3 = 7 + 512, + StopCFM3 = 8 + 512 + } + public class OdeCharacter : PhysicsActor + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Vector3 _position; + private d.Vector3 _zeroPosition; + // private d.Matrix3 m_StandUpRotation; + private bool _zeroFlag = false; + private bool m_lastUpdateSent = false; + private Vector3 _velocity; + private Vector3 _target_velocity; + private Vector3 _acceleration; + private Vector3 m_rotationalVelocity; + private float m_mass = 80f; + public float m_density = 60f; + private bool m_pidControllerActive = true; + public float PID_D = 800.0f; + public float PID_P = 900.0f; + //private static float POSTURE_SERVO = 10000.0f; + public float CAPSULE_RADIUS = 0.37f; + public float CAPSULE_LENGTH = 2.140599f; + public float m_tensor = 3800000f; + public float heightFudgeFactor = 0.52f; + public float walkDivisor = 1.3f; + public float runDivisor = 0.8f; + private bool flying = false; + private bool m_iscolliding = false; + private bool m_iscollidingGround = false; + private bool m_wascolliding = false; + private bool m_wascollidingGround = false; + private bool m_iscollidingObj = false; + private bool m_alwaysRun = false; + private bool m_hackSentFall = false; + private bool m_hackSentFly = false; + private int m_requestedUpdateFrequency = 0; + private Vector3 m_taintPosition = Vector3.Zero; + public uint m_localID = 0; + public bool m_returnCollisions = false; + // taints and their non-tainted counterparts + public bool m_isPhysical = false; // the current physical status + public bool m_tainted_isPhysical = false; // set when the physical status is tainted (false=not existing in physics engine, true=existing) + public float MinimumGroundFlightOffset = 3f; + + private float m_tainted_CAPSULE_LENGTH; // set when the capsule length changes. + private float m_tiltMagnitudeWhenProjectedOnXYPlane = 0.1131371f; // used to introduce a fixed tilt because a straight-up capsule falls through terrain, probably a bug in terrain collider + + + private float m_buoyancy = 0f; + + // private CollisionLocker ode; + + private string m_name = String.Empty; + + private bool[] m_colliderarr = new bool[11]; + private bool[] m_colliderGroundarr = new bool[11]; + + // Default we're a Character + private CollisionCategories m_collisionCategories = (CollisionCategories.Character); + + // Default, Collide with Other Geometries, spaces, bodies and characters. + private CollisionCategories m_collisionFlags = (CollisionCategories.Geom + | CollisionCategories.Space + | CollisionCategories.Body + | CollisionCategories.Character + | CollisionCategories.Land); + public IntPtr Body = IntPtr.Zero; + private OdeScene _parent_scene; + public IntPtr Shell = IntPtr.Zero; + public IntPtr Amotor = IntPtr.Zero; + public d.Mass ShellMass; + public bool collidelock = false; + + public int m_eventsubscription = 0; + private CollisionEventUpdate CollisionEventsThisFrame = new CollisionEventUpdate(); + + // unique UUID of this character object + public UUID m_uuid; + public bool bad = false; + + public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, CollisionLocker dode, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) + { + m_uuid = UUID.Random(); + + if (pos.IsFinite()) + { + if (pos.Z > 9999999f) + { + pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + if (pos.Z < -90000f) + { + pos.Z = parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + _position = pos; + m_taintPosition.X = pos.X; + m_taintPosition.Y = pos.Y; + m_taintPosition.Z = pos.Z; + } + else + { + _position = new Vector3(((float)_parent_scene.WorldExtents.X * 0.5f), ((float)_parent_scene.WorldExtents.Y * 0.5f), parent_scene.GetTerrainHeightAtXY(128f, 128f) + 10f); + m_taintPosition.X = _position.X; + m_taintPosition.Y = _position.Y; + m_taintPosition.Z = _position.Z; + m_log.Warn("[PHYSICS]: Got NaN Position on Character Create"); + } + + _parent_scene = parent_scene; + + PID_D = pid_d; + PID_P = pid_p; + CAPSULE_RADIUS = capsule_radius; + m_tensor = tensor; + m_density = density; + heightFudgeFactor = height_fudge_factor; + walkDivisor = walk_divisor; + runDivisor = rundivisor; + + // m_StandUpRotation = + // new d.Matrix3(0.5f, 0.7071068f, 0.5f, -0.7071068f, 0f, 0.7071068f, 0.5f, -0.7071068f, + // 0.5f); + + for (int i = 0; i < 11; i++) + { + m_colliderarr[i] = false; + } + CAPSULE_LENGTH = (size.Z * 1.15f) - CAPSULE_RADIUS * 2.0f; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + m_tainted_CAPSULE_LENGTH = CAPSULE_LENGTH; + + m_isPhysical = false; // current status: no ODE information exists + m_tainted_isPhysical = true; // new tainted status: need to create ODE information + + _parent_scene.AddPhysicsActorTaint(this); + + m_name = avName; + } + + public override int PhysicsActorType + { + get { return (int) ActorTypes.Agent; } + set { return; } + } + + /// + /// If this is set, the avatar will move faster + /// + public override bool SetAlwaysRun + { + get { return m_alwaysRun; } + set { m_alwaysRun = value; } + } + + public override uint LocalID + { + set { m_localID = value; } + } + + public override bool Grabbed + { + set { return; } + } + + public override bool Selected + { + set { return; } + } + + public override float Buoyancy + { + get { return m_buoyancy; } + set { m_buoyancy = value; } + } + + public override bool FloatOnWater + { + set { return; } + } + + public override bool IsPhysical + { + get { return false; } + set { return; } + } + + public override bool ThrottleUpdates + { + get { return false; } + set { return; } + } + + public override bool Flying + { + get { return flying; } + set { flying = value; } + } + + /// + /// Returns if the avatar is colliding in general. + /// This includes the ground and objects and avatar. + /// + public override bool IsColliding + { + get { return m_iscolliding; } + set + { + int i; + int truecount = 0; + int falsecount = 0; + + if (m_colliderarr.Length >= 10) + { + for (i = 0; i < 10; i++) + { + m_colliderarr[i] = m_colliderarr[i + 1]; + } + } + m_colliderarr[10] = value; + + for (i = 0; i < 11; i++) + { + if (m_colliderarr[i]) + { + truecount++; + } + else + { + falsecount++; + } + } + + // Equal truecounts and false counts means we're colliding with something. + + if (falsecount > 1.2*truecount) + { + m_iscolliding = false; + } + else + { + m_iscolliding = true; + } + if (m_wascolliding != m_iscolliding) + { + //base.SendCollisionUpdate(new CollisionEventUpdate()); + } + m_wascolliding = m_iscolliding; + } + } + + /// + /// Returns if an avatar is colliding with the ground + /// + public override bool CollidingGround + { + get { return m_iscollidingGround; } + set + { + // Collisions against the ground are not really reliable + // So, to get a consistant value we have to average the current result over time + // Currently we use 1 second = 10 calls to this. + int i; + int truecount = 0; + int falsecount = 0; + + if (m_colliderGroundarr.Length >= 10) + { + for (i = 0; i < 10; i++) + { + m_colliderGroundarr[i] = m_colliderGroundarr[i + 1]; + } + } + m_colliderGroundarr[10] = value; + + for (i = 0; i < 11; i++) + { + if (m_colliderGroundarr[i]) + { + truecount++; + } + else + { + falsecount++; + } + } + + // Equal truecounts and false counts means we're colliding with something. + + if (falsecount > 1.2*truecount) + { + m_iscollidingGround = false; + } + else + { + m_iscollidingGround = true; + } + if (m_wascollidingGround != m_iscollidingGround) + { + //base.SendCollisionUpdate(new CollisionEventUpdate()); + } + m_wascollidingGround = m_iscollidingGround; + } + } + + /// + /// Returns if the avatar is colliding with an object + /// + public override bool CollidingObj + { + get { return m_iscollidingObj; } + set + { + m_iscollidingObj = value; + if (value) + m_pidControllerActive = false; + else + m_pidControllerActive = true; + } + } + + /// + /// turn the PID controller on or off. + /// The PID Controller will turn on all by itself in many situations + /// + /// + public void SetPidStatus(bool status) + { + m_pidControllerActive = status; + } + + public override bool Stopped + { + get { return _zeroFlag; } + } + + /// + /// This 'puts' an avatar somewhere in the physics space. + /// Not really a good choice unless you 'know' it's a good + /// spot otherwise you're likely to orbit the avatar. + /// + public override Vector3 Position + { + get { return _position; } + set + { + if (Body == IntPtr.Zero || Shell == IntPtr.Zero) + { + if (value.IsFinite()) + { + if (value.Z > 9999999f) + { + value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + if (value.Z < -90000f) + { + value.Z = _parent_scene.GetTerrainHeightAtXY(127, 127) + 5; + } + + _position.X = value.X; + _position.Y = value.Y; + _position.Z = value.Z; + + m_taintPosition.X = value.X; + m_taintPosition.Y = value.Y; + m_taintPosition.Z = value.Z; + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN Position from Scene on a Character"); + } + } + } + } + + public override Vector3 RotationalVelocity + { + get { return m_rotationalVelocity; } + set { m_rotationalVelocity = value; } + } + + /// + /// This property sets the height of the avatar only. We use the height to make sure the avatar stands up straight + /// and use it to offset landings properly + /// + public override Vector3 Size + { + get { return new Vector3(CAPSULE_RADIUS * 2, CAPSULE_RADIUS * 2, CAPSULE_LENGTH); } + set + { + if (value.IsFinite()) + { + m_pidControllerActive = true; + + Vector3 SetSize = value; + m_tainted_CAPSULE_LENGTH = (SetSize.Z*1.15f) - CAPSULE_RADIUS*2.0f; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + + Velocity = Vector3.Zero; + + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN Size from Scene on a Character"); + } + } + } + + private void AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3 movementVector) + { + movementVector.Z = 0f; + float magnitude = (float)Math.Sqrt((double)(movementVector.X * movementVector.X + movementVector.Y * movementVector.Y)); + if (magnitude < 0.1f) return; + + // normalize the velocity vector + float invMagnitude = 1.0f / magnitude; + movementVector.X *= invMagnitude; + movementVector.Y *= invMagnitude; + + // if we change the capsule heading too often, the capsule can fall down + // therefore we snap movement vector to just 1 of 4 predefined directions (ne, nw, se, sw), + // meaning only 4 possible capsule tilt orientations + if (movementVector.X > 0) + { + // east + if (movementVector.Y > 0) + { + // northeast + movementVector.X = (float)Math.Sqrt(2.0); + movementVector.Y = (float)Math.Sqrt(2.0); + } + else + { + // southeast + movementVector.X = (float)Math.Sqrt(2.0); + movementVector.Y = -(float)Math.Sqrt(2.0); + } + } + else + { + // west + if (movementVector.Y > 0) + { + // northwest + movementVector.X = -(float)Math.Sqrt(2.0); + movementVector.Y = (float)Math.Sqrt(2.0); + } + else + { + // southwest + movementVector.X = -(float)Math.Sqrt(2.0); + movementVector.Y = -(float)Math.Sqrt(2.0); + } + } + + + // movementVector.Z is zero + + // calculate tilt components based on desired amount of tilt and current (snapped) heading. + // the "-" sign is to force the tilt to be OPPOSITE the direction of movement. + float xTiltComponent = -movementVector.X * m_tiltMagnitudeWhenProjectedOnXYPlane; + float yTiltComponent = -movementVector.Y * m_tiltMagnitudeWhenProjectedOnXYPlane; + + //m_log.Debug("[PHYSICS] changing avatar tilt"); + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, xTiltComponent); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, xTiltComponent); // must be same as lowstop, else a different, spurious tilt is introduced + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, yTiltComponent); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, yTiltComponent); // same as lowstop + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + } + + /// + /// This creates the Avatar's physical Surrogate at the position supplied + /// + /// + /// + /// + + // WARNING: This MUST NOT be called outside of ProcessTaints, else we can have unsynchronized access + // to ODE internals. ProcessTaints is called from within thread-locked Simulate(), so it is the only + // place that is safe to call this routine AvatarGeomAndBodyCreation. + private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor) + { + //CAPSULE_LENGTH = -5; + //CAPSULE_RADIUS = -5; + int dAMotorEuler = 1; + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + if (CAPSULE_LENGTH <= 0) + { + m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); + CAPSULE_LENGTH = 0.01f; + + } + + if (CAPSULE_RADIUS <= 0) + { + m_log.Warn("[PHYSICS]: The capsule size you specified in opensim.ini is invalid! Setting it to the smallest possible size!"); + CAPSULE_RADIUS = 0.01f; + + } + Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); + + d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); + d.GeomSetCollideBits(Shell, (int)m_collisionFlags); + + d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH); + Body = d.BodyCreate(_parent_scene.world); + d.BodySetPosition(Body, npositionX, npositionY, npositionZ); + + _position.X = npositionX; + _position.Y = npositionY; + _position.Z = npositionZ; + + + m_taintPosition.X = npositionX; + m_taintPosition.Y = npositionY; + m_taintPosition.Z = npositionZ; + + d.BodySetMass(Body, ref ShellMass); + d.Matrix3 m_caprot; + // 90 Stand up on the cap of the capped cyllinder + if (_parent_scene.IsAvCapsuleTilted) + { + d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2)); + } + else + { + d.RFromAxisAndAngle(out m_caprot, 0, 0, 1, (float)(Math.PI / 2)); + } + + + d.GeomSetRotation(Shell, ref m_caprot); + d.BodySetRotation(Body, ref m_caprot); + + d.GeomSetBody(Shell, Body); + + + // The purpose of the AMotor here is to keep the avatar's physical + // surrogate from rotating while moving + Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + d.JointAttach(Amotor, Body, IntPtr.Zero); + d.JointSetAMotorMode(Amotor, dAMotorEuler); + d.JointSetAMotorNumAxes(Amotor, 3); + d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0); + d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0); + d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1); + d.JointSetAMotorAngle(Amotor, 0, 0); + d.JointSetAMotorAngle(Amotor, 1, 0); + d.JointSetAMotorAngle(Amotor, 2, 0); + + // These lowstops and high stops are effectively (no wiggle room) + if (_parent_scene.IsAvCapsuleTilted) + { + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f); + } + else + { + #region Documentation of capsule motor LowStop and HighStop parameters + // Intentionally introduce some tilt into the capsule by setting + // the motor stops to small epsilon values. This small tilt prevents + // the capsule from falling into the terrain; a straight-up capsule + // (with -0..0 motor stops) falls into the terrain for reasons yet + // to be comprehended in their entirety. + #endregion + AlignAvatarTiltWithCurrentDirectionOfMovement(Vector3.Zero); + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0.08f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0.08f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.08f); // must be same as lowstop, else a different, spurious tilt is introduced + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); // same as lowstop + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.08f); // same as lowstop + } + + // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the + // capped cyllinder will fall over + d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor); + + //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); + //d.QfromR( + //d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068, + // + //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); + //standupStraight(); + } + + // + /// + /// Uses the capped cyllinder volume formula to calculate the avatar's mass. + /// This may be used in calculations in the scene/scenepresence + /// + public override float Mass + { + get + { + float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH); + return m_density*AVvolume; + } + } + public override void link(PhysicsActor obj) + { + + } + + public override void delink() + { + + } + + public override void LockAngularMotion(Vector3 axis) + { + + } + +// This code is very useful. Written by DanX0r. We're just not using it right now. +// Commented out to prevent a warning. +// +// private void standupStraight() +// { +// // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air. +// // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you +// // change appearance and when you enter the simulator +// // After this routine is done, the amotor stabilizes much quicker +// d.Vector3 feet; +// d.Vector3 head; +// d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet); +// d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head); +// float posture = head.Z - feet.Z; + +// // restoring force proportional to lack of posture: +// float servo = (2.5f - posture) * POSTURE_SERVO; +// d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f); +// d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f); +// //d.Matrix3 bodyrotation = d.BodyGetRotation(Body); +// //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22); +// } + + public override Vector3 Force + { + get { return _target_velocity; } + set { return; } + } + + public override int VehicleType + { + get { return 0; } + set { return; } + } + + public override void VehicleFloatParam(int param, float value) + { + + } + + public override void VehicleVectorParam(int param, Vector3 value) + { + + } + + public override void VehicleRotationParam(int param, Quaternion rotation) + { + + } + + public override void SetVolumeDetect(int param) + { + + } + + public override Vector3 CenterOfMass + { + get { return Vector3.Zero; } + } + + public override Vector3 GeometricCenter + { + get { return Vector3.Zero; } + } + + public override PrimitiveBaseShape Shape + { + set { return; } + } + + public override Vector3 Velocity + { + get { + // There's a problem with Vector3.Zero! Don't Use it Here! + if (_zeroFlag) + return Vector3.Zero; + m_lastUpdateSent = false; + return _velocity; + } + set + { + if (value.IsFinite()) + { + m_pidControllerActive = true; + _target_velocity = value; + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN velocity from Scene in a Character"); + } + } + } + + public override Vector3 Torque + { + get { return Vector3.Zero; } + set { return; } + } + + public override float CollisionScore + { + get { return 0f; } + set { } + } + + public override bool Kinematic + { + get { return false; } + set { } + } + + public override Quaternion Orientation + { + get { return Quaternion.Identity; } + set { + //Matrix3 or = Orientation.ToRotationMatrix(); + //d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22); + //d.BodySetRotation(Body, ref ord); + } + } + + public override Vector3 Acceleration + { + get { return _acceleration; } + } + + public void SetAcceleration(Vector3 accel) + { + m_pidControllerActive = true; + _acceleration = accel; + } + + /// + /// Adds the force supplied to the Target Velocity + /// The PID controller takes this target velocity and tries to make it a reality + /// + /// + public override void AddForce(Vector3 force, bool pushforce) + { + if (force.IsFinite()) + { + if (pushforce) + { + m_pidControllerActive = false; + force *= 100f; + doForce(force); + // If uncommented, things get pushed off world + // + // m_log.Debug("Push!"); + // _target_velocity.X += force.X; + // _target_velocity.Y += force.Y; + // _target_velocity.Z += force.Z; + } + else + { + m_pidControllerActive = true; + _target_velocity.X += force.X; + _target_velocity.Y += force.Y; + _target_velocity.Z += force.Z; + } + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN force applied to a Character"); + } + //m_lastUpdateSent = false; + } + + public override void AddAngularForce(Vector3 force, bool pushforce) + { + + } + + /// + /// After all of the forces add up with 'add force' we apply them with doForce + /// + /// + public void doForce(Vector3 force) + { + if (!collidelock) + { + d.BodyAddForce(Body, force.X, force.Y, force.Z); + //d.BodySetRotation(Body, ref m_StandUpRotation); + //standupStraight(); + + } + } + + public override void SetMomentum(Vector3 momentum) + { + } + + + /// + /// Called from Simulate + /// This is the avatar's movement control + PID Controller + /// + /// + public void Move(float timeStep, List defects) + { + // no lock; for now it's only called from within Simulate() + + // If the PID Controller isn't active then we set our force + // calculating base velocity to the current position + + if (Body == IntPtr.Zero) + return; + + if (m_pidControllerActive == false) + { + _zeroPosition = d.BodyGetPosition(Body); + } + //PidStatus = true; + + d.Vector3 localpos = d.BodyGetPosition(Body); + Vector3 localPos = new Vector3(localpos.X, localpos.Y, localpos.Z); + + if (!localPos.IsFinite()) + { + + m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); + defects.Add(this); + // _parent_scene.RemoveCharacter(this); + + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) + { + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) + { + //kill the body + d.BodyDestroy(Body); + + Body = IntPtr.Zero; + } + + if (Shell != IntPtr.Zero) + { + d.GeomDestroy(Shell); + _parent_scene.geom_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } + + return; + } + + Vector3 vec = Vector3.Zero; + d.Vector3 vel = d.BodyGetLinearVel(Body); + + float movementdivisor = 1f; + + if (!m_alwaysRun) + { + movementdivisor = walkDivisor; + } + else + { + movementdivisor = runDivisor; + } + + // if velocity is zero, use position control; otherwise, velocity control + if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding) + { + // keep track of where we stopped. No more slippin' & slidin' + if (!_zeroFlag) + { + _zeroFlag = true; + _zeroPosition = d.BodyGetPosition(Body); + } + if (m_pidControllerActive) + { + // We only want to deactivate the PID Controller if we think we want to have our surrogate + // react to the physics scene by moving it's position. + // Avatar to Avatar collisions + // Prim to avatar collisions + + d.Vector3 pos = d.BodyGetPosition(Body); + vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); + vec.Y = (_target_velocity.Y - vel.Y)*(PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2); + if (flying) + { + vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; + } + } + //PidStatus = true; + } + else + { + m_pidControllerActive = true; + _zeroFlag = false; + if (m_iscolliding && !flying) + { + // We're standing on something + vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D); + vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D); + } + else if (m_iscolliding && flying) + { + // We're flying and colliding with something + vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*(PID_D / 16); + vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*(PID_D / 16); + } + else if (!m_iscolliding && flying) + { + // we're in mid air suspended + vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D/6); + vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D/6); + } + + if (m_iscolliding && !flying && _target_velocity.Z > 0.0f) + { + // We're colliding with something and we're not flying but we're moving + // This means we're walking or running. + d.Vector3 pos = d.BodyGetPosition(Body); + vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P; + if (_target_velocity.X > 0) + { + vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D; + } + if (_target_velocity.Y > 0) + { + vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D; + } + } + else if (!m_iscolliding && !flying) + { + // we're not colliding and we're not flying so that means we're falling! + // m_iscolliding includes collisions with the ground. + + // d.Vector3 pos = d.BodyGetPosition(Body); + if (_target_velocity.X > 0) + { + vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D; + } + if (_target_velocity.Y > 0) + { + vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D; + } + } + + if (flying) + { + vec.Z = (_target_velocity.Z - vel.Z) * (PID_D); + } + } + if (flying) + { + vec.Z += ((-1 * _parent_scene.gravityz)*m_mass); + + //Added for auto fly height. Kitto Flora + //d.Vector3 pos = d.BodyGetPosition(Body); + float target_altitude = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + MinimumGroundFlightOffset; + + if (_position.Z < target_altitude) + { + vec.Z += (target_altitude - _position.Z) * PID_P * 5.0f; + } + // end add Kitto Flora + } + if (vec.IsFinite()) + { + doForce(vec); + if (!_zeroFlag) + { + AlignAvatarTiltWithCurrentDirectionOfMovement(vec); + } + } + else + { + m_log.Warn("[PHYSICS]: Got a NaN force vector in Move()"); + m_log.Warn("[PHYSICS]: Avatar Position is non-finite!"); + defects.Add(this); + // _parent_scene.RemoveCharacter(this); + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) + { + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) + { + //kill the body + d.BodyDestroy(Body); + + Body = IntPtr.Zero; + } + + if (Shell != IntPtr.Zero) + { + d.GeomDestroy(Shell); + _parent_scene.geom_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } + } + } + + /// + /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. + /// + public void UpdatePositionAndVelocity() + { + // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! + d.Vector3 vec; + try + { + vec = d.BodyGetPosition(Body); + } + catch (NullReferenceException) + { + bad = true; + _parent_scene.BadCharacter(this); + vec = new d.Vector3(_position.X, _position.Y, _position.Z); + base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! + m_log.WarnFormat("[ODEPLUGIN]: Avatar Null reference for Avatar {0}, physical actor {1}", m_name, m_uuid); + } + + + // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) + if (vec.X < 0.0f) vec.X = 0.0f; + if (vec.Y < 0.0f) vec.Y = 0.0f; + if (vec.X > (int)_parent_scene.WorldExtents.X - 0.05f) vec.X = (int)_parent_scene.WorldExtents.X - 0.05f; + if (vec.Y > (int)_parent_scene.WorldExtents.Y - 0.05f) vec.Y = (int)_parent_scene.WorldExtents.Y - 0.05f; + + _position.X = vec.X; + _position.Y = vec.Y; + _position.Z = vec.Z; + + // Did we move last? = zeroflag + // This helps keep us from sliding all over + + if (_zeroFlag) + { + _velocity.X = 0.0f; + _velocity.Y = 0.0f; + _velocity.Z = 0.0f; + + // Did we send out the 'stopped' message? + if (!m_lastUpdateSent) + { + m_lastUpdateSent = true; + //base.RequestPhysicsterseUpdate(); + + } + } + else + { + m_lastUpdateSent = false; + try + { + vec = d.BodyGetLinearVel(Body); + } + catch (NullReferenceException) + { + vec.X = _velocity.X; + vec.Y = _velocity.Y; + vec.Z = _velocity.Z; + } + _velocity.X = (vec.X); + _velocity.Y = (vec.Y); + + _velocity.Z = (vec.Z); + + if (_velocity.Z < -6 && !m_hackSentFall) + { + m_hackSentFall = true; + m_pidControllerActive = false; + } + else if (flying && !m_hackSentFly) + { + //m_hackSentFly = true; + //base.SendCollisionUpdate(new CollisionEventUpdate()); + } + else + { + m_hackSentFly = false; + m_hackSentFall = false; + } + } + } + + /// + /// Cleanup the things we use in the scene. + /// + public void Destroy() + { + m_tainted_isPhysical = false; + _parent_scene.AddPhysicsActorTaint(this); + } + + public override void CrossingFailure() + { + } + + public override Vector3 PIDTarget { set { return; } } + public override bool PIDActive { set { return; } } + public override float PIDTau { set { return; } } + + public override float PIDHoverHeight { set { return; } } + public override bool PIDHoverActive { set { return; } } + public override PIDHoverType PIDHoverType { set { return; } } + public override float PIDHoverTau { set { return; } } + + public override Quaternion APIDTarget{ set { return; } } + + public override bool APIDActive{ set { return; } } + + public override float APIDStrength{ set { return; } } + + public override float APIDDamping{ set { return; } } + + + public override void SubscribeEvents(int ms) + { + m_requestedUpdateFrequency = ms; + m_eventsubscription = ms; + _parent_scene.addCollisionEventReporting(this); + } + public override void UnSubscribeEvents() + { + _parent_scene.remCollisionEventReporting(this); + m_requestedUpdateFrequency = 0; + m_eventsubscription = 0; + } + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) + { + if (m_eventsubscription > 0) + { + CollisionEventsThisFrame.addCollider(CollidedWith, contact); + } + } + + public void SendCollisions() + { + if (m_eventsubscription > m_requestedUpdateFrequency) + { + if (CollisionEventsThisFrame != null) + { + base.SendCollisionUpdate(CollisionEventsThisFrame); + } + CollisionEventsThisFrame = new CollisionEventUpdate(); + m_eventsubscription = 0; + } + } + public override bool SubscribedEvents() + { + if (m_eventsubscription > 0) + return true; + return false; + } + + public void ProcessTaints(float timestep) + { + + if (m_tainted_isPhysical != m_isPhysical) + { + if (m_tainted_isPhysical) + { + // Create avatar capsule and related ODE data + if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) + { + m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " + + (Shell!=IntPtr.Zero ? "Shell ":"") + + (Body!=IntPtr.Zero ? "Body ":"") + + (Amotor!=IntPtr.Zero ? "Amotor ":"")); + } + AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); + + _parent_scene.geom_name_map[Shell] = m_name; + _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; + _parent_scene.AddCharacter(this); + } + else + { + _parent_scene.RemoveCharacter(this); + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) + { + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) + { + //kill the body + d.BodyDestroy(Body); + + Body = IntPtr.Zero; + } + + if (Shell != IntPtr.Zero) + { + d.GeomDestroy(Shell); + _parent_scene.geom_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } + + } + + m_isPhysical = m_tainted_isPhysical; + } + + if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) + { + if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) + { + + m_pidControllerActive = true; + // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() + d.JointDestroy(Amotor); + float prevCapsule = CAPSULE_LENGTH; + CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + d.BodyDestroy(Body); + d.GeomDestroy(Shell); + AvatarGeomAndBodyCreation(_position.X, _position.Y, + _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); + Velocity = Vector3.Zero; + + _parent_scene.geom_name_map[Shell] = m_name; + _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; + } + else + { + m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " + + (Shell==IntPtr.Zero ? "Shell ":"") + + (Body==IntPtr.Zero ? "Body ":"") + + (Amotor==IntPtr.Zero ? "Amotor ":"")); + } + } + + if (!m_taintPosition.ApproxEquals(_position, 0.05f)) + { + if (Body != IntPtr.Zero) + { + d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); + + _position.X = m_taintPosition.X; + _position.Y = m_taintPosition.Y; + _position.Z = m_taintPosition.Z; + } + } + + } + + internal void AddCollisionFrameTime(int p) + { + // protect it from overflow crashing + if (m_eventsubscription + p >= int.MaxValue) + m_eventsubscription = 0; + m_eventsubscription += p; + } + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments new file mode 100644 index 0000000..1060aa6 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments @@ -0,0 +1,630 @@ +/* + * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + * + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using log4net; +using OpenMetaverse; +using Ode.NET; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.OdePlugin +{ + public class ODEDynamics + { + public Vehicle Type + { + get { return m_type; } + } + + public IntPtr Body + { + get { return m_body; } + } + + private int frcount = 0; // Used to limit dynamics debug output to + // every 100th frame + + // private OdeScene m_parentScene = null; + private IntPtr m_body = IntPtr.Zero; + private IntPtr m_jointGroup = IntPtr.Zero; + private IntPtr m_aMotor = IntPtr.Zero; + + + // Vehicle properties + private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind + // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier + private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: + // HOVER_TERRAIN_ONLY + // HOVER_GLOBAL_HEIGHT + // NO_DEFLECTION_UP + // HOVER_WATER_ONLY + // HOVER_UP_ONLY + // LIMIT_MOTOR_UP + // LIMIT_ROLL_ONLY + + // Linear properties + private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time + private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL + private Vector3 m_dir = Vector3.Zero; // velocity applied to body + private Vector3 m_linearFrictionTimescale = Vector3.Zero; + private float m_linearMotorDecayTimescale = 0; + private float m_linearMotorTimescale = 0; + private Vector3 m_lastLinearVelocityVector = Vector3.Zero; + // private bool m_LinearMotorSetLastFrame = false; + // private Vector3 m_linearMotorOffset = Vector3.Zero; + + //Angular properties + private Vector3 m_angularMotorDirection = Vector3.Zero; + private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero; + private Vector3 m_angularFrictionTimescale = Vector3.Zero; + private float m_angularMotorDecayTimescale = 0; + private float m_angularMotorTimescale = 0; + private Vector3 m_lastAngularVelocityVector = Vector3.Zero; + + //Deflection properties + // private float m_angularDeflectionEfficiency = 0; + // private float m_angularDeflectionTimescale = 0; + // private float m_linearDeflectionEfficiency = 0; + // private float m_linearDeflectionTimescale = 0; + + //Banking properties + // private float m_bankingEfficiency = 0; + // private float m_bankingMix = 0; + // private float m_bankingTimescale = 0; + + //Hover and Buoyancy properties + private float m_VhoverHeight = 0f; + private float m_VhoverEfficiency = 0f; + private float m_VhoverTimescale = 0f; + private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height + private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. + // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + + //Attractor properties + private float m_verticalAttractionEfficiency = 0; + private float m_verticalAttractionTimescale = 0; + + + + + + internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) + { + switch (pParam) + { + case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionEfficiency = pValue; + break; + case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorDecayTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorTimescale = pValue; + break; + case Vehicle.BANKING_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingEfficiency = pValue; + break; + case Vehicle.BANKING_MIX: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingMix = pValue; + break; + case Vehicle.BANKING_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingTimescale = pValue; + break; + case Vehicle.BUOYANCY: + if (pValue < -1f) pValue = -1f; + if (pValue > 1f) pValue = 1f; + m_VehicleBuoyancy = pValue; + break; + case Vehicle.HOVER_EFFICIENCY: + if (pValue < 0f) pValue = 0f; + if (pValue > 1f) pValue = 1f; + m_VhoverEfficiency = pValue; + break; + case Vehicle.HOVER_HEIGHT: + m_VhoverHeight = pValue; + break; + case Vehicle.HOVER_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_VhoverTimescale = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionEfficiency = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorDecayTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorTimescale = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: + if (pValue < 0.0f) pValue = 0.0f; + if (pValue > 1.0f) pValue = 1.0f; + m_verticalAttractionEfficiency = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_verticalAttractionTimescale = pValue; + break; + + // These are vector properties but the engine lets you use a single float value to + // set all of the components to the same value + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue, pValue, pValue); + m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue, pValue, pValue); + m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); + break; + + } + + }//end ProcessFloatVehicleParam + + internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue) + { + switch (pParam) + { + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + } + + }//end ProcessVectorVehicleParam + + internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) + { + switch (pParam) + { + case Vehicle.REFERENCE_FRAME: + // m_referenceFrame = pValue; + break; + } + + }//end ProcessRotationVehicleParam + + internal void ProcessTypeChange(Vehicle pType) + { +Console.WriteLine("ProcessTypeChange to " + pType); + + // Set Defaults For Type + m_type = pType; + switch (pType) + { + case Vehicle.TYPE_SLED: + m_linearFrictionTimescale = new Vector3(30, 1, 1000); + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1000; + m_linearMotorDecayTimescale = 120; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1000; + m_angularMotorDecayTimescale = 120; + m_VhoverHeight = 0; + m_VhoverEfficiency = 1; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 1; + // m_linearDeflectionTimescale = 1; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 1000; + // m_bankingEfficiency = 0; + // m_bankingMix = 1; + // m_bankingTimescale = 10; + // m_referenceFrame = Quaternion.Identity; + m_flags &= + ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_CAR: + m_linearFrictionTimescale = new Vector3(100, 2, 1000); + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1; + m_angularMotorDecayTimescale = 0.8f; + m_VhoverHeight = 0; + m_VhoverEfficiency = 0; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // // m_linearDeflectionEfficiency = 1; + // // m_linearDeflectionTimescale = 2; + // // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 10; + m_verticalAttractionEfficiency = 1; + m_verticalAttractionTimescale = 10; + // m_bankingEfficiency = -0.2f; + // m_bankingMix = 1; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_BOAT: + m_linearFrictionTimescale = new Vector3(10, 3, 2); + m_angularFrictionTimescale = new Vector3(10,10,10); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; + m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 2; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 0.5f; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 0.5f; + m_verticalAttractionTimescale = 5; + // m_bankingEfficiency = -0.3f; + // m_bankingMix = 0.8f; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_AIRPLANE: + m_linearFrictionTimescale = new Vector3(200, 10, 5); + m_angularFrictionTimescale = new Vector3(20, 20, 20); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 2; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; + m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 2; + m_verticalAttractionEfficiency = 0.9f; + m_verticalAttractionTimescale = 2; + // m_bankingEfficiency = 1; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 2; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); + break; + case Vehicle.TYPE_BALLOON: + m_linearFrictionTimescale = new Vector3(5, 5, 5); + m_angularFrictionTimescale = new Vector3(10, 10, 10); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 6; + m_angularMotorDecayTimescale = 10; + m_VhoverHeight = 5; + m_VhoverEfficiency = 0.8f; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0; + // m_linearDeflectionTimescale = 5; + // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 1; + m_verticalAttractionTimescale = 1000; + // m_bankingEfficiency = 0; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 5; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + break; + + } + }//end SetDefaultsForType + + internal void Enable(IntPtr pBody, OdeScene pParentScene) + { +//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy); + if (m_type == Vehicle.TYPE_NONE) + return; + + m_body = pBody; + //KF: This used to set up the linear and angular joints + } + + internal void Step(float pTimestep, OdeScene pParentScene) + { + if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) + return; + frcount++; // used to limit debug comment output + if (frcount > 100) + frcount = 0; + + MoveLinear(pTimestep, pParentScene); + MoveAngular(pTimestep); + }// end Step + + private void MoveLinear(float pTimestep, OdeScene _pParentScene) + { + if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + + // add drive to body + Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); + m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? + + // This will work temporarily, but we really need to compare speed on an axis + // KF: Limit body velocity to applied velocity? + if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) + m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; + if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) + m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; + if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) + m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; + + // decay applied velocity + Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); + //Console.WriteLine("decay: " + decayfraction); + m_linearMotorDirection -= m_linearMotorDirection * decayfraction; + //Console.WriteLine("actual: " + m_linearMotorDirection); + } + else + { // requested is not significant + // if what remains of applied is small, zero it. + if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) + m_lastLinearVelocityVector = Vector3.Zero; + } + + + // convert requested object velocity to world-referenced vector + m_dir = m_lastLinearVelocityVector; + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object + m_dir *= rotq; // apply obj rotation to velocity vector + + // add Gravity andBuoyancy + // KF: So far I have found no good method to combine a script-requested + // .Z velocity and gravity. Therefore only 0g will used script-requested + // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. + Vector3 grav = Vector3.Zero; + if(m_VehicleBuoyancy < 1.0f) + { + // There is some gravity, make a gravity force vector + // that is applied after object velocity. + d.Mass objMass; + d.BodyGetMass(Body, out objMass); + // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; + grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); + // Preserve the current Z velocity + d.Vector3 vel_now = d.BodyGetLinearVel(Body); + m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity + } // else its 1.0, no gravity. + + // Check if hovering + if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) + { + // We should hover, get the target height + d.Vector3 pos = d.BodyGetPosition(Body); + if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) + { + m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; + } + else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) + { + m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; + } + else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) + { + m_VhoverTargetHeight = m_VhoverHeight; + } + + if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) + { + // If body is aready heigher, use its height as target height + if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; + } + +// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped +// m_VhoverTimescale = 0f; // time to acheive height +// pTimestep is time since last frame,in secs + float herr0 = pos.Z - m_VhoverTargetHeight; +//if(frcount == 0) Console.WriteLine("herr0=" + herr0); + // Replace Vertical speed with correction figure if significant + if(Math.Abs(herr0) > 0.01f ) + { + d.Mass objMass; + d.BodyGetMass(Body, out objMass); + m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); + // m_VhoverEfficiency is not yet implemented + } + else + { + m_dir.Z = 0f; + } + } + + // Apply velocity + d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); +//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z); + // apply gravity force + d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); +//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z); + + + // apply friction + Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); + m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; + } // end MoveLinear() + + private void MoveAngular(float pTimestep) + { + + // m_angularMotorDirection is the latest value from the script, and is decayed here + // m_angularMotorDirectionLASTSET is the latest value from the script + // m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here + + if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + // ramp up to new value + Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep); + m_lastAngularVelocityVector += (addAmount * 10f); +//if(frcount == 0) Console.WriteLine("add: " + addAmount); + + // limit applied value to what was set by script + // This will work temporarily, but we really need to compare speed on an axis + if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X)) + m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X; + if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y)) + m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y; + if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z)) + m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z; + + // decay the requested value + Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep))); + //Console.WriteLine("decay: " + decayfraction); + m_angularMotorDirection -= m_angularMotorDirection * decayfraction; + //Console.WriteLine("actual: " + m_linearMotorDirection); + } + // KF: m_lastAngularVelocityVector is rotational speed in rad/sec ? + + // Vertical attractor section + +// d.Mass objMass; +// d.BodyGetMass(Body, out objMass); +// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep); + float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep); + // get present body rotation + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); + // make a vector pointing up + Vector3 verterr = Vector3.Zero; + verterr.Z = 1.0f; + // rotate it to Body Angle + verterr = verterr * rotq; + // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. + // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go + // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. + if (verterr.Z < 0.0f) + { + verterr.X = 2.0f - verterr.X; + verterr.Y = 2.0f - verterr.Y; + } + // Error is 0 (no error) to +/- 2 (max error) + // scale it by servo + verterr = verterr * servo; + + // rotate to object frame + // verterr = verterr * rotq; + + // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so + // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. + m_lastAngularVelocityVector.X += verterr.Y; + m_lastAngularVelocityVector.Y -= verterr.X; +/* +if(frcount == 0) + { +// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector); + Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}", + Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency)); + } + */ + d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z); + // apply friction + Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); + m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount; + + } //end MoveAngular + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs new file mode 100644 index 0000000..78b15be --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -0,0 +1,673 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + * + */ + +/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using log4net; +using OpenMetaverse; +using Ode.NET; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.OdePlugin +{ + public class ODEDynamics + { + public Vehicle Type + { + get { return m_type; } + } + + public IntPtr Body + { + get { return m_body; } + } + + private int frcount = 0; // Used to limit dynamics debug output to + // every 100th frame + + // private OdeScene m_parentScene = null; + private IntPtr m_body = IntPtr.Zero; +// private IntPtr m_jointGroup = IntPtr.Zero; +// private IntPtr m_aMotor = IntPtr.Zero; + + + // Vehicle properties + private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind + // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier + private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: + // HOVER_TERRAIN_ONLY + // HOVER_GLOBAL_HEIGHT + // NO_DEFLECTION_UP + // HOVER_WATER_ONLY + // HOVER_UP_ONLY + // LIMIT_MOTOR_UP + // LIMIT_ROLL_ONLY + + // Linear properties + private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time + private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL + private Vector3 m_dir = Vector3.Zero; // velocity applied to body + private Vector3 m_linearFrictionTimescale = Vector3.Zero; + private float m_linearMotorDecayTimescale = 0; + private float m_linearMotorTimescale = 0; + private Vector3 m_lastLinearVelocityVector = Vector3.Zero; + // private bool m_LinearMotorSetLastFrame = false; + // private Vector3 m_linearMotorOffset = Vector3.Zero; + + //Angular properties + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + private int m_angularMotorApply = 0; // application frame counter + private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity + private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate + private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate + private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + // private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body + + //Deflection properties + // private float m_angularDeflectionEfficiency = 0; + // private float m_angularDeflectionTimescale = 0; + // private float m_linearDeflectionEfficiency = 0; + // private float m_linearDeflectionTimescale = 0; + + //Banking properties + // private float m_bankingEfficiency = 0; + // private float m_bankingMix = 0; + // private float m_bankingTimescale = 0; + + //Hover and Buoyancy properties + private float m_VhoverHeight = 0f; +// private float m_VhoverEfficiency = 0f; + private float m_VhoverTimescale = 0f; + private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height + private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. + // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + + //Attractor properties + private float m_verticalAttractionEfficiency = 1.0f; // damped + private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + + + + + + internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) + { + switch (pParam) + { + case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionEfficiency = pValue; + break; + case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorDecayTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorTimescale = pValue; + break; + case Vehicle.BANKING_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingEfficiency = pValue; + break; + case Vehicle.BANKING_MIX: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingMix = pValue; + break; + case Vehicle.BANKING_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingTimescale = pValue; + break; + case Vehicle.BUOYANCY: + if (pValue < -1f) pValue = -1f; + if (pValue > 1f) pValue = 1f; + m_VehicleBuoyancy = pValue; + break; +// case Vehicle.HOVER_EFFICIENCY: +// if (pValue < 0f) pValue = 0f; +// if (pValue > 1f) pValue = 1f; +// m_VhoverEfficiency = pValue; +// break; + case Vehicle.HOVER_HEIGHT: + m_VhoverHeight = pValue; + break; + case Vehicle.HOVER_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_VhoverTimescale = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionEfficiency = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorDecayTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorTimescale = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: + if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable + if (pValue > 1.0f) pValue = 1.0f; + m_verticalAttractionEfficiency = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_verticalAttractionTimescale = pValue; + break; + + // These are vector properties but the engine lets you use a single float value to + // set all of the components to the same value + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue, pValue, pValue); + m_angularMotorApply = 10; + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue, pValue, pValue); + m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); + break; + + } + + }//end ProcessFloatVehicleParam + + internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) + { + switch (pParam) + { + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + // Limit requested angular speed to 2 rps= 4 pi rads/sec + if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; + if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; + if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; + if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; + if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; + if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; + m_angularMotorApply = 10; + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + } + + }//end ProcessVectorVehicleParam + + internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) + { + switch (pParam) + { + case Vehicle.REFERENCE_FRAME: + // m_referenceFrame = pValue; + break; + } + + }//end ProcessRotationVehicleParam + + internal void ProcessTypeChange(Vehicle pType) + { + // Set Defaults For Type + m_type = pType; + switch (pType) + { + case Vehicle.TYPE_SLED: + m_linearFrictionTimescale = new Vector3(30, 1, 1000); + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1000; + m_linearMotorDecayTimescale = 120; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1000; + m_angularMotorDecayTimescale = 120; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 1; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 1; + // m_linearDeflectionTimescale = 1; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 1000; + // m_bankingEfficiency = 0; + // m_bankingMix = 1; + // m_bankingTimescale = 10; + // m_referenceFrame = Quaternion.Identity; + m_flags &= + ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_CAR: + m_linearFrictionTimescale = new Vector3(100, 2, 1000); + m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 1; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 1; + m_angularMotorDecayTimescale = 0.8f; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // // m_linearDeflectionEfficiency = 1; + // // m_linearDeflectionTimescale = 2; + // // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 10; + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 10f; + // m_bankingEfficiency = -0.2f; + // m_bankingMix = 1; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_BOAT: + m_linearFrictionTimescale = new Vector3(10, 3, 2); + m_angularFrictionTimescale = new Vector3(10,10,10); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 2; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 0.5f; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 0.5f; + m_verticalAttractionTimescale = 5f; + // m_bankingEfficiency = -0.3f; + // m_bankingMix = 0.8f; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_AIRPLANE: + m_linearFrictionTimescale = new Vector3(200, 10, 5); + m_angularFrictionTimescale = new Vector3(20, 20, 20); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 2; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 2; + m_verticalAttractionEfficiency = 0.9f; + m_verticalAttractionTimescale = 2f; + // m_bankingEfficiency = 1; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 2; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); + break; + case Vehicle.TYPE_BALLOON: + m_linearFrictionTimescale = new Vector3(5, 5, 5); + m_angularFrictionTimescale = new Vector3(10, 10, 10); + m_linearMotorDirection = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorTimescale = 6; + m_angularMotorDecayTimescale = 10; + m_VhoverHeight = 5; +// m_VhoverEfficiency = 0.8f; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0; + // m_linearDeflectionTimescale = 5; + // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 100f; + // m_bankingEfficiency = 0; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 5; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + break; + + } + }//end SetDefaultsForType + + internal void Enable(IntPtr pBody, OdeScene pParentScene) + { + if (m_type == Vehicle.TYPE_NONE) + return; + + m_body = pBody; + } + + internal void Step(float pTimestep, OdeScene pParentScene) + { + if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) + return; + frcount++; // used to limit debug comment output + if (frcount > 100) + frcount = 0; + + MoveLinear(pTimestep, pParentScene); + MoveAngular(pTimestep); + }// end Step + + private void MoveLinear(float pTimestep, OdeScene _pParentScene) + { + if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + + // add drive to body + Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); + m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? + + // This will work temporarily, but we really need to compare speed on an axis + // KF: Limit body velocity to applied velocity? + if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) + m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; + if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) + m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; + if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) + m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; + + // decay applied velocity + Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); + //Console.WriteLine("decay: " + decayfraction); + m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; + //Console.WriteLine("actual: " + m_linearMotorDirection); + } + else + { // requested is not significant + // if what remains of applied is small, zero it. + if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) + m_lastLinearVelocityVector = Vector3.Zero; + } + + + // convert requested object velocity to world-referenced vector + m_dir = m_lastLinearVelocityVector; + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object + m_dir *= rotq; // apply obj rotation to velocity vector + + // add Gravity and Buoyancy + // KF: So far I have found no good method to combine a script-requested + // .Z velocity and gravity. Therefore only 0g will used script-requested + // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. + Vector3 grav = Vector3.Zero; + if(m_VehicleBuoyancy < 1.0f) + { + // There is some gravity, make a gravity force vector + // that is applied after object velocity. + d.Mass objMass; + d.BodyGetMass(Body, out objMass); + // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; + grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); + // Preserve the current Z velocity + d.Vector3 vel_now = d.BodyGetLinearVel(Body); + m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity + } // else its 1.0, no gravity. + + // Check if hovering + if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) + { + // We should hover, get the target height + d.Vector3 pos = d.BodyGetPosition(Body); + if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) + { + m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; + } + else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) + { + m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; + } + else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) + { + m_VhoverTargetHeight = m_VhoverHeight; + } + + if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) + { + // If body is aready heigher, use its height as target height + if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; + } + +// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped +// m_VhoverTimescale = 0f; // time to acheive height +// pTimestep is time since last frame,in secs + float herr0 = pos.Z - m_VhoverTargetHeight; + // Replace Vertical speed with correction figure if significant + if(Math.Abs(herr0) > 0.01f ) + { + d.Mass objMass; + d.BodyGetMass(Body, out objMass); + m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); + //KF: m_VhoverEfficiency is not yet implemented + } + else + { + m_dir.Z = 0f; + } + } + + // Apply velocity + d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); + // apply gravity force + d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); + + + // apply friction + Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); + m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; + } // end MoveLinear() + + private void MoveAngular(float pTimestep) + { + /* + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + private int m_angularMotorApply = 0; // application frame counter + private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down) + private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate + private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate + private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + */ +//if(frcount == 0) Console.WriteLine("MoveAngular "); + + // Get what the body is doing, this includes 'external' influences + d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); + // Vector3 angularVelocity = Vector3.Zero; + + if (m_angularMotorApply > 0) + { + // ramp up to new value + // current velocity += error / ( time to get there / step interval ) + // requested speed - last motor speed + m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); + m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); + m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); + + m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected + // velocity may still be acheived. + } + else + { + // no motor recently applied, keep the body velocity + /* m_angularMotorVelocity.X = angularVelocity.X; + m_angularMotorVelocity.Y = angularVelocity.Y; + m_angularMotorVelocity.Z = angularVelocity.Z; */ + + // and decay the velocity + m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); + } // end motor section + + + // Vertical attractor section + Vector3 vertattr = Vector3.Zero; + + if(m_verticalAttractionTimescale < 300) + { + float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); + // get present body rotation + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); + // make a vector pointing up + Vector3 verterr = Vector3.Zero; + verterr.Z = 1.0f; + // rotate it to Body Angle + verterr = verterr * rotq; + // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. + // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go + // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. + if (verterr.Z < 0.0f) + { + verterr.X = 2.0f - verterr.X; + verterr.Y = 2.0f - verterr.Y; + } + // Error is 0 (no error) to +/- 2 (max error) + // scale it by VAservo + verterr = verterr * VAservo; +//if(frcount == 0) Console.WriteLine("VAerr=" + verterr); + + // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so + // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. + vertattr.X = verterr.Y; + vertattr.Y = - verterr.X; + vertattr.Z = 0f; + + // scaling appears better usingsquare-law + float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); + vertattr.X += bounce * angularVelocity.X; + vertattr.Y += bounce * angularVelocity.Y; + + } // else vertical attractor is off + + // m_lastVertAttractor = vertattr; + + // Bank section tba + // Deflection section tba + + // Sum velocities + m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection + + if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + } + else + { + m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. + } + + // apply friction + Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); + m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; + + // Apply to the body + d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); + + } //end MoveAngular + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs new file mode 100644 index 0000000..983431d --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -0,0 +1,3271 @@ +/* Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + */ + +/* + * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces + * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: + * ODEPrim.cs contains methods dealing with Prim editing, Prim + * characteristics and Kinetic motion. + * ODEDynamics.cs contains methods dealing with Prim Physical motion + * (dynamics) and the associated settings. Old Linear and angular + * motors for dynamic motion have been replace with MoveLinear() + * and MoveAngular(); 'Physical' is used only to switch ODE dynamic + * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to + * switch between 'VEHICLE' parameter use and general dynamics + * settings use. + */ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; +using log4net; +using OpenMetaverse; +using Ode.NET; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; + +namespace OpenSim.Region.Physics.OdePlugin +{ + /// + /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves. + /// + + public class OdePrim : PhysicsActor + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Vector3 _position; + private Vector3 _velocity; + private Vector3 _torque; + private Vector3 m_lastVelocity; + private Vector3 m_lastposition; + private Quaternion m_lastorientation = new Quaternion(); + private Vector3 m_rotationalVelocity; + private Vector3 _size; + private Vector3 _acceleration; + // private d.Vector3 _zeroPosition = new d.Vector3(0.0f, 0.0f, 0.0f); + private Quaternion _orientation; + private Vector3 m_taintposition; + private Vector3 m_taintsize; + private Vector3 m_taintVelocity; + private Vector3 m_taintTorque; + private Quaternion m_taintrot; + private Vector3 m_angularlock = Vector3.One; + private Vector3 m_taintAngularLock = Vector3.One; + private IntPtr Amotor = IntPtr.Zero; + + private Vector3 m_PIDTarget; + private float m_PIDTau; + private float PID_D = 35f; + private float PID_G = 25f; + private bool m_usePID = false; + + private Quaternion m_APIDTarget = new Quaternion(); + private float m_APIDStrength = 0.5f; + private float m_APIDDamping = 0.5f; + private bool m_useAPID = false; + + // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), + // and are for non-VEHICLES only. + + private float m_PIDHoverHeight; + private float m_PIDHoverTau; + private bool m_useHoverPID; + private PIDHoverType m_PIDHoverType = PIDHoverType.Ground; + private float m_targetHoverHeight; + private float m_groundHeight; + private float m_waterHeight; + private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. + + // private float m_tensor = 5f; + private int body_autodisable_frames = 20; + + + private const CollisionCategories m_default_collisionFlags = (CollisionCategories.Geom + | CollisionCategories.Space + | CollisionCategories.Body + | CollisionCategories.Character + ); + private bool m_taintshape; + private bool m_taintPhysics; + private bool m_collidesLand = true; + private bool m_collidesWater; + public bool m_returnCollisions; + + // Default we're a Geometry + private CollisionCategories m_collisionCategories = (CollisionCategories.Geom); + + // Default, Collide with Other Geometries, spaces and Bodies + private CollisionCategories m_collisionFlags = m_default_collisionFlags; + + public bool m_taintremove; + public bool m_taintdisable; + public bool m_disabled; + public bool m_taintadd; + public bool m_taintselected; + public bool m_taintCollidesWater; + + public uint m_localID; + + //public GCHandle gc; + private CollisionLocker ode; + + private bool m_taintforce = false; + private bool m_taintaddangularforce = false; + private Vector3 m_force; + private List m_forcelist = new List(); + private List m_angularforcelist = new List(); + + private IMesh _mesh; + private PrimitiveBaseShape _pbs; + private OdeScene _parent_scene; + public IntPtr m_targetSpace = IntPtr.Zero; + public IntPtr prim_geom; + public IntPtr prev_geom; + public IntPtr _triMeshData; + + private IntPtr _linkJointGroup = IntPtr.Zero; + private PhysicsActor _parent; + private PhysicsActor m_taintparent; + + private List childrenPrim = new List(); + + private bool iscolliding; + private bool m_isphysical; + private bool m_isSelected; + + internal bool m_isVolumeDetect; // If true, this prim only detects collisions but doesn't collide actively + + private bool m_throttleUpdates; + private int throttleCounter; + public int m_interpenetrationcount; + public float m_collisionscore; + public int m_roundsUnderMotionThreshold; + private int m_crossingfailures; + + public bool outofBounds; + private float m_density = 10.000006836f; // Aluminum g/cm3; + + public bool _zeroFlag; + private bool m_lastUpdateSent; + + public IntPtr Body = IntPtr.Zero; + public String m_primName; + private Vector3 _target_velocity; + public d.Mass pMass; + + public int m_eventsubscription; + private CollisionEventUpdate CollisionEventsThisFrame; + + private IntPtr m_linkJoint = IntPtr.Zero; + + public volatile bool childPrim; + + private ODEDynamics m_vehicle; + + internal int m_material = (int)Material.Wood; + + private int frcount = 0; // Used to limit dynamics debug output to + + + public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, + Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) + { + m_vehicle = new ODEDynamics(); + //gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned); + ode = dode; + if (!pos.IsFinite()) + { + pos = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), + parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f); + m_log.Warn("[PHYSICS]: Got nonFinite Object create Position"); + } + _position = pos; + m_taintposition = pos; + PID_D = parent_scene.bodyPIDD; + PID_G = parent_scene.bodyPIDG; + m_density = parent_scene.geomDefaultDensity; + // m_tensor = parent_scene.bodyMotorJointMaxforceTensor; + body_autodisable_frames = parent_scene.bodyFramesAutoDisable; + + + prim_geom = IntPtr.Zero; + prev_geom = IntPtr.Zero; + + if (!pos.IsFinite()) + { + size = new Vector3(0.5f, 0.5f, 0.5f); + m_log.Warn("[PHYSICS]: Got nonFinite Object create Size"); + } + + if (size.X <= 0) size.X = 0.01f; + if (size.Y <= 0) size.Y = 0.01f; + if (size.Z <= 0) size.Z = 0.01f; + + _size = size; + m_taintsize = _size; + + if (!QuaternionIsFinite(rotation)) + { + rotation = Quaternion.Identity; + m_log.Warn("[PHYSICS]: Got nonFinite Object create Rotation"); + } + + _orientation = rotation; + m_taintrot = _orientation; + _mesh = mesh; + _pbs = pbs; + + _parent_scene = parent_scene; + m_targetSpace = (IntPtr)0; + + if (pos.Z < 0) + m_isphysical = false; + else + { + m_isphysical = pisPhysical; + // If we're physical, we need to be in the master space for now. + // linksets *should* be in a space together.. but are not currently + if (m_isphysical) + m_targetSpace = _parent_scene.space; + } + m_primName = primName; + m_taintadd = true; + _parent_scene.AddPhysicsActorTaint(this); + // don't do .add() here; old geoms get recycled with the same hash + } + + public override int PhysicsActorType + { + get { return (int) ActorTypes.Prim; } + set { return; } + } + + public override bool SetAlwaysRun + { + get { return false; } + set { return; } + } + + public override uint LocalID + { + set { + //m_log.Info("[PHYSICS]: Setting TrackerID: " + value); + m_localID = value; } + } + + public override bool Grabbed + { + set { return; } + } + + public override bool Selected + { + set { + + + // This only makes the object not collidable if the object + // is physical or the object is modified somehow *IN THE FUTURE* + // without this, if an avatar selects prim, they can walk right + // through it while it's selected + m_collisionscore = 0; + if ((m_isphysical && !_zeroFlag) || !value) + { + m_taintselected = value; + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_taintselected = value; + m_isSelected = value; + } + if(m_isSelected) disableBodySoft(); + } + } + + public void SetGeom(IntPtr geom) + { + prev_geom = prim_geom; + prim_geom = geom; +//Console.WriteLine("SetGeom to " + prim_geom + " for " + m_primName); + if (prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + + if (childPrim) + { + if (_parent != null && _parent is OdePrim) + { + OdePrim parent = (OdePrim)_parent; +//Console.WriteLine("SetGeom calls ChildSetGeom"); + parent.ChildSetGeom(this); + } + } + //m_log.Warn("Setting Geom to: " + prim_geom); + } + + + + public void enableBodySoft() + { + if (!childPrim) + { + if (m_isphysical && Body != IntPtr.Zero) + { + d.BodyEnable(Body); + if (m_vehicle.Type != Vehicle.TYPE_NONE) + m_vehicle.Enable(Body, _parent_scene); + } + + m_disabled = false; + } + } + + public void disableBodySoft() + { + m_disabled = true; + + if (m_isphysical && Body != IntPtr.Zero) + { + d.BodyDisable(Body); + } + } + + public void enableBody() + { + // Don't enable this body if we're a child prim + // this should be taken care of in the parent function not here + if (!childPrim) + { + // Sets the geom to a body + Body = d.BodyCreate(_parent_scene.world); + + setMass(); + d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + d.BodySetQuaternion(Body, ref myrot); + d.GeomSetBody(prim_geom, Body); + m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + + d.BodySetAutoDisableFlag(Body, true); + d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + + // disconnect from world gravity so we can apply buoyancy + d.BodySetGravityMode (Body, false); + + m_interpenetrationcount = 0; + m_collisionscore = 0; + m_disabled = false; + + // The body doesn't already have a finite rotation mode set here + if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0.0f)) && _parent == null) + { + createAMotor(m_angularlock); + } + if (m_vehicle.Type != Vehicle.TYPE_NONE) + { + m_vehicle.Enable(Body, _parent_scene); + } + + _parent_scene.addActivePrim(this); + } + } + + #region Mass Calculation + + private float CalculateMass() + { + float volume = 0; + + // No material is passed to the physics engines yet.. soo.. + // we're using the m_density constant in the class definition + + float returnMass = 0; + + switch (_pbs.ProfileShape) + { + case ProfileShape.Square: + // Profile Volume + + volume = _size.X*_size.Y*_size.Z; + + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage + + if (((float) _pbs.ProfileHollow/50000f) > 0.0) + { + float hollowAmount = (float) _pbs.ProfileHollow/50000f; + + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + // Cube Hollow volume calculation + float hollowsizex = _size.X*hollowAmount; + float hollowsizey = _size.Y*hollowAmount; + float hollowsizez = _size.Z*hollowAmount; + hollowVolume = hollowsizex*hollowsizey*hollowsizez; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X/2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount); + break; + + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + + break; + case ProfileShape.Circle: + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + // Cylinder + float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z); + float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z); + + // Approximating the cylinder's irregularity. + if (volume1 > volume2) + { + volume = (float)volume1 - (volume1 - volume2); + } + else if (volume2 > volume1) + { + volume = (float)volume2 - (volume2 - volume1); + } + else + { + // Regular cylinder + volume = volume1; + } + } + else + { + // We don't know what the shape is yet, so use default + volume = _size.X * _size.Y * _size.Z; + } + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage + + if (((float)_pbs.ProfileHollow / 50000f) > 0.0) + { + float hollowAmount = (float)_pbs.ProfileHollow / 50000f; + + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X / 2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); + break; + + case HollowShape.Square: + // Cube Hollow volume calculation + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + break; + + case ProfileShape.HalfCircle: + if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Y && _size.Y == _size.Z) + { + // regular sphere + // v = 4/3 * pi * r^3 + float sradius3 = (float)Math.Pow((_size.X / 2), 3); + volume = (float)((4f / 3f) * Math.PI * sradius3); + } + else + { + // we treat this as a box currently + volume = _size.X * _size.Y * _size.Z; + } + } + else + { + // We don't know what the shape is yet, so use default + volume = _size.X * _size.Y * _size.Z; + } + break; + + case ProfileShape.EquilateralTriangle: + /* + v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h + + // seed mesh + Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); + Vertex PM = new Vertex(+0.5f, 0f, 0.0f); + Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f); + */ + float xA = -0.25f * _size.X; + float yA = -0.45f * _size.Y; + + float xB = 0.5f * _size.X; + float yB = 0; + + float xC = -0.25f * _size.X; + float yC = 0.45f * _size.Y; + + volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); + + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage + float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f); + if (((float)fhollowFactor / 50000f) > 0.0) + { + float hollowAmount = (float)fhollowFactor / 50000f; + + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + case HollowShape.Square: + // Cube Hollow volume calculation + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X / 2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + break; + + default: + // we don't have all of the volume formulas yet so + // use the common volume formula for all + volume = _size.X*_size.Y*_size.Z; + break; + } + + // Calculate Path cut effect on volume + // Not exact, in the triangle hollow example + // They should never be zero or less then zero.. + // we'll ignore it if it's less then zero + + // ProfileEnd and ProfileBegin are values + // from 0 to 50000 + + // Turning them back into percentages so that I can cut that percentage off the volume + + float PathCutEndAmount = _pbs.ProfileEnd; + float PathCutStartAmount = _pbs.ProfileBegin; + if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f) + { + float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f); + + // Check the return amount for sanity + if (pathCutAmount >= 0.99f) + pathCutAmount = 0.99f; + + volume = volume - (volume*pathCutAmount); + } + UInt16 taperX = _pbs.PathScaleX; + UInt16 taperY = _pbs.PathScaleY; + float taperFactorX = 0; + float taperFactorY = 0; + + // Mass = density * volume + if (taperX != 100) + { + if (taperX > 100) + { + taperFactorX = 1.0f - ((float)taperX / 200); + //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString()); + } + else + { + taperFactorX = 1.0f - ((100 - (float)taperX) / 100); + //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString()); + } + volume = (float)volume * ((taperFactorX / 3f) + 0.001f); + } + + if (taperY != 100) + { + if (taperY > 100) + { + taperFactorY = 1.0f - ((float)taperY / 200); + //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString()); + } + else + { + taperFactorY = 1.0f - ((100 - (float)taperY) / 100); + //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString()); + } + volume = (float)volume * ((taperFactorY / 3f) + 0.001f); + } + returnMass = m_density*volume; + if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. + + + + // Recursively calculate mass + bool HasChildPrim = false; + lock (childrenPrim) + { + if (childrenPrim.Count > 0) + { + HasChildPrim = true; + } + + } + if (HasChildPrim) + { + OdePrim[] childPrimArr = new OdePrim[0]; + + lock (childrenPrim) + childPrimArr = childrenPrim.ToArray(); + + for (int i = 0; i < childPrimArr.Length; i++) + { + if (childPrimArr[i] != null && !childPrimArr[i].m_taintremove) + returnMass += childPrimArr[i].CalculateMass(); + // failsafe, this shouldn't happen but with OpenSim, you never know :) + if (i > 256) + break; + } + } + if (returnMass > _parent_scene.maximumMassObject) + returnMass = _parent_scene.maximumMassObject; + return returnMass; + }// end CalculateMass + + #endregion + + public void setMass() + { + if (Body != (IntPtr) 0) + { + float newmass = CalculateMass(); + + //m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString()); + + d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z); + d.BodySetMass(Body, ref pMass); + } + } + + public void disableBody() + { + //this kills the body so things like 'mesh' can re-create it. + lock (this) + { + if (!childPrim) + { + if (Body != IntPtr.Zero) + { + _parent_scene.remActivePrim(this); + m_collisionCategories &= ~CollisionCategories.Body; + m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); + + if (prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + + + d.BodyDestroy(Body); + lock (childrenPrim) + { + if (childrenPrim.Count > 0) + { + foreach (OdePrim prm in childrenPrim) + { + _parent_scene.remActivePrim(prm); + prm.Body = IntPtr.Zero; + } + } + } + Body = IntPtr.Zero; + } + } + else + { + _parent_scene.remActivePrim(this); + + m_collisionCategories &= ~CollisionCategories.Body; + m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); + + if (prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + + + Body = IntPtr.Zero; + } + } + m_disabled = true; + m_collisionscore = 0; + } + + private static Dictionary m_MeshToTriMeshMap = new Dictionary(); + + public void setMesh(OdeScene parent_scene, IMesh mesh) + { + // This sleeper is there to moderate how long it takes between + // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object + + //Thread.Sleep(10); + + //Kill Body so that mesh can re-make the geom + if (IsPhysical && Body != IntPtr.Zero) + { + if (childPrim) + { + if (_parent != null) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildDelink(this); + } + } + else + { + disableBody(); + } + } + + IntPtr vertices, indices; + int vertexCount, indexCount; + int vertexStride, triStride; + mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap + mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage + + mesh.releaseSourceMeshData(); // free up the original mesh data to save memory + if (m_MeshToTriMeshMap.ContainsKey(mesh)) + { + _triMeshData = m_MeshToTriMeshMap[mesh]; + } + else + { + _triMeshData = d.GeomTriMeshDataCreate(); + + d.GeomTriMeshDataBuildSimple(_triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride); + d.GeomTriMeshDataPreprocess(_triMeshData); + m_MeshToTriMeshMap[mesh] = _triMeshData; + } + + _parent_scene.waitForSpaceUnlock(m_targetSpace); + try + { + if (prim_geom == IntPtr.Zero) + { + SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); + } + } + catch (AccessViolationException) + { + m_log.Error("[PHYSICS]: MESH LOCKED"); + return; + } + + + // if (IsPhysical && Body == (IntPtr) 0) + // { + // Recreate the body + // m_interpenetrationcount = 0; + // m_collisionscore = 0; + + // enableBody(); + // } + } + + public void ProcessTaints(float timestep) + { +//Console.WriteLine("ProcessTaints for " + m_primName ); + if (m_taintadd) + { + changeadd(timestep); + } + + if (prim_geom != IntPtr.Zero) + { + if (!_position.ApproxEquals(m_taintposition, 0f)) + changemove(timestep); + + if (m_taintrot != _orientation) + { + if(childPrim && IsPhysical) // For physical child prim... + { + rotate(timestep); + // KF: ODE will also rotate the parent prim! + // so rotate the root back to where it was + OdePrim parent = (OdePrim)_parent; + parent.rotate(timestep); + } + else + { + //Just rotate the prim + rotate(timestep); + } + } + // + + if (m_taintPhysics != m_isphysical && !(m_taintparent != _parent)) + changePhysicsStatus(timestep); + // + + if (!_size.ApproxEquals(m_taintsize,0f)) + changesize(timestep); + // + + if (m_taintshape) + changeshape(timestep); + // + + if (m_taintforce) + changeAddForce(timestep); + + if (m_taintaddangularforce) + changeAddAngularForce(timestep); + + if (!m_taintTorque.ApproxEquals(Vector3.Zero, 0.001f)) + changeSetTorque(timestep); + + if (m_taintdisable) + changedisable(timestep); + + if (m_taintselected != m_isSelected) + changeSelectedStatus(timestep); + + if (!m_taintVelocity.ApproxEquals(Vector3.Zero, 0.001f)) + changevelocity(timestep); + + if (m_taintparent != _parent) + changelink(timestep); + + if (m_taintCollidesWater != m_collidesWater) + changefloatonwater(timestep); + + if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) + changeAngularLock(timestep); + + } + else + { + m_log.Error("[PHYSICS]: The scene reused a disposed PhysActor! *waves finger*, Don't be evil. A couple of things can cause this. An improper prim breakdown(be sure to set prim_geom to zero after d.GeomDestroy! An improper buildup (creating the geom failed). Or, the Scene Reused a physics actor after disposing it.)"); + } + } + + + private void changeAngularLock(float timestep) + { + // do we have a Physical object? + if (Body != IntPtr.Zero) + { + //Check that we have a Parent + //If we have a parent then we're not authorative here + if (_parent == null) + { + if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f)) + { + //d.BodySetFiniteRotationMode(Body, 0); + //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z); + createAMotor(m_taintAngularLock); + } + else + { + if (Amotor != IntPtr.Zero) + { + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + } + } + } + // Store this for later in case we get turned into a separate body + m_angularlock = m_taintAngularLock; + + } + + private void changelink(float timestep) + { + // If the newly set parent is not null + // create link + if (_parent == null && m_taintparent != null) + { + if (m_taintparent.PhysicsActorType == (int)ActorTypes.Prim) + { + OdePrim obj = (OdePrim)m_taintparent; + //obj.disableBody(); +//Console.WriteLine("changelink calls ParentPrim"); + obj.ParentPrim(this); + + /* + if (obj.Body != (IntPtr)0 && Body != (IntPtr)0 && obj.Body != Body) + { + _linkJointGroup = d.JointGroupCreate(0); + m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); + d.JointAttach(m_linkJoint, obj.Body, Body); + d.JointSetFixed(m_linkJoint); + } + */ + } + } + // If the newly set parent is null + // destroy link + else if (_parent != null && m_taintparent == null) + { +//Console.WriteLine(" changelink B"); + + if (_parent is OdePrim) + { + OdePrim obj = (OdePrim)_parent; + obj.ChildDelink(this); + childPrim = false; + //_parent = null; + } + + /* + if (Body != (IntPtr)0 && _linkJointGroup != (IntPtr)0) + d.JointGroupDestroy(_linkJointGroup); + + _linkJointGroup = (IntPtr)0; + m_linkJoint = (IntPtr)0; + */ + } + + _parent = m_taintparent; + m_taintPhysics = m_isphysical; + } + + // I'm the parent + // prim is the child + public void ParentPrim(OdePrim prim) + { +//Console.WriteLine("ParentPrim " + m_primName); + if (this.m_localID != prim.m_localID) + { + if (Body == IntPtr.Zero) + { + Body = d.BodyCreate(_parent_scene.world); + setMass(); + } + if (Body != IntPtr.Zero) + { + lock (childrenPrim) + { + if (!childrenPrim.Contains(prim)) + { +//Console.WriteLine("childrenPrim.Add " + prim); + childrenPrim.Add(prim); + + foreach (OdePrim prm in childrenPrim) + { + d.Mass m2; + d.MassSetZero(out m2); + d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); + + + d.Quaternion quat = new d.Quaternion(); + quat.W = prm._orientation.W; + quat.X = prm._orientation.X; + quat.Y = prm._orientation.Y; + quat.Z = prm._orientation.Z; + + d.Matrix3 mat = new d.Matrix3(); + d.RfromQ(out mat, ref quat); + d.MassRotate(ref m2, ref mat); + d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); + d.MassAdd(ref pMass, ref m2); + } + foreach (OdePrim prm in childrenPrim) + { + + prm.m_collisionCategories |= CollisionCategories.Body; + prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + + if (prm.prim_geom == IntPtr.Zero) + { + m_log.Warn("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); + continue; + } +//Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + m_primName); + d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); + d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); + + + d.Quaternion quat = new d.Quaternion(); + quat.W = prm._orientation.W; + quat.X = prm._orientation.X; + quat.Y = prm._orientation.Y; + quat.Z = prm._orientation.Z; + + d.Matrix3 mat = new d.Matrix3(); + d.RfromQ(out mat, ref quat); + if (Body != IntPtr.Zero) + { + d.GeomSetBody(prm.prim_geom, Body); + prm.childPrim = true; + d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); + //d.GeomSetOffsetPosition(prim.prim_geom, + // (Position.X - prm.Position.X) - pMass.c.X, + // (Position.Y - prm.Position.Y) - pMass.c.Y, + // (Position.Z - prm.Position.Z) - pMass.c.Z); + d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); + //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); + d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); + d.BodySetMass(Body, ref pMass); + } + else + { + m_log.Debug("[PHYSICS]:I ain't got no boooooooooddy, no body"); + } + + + prm.m_interpenetrationcount = 0; + prm.m_collisionscore = 0; + prm.m_disabled = false; + + // The body doesn't already have a finite rotation mode set here + if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) + { + prm.createAMotor(m_angularlock); + } + prm.Body = Body; + _parent_scene.addActivePrim(prm); + } + m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + +//Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + m_primName); + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); +//Console.WriteLine(" Post GeomSetCategoryBits 2"); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + + + d.Quaternion quat2 = new d.Quaternion(); + quat2.W = _orientation.W; + quat2.X = _orientation.X; + quat2.Y = _orientation.Y; + quat2.Z = _orientation.Z; + + d.Matrix3 mat2 = new d.Matrix3(); + d.RfromQ(out mat2, ref quat2); + d.GeomSetBody(prim_geom, Body); + d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); + //d.GeomSetOffsetPosition(prim.prim_geom, + // (Position.X - prm.Position.X) - pMass.c.X, + // (Position.Y - prm.Position.Y) - pMass.c.Y, + // (Position.Z - prm.Position.Z) - pMass.c.Z); + //d.GeomSetOffsetRotation(prim_geom, ref mat2); + d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); + d.BodySetMass(Body, ref pMass); + + d.BodySetAutoDisableFlag(Body, true); + d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + + + m_interpenetrationcount = 0; + m_collisionscore = 0; + m_disabled = false; + + // The body doesn't already have a finite rotation mode set here + if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) + { + createAMotor(m_angularlock); + } + d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); + if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); + _parent_scene.addActivePrim(this); + } + } + } + } + + } + + private void ChildSetGeom(OdePrim odePrim) + { + //if (m_isphysical && Body != IntPtr.Zero) + lock (childrenPrim) + { + foreach (OdePrim prm in childrenPrim) + { + //prm.childPrim = true; + prm.disableBody(); + //prm.m_taintparent = null; + //prm._parent = null; + //prm.m_taintPhysics = false; + //prm.m_disabled = true; + //prm.childPrim = false; + } + } + disableBody(); + + + if (Body != IntPtr.Zero) + { + _parent_scene.remActivePrim(this); + } + + lock (childrenPrim) + { + foreach (OdePrim prm in childrenPrim) + { +//Console.WriteLine("ChildSetGeom calls ParentPrim"); + ParentPrim(prm); + } + } + + } + + private void ChildDelink(OdePrim odePrim) + { + // Okay, we have a delinked child.. need to rebuild the body. + lock (childrenPrim) + { + foreach (OdePrim prm in childrenPrim) + { + prm.childPrim = true; + prm.disableBody(); + //prm.m_taintparent = null; + //prm._parent = null; + //prm.m_taintPhysics = false; + //prm.m_disabled = true; + //prm.childPrim = false; + } + } + disableBody(); + + lock (childrenPrim) + { + //Console.WriteLine("childrenPrim.Remove " + odePrim); + childrenPrim.Remove(odePrim); + } + + + + + if (Body != IntPtr.Zero) + { + _parent_scene.remActivePrim(this); + } + + + + lock (childrenPrim) + { + foreach (OdePrim prm in childrenPrim) + { +//Console.WriteLine("ChildDelink calls ParentPrim"); + ParentPrim(prm); + } + } + + + } + + private void changeSelectedStatus(float timestep) + { + if (m_taintselected) + { + m_collisionCategories = CollisionCategories.Selected; + m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); + + // We do the body disable soft twice because 'in theory' a collision could have happened + // in between the disabling and the collision properties setting + // which would wake the physical body up from a soft disabling and potentially cause it to fall + // through the ground. + + // NOTE FOR JOINTS: this doesn't always work for jointed assemblies because if you select + // just one part of the assembly, the rest of the assembly is non-selected and still simulating, + // so that causes the selected part to wake up and continue moving. + + // even if you select all parts of a jointed assembly, it is not guaranteed that the entire + // assembly will stop simulating during the selection, because of the lack of atomicity + // of select operations (their processing could be interrupted by a thread switch, causing + // simulation to continue before all of the selected object notifications trickle down to + // the physics engine). + + // e.g. we select 100 prims that are connected by joints. non-atomically, the first 50 are + // selected and disabled. then, due to a thread switch, the selection processing is + // interrupted and the physics engine continues to simulate, so the last 50 items, whose + // selection was not yet processed, continues to simulate. this wakes up ALL of the + // first 50 again. then the last 50 are disabled. then the first 50, which were just woken + // up, start simulating again, which in turn wakes up the last 50. + + if (m_isphysical) + { + disableBodySoft(); + } + + if (prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + + if (m_isphysical) + { + disableBodySoft(); + } + } + else + { + m_collisionCategories = CollisionCategories.Geom; + + if (m_isphysical) + m_collisionCategories |= CollisionCategories.Body; + + m_collisionFlags = m_default_collisionFlags; + + if (m_collidesLand) + m_collisionFlags |= CollisionCategories.Land; + if (m_collidesWater) + m_collisionFlags |= CollisionCategories.Water; + + if (prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + if (m_isphysical) + { + if (Body != IntPtr.Zero) + { + d.BodySetLinearVel(Body, 0f, 0f, 0f); + d.BodySetForce(Body, 0, 0, 0); + enableBodySoft(); + } + } + } + + resetCollisionAccounting(); + m_isSelected = m_taintselected; + }//end changeSelectedStatus + + public void ResetTaints() + { + m_taintposition = _position; + m_taintrot = _orientation; + m_taintPhysics = m_isphysical; + m_taintselected = m_isSelected; + m_taintsize = _size; + m_taintshape = false; + m_taintforce = false; + m_taintdisable = false; + m_taintVelocity = Vector3.Zero; + } + + public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) + { +//Console.WriteLine("CreateGeom:"); + if (_mesh != null) + { + setMesh(_parent_scene, _mesh); + } + else + { + if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) + { + if (((_size.X / 2f) > 0f)) + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + try + { +//Console.WriteLine(" CreateGeom 1"); + SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2)); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); + ode.dunlock(_parent_scene.world); + return; + } + } + else + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + try + { +//Console.WriteLine(" CreateGeom 2"); + SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); + ode.dunlock(_parent_scene.world); + return; + } + } + } + else + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + try + { +//Console.WriteLine(" CreateGeom 3"); + SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); + ode.dunlock(_parent_scene.world); + return; + } + } + } + + else + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + try + { +//Console.WriteLine(" CreateGeom 4"); + SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z)); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to create physics proxy for object"); + ode.dunlock(_parent_scene.world); + return; + } + } + } + } + + public void changeadd(float timestep) + { + int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position); + IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position); + + if (targetspace == IntPtr.Zero) + targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); + + m_targetSpace = targetspace; + + if (_mesh == null) + { + if (_parent_scene.needsMeshing(_pbs)) + { + // Don't need to re-enable body.. it's done in SetMesh + _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); + // createmesh returns null when it's a shape that isn't a cube. + // m_log.Debug(m_localID); + } + } + + + lock (_parent_scene.OdeLock) + { +//Console.WriteLine("changeadd 1"); + CreateGeom(m_targetSpace, _mesh); + + if (prim_geom != IntPtr.Zero) + { + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + d.GeomSetQuaternion(prim_geom, ref myrot); + } + + if (m_isphysical && Body == IntPtr.Zero) + { + enableBody(); + } + } + + _parent_scene.geom_name_map[prim_geom] = this.m_primName; + _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; + + changeSelectedStatus(timestep); + + m_taintadd = false; + } + + public void changemove(float timestep) + { + if (m_isphysical) + { + + if (!m_disabled && !m_taintremove && !childPrim) + { + if (Body == IntPtr.Zero) + enableBody(); + //Prim auto disable after 20 frames, + //if you move it, re-enable the prim manually. + if (_parent != null) + { + if (m_linkJoint != IntPtr.Zero) + { + d.JointDestroy(m_linkJoint); + m_linkJoint = IntPtr.Zero; + } + } + if (Body != IntPtr.Zero) + { + d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + + if (_parent != null) + { + OdePrim odParent = (OdePrim)_parent; + if (Body != (IntPtr)0 && odParent.Body != (IntPtr)0 && Body != odParent.Body) + { +// KF: Fixed Joints were removed? Anyway - this Console.WriteLine does not show up, so routine is not used?? +Console.WriteLine(" JointCreateFixed"); + m_linkJoint = d.JointCreateFixed(_parent_scene.world, _linkJointGroup); + d.JointAttach(m_linkJoint, Body, odParent.Body); + d.JointSetFixed(m_linkJoint); + } + } + d.BodyEnable(Body); + if (m_vehicle.Type != Vehicle.TYPE_NONE) + { + m_vehicle.Enable(Body, _parent_scene); + } + } + else + { + m_log.Warn("[PHYSICS]: Body Still null after enableBody(). This is a crash scenario."); + } + } + //else + // { + //m_log.Debug("[BUG]: race!"); + //} + } + else + { + // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); + // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); + _parent_scene.waitForSpaceUnlock(m_targetSpace); + + IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace); + m_targetSpace = tempspace; + + _parent_scene.waitForSpaceUnlock(m_targetSpace); + if (prim_geom != IntPtr.Zero) + { + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + + _parent_scene.waitForSpaceUnlock(m_targetSpace); + d.SpaceAdd(m_targetSpace, prim_geom); + } + } + + changeSelectedStatus(timestep); + + resetCollisionAccounting(); + m_taintposition = _position; + } + + public void Move(float timestep) + { + float fx = 0; + float fy = 0; + float fz = 0; + + frcount++; // used to limit debug comment output + if (frcount > 100) + frcount = 0; + + if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. + { +//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type + + // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); + if (m_vehicle.Type != Vehicle.TYPE_NONE) + { + // 'VEHICLES' are dealt with in ODEDynamics.cs + m_vehicle.Step(timestep, _parent_scene); + } + else + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 + // NON-'VEHICLES' are dealt with here + if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) + { + d.Vector3 avel2 = d.BodyGetAngularVel(Body); + if (m_angularlock.X == 1) + avel2.X = 0; + if (m_angularlock.Y == 1) + avel2.Y = 0; + if (m_angularlock.Z == 1) + avel2.Z = 0; + d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); + } + //float PID_P = 900.0f; + + float m_mass = CalculateMass(); + +// fz = 0f; + //m_log.Info(m_collisionFlags.ToString()); + + + //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle. + // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up + // NB Prims in ODE are no subject to global gravity + fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass + + if (m_usePID) + { +//if(frcount == 0) Console.WriteLine("PID " + m_primName); + // KF - this is for object MoveToTarget. + + //if (!d.BodyIsEnabled(Body)) + //d.BodySetForce(Body, 0f, 0f, 0f); + + // no lock; for now it's only called from within Simulate() + + // If the PID Controller isn't active then we set our force + // calculating base velocity to the current position + + if ((m_PIDTau < 1) && (m_PIDTau != 0)) + { + //PID_G = PID_G / m_PIDTau; + m_PIDTau = 1; + } + + if ((PID_G - m_PIDTau) <= 0) + { + PID_G = m_PIDTau + 1; + } + //PidStatus = true; + + // PhysicsVector vec = new PhysicsVector(); + d.Vector3 vel = d.BodyGetLinearVel(Body); + + d.Vector3 pos = d.BodyGetPosition(Body); + _target_velocity = + new Vector3( + (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), + (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), + (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) + ); + + // if velocity is zero, use position control; otherwise, velocity control + + if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f)) + { + // keep track of where we stopped. No more slippin' & slidin' + + // We only want to deactivate the PID Controller if we think we want to have our surrogate + // react to the physics scene by moving it's position. + // Avatar to Avatar collisions + // Prim to avatar collisions + + //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); + //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); + //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; + d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); + d.BodySetLinearVel(Body, 0, 0, 0); + d.BodyAddForce(Body, 0, 0, fz); + return; + } + else + { + _zeroFlag = false; + + // We're flying and colliding with something + fx = ((_target_velocity.X) - vel.X) * (PID_D); + fy = ((_target_velocity.Y) - vel.Y) * (PID_D); + + // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; + + fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); + } + } // end if (m_usePID) + + // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller + if (m_useHoverPID && !m_usePID) + { +//Console.WriteLine("Hover " + m_primName); + + // If we're using the PID controller, then we have no gravity + fz = (-1 * _parent_scene.gravityz) * m_mass; + + // no lock; for now it's only called from within Simulate() + + // If the PID Controller isn't active then we set our force + // calculating base velocity to the current position + + if ((m_PIDTau < 1)) + { + PID_G = PID_G / m_PIDTau; + } + + if ((PID_G - m_PIDTau) <= 0) + { + PID_G = m_PIDTau + 1; + } + + + // Where are we, and where are we headed? + d.Vector3 pos = d.BodyGetPosition(Body); + d.Vector3 vel = d.BodyGetLinearVel(Body); + + + // Non-Vehicles have a limited set of Hover options. + // determine what our target height really is based on HoverType + switch (m_PIDHoverType) + { + case PIDHoverType.Ground: + m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); + m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; + break; + case PIDHoverType.GroundAndWater: + m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); + m_waterHeight = _parent_scene.GetWaterLevel(); + if (m_groundHeight > m_waterHeight) + { + m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; + } + else + { + m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; + } + break; + + } // end switch (m_PIDHoverType) + + + _target_velocity = + new Vector3(0.0f, 0.0f, + (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) + ); + + // if velocity is zero, use position control; otherwise, velocity control + + if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) + { + // keep track of where we stopped. No more slippin' & slidin' + + // We only want to deactivate the PID Controller if we think we want to have our surrogate + // react to the physics scene by moving it's position. + // Avatar to Avatar collisions + // Prim to avatar collisions + + d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); + d.BodySetLinearVel(Body, vel.X, vel.Y, 0); + d.BodyAddForce(Body, 0, 0, fz); + //KF this prevents furthur motions return; + } + else + { + _zeroFlag = false; + + // We're flying and colliding with something + fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); + } + } // end m_useHoverPID && !m_usePID + + if (m_useAPID) + { + // RotLookAt, apparently overrides all other rotation sources. Inputs: + // Quaternion m_APIDTarget + // float m_APIDStrength // From SL experiments, this is the time to get there + // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly + // Also in SL the mass of the object has no effect on time to get there. + // Factors: +//if(frcount == 0) Console.WriteLine("APID "); + // get present body rotation + float limit = 1.0f; + float scaler = 50f; // adjusts damping time + float RLAservo = 0f; + + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); + Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget; + float diff_angle; + Vector3 diff_axis; + rot_diff.GetAxisAngle(out diff_axis, out diff_angle); + diff_axis.Normalize(); + if(diff_angle > 0.01f) // diff_angle is always +ve + { +// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); + Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z); + rotforce = rotforce * rotq; + if(diff_angle > limit) diff_angle = limit; // cap the rotate rate +// RLAservo = timestep / m_APIDStrength * m_mass * scaler; + // rotforce = rotforce * RLAservo * diff_angle ; + // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); + RLAservo = timestep / m_APIDStrength * scaler; + rotforce = rotforce * RLAservo * diff_angle ; + d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); +//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); + } +//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); + } // end m_useAPID + + fx *= m_mass; + fy *= m_mass; + //fz *= m_mass; + + fx += m_force.X; + fy += m_force.Y; + fz += m_force.Z; + + //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); + if (fx != 0 || fy != 0 || fz != 0) + { + //m_taintdisable = true; + //base.RaiseOutOfBounds(Position); + //d.BodySetLinearVel(Body, fx, fy, 0f); + if (!d.BodyIsEnabled(Body)) + { + // A physical body at rest on a surface will auto-disable after a while, + // this appears to re-enable it incase the surface it is upon vanishes, + // and the body should fall again. + d.BodySetLinearVel(Body, 0f, 0f, 0f); + d.BodySetForce(Body, 0, 0, 0); + enableBodySoft(); + } + + // 35x10 = 350n times the mass per second applied maximum. + float nmax = 35f * m_mass; + float nmin = -35f * m_mass; + + + if (fx > nmax) + fx = nmax; + if (fx < nmin) + fx = nmin; + if (fy > nmax) + fy = nmax; + if (fy < nmin) + fy = nmin; + d.BodyAddForce(Body, fx, fy, fz); +//Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); + } + } + } + else + { // is not physical, or is not a body or is selected + // _zeroPosition = d.BodyGetPosition(Body); + return; +//Console.WriteLine("Nothing " + m_primName); + + } + } + + + + public void rotate(float timestep) + { + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + if (Body != IntPtr.Zero) + { + // KF: If this is a root prim do BodySet + d.BodySetQuaternion(Body, ref myrot); + if (m_isphysical) + { + if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) + createAMotor(m_angularlock); + } + } + else + { + // daughter prim, do Geom set + d.GeomSetQuaternion(prim_geom, ref myrot); + } + + resetCollisionAccounting(); + m_taintrot = _orientation; + } + + private void resetCollisionAccounting() + { + m_collisionscore = 0; + m_interpenetrationcount = 0; + m_disabled = false; + } + + public void changedisable(float timestep) + { + m_disabled = true; + if (Body != IntPtr.Zero) + { + d.BodyDisable(Body); + Body = IntPtr.Zero; + } + + m_taintdisable = false; + } + + public void changePhysicsStatus(float timestep) + { + if (m_isphysical == true) + { + if (Body == IntPtr.Zero) + { + if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) + { + changeshape(2f); + } + else + { + enableBody(); + } + } + } + else + { + if (Body != IntPtr.Zero) + { + if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) + { + + + if (prim_geom != IntPtr.Zero) + { + try + { + d.GeomDestroy(prim_geom); + prim_geom = IntPtr.Zero; + _mesh = null; + } + catch (System.AccessViolationException) + { + prim_geom = IntPtr.Zero; + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + } +//Console.WriteLine("changePhysicsStatus for " + m_primName ); + changeadd(2f); + } + if (childPrim) + { + if (_parent != null) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildDelink(this); + } + } + else + { + disableBody(); + } + } + } + + changeSelectedStatus(timestep); + + resetCollisionAccounting(); + m_taintPhysics = m_isphysical; + } + + public void changesize(float timestamp) + { + + string oldname = _parent_scene.geom_name_map[prim_geom]; + + if (_size.X <= 0) _size.X = 0.01f; + if (_size.Y <= 0) _size.Y = 0.01f; + if (_size.Z <= 0) _size.Z = 0.01f; + + // Cleanup of old prim geometry + if (_mesh != null) + { + // Cleanup meshing here + } + //kill body to rebuild + if (IsPhysical && Body != IntPtr.Zero) + { + if (childPrim) + { + if (_parent != null) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildDelink(this); + } + } + else + { + disableBody(); + } + } + if (d.SpaceQuery(m_targetSpace, prim_geom)) + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + d.SpaceRemove(m_targetSpace, prim_geom); + } + d.GeomDestroy(prim_geom); + prim_geom = IntPtr.Zero; + // we don't need to do space calculation because the client sends a position update also. + + // Construction of new prim + if (_parent_scene.needsMeshing(_pbs)) + { + float meshlod = _parent_scene.meshSculptLOD; + + if (IsPhysical) + meshlod = _parent_scene.MeshSculptphysicalLOD; + // Don't need to re-enable body.. it's done in SetMesh + + IMesh mesh = null; + + if (_parent_scene.needsMeshing(_pbs)) + mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + + //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); +//Console.WriteLine("changesize 1"); + CreateGeom(m_targetSpace, mesh); + + + } + else + { + _mesh = null; +//Console.WriteLine("changesize 2"); + CreateGeom(m_targetSpace, _mesh); + } + + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + d.GeomSetQuaternion(prim_geom, ref myrot); + + //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); + if (IsPhysical && Body == IntPtr.Zero && !childPrim) + { + // Re creates body on size. + // EnableBody also does setMass() + enableBody(); + d.BodyEnable(Body); + } + + _parent_scene.geom_name_map[prim_geom] = oldname; + + changeSelectedStatus(timestamp); + if (childPrim) + { + if (_parent is OdePrim) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildSetGeom(this); + } + } + resetCollisionAccounting(); + m_taintsize = _size; + } + + + + public void changefloatonwater(float timestep) + { + m_collidesWater = m_taintCollidesWater; + + if (prim_geom != IntPtr.Zero) + { + if (m_collidesWater) + { + m_collisionFlags |= CollisionCategories.Water; + } + else + { + m_collisionFlags &= ~CollisionCategories.Water; + } + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + } + + public void changeshape(float timestamp) + { + string oldname = _parent_scene.geom_name_map[prim_geom]; + + // Cleanup of old prim geometry and Bodies + if (IsPhysical && Body != IntPtr.Zero) + { + if (childPrim) + { + if (_parent != null) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildDelink(this); + } + } + else + { + disableBody(); + } + } + try + { + d.GeomDestroy(prim_geom); + } + catch (System.AccessViolationException) + { + prim_geom = IntPtr.Zero; + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + prim_geom = IntPtr.Zero; + // we don't need to do space calculation because the client sends a position update also. + if (_size.X <= 0) _size.X = 0.01f; + if (_size.Y <= 0) _size.Y = 0.01f; + if (_size.Z <= 0) _size.Z = 0.01f; + // Construction of new prim + + if (_parent_scene.needsMeshing(_pbs)) + { + // Don't need to re-enable body.. it's done in SetMesh + float meshlod = _parent_scene.meshSculptLOD; + + if (IsPhysical) + meshlod = _parent_scene.MeshSculptphysicalLOD; + + IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + // createmesh returns null when it doesn't mesh. + CreateGeom(m_targetSpace, mesh); + } + else + { + _mesh = null; +//Console.WriteLine("changeshape"); + CreateGeom(m_targetSpace, null); + } + + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + //myrot.W = _orientation.w; + myrot.W = _orientation.W; + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + d.GeomSetQuaternion(prim_geom, ref myrot); + + //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); + if (IsPhysical && Body == IntPtr.Zero) + { + // Re creates body on size. + // EnableBody also does setMass() + enableBody(); + if (Body != IntPtr.Zero) + { + d.BodyEnable(Body); + } + } + _parent_scene.geom_name_map[prim_geom] = oldname; + + changeSelectedStatus(timestamp); + if (childPrim) + { + if (_parent is OdePrim) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildSetGeom(this); + } + } + resetCollisionAccounting(); + m_taintshape = false; + } + + public void changeAddForce(float timestamp) + { + if (!m_isSelected) + { + lock (m_forcelist) + { + //m_log.Info("[PHYSICS]: dequeing forcelist"); + if (IsPhysical) + { + Vector3 iforce = Vector3.Zero; + int i = 0; + try + { + for (i = 0; i < m_forcelist.Count; i++) + { + + iforce = iforce + (m_forcelist[i] * 100); + } + } + catch (IndexOutOfRangeException) + { + m_forcelist = new List(); + m_collisionscore = 0; + m_interpenetrationcount = 0; + m_taintforce = false; + return; + } + catch (ArgumentOutOfRangeException) + { + m_forcelist = new List(); + m_collisionscore = 0; + m_interpenetrationcount = 0; + m_taintforce = false; + return; + } + d.BodyEnable(Body); + d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z); + } + m_forcelist.Clear(); + } + + m_collisionscore = 0; + m_interpenetrationcount = 0; + } + + m_taintforce = false; + + } + + + + public void changeSetTorque(float timestamp) + { + if (!m_isSelected) + { + if (IsPhysical && Body != IntPtr.Zero) + { + d.BodySetTorque(Body, m_taintTorque.X, m_taintTorque.Y, m_taintTorque.Z); + } + } + + m_taintTorque = Vector3.Zero; + } + + public void changeAddAngularForce(float timestamp) + { + if (!m_isSelected) + { + lock (m_angularforcelist) + { + //m_log.Info("[PHYSICS]: dequeing forcelist"); + if (IsPhysical) + { + Vector3 iforce = Vector3.Zero; + for (int i = 0; i < m_angularforcelist.Count; i++) + { + iforce = iforce + (m_angularforcelist[i] * 100); + } + d.BodyEnable(Body); + d.BodyAddTorque(Body, iforce.X, iforce.Y, iforce.Z); + + } + m_angularforcelist.Clear(); + } + + m_collisionscore = 0; + m_interpenetrationcount = 0; + } + + m_taintaddangularforce = false; + } + + private void changevelocity(float timestep) + { + if (!m_isSelected) + { + Thread.Sleep(20); + if (IsPhysical) + { + if (Body != IntPtr.Zero) + { + d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); + } + } + + //resetCollisionAccounting(); + } + m_taintVelocity = Vector3.Zero; + } + + public override bool IsPhysical + { + get { return m_isphysical; } + set { + m_isphysical = value; + if (!m_isphysical) // Zero the remembered last velocity + m_lastVelocity = Vector3.Zero; + } + } + + public void setPrimForRemoval() + { + m_taintremove = true; + } + + public override bool Flying + { + // no flying prims for you + get { return false; } + set { } + } + + public override bool IsColliding + { + get { return iscolliding; } + set { iscolliding = value; } + } + + public override bool CollidingGround + { + get { return false; } + set { return; } + } + + public override bool CollidingObj + { + get { return false; } + set { return; } + } + + public override bool ThrottleUpdates + { + get { return m_throttleUpdates; } + set { m_throttleUpdates = value; } + } + + public override bool Stopped + { + get { return _zeroFlag; } + } + + public override Vector3 Position + { + get { return _position; } + + set { _position = value; + //m_log.Info("[PHYSICS]: " + _position.ToString()); + } + } + + public override Vector3 Size + { + get { return _size; } + set + { + if (value.IsFinite()) + { + _size = value; + } + else + { + m_log.Warn("[PHYSICS]: Got NaN Size on object"); + } + } + } + + public override float Mass + { + get { return CalculateMass(); } + } + + public override Vector3 Force + { + //get { return Vector3.Zero; } + get { return m_force; } + set + { + if (value.IsFinite()) + { + m_force = value; + } + else + { + m_log.Warn("[PHYSICS]: NaN in Force Applied to an Object"); + } + } + } + + public override int VehicleType + { + get { return (int)m_vehicle.Type; } + set { m_vehicle.ProcessTypeChange((Vehicle)value); } + } + + public override void VehicleFloatParam(int param, float value) + { + m_vehicle.ProcessFloatVehicleParam((Vehicle) param, value); + } + + public override void VehicleVectorParam(int param, Vector3 value) + { + m_vehicle.ProcessVectorVehicleParam((Vehicle) param, value); + } + + public override void VehicleRotationParam(int param, Quaternion rotation) + { + m_vehicle.ProcessRotationVehicleParam((Vehicle) param, rotation); + } + + public override void SetVolumeDetect(int param) + { + lock (_parent_scene.OdeLock) + { + m_isVolumeDetect = (param!=0); + } + } + + public override Vector3 CenterOfMass + { + get { return Vector3.Zero; } + } + + public override Vector3 GeometricCenter + { + get { return Vector3.Zero; } + } + + public override PrimitiveBaseShape Shape + { + set + { + _pbs = value; + m_taintshape = true; + } + } + + public override Vector3 Velocity + { + get + { + // Averate previous velocity with the new one so + // client object interpolation works a 'little' better + if (_zeroFlag) + return Vector3.Zero; + + Vector3 returnVelocity = Vector3.Zero; + returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2; + returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2; + returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2; + return returnVelocity; + } + set + { + if (value.IsFinite()) + { + _velocity = value; + + m_taintVelocity = value; + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got NaN Velocity in Object"); + } + + } + } + + public override Vector3 Torque + { + get + { + if (!m_isphysical || Body == IntPtr.Zero) + return Vector3.Zero; + + return _torque; + } + + set + { + if (value.IsFinite()) + { + m_taintTorque = value; + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got NaN Torque in Object"); + } + } + } + + public override float CollisionScore + { + get { return m_collisionscore; } + set { m_collisionscore = value; } + } + + public override bool Kinematic + { + get { return false; } + set { } + } + + public override Quaternion Orientation + { + get { return _orientation; } + set + { + if (QuaternionIsFinite(value)) + { + _orientation = value; + } + else + m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object"); + + } + } + + internal static bool QuaternionIsFinite(Quaternion q) + { + if (Single.IsNaN(q.X) || Single.IsInfinity(q.X)) + return false; + if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y)) + return false; + if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z)) + return false; + if (Single.IsNaN(q.W) || Single.IsInfinity(q.W)) + return false; + return true; + } + + public override Vector3 Acceleration + { + get { return _acceleration; } + } + + + public void SetAcceleration(Vector3 accel) + { + _acceleration = accel; + } + + public override void AddForce(Vector3 force, bool pushforce) + { + if (force.IsFinite()) + { + lock (m_forcelist) + m_forcelist.Add(force); + + m_taintforce = true; + } + else + { + m_log.Warn("[PHYSICS]: Got Invalid linear force vector from Scene in Object"); + } + //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString()); + } + + public override void AddAngularForce(Vector3 force, bool pushforce) + { + if (force.IsFinite()) + { + m_angularforcelist.Add(force); + m_taintaddangularforce = true; + } + else + { + m_log.Warn("[PHYSICS]: Got Invalid Angular force vector from Scene in Object"); + } + } + + public override Vector3 RotationalVelocity + { + get + { + Vector3 pv = Vector3.Zero; + if (_zeroFlag) + return pv; + m_lastUpdateSent = false; + + if (m_rotationalVelocity.ApproxEquals(pv, 0.2f)) + return pv; + + return m_rotationalVelocity; + } + set + { + if (value.IsFinite()) + { + m_rotationalVelocity = value; + } + else + { + m_log.Warn("[PHYSICS]: Got NaN RotationalVelocity in Object"); + } + } + } + + public override void CrossingFailure() + { + m_crossingfailures++; + if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { + base.RaiseOutOfBounds(_position); + return; + } + else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { + m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName); + } + } + + public override float Buoyancy + { + get { return m_buoyancy; } + set { m_buoyancy = value; } + } + + public override void link(PhysicsActor obj) + { + m_taintparent = obj; + } + + public override void delink() + { + m_taintparent = null; + } + + public override void LockAngularMotion(Vector3 axis) + { + // reverse the zero/non zero values for ODE. + if (axis.IsFinite()) + { + axis.X = (axis.X > 0) ? 1f : 0f; + axis.Y = (axis.Y > 0) ? 1f : 0f; + axis.Z = (axis.Z > 0) ? 1f : 0f; + m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); + m_taintAngularLock = axis; + } + else + { + m_log.Warn("[PHYSICS]: Got NaN locking axis from Scene on Object"); + } + } + + public void UpdatePositionAndVelocity() + { + // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! + if (_parent == null) + { + Vector3 pv = Vector3.Zero; + bool lastZeroFlag = _zeroFlag; + if (Body != (IntPtr)0) // FIXME -> or if it is a joint + { + d.Vector3 vec = d.BodyGetPosition(Body); + d.Quaternion ori = d.BodyGetQuaternion(Body); + d.Vector3 vel = d.BodyGetLinearVel(Body); + d.Vector3 rotvel = d.BodyGetAngularVel(Body); + d.Vector3 torque = d.BodyGetTorque(Body); + _torque = new Vector3(torque.X, torque.Y, torque.Z); + Vector3 l_position = Vector3.Zero; + Quaternion l_orientation = Quaternion.Identity; + + // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) + //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + + m_lastposition = _position; + m_lastorientation = _orientation; + + l_position.X = vec.X; + l_position.Y = vec.Y; + l_position.Z = vec.Z; + l_orientation.X = ori.X; + l_orientation.Y = ori.Y; + l_orientation.Z = ori.Z; + l_orientation.W = ori.W; + +// if(l_position.Y != m_lastposition.Y){ +// Console.WriteLine("UP&V {0} {1}", m_primName, l_position); +// } + + if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) + { + //base.RaiseOutOfBounds(l_position); + + if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { + _position = l_position; + //_parent_scene.remActivePrim(this); + if (_parent == null) + base.RequestPhysicsterseUpdate(); + return; + } + else + { + if (_parent == null) + base.RaiseOutOfBounds(l_position); + return; + } + } + + if (l_position.Z < 0) + { + // This is so prim that get lost underground don't fall forever and suck up + // + // Sim resources and memory. + // Disables the prim's movement physics.... + // It's a hack and will generate a console message if it fails. + + //IsPhysical = false; + if (_parent == null) + base.RaiseOutOfBounds(_position); + + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + + if (_parent == null) + base.RequestPhysicsterseUpdate(); + + m_throttleUpdates = false; + throttleCounter = 0; + _zeroFlag = true; + //outofBounds = true; + } + + //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); +//Console.WriteLine("Adiff " + m_primName + " = " + Adiff); + if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) + && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) + && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) +// && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01)) + && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large + { + _zeroFlag = true; +//Console.WriteLine("ZFT 2"); + m_throttleUpdates = false; + } + else + { + //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); + _zeroFlag = false; + m_lastUpdateSent = false; + //m_throttleUpdates = false; + } + + if (_zeroFlag) + { + _velocity.X = 0.0f; + _velocity.Y = 0.0f; + _velocity.Z = 0.0f; + + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + + //_orientation.w = 0f; + //_orientation.X = 0f; + //_orientation.Y = 0f; + //_orientation.Z = 0f; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + if (!m_lastUpdateSent) + { + m_throttleUpdates = false; + throttleCounter = 0; + m_rotationalVelocity = pv; + + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } + + m_lastUpdateSent = true; + } + } + else + { + if (lastZeroFlag != _zeroFlag) + { + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } + } + + m_lastVelocity = _velocity; + + _position = l_position; + + _velocity.X = vel.X; + _velocity.Y = vel.Y; + _velocity.Z = vel.Z; + + _acceleration = ((_velocity - m_lastVelocity) / 0.1f); + _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); + //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); + + if (_velocity.ApproxEquals(pv, 0.5f)) + { + m_rotationalVelocity = pv; + } + else + { + m_rotationalVelocity = new Vector3(rotvel.X, rotvel.Y, rotvel.Z); + } + + //m_log.Debug("ODE: " + m_rotationalVelocity.ToString()); + _orientation.X = ori.X; + _orientation.Y = ori.Y; + _orientation.Z = ori.Z; + _orientation.W = ori.W; + m_lastUpdateSent = false; + if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) + { + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } + } + else + { + throttleCounter++; + } + } + m_lastposition = l_position; + } + else + { + // Not a body.. so Make sure the client isn't interpolating + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + _zeroFlag = true; + } + } + } + + public override bool FloatOnWater + { + set { + m_taintCollidesWater = value; + _parent_scene.AddPhysicsActorTaint(this); + } + } + + public override void SetMomentum(Vector3 momentum) + { + } + + public override Vector3 PIDTarget + { + set + { + if (value.IsFinite()) + { + m_PIDTarget = value; + } + else + m_log.Warn("[PHYSICS]: Got NaN PIDTarget from Scene on Object"); + } + } + public override bool PIDActive { set { m_usePID = value; } } + public override float PIDTau { set { m_PIDTau = value; } } + + // For RotLookAt + public override Quaternion APIDTarget { set { m_APIDTarget = value; } } + public override bool APIDActive { set { m_useAPID = value; } } + public override float APIDStrength { set { m_APIDStrength = value; } } + public override float APIDDamping { set { m_APIDDamping = value; } } + + public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } + public override bool PIDHoverActive { set { m_useHoverPID = value; } } + public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } + public override float PIDHoverTau { set { m_PIDHoverTau = value; } } + + private void createAMotor(Vector3 axis) + { + if (Body == IntPtr.Zero) + return; + + if (Amotor != IntPtr.Zero) + { + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; + } + + float axisnum = 3; + + axisnum = (axisnum - (axis.X + axis.Y + axis.Z)); + + // PhysicsVector totalSize = new PhysicsVector(_size.X, _size.Y, _size.Z); + + + // Inverse Inertia Matrix, set the X, Y, and/r Z inertia to 0 then invert it again. + d.Mass objMass; + d.MassSetZero(out objMass); + DMassCopy(ref pMass, ref objMass); + + //m_log.DebugFormat("1-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); + + Matrix4 dMassMat = FromDMass(objMass); + + Matrix4 mathmat = Inverse(dMassMat); + + /* + //m_log.DebugFormat("2-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", mathmat[0, 0], mathmat[0, 1], mathmat[0, 2], mathmat[1, 0], mathmat[1, 1], mathmat[1, 2], mathmat[2, 0], mathmat[2, 1], mathmat[2, 2]); + + mathmat = Inverse(mathmat); + + + objMass = FromMatrix4(mathmat, ref objMass); + //m_log.DebugFormat("3-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); + + mathmat = Inverse(mathmat); + */ + if (axis.X == 0) + { + mathmat.M33 = 50.0000001f; + //objMass.I.M22 = 0; + } + if (axis.Y == 0) + { + mathmat.M22 = 50.0000001f; + //objMass.I.M11 = 0; + } + if (axis.Z == 0) + { + mathmat.M11 = 50.0000001f; + //objMass.I.M00 = 0; + } + + + + mathmat = Inverse(mathmat); + objMass = FromMatrix4(mathmat, ref objMass); + //m_log.DebugFormat("4-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); + + //return; + if (d.MassCheck(ref objMass)) + { + d.BodySetMass(Body, ref objMass); + } + else + { + //m_log.Debug("[PHYSICS]: Mass invalid, ignoring"); + } + + if (axisnum <= 0) + return; + // int dAMotorEuler = 1; + + Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + d.JointAttach(Amotor, Body, IntPtr.Zero); + d.JointSetAMotorMode(Amotor, 0); + + d.JointSetAMotorNumAxes(Amotor,(int)axisnum); + int i = 0; + + if (axis.X == 0) + { + d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0); + i++; + } + + if (axis.Y == 0) + { + d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0); + i++; + } + + if (axis.Z == 0) + { + d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1); + i++; + } + + for (int j = 0; j < (int)axisnum; j++) + { + //d.JointSetAMotorAngle(Amotor, j, 0); + } + + //d.JointSetAMotorAngle(Amotor, 1, 0); + //d.JointSetAMotorAngle(Amotor, 2, 0); + + // These lowstops and high stops are effectively (no wiggle room) + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0f); + //d.JointSetAMotorParam(Amotor, (int) dParam.Vel, 9000f); + d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.FMax, Mass * 50f);// + + } + + public Matrix4 FromDMass(d.Mass pMass) + { + Matrix4 obj; + obj.M11 = pMass.I.M00; + obj.M12 = pMass.I.M01; + obj.M13 = pMass.I.M02; + obj.M14 = 0; + obj.M21 = pMass.I.M10; + obj.M22 = pMass.I.M11; + obj.M23 = pMass.I.M12; + obj.M24 = 0; + obj.M31 = pMass.I.M20; + obj.M32 = pMass.I.M21; + obj.M33 = pMass.I.M22; + obj.M34 = 0; + obj.M41 = 0; + obj.M42 = 0; + obj.M43 = 0; + obj.M44 = 1; + return obj; + } + + public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) + { + obj.I.M00 = pMat[0, 0]; + obj.I.M01 = pMat[0, 1]; + obj.I.M02 = pMat[0, 2]; + obj.I.M10 = pMat[1, 0]; + obj.I.M11 = pMat[1, 1]; + obj.I.M12 = pMat[1, 2]; + obj.I.M20 = pMat[2, 0]; + obj.I.M21 = pMat[2, 1]; + obj.I.M22 = pMat[2, 2]; + return obj; + } + + public override void SubscribeEvents(int ms) + { + m_eventsubscription = ms; + _parent_scene.addCollisionEventReporting(this); + } + + public override void UnSubscribeEvents() + { + _parent_scene.remCollisionEventReporting(this); + m_eventsubscription = 0; + } + + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) + { + if (CollisionEventsThisFrame == null) + CollisionEventsThisFrame = new CollisionEventUpdate(); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); + } + + public void SendCollisions() + { + if (CollisionEventsThisFrame == null) + return; + + base.SendCollisionUpdate(CollisionEventsThisFrame); + + if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) + CollisionEventsThisFrame = null; + else + CollisionEventsThisFrame = new CollisionEventUpdate(); + } + + public override bool SubscribedEvents() + { + if (m_eventsubscription > 0) + return true; + return false; + } + + public static Matrix4 Inverse(Matrix4 pMat) + { + if (determinant3x3(pMat) == 0) + { + return Matrix4.Identity; // should probably throw an error. singluar matrix inverse not possible + } + + + + return (Adjoint(pMat) / determinant3x3(pMat)); + } + + public static Matrix4 Adjoint(Matrix4 pMat) + { + Matrix4 adjointMatrix = new Matrix4(); + for (int i=0; i<4; i++) + { + for (int j=0; j<4; j++) + { + Matrix4SetValue(ref adjointMatrix, i, j, (float)(Math.Pow(-1, i + j) * (determinant3x3(Minor(pMat, i, j))))); + } + } + + adjointMatrix = Transpose(adjointMatrix); + return adjointMatrix; + } + + public static Matrix4 Minor(Matrix4 matrix, int iRow, int iCol) + { + Matrix4 minor = new Matrix4(); + int m = 0, n = 0; + for (int i = 0; i < 4; i++) + { + if (i == iRow) + continue; + n = 0; + for (int j = 0; j < 4; j++) + { + if (j == iCol) + continue; + Matrix4SetValue(ref minor, m,n, matrix[i, j]); + n++; + } + m++; + } + return minor; + } + + public static Matrix4 Transpose(Matrix4 pMat) + { + Matrix4 transposeMatrix = new Matrix4(); + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + Matrix4SetValue(ref transposeMatrix, i, j, pMat[j, i]); + return transposeMatrix; + } + + public static void Matrix4SetValue(ref Matrix4 pMat, int r, int c, float val) + { + switch (r) + { + case 0: + switch (c) + { + case 0: + pMat.M11 = val; + break; + case 1: + pMat.M12 = val; + break; + case 2: + pMat.M13 = val; + break; + case 3: + pMat.M14 = val; + break; + } + + break; + case 1: + switch (c) + { + case 0: + pMat.M21 = val; + break; + case 1: + pMat.M22 = val; + break; + case 2: + pMat.M23 = val; + break; + case 3: + pMat.M24 = val; + break; + } + + break; + case 2: + switch (c) + { + case 0: + pMat.M31 = val; + break; + case 1: + pMat.M32 = val; + break; + case 2: + pMat.M33 = val; + break; + case 3: + pMat.M34 = val; + break; + } + + break; + case 3: + switch (c) + { + case 0: + pMat.M41 = val; + break; + case 1: + pMat.M42 = val; + break; + case 2: + pMat.M43 = val; + break; + case 3: + pMat.M44 = val; + break; + } + + break; + } + } + private static float determinant3x3(Matrix4 pMat) + { + float det = 0; + float diag1 = pMat[0, 0]*pMat[1, 1]*pMat[2, 2]; + float diag2 = pMat[0, 1]*pMat[2, 1]*pMat[2, 0]; + float diag3 = pMat[0, 2]*pMat[1, 0]*pMat[2, 1]; + float diag4 = pMat[2, 0]*pMat[1, 1]*pMat[0, 2]; + float diag5 = pMat[2, 1]*pMat[1, 2]*pMat[0, 0]; + float diag6 = pMat[2, 2]*pMat[1, 0]*pMat[0, 1]; + + det = diag1 + diag2 + diag3 - (diag4 + diag5 + diag6); + return det; + + } + + private static void DMassCopy(ref d.Mass src, ref d.Mass dst) + { + dst.c.W = src.c.W; + dst.c.X = src.c.X; + dst.c.Y = src.c.Y; + dst.c.Z = src.c.Z; + dst.mass = src.mass; + dst.I.M00 = src.I.M00; + dst.I.M01 = src.I.M01; + dst.I.M02 = src.I.M02; + dst.I.M10 = src.I.M10; + dst.I.M11 = src.I.M11; + dst.I.M12 = src.I.M12; + dst.I.M20 = src.I.M20; + dst.I.M21 = src.I.M21; + dst.I.M22 = src.I.M22; + } + + public override void SetMaterial(int pMaterial) + { + m_material = pMaterial; + } + + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/ChOdePlugin/ODERayCastRequestManager.cs new file mode 100644 index 0000000..7314107 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/ODERayCastRequestManager.cs @@ -0,0 +1,375 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; +using OpenMetaverse; +using OpenSim.Region.Physics.Manager; +using Ode.NET; +using log4net; + +namespace OpenSim.Region.Physics.OdePlugin +{ + /// + /// Processes raycast requests as ODE is in a state to be able to do them. + /// This ensures that it's thread safe and there will be no conflicts. + /// Requests get returned by a different thread then they were requested by. + /// + public class ODERayCastRequestManager + { + /// + /// Pending Raycast Requests + /// + protected List m_PendingRequests = new List(); + + /// + /// Scene that created this object. + /// + private OdeScene m_scene; + + /// + /// ODE contact array to be filled by the collision testing + /// + d.ContactGeom[] contacts = new d.ContactGeom[5]; + + /// + /// ODE near callback delegate + /// + private d.NearCallback nearCallback; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private List m_contactResults = new List(); + + + public ODERayCastRequestManager(OdeScene pScene) + { + m_scene = pScene; + nearCallback = near; + + } + + /// + /// Queues a raycast + /// + /// Origin of Ray + /// Ray normal + /// Ray length + /// Return method to send the results + public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) + { + lock (m_PendingRequests) + { + ODERayCastRequest req = new ODERayCastRequest(); + req.callbackMethod = retMethod; + req.length = length; + req.Normal = direction; + req.Origin = position; + + m_PendingRequests.Add(req); + } + } + + /// + /// Process all queued raycast requests + /// + /// Time in MS the raycasts took to process. + public int ProcessQueuedRequests() + { + int time = System.Environment.TickCount; + lock (m_PendingRequests) + { + if (m_PendingRequests.Count > 0) + { + ODERayCastRequest[] reqs = m_PendingRequests.ToArray(); + for (int i = 0; i < reqs.Length; i++) + { + if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast + RayCast(reqs[i]); // if there isn't anyone to send results + } + /* + foreach (ODERayCastRequest req in m_PendingRequests) + { + if (req.callbackMethod != null) // quick optimization here, don't raycast + RayCast(req); // if there isn't anyone to send results to + + } + */ + m_PendingRequests.Clear(); + } + } + + lock (m_contactResults) + m_contactResults.Clear(); + + return System.Environment.TickCount - time; + } + + /// + /// Method that actually initiates the raycast + /// + /// + private void RayCast(ODERayCastRequest req) + { + // Create the ray + IntPtr ray = d.CreateRay(m_scene.space, req.length); + d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z); + + // Collide test + d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback); + + // Remove Ray + d.GeomDestroy(ray); + + + // Define default results + bool hitYN = false; + uint hitConsumerID = 0; + float distance = 999999999999f; + Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f); + Vector3 snormal = Vector3.Zero; + + // Find closest contact and object. + lock (m_contactResults) + { + foreach (ContactResult cResult in m_contactResults) + { + if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact)) + { + closestcontact = cResult.Pos; + hitConsumerID = cResult.ConsumerID; + distance = cResult.Depth; + hitYN = true; + snormal = cResult.Normal; + } + } + + m_contactResults.Clear(); + } + + // Return results + if (req.callbackMethod != null) + req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal); + } + + // This is the standard Near. Uses space AABBs to speed up detection. + private void near(IntPtr space, IntPtr g1, IntPtr g2) + { + + //Don't test against heightfield Geom, or you'll be sorry! + + /* + terminate called after throwing an instance of 'std::bad_alloc' + what(): std::bad_alloc + Stacktrace: + + at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004> + at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff> + at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280> + at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff + fffff> + at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004> + at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff> + at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) < + 0x00114> + at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb> + at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6> + at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042> + at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e> + at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019> + at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff> + + Native stacktrace: + + mono [0x80d2a42] + [0xb7f5840c] + /lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018] + /usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988] + /usr/lib/libstdc++.so.6 [0xb45fa865] + /usr/lib/libstdc++.so.6 [0xb45fa8a2] + /usr/lib/libstdc++.so.6 [0xb45fa9da] + /usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033] + /usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d] + libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4] + libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b] + libode.so(dCollide+0x102) [0xb46571b2] + [0x95cfdec9] + [0x8ea07fe1] + [0xab260146] + libode.so [0xb465a5c4] + libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5] + libode.so(dSpaceCollide2+0x177) [0xb465ac67] + [0x95cf978e] + [0x8ea07945] + [0x95cf2bbc] + [0xab2787e7] + [0xab419fb3] + [0xab416657] + [0xab415bda] + [0xb609b08e] + mono(mono_runtime_delegate_invoke+0x34) [0x8192534] + mono [0x81a2f0f] + mono [0x81d28b6] + mono [0x81ea2c6] + /lib/i686/cmov/libpthread.so.0 [0xb7e744c0] + /lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de] + */ + + // Exclude heightfield geom + + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass) + return; + + // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms. + if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) + { + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + + // Separating static prim geometry spaces. + // We'll be calling near recursivly if one + // of them is a space to find all of the + // contact points in the space + try + { + d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to collide test a space"); + return; + } + //Colliding a space or a geom with a space or a geom. so drill down + + //Collide all geoms in each space.. + //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); + //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); + return; + } + + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + + int count = 0; + try + { + + if (g1 == g2) + return; // Can't collide with yourself + + lock (contacts) + { + count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf); + } + } + catch (SEHException) + { + m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); + } + catch (Exception e) + { + m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); + return; + } + + PhysicsActor p1 = null; + PhysicsActor p2 = null; + + if (g1 != IntPtr.Zero) + m_scene.actor_name_map.TryGetValue(g1, out p1); + + if (g2 != IntPtr.Zero) + m_scene.actor_name_map.TryGetValue(g1, out p2); + + // Loop over contacts, build results. + for (int i = 0; i < count; i++) + { + if (p1 != null) { + if (p1 is OdePrim) + { + ContactResult collisionresult = new ContactResult(); + + collisionresult.ConsumerID = ((OdePrim)p1).m_localID; + collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); + collisionresult.Depth = contacts[i].depth; + collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, + contacts[i].normal.Z); + lock (m_contactResults) + m_contactResults.Add(collisionresult); + } + } + + if (p2 != null) + { + if (p2 is OdePrim) + { + ContactResult collisionresult = new ContactResult(); + + collisionresult.ConsumerID = ((OdePrim)p2).m_localID; + collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z); + collisionresult.Depth = contacts[i].depth; + collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y, + contacts[i].normal.Z); + + lock (m_contactResults) + m_contactResults.Add(collisionresult); + } + } + + + } + + } + + /// + /// Dereference the creator scene so that it can be garbage collected if needed. + /// + internal void Dispose() + { + m_scene = null; + } + } + + public struct ODERayCastRequest + { + public Vector3 Origin; + public Vector3 Normal; + public float length; + public RaycastCallback callbackMethod; + } + + public struct ContactResult + { + public Vector3 Pos; + public float Depth; + public uint ConsumerID; + public Vector3 Normal; + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePhysicsJoint.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePhysicsJoint.cs new file mode 100644 index 0000000..b4a3c48 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePhysicsJoint.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using OpenMetaverse; +using Ode.NET; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenSim.Region.Physics.OdePlugin; + +namespace OpenSim.Region.Physics.OdePlugin +{ + class OdePhysicsJoint : PhysicsJoint + { + public override bool IsInPhysicsEngine + { + get + { + return (jointID != IntPtr.Zero); + } + } + public IntPtr jointID; + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs new file mode 100644 index 0000000..f48649e --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -0,0 +1,3865 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#define USE_DRAWSTUFF + +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; +using System.IO; +using System.Diagnostics; +using log4net; +using Nini.Config; +using Ode.NET; +#if USE_DRAWSTUFF +using Drawstuff.NET; +#endif +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using OpenMetaverse; + +//using OpenSim.Region.Physics.OdePlugin.Meshing; + +namespace OpenSim.Region.Physics.OdePlugin +{ + /// + /// ODE plugin + /// + public class OdePlugin : IPhysicsPlugin + { + //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + + private CollisionLocker ode; + private OdeScene _mScene; + + public OdePlugin() + { + ode = new CollisionLocker(); + } + + public bool Init() + { + return true; + } + + public PhysicsScene GetScene(String sceneIdentifier) + { + if (_mScene == null) + { + // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to + // http://opensimulator.org/mantis/view.php?id=2750). + d.InitODE(); + + _mScene = new OdeScene(ode, sceneIdentifier); + } + return (_mScene); + } + + public string GetName() + { + return ("ChODE"); + } + + public void Dispose() + { + } + } + + public enum StatusIndicators : int + { + Generic = 0, + Start = 1, + End = 2 + } + + public struct sCollisionData + { + public uint ColliderLocalId; + public uint CollidedWithLocalId; + public int NumberOfCollisions; + public int CollisionType; + public int StatusIndicator; + public int lastframe; + } + + [Flags] + public enum CollisionCategories : int + { + Disabled = 0, + Geom = 0x00000001, + Body = 0x00000002, + Space = 0x00000004, + Character = 0x00000008, + Land = 0x00000010, + Water = 0x00000020, + Wind = 0x00000040, + Sensor = 0x00000080, + Selected = 0x00000100 + } + + /// + /// Material type for a primitive + /// + public enum Material : int + { + /// + Stone = 0, + /// + Metal = 1, + /// + Glass = 2, + /// + Wood = 3, + /// + Flesh = 4, + /// + Plastic = 5, + /// + Rubber = 6 + + } + + public sealed class OdeScene : PhysicsScene + { + private readonly ILog m_log; + // private Dictionary m_storedCollisions = new Dictionary(); + + CollisionLocker ode; + + private Random fluidRandomizer = new Random(Environment.TickCount); + + private const uint m_regionWidth = Constants.RegionSize; + private const uint m_regionHeight = Constants.RegionSize; + + private float ODE_STEPSIZE = 0.020f; + private float metersInSpace = 29.9f; + private float m_timeDilation = 1.0f; + + public float gravityx = 0f; + public float gravityy = 0f; + public float gravityz = -9.8f; + + private float contactsurfacelayer = 0.001f; + + private int worldHashspaceLow = -4; + private int worldHashspaceHigh = 128; + + private int smallHashspaceLow = -4; + private int smallHashspaceHigh = 66; + + private float waterlevel = 0f; + private int framecount = 0; + //private int m_returncollisions = 10; + + private readonly IntPtr contactgroup; + + internal IntPtr LandGeom; + internal IntPtr WaterGeom; + + private float nmTerrainContactFriction = 255.0f; + private float nmTerrainContactBounce = 0.1f; + private float nmTerrainContactERP = 0.1025f; + + private float mTerrainContactFriction = 75f; + private float mTerrainContactBounce = 0.1f; + private float mTerrainContactERP = 0.05025f; + + private float nmAvatarObjectContactFriction = 250f; + private float nmAvatarObjectContactBounce = 0.1f; + + private float mAvatarObjectContactFriction = 75f; + private float mAvatarObjectContactBounce = 0.1f; + + private float avPIDD = 3200f; + private float avPIDP = 1400f; + private float avCapRadius = 0.37f; + private float avStandupTensor = 2000000f; + private bool avCapsuleTilted = true; // true = old compatibility mode with leaning capsule; false = new corrected mode + public bool IsAvCapsuleTilted { get { return avCapsuleTilted; } set { avCapsuleTilted = value; } } + private float avDensity = 80f; + private float avHeightFudgeFactor = 0.52f; + private float avMovementDivisorWalk = 1.3f; + private float avMovementDivisorRun = 0.8f; + private float minimumGroundFlightOffset = 3f; + public float maximumMassObject = 10000.01f; + + public bool meshSculptedPrim = true; + public bool forceSimplePrimMeshing = false; + + public float meshSculptLOD = 32; + public float MeshSculptphysicalLOD = 16; + + public float geomDefaultDensity = 10.000006836f; + + public int geomContactPointsStartthrottle = 3; + public int geomUpdatesPerThrottledUpdate = 15; + + public float bodyPIDD = 35f; + public float bodyPIDG = 25; + + public int geomCrossingFailuresBeforeOutofbounds = 5; + + public float bodyMotorJointMaxforceTensor = 2; + + public int bodyFramesAutoDisable = 20; + + + + private float[] _watermap; + private bool m_filterCollisions = true; + + private d.NearCallback nearCallback; + public d.TriCallback triCallback; + public d.TriArrayCallback triArrayCallback; + private readonly HashSet _characters = new HashSet(); + private readonly HashSet _prims = new HashSet(); + private readonly HashSet _activeprims = new HashSet(); + private readonly HashSet _taintedPrimH = new HashSet(); + private readonly Object _taintedPrimLock = new Object(); + private readonly List _taintedPrimL = new List(); + private readonly HashSet _taintedActors = new HashSet(); + private readonly List _perloopContact = new List(); + private readonly List _collisionEventPrim = new List(); + private readonly HashSet _badCharacter = new HashSet(); + public Dictionary geom_name_map = new Dictionary(); + public Dictionary actor_name_map = new Dictionary(); + private bool m_NINJA_physics_joints_enabled = false; + //private Dictionary jointpart_name_map = new Dictionary(); + private readonly Dictionary> joints_connecting_actor = new Dictionary>(); + private d.ContactGeom[] contacts; + private readonly List requestedJointsToBeCreated = new List(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active + private readonly List pendingJoints = new List(); // can lock for longer. accessed only by OdeScene. + private readonly List activeJoints = new List(); // can lock for longer. accessed only by OdeScene. + private readonly List requestedJointsToBeDeleted = new List(); // lock only briefly. accessed by external code (to request deletion of joints) and by OdeScene.Simulate() to move those joints out of pending/active + private Object externalJointRequestsLock = new Object(); + private readonly Dictionary SOPName_to_activeJoint = new Dictionary(); + private readonly Dictionary SOPName_to_pendingJoint = new Dictionary(); + private readonly DoubleDictionary RegionTerrain = new DoubleDictionary(); + private readonly Dictionary TerrainHeightFieldHeights = new Dictionary(); + + private d.Contact contact; + private d.Contact TerrainContact; + private d.Contact AvatarMovementprimContact; + private d.Contact AvatarMovementTerrainContact; + private d.Contact WaterContact; + private d.Contact[,] m_materialContacts; + +//Ckrinke: Comment out until used. We declare it, initialize it, but do not use it +//Ckrinke private int m_randomizeWater = 200; + private int m_physicsiterations = 10; + private const float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag + private readonly PhysicsActor PANull = new NullPhysicsActor(); + private float step_time = 0.0f; +//Ckrinke: Comment out until used. We declare it, initialize it, but do not use it +//Ckrinke private int ms = 0; + public IntPtr world; + //private bool returncollisions = false; + // private uint obj1LocalID = 0; + private uint obj2LocalID = 0; + //private int ctype = 0; + private OdeCharacter cc1; + private OdePrim cp1; + private OdeCharacter cc2; + private OdePrim cp2; + //private int cStartStop = 0; + //private string cDictKey = ""; + + public IntPtr space; + + //private IntPtr tmpSpace; + // split static geometry collision handling into spaces of 30 meters + public IntPtr[,] staticPrimspace; + + public Object OdeLock; + + public IMesher mesher; + + private IConfigSource m_config; + + public bool physics_logging = false; + public int physics_logging_interval = 0; + public bool physics_logging_append_existing_logfile = false; + + public d.Vector3 xyz = new d.Vector3(128.1640f, 128.3079f, 25.7600f); + public d.Vector3 hpr = new d.Vector3(125.5000f, -17.0000f, 0.0000f); + + // TODO: unused: private uint heightmapWidth = m_regionWidth + 1; + // TODO: unused: private uint heightmapHeight = m_regionHeight + 1; + // TODO: unused: private uint heightmapWidthSamples; + // TODO: unused: private uint heightmapHeightSamples; + + private volatile int m_global_contactcount = 0; + + private Vector3 m_worldOffset = Vector3.Zero; + public Vector2 WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); + private PhysicsScene m_parentScene = null; + + private ODERayCastRequestManager m_rayCastManager; + + /// + /// Initiailizes the scene + /// Sets many properties that ODE requires to be stable + /// These settings need to be tweaked 'exactly' right or weird stuff happens. + /// + public OdeScene(CollisionLocker dode, string sceneIdentifier) + { + m_log + = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType.ToString() + "." + sceneIdentifier); + + OdeLock = new Object(); + ode = dode; + nearCallback = near; + triCallback = TriCallback; + triArrayCallback = TriArrayCallback; + m_rayCastManager = new ODERayCastRequestManager(this); + lock (OdeLock) + { + // Create the world and the first space + world = d.WorldCreate(); + space = d.HashSpaceCreate(IntPtr.Zero); + + + contactgroup = d.JointGroupCreate(0); + //contactgroup + + d.WorldSetAutoDisableFlag(world, false); + #if USE_DRAWSTUFF + + Thread viewthread = new Thread(new ParameterizedThreadStart(startvisualization)); + viewthread.Start(); + #endif + } + + + _watermap = new float[258 * 258]; + + // Zero out the prim spaces array (we split our space into smaller spaces so + // we can hit test less. + } + +#if USE_DRAWSTUFF + public void startvisualization(object o) + { + ds.Functions fn; + fn.version = ds.VERSION; + fn.start = new ds.CallbackFunction(start); + fn.step = new ds.CallbackFunction(step); + fn.command = new ds.CallbackFunction(command); + fn.stop = null; + fn.path_to_textures = "./textures"; + string[] args = new string[0]; + ds.SimulationLoop(args.Length, args, 352, 288, ref fn); + } +#endif + + // Initialize the mesh plugin + public override void Initialise(IMesher meshmerizer, IConfigSource config) + { + mesher = meshmerizer; + m_config = config; + // Defaults + + if (Environment.OSVersion.Platform == PlatformID.Unix) + { + avPIDD = 3200.0f; + avPIDP = 1400.0f; + avStandupTensor = 2000000f; + } + else + { + avPIDD = 2200.0f; + avPIDP = 900.0f; + avStandupTensor = 550000f; + } + + int contactsPerCollision = 80; + + if (m_config != null) + { + IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; + if (physicsconfig != null) + { + gravityx = physicsconfig.GetFloat("world_gravityx", 0f); + gravityy = physicsconfig.GetFloat("world_gravityy", 0f); + gravityz = physicsconfig.GetFloat("world_gravityz", -9.8f); + + worldHashspaceLow = physicsconfig.GetInt("world_hashspace_size_low", -4); + worldHashspaceHigh = physicsconfig.GetInt("world_hashspace_size_high", 128); + + metersInSpace = physicsconfig.GetFloat("meters_in_small_space", 29.9f); + smallHashspaceLow = physicsconfig.GetInt("small_hashspace_size_low", -4); + smallHashspaceHigh = physicsconfig.GetInt("small_hashspace_size_high", 66); + + contactsurfacelayer = physicsconfig.GetFloat("world_contact_surface_layer", 0.001f); + + nmTerrainContactFriction = physicsconfig.GetFloat("nm_terraincontact_friction", 255.0f); + nmTerrainContactBounce = physicsconfig.GetFloat("nm_terraincontact_bounce", 0.1f); + nmTerrainContactERP = physicsconfig.GetFloat("nm_terraincontact_erp", 0.1025f); + + mTerrainContactFriction = physicsconfig.GetFloat("m_terraincontact_friction", 75f); + mTerrainContactBounce = physicsconfig.GetFloat("m_terraincontact_bounce", 0.05f); + mTerrainContactERP = physicsconfig.GetFloat("m_terraincontact_erp", 0.05025f); + + nmAvatarObjectContactFriction = physicsconfig.GetFloat("objectcontact_friction", 250f); + nmAvatarObjectContactBounce = physicsconfig.GetFloat("objectcontact_bounce", 0.2f); + + mAvatarObjectContactFriction = physicsconfig.GetFloat("m_avatarobjectcontact_friction", 75f); + mAvatarObjectContactBounce = physicsconfig.GetFloat("m_avatarobjectcontact_bounce", 0.1f); + + ODE_STEPSIZE = physicsconfig.GetFloat("world_stepsize", 0.020f); + m_physicsiterations = physicsconfig.GetInt("world_internal_steps_without_collisions", 10); + + avDensity = physicsconfig.GetFloat("av_density", 80f); + avHeightFudgeFactor = physicsconfig.GetFloat("av_height_fudge_factor", 0.52f); + avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", 1.3f); + avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", 0.8f); + avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f); + avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", false); + + contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80); + + geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); + geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); + geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); + + geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); + bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); + + bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", 35f); + bodyPIDG = physicsconfig.GetFloat("body_pid_gain", 25f); + + forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing); + meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", true); + meshSculptLOD = physicsconfig.GetFloat("mesh_lod", 32f); + MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", 16f); + m_filterCollisions = physicsconfig.GetBoolean("filter_collisions", false); + + if (Environment.OSVersion.Platform == PlatformID.Unix) + { + avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", 2200.0f); + avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", 900.0f); + avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor_linux", 550000f); + bodyMotorJointMaxforceTensor = physicsconfig.GetFloat("body_motor_joint_maxforce_tensor_linux", 5f); + } + else + { + avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", 2200.0f); + avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", 900.0f); + avStandupTensor = physicsconfig.GetFloat("av_capsule_standup_tensor_win", 550000f); + bodyMotorJointMaxforceTensor = physicsconfig.GetFloat("body_motor_joint_maxforce_tensor_win", 5f); + } + + physics_logging = physicsconfig.GetBoolean("physics_logging", false); + physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); + physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); + + m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false); + minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f); + maximumMassObject = physicsconfig.GetFloat("maximum_mass_object", 10000.01f); + } + } + + contacts = new d.ContactGeom[contactsPerCollision]; + + staticPrimspace = new IntPtr[(int)(300 / metersInSpace), (int)(300 / metersInSpace)]; + + // Centeral contact friction and bounce + // ckrinke 11/10/08 Enabling soft_erp but not soft_cfm until I figure out why + // an avatar falls through in Z but not in X or Y when walking on a prim. + contact.surface.mode |= d.ContactFlags.SoftERP; + contact.surface.mu = nmAvatarObjectContactFriction; + contact.surface.bounce = nmAvatarObjectContactBounce; + contact.surface.soft_cfm = 0.010f; + contact.surface.soft_erp = 0.010f; + + // Terrain contact friction and Bounce + // This is the *non* moving version. Use this when an avatar + // isn't moving to keep it in place better + TerrainContact.surface.mode |= d.ContactFlags.SoftERP; + TerrainContact.surface.mu = nmTerrainContactFriction; + TerrainContact.surface.bounce = nmTerrainContactBounce; + TerrainContact.surface.soft_erp = nmTerrainContactERP; + + WaterContact.surface.mode |= (d.ContactFlags.SoftERP | d.ContactFlags.SoftCFM); + WaterContact.surface.mu = 0f; // No friction + WaterContact.surface.bounce = 0.0f; // No bounce + WaterContact.surface.soft_cfm = 0.010f; + WaterContact.surface.soft_erp = 0.010f; + + // Prim contact friction and bounce + // THis is the *non* moving version of friction and bounce + // Use this when an avatar comes in contact with a prim + // and is moving + AvatarMovementprimContact.surface.mu = mAvatarObjectContactFriction; + AvatarMovementprimContact.surface.bounce = mAvatarObjectContactBounce; + + // Terrain contact friction bounce and various error correcting calculations + // Use this when an avatar is in contact with the terrain and moving. + AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP; + AvatarMovementTerrainContact.surface.mu = mTerrainContactFriction; + AvatarMovementTerrainContact.surface.bounce = mTerrainContactBounce; + AvatarMovementTerrainContact.surface.soft_erp = mTerrainContactERP; + + + /* + + Stone = 0, + /// + Metal = 1, + /// + Glass = 2, + /// + Wood = 3, + /// + Flesh = 4, + /// + Plastic = 5, + /// + Rubber = 6 + */ + + m_materialContacts = new d.Contact[7,2]; + + m_materialContacts[(int)Material.Stone, 0] = new d.Contact(); + m_materialContacts[(int)Material.Stone, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Stone, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Stone, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Stone, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Stone, 1] = new d.Contact(); + m_materialContacts[(int)Material.Stone, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Stone, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Stone, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Stone, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Stone, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Metal, 0] = new d.Contact(); + m_materialContacts[(int)Material.Metal, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Metal, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Metal, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Metal, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Metal, 1] = new d.Contact(); + m_materialContacts[(int)Material.Metal, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Metal, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Metal, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Metal, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Metal, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Glass, 0] = new d.Contact(); + m_materialContacts[(int)Material.Glass, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 0].surface.mu = 1f; + m_materialContacts[(int)Material.Glass, 0].surface.bounce = 0.5f; + m_materialContacts[(int)Material.Glass, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Glass, 0].surface.soft_erp = 0.010f; + + /* + private float nmAvatarObjectContactFriction = 250f; + private float nmAvatarObjectContactBounce = 0.1f; + + private float mAvatarObjectContactFriction = 75f; + private float mAvatarObjectContactBounce = 0.1f; + */ + m_materialContacts[(int)Material.Glass, 1] = new d.Contact(); + m_materialContacts[(int)Material.Glass, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Glass, 1].surface.mu = 1f; + m_materialContacts[(int)Material.Glass, 1].surface.bounce = 0.5f; + m_materialContacts[(int)Material.Glass, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Glass, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Wood, 0] = new d.Contact(); + m_materialContacts[(int)Material.Wood, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Wood, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Wood, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Wood, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Wood, 1] = new d.Contact(); + m_materialContacts[(int)Material.Wood, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Wood, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Wood, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Wood, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Wood, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Flesh, 0] = new d.Contact(); + m_materialContacts[(int)Material.Flesh, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Flesh, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Flesh, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Flesh, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Flesh, 1] = new d.Contact(); + m_materialContacts[(int)Material.Flesh, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Flesh, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Flesh, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Flesh, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Flesh, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Plastic, 0] = new d.Contact(); + m_materialContacts[(int)Material.Plastic, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Plastic, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Plastic, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Plastic, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Plastic, 1] = new d.Contact(); + m_materialContacts[(int)Material.Plastic, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Plastic, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Plastic, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Plastic, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Plastic, 1].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Rubber, 0] = new d.Contact(); + m_materialContacts[(int)Material.Rubber, 0].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 0].surface.mu = nmAvatarObjectContactFriction; + m_materialContacts[(int)Material.Rubber, 0].surface.bounce = nmAvatarObjectContactBounce; + m_materialContacts[(int)Material.Rubber, 0].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Rubber, 0].surface.soft_erp = 0.010f; + + m_materialContacts[(int)Material.Rubber, 1] = new d.Contact(); + m_materialContacts[(int)Material.Rubber, 1].surface.mode |= d.ContactFlags.SoftERP; + m_materialContacts[(int)Material.Rubber, 1].surface.mu = mAvatarObjectContactFriction; + m_materialContacts[(int)Material.Rubber, 1].surface.bounce = mAvatarObjectContactBounce; + m_materialContacts[(int)Material.Rubber, 1].surface.soft_cfm = 0.010f; + m_materialContacts[(int)Material.Rubber, 1].surface.soft_erp = 0.010f; + + d.HashSpaceSetLevels(space, worldHashspaceLow, worldHashspaceHigh); + + // Set the gravity,, don't disable things automatically (we set it explicitly on some things) + + d.WorldSetGravity(world, gravityx, gravityy, gravityz); + d.WorldSetContactSurfaceLayer(world, contactsurfacelayer); + + d.WorldSetLinearDamping(world, 256f); + d.WorldSetAngularDamping(world, 256f); + d.WorldSetAngularDampingThreshold(world, 256f); + d.WorldSetLinearDampingThreshold(world, 256f); + d.WorldSetMaxAngularSpeed(world, 256f); + + // Set how many steps we go without running collision testing + // This is in addition to the step size. + // Essentially Steps * m_physicsiterations + d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + //d.WorldSetContactMaxCorrectingVel(world, 1000.0f); + + + + for (int i = 0; i < staticPrimspace.GetLength(0); i++) + { + for (int j = 0; j < staticPrimspace.GetLength(1); j++) + { + staticPrimspace[i, j] = IntPtr.Zero; + } + } + } + + internal void waitForSpaceUnlock(IntPtr space) + { + //if (space != IntPtr.Zero) + //while (d.SpaceLockQuery(space)) { } // Wait and do nothing + } + + /// + /// Debug space message for printing the space that a prim/avatar is in. + /// + /// + /// Returns which split up space the given position is in. + public string whichspaceamIin(Vector3 pos) + { + return calculateSpaceForGeom(pos).ToString(); + } + + #region Collision Detection + + /// + /// This is our near callback. A geometry is near a body + /// + /// The space that contains the geoms. Remember, spaces are also geoms + /// a geometry or space + /// another geometry or space + private void near(IntPtr space, IntPtr g1, IntPtr g2) + { + // no lock here! It's invoked from within Simulate(), which is thread-locked + + // Test if we're colliding a geom with a space. + // If so we have to drill down into the space recursively + + if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) + { + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + + // Separating static prim geometry spaces. + // We'll be calling near recursivly if one + // of them is a space to find all of the + // contact points in the space + try + { + d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to collide test a space"); + return; + } + //Colliding a space or a geom with a space or a geom. so drill down + + //Collide all geoms in each space.. + //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback); + //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback); + return; + } + + if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) + return; + + IntPtr b1 = d.GeomGetBody(g1); + IntPtr b2 = d.GeomGetBody(g2); + + // d.GeomClassID id = d.GeomGetClass(g1); + + String name1 = null; + String name2 = null; + + if (!geom_name_map.TryGetValue(g1, out name1)) + { + name1 = "null"; + } + if (!geom_name_map.TryGetValue(g2, out name2)) + { + name2 = "null"; + } + + //if (id == d.GeomClassId.TriMeshClass) + //{ + // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2); + //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); + //} + + // Figure out how many contact points we have + int count = 0; + try + { + // Colliding Geom To Geom + // This portion of the function 'was' blatantly ripped off from BoxStack.cs + + if (g1 == g2) + return; // Can't collide with yourself + + if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) + return; + + lock (contacts) + { + count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); + if (count > contacts.Length) + m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); + } + } + catch (SEHException) + { + m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim."); + ode.drelease(world); + base.TriggerPhysicsBasedRestart(); + } + catch (Exception e) + { + m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message); + return; + } + + PhysicsActor p1; + PhysicsActor p2; + + if (!actor_name_map.TryGetValue(g1, out p1)) + { + p1 = PANull; + } + + if (!actor_name_map.TryGetValue(g2, out p2)) + { + p2 = PANull; + } + + ContactPoint maxDepthContact = new ContactPoint(); + if (p1.CollisionScore + count >= float.MaxValue) + p1.CollisionScore = 0; + p1.CollisionScore += count; + + if (p2.CollisionScore + count >= float.MaxValue) + p2.CollisionScore = 0; + p2.CollisionScore += count; + + for (int i = 0; i < count; i++) + { + d.ContactGeom curContact = contacts[i]; + + if (curContact.depth > maxDepthContact.PenetrationDepth) + { + maxDepthContact = new ContactPoint( + new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), + new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), + curContact.depth + ); + } + + //m_log.Warn("[CCOUNT]: " + count); + IntPtr joint; + // If we're colliding with terrain, use 'TerrainContact' instead of contact. + // allows us to have different settings + + // We only need to test p2 for 'jump crouch purposes' + if (p2 is OdeCharacter && p1.PhysicsActorType == (int)ActorTypes.Prim) + { + // Testing if the collision is at the feet of the avatar + + //m_log.DebugFormat("[PHYSICS]: {0} - {1} - {2} - {3}", curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); + if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)) + p2.IsColliding = true; + } + else + { + p2.IsColliding = true; + } + + //if ((framecount % m_returncollisions) == 0) + + switch (p1.PhysicsActorType) + { + case (int)ActorTypes.Agent: + p2.CollidingObj = true; + break; + case (int)ActorTypes.Prim: + if (p2.Velocity.LengthSquared() > 0.0f) + p2.CollidingObj = true; + break; + case (int)ActorTypes.Unknown: + p2.CollidingGround = true; + break; + default: + p2.CollidingGround = true; + break; + } + + // we don't want prim or avatar to explode + + #region InterPenetration Handling - Unintended physics explosions +# region disabled code1 + + if (curContact.depth >= 0.08f) + { + //This is disabled at the moment only because it needs more tweaking + //It will eventually be uncommented + /* + if (contact.depth >= 1.00f) + { + //m_log.Debug("[PHYSICS]: " + contact.depth.ToString()); + } + + //If you interpenetrate a prim with an agent + if ((p2.PhysicsActorType == (int) ActorTypes.Agent && + p1.PhysicsActorType == (int) ActorTypes.Prim) || + (p1.PhysicsActorType == (int) ActorTypes.Agent && + p2.PhysicsActorType == (int) ActorTypes.Prim)) + { + + //contact.depth = contact.depth * 4.15f; + /* + if (p2.PhysicsActorType == (int) ActorTypes.Agent) + { + p2.CollidingObj = true; + contact.depth = 0.003f; + p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f); + OdeCharacter character = (OdeCharacter) p2; + character.SetPidStatus(true); + contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2)); + + } + else + { + + //contact.depth = 0.0000000f; + } + if (p1.PhysicsActorType == (int) ActorTypes.Agent) + { + + p1.CollidingObj = true; + contact.depth = 0.003f; + p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f); + contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2)); + OdeCharacter character = (OdeCharacter)p1; + character.SetPidStatus(true); + } + else + { + + //contact.depth = 0.0000000f; + } + + + + } +*/ + // If you interpenetrate a prim with another prim + /* + if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim) + { + #region disabledcode2 + //OdePrim op1 = (OdePrim)p1; + //OdePrim op2 = (OdePrim)p2; + //op1.m_collisionscore++; + //op2.m_collisionscore++; + + //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000) + //{ + //op1.m_taintdisable = true; + //AddPhysicsActorTaint(p1); + //op2.m_taintdisable = true; + //AddPhysicsActorTaint(p2); + //} + + //if (contact.depth >= 0.25f) + //{ + // Don't collide, one or both prim will expld. + + //op1.m_interpenetrationcount++; + //op2.m_interpenetrationcount++; + //interpenetrations_before_disable = 200; + //if (op1.m_interpenetrationcount >= interpenetrations_before_disable) + //{ + //op1.m_taintdisable = true; + //AddPhysicsActorTaint(p1); + //} + //if (op2.m_interpenetrationcount >= interpenetrations_before_disable) + //{ + // op2.m_taintdisable = true; + //AddPhysicsActorTaint(p2); + //} + + //contact.depth = contact.depth / 8f; + //contact.normal = new d.Vector3(0, 0, 1); + //} + //if (op1.m_disabled || op2.m_disabled) + //{ + //Manually disabled objects stay disabled + //contact.depth = 0f; + //} + #endregion + } + */ +#endregion + if (curContact.depth >= 1.00f) + { + //m_log.Info("[P]: " + contact.depth.ToString()); + if ((p2.PhysicsActorType == (int) ActorTypes.Agent && + p1.PhysicsActorType == (int) ActorTypes.Unknown) || + (p1.PhysicsActorType == (int) ActorTypes.Agent && + p2.PhysicsActorType == (int) ActorTypes.Unknown)) + { + if (p2.PhysicsActorType == (int) ActorTypes.Agent) + { + if (p2 is OdeCharacter) + { + OdeCharacter character = (OdeCharacter) p2; + + //p2.CollidingObj = true; + curContact.depth = 0.00000003f; + p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f); + curContact.pos = + new d.Vector3(curContact.pos.X + (p1.Size.X/2), + curContact.pos.Y + (p1.Size.Y/2), + curContact.pos.Z + (p1.Size.Z/2)); + character.SetPidStatus(true); + } + } + + + if (p1.PhysicsActorType == (int) ActorTypes.Agent) + { + if (p1 is OdeCharacter) + { + OdeCharacter character = (OdeCharacter) p1; + + //p2.CollidingObj = true; + curContact.depth = 0.00000003f; + p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f); + curContact.pos = + new d.Vector3(curContact.pos.X + (p1.Size.X/2), + curContact.pos.Y + (p1.Size.Y/2), + curContact.pos.Z + (p1.Size.Z/2)); + character.SetPidStatus(true); + } + } + } + } + } + + #endregion + + // Logic for collision handling + // Note, that if *all* contacts are skipped (VolumeDetect) + // The prim still detects (and forwards) collision events but + // appears to be phantom for the world + Boolean skipThisContact = false; + + if ((p1 is OdePrim) && (((OdePrim)p1).m_isVolumeDetect)) + skipThisContact = true; // No collision on volume detect prims + + if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect)) + skipThisContact = true; // No collision on volume detect prims + + if (!skipThisContact && curContact.depth < 0f) + skipThisContact = true; + + if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType)) + skipThisContact = true; + + const int maxContactsbeforedeath = 4000; + joint = IntPtr.Zero; + + if (!skipThisContact) + { + // If we're colliding against terrain + if (name1 == "Terrain" || name2 == "Terrain") + { + // If we're moving + if ((p2.PhysicsActorType == (int) ActorTypes.Agent) && + (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + { + // Use the movement terrain contact + AvatarMovementTerrainContact.geom = curContact; + _perloopContact.Add(curContact); + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact); + m_global_contactcount++; + } + } + else + { + if (p2.PhysicsActorType == (int)ActorTypes.Agent) + { + // Use the non moving terrain contact + TerrainContact.geom = curContact; + _perloopContact.Add(curContact); + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref TerrainContact); + m_global_contactcount++; + } + } + else + { + if (p2.PhysicsActorType == (int)ActorTypes.Prim && p1.PhysicsActorType == (int)ActorTypes.Prim) + { + // prim prim contact + // int pj294950 = 0; + int movintYN = 0; + int material = (int) Material.Wood; + // prim terrain contact + if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) + { + movintYN = 1; + } + + if (p2 is OdePrim) + material = ((OdePrim)p2).m_material; + + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, movintYN].geom = curContact; + _perloopContact.Add(curContact); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + m_global_contactcount++; + + } + + } + else + { + + int movintYN = 0; + // prim terrain contact + if (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f) + { + movintYN = 1; + } + + int material = (int)Material.Wood; + + if (p2 is OdePrim) + material = ((OdePrim)p2).m_material; + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, movintYN].geom = curContact; + _perloopContact.Add(curContact); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, movintYN]); + m_global_contactcount++; + + } + } + } + } + //if (p2.PhysicsActorType == (int)ActorTypes.Prim) + //{ + //m_log.Debug("[PHYSICS]: prim contacting with ground"); + //} + } + else if (name1 == "Water" || name2 == "Water") + { + /* + if ((p2.PhysicsActorType == (int) ActorTypes.Prim)) + { + } + else + { + } + */ + //WaterContact.surface.soft_cfm = 0.0000f; + //WaterContact.surface.soft_erp = 0.00000f; + if (curContact.depth > 0.1f) + { + curContact.depth *= 52; + //contact.normal = new d.Vector3(0, 0, 1); + //contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f); + } + WaterContact.geom = curContact; + _perloopContact.Add(curContact); + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref WaterContact); + m_global_contactcount++; + } + //m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth); + } + else + { + // we're colliding with prim or avatar + // check if we're moving + if ((p2.PhysicsActorType == (int)ActorTypes.Agent)) + { + if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f)) + { + // Use the Movement prim contact + AvatarMovementprimContact.geom = curContact; + _perloopContact.Add(curContact); + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact); + m_global_contactcount++; + } + } + else + { + // Use the non movement contact + contact.geom = curContact; + _perloopContact.Add(curContact); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref contact); + m_global_contactcount++; + } + } + } + else if (p2.PhysicsActorType == (int)ActorTypes.Prim) + { + //p1.PhysicsActorType + int material = (int)Material.Wood; + + if (p2 is OdePrim) + material = ((OdePrim)p2).m_material; + + //m_log.DebugFormat("Material: {0}", material); + m_materialContacts[material, 0].geom = curContact; + _perloopContact.Add(curContact); + + if (m_global_contactcount < maxContactsbeforedeath) + { + joint = d.JointCreateContact(world, contactgroup, ref m_materialContacts[material, 0]); + m_global_contactcount++; + + } + } + } + + if (m_global_contactcount < maxContactsbeforedeath && joint != IntPtr.Zero) // stack collide! + { + d.JointAttach(joint, b1, b2); + m_global_contactcount++; + } + + } + collision_accounting_events(p1, p2, maxDepthContact); + if (count > geomContactPointsStartthrottle) + { + // If there are more then 3 contact points, it's likely + // that we've got a pile of objects, so ... + // We don't want to send out hundreds of terse updates over and over again + // so lets throttle them and send them again after it's somewhat sorted out. + p2.ThrottleUpdates = true; + } + //m_log.Debug(count.ToString()); + //m_log.Debug("near: A collision was detected between {1} and {2}", 0, name1, name2); + } + } + + private bool checkDupe(d.ContactGeom contactGeom, int atype) + { + bool result = false; + //return result; + if (!m_filterCollisions) + return false; + + ActorTypes at = (ActorTypes)atype; + lock (_perloopContact) + { + foreach (d.ContactGeom contact in _perloopContact) + { + //if ((contact.g1 == contactGeom.g1 && contact.g2 == contactGeom.g2)) + //{ + // || (contact.g2 == contactGeom.g1 && contact.g1 == contactGeom.g2) + if (at == ActorTypes.Agent) + { + if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) + { + + if (Math.Abs(contact.depth - contactGeom.depth) < 0.052f) + { + //contactGeom.depth *= .00005f; + //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); + // m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); + result = true; + break; + } + else + { + //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); + } + } + else + { + //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); + //int i = 0; + } + } + else if (at == ActorTypes.Prim) + { + //d.AABB aabb1 = new d.AABB(); + //d.AABB aabb2 = new d.AABB(); + + //d.GeomGetAABB(contactGeom.g2, out aabb2); + //d.GeomGetAABB(contactGeom.g1, out aabb1); + //aabb1. + if (((Math.Abs(contactGeom.normal.X - contact.normal.X) < 1.026f) && (Math.Abs(contactGeom.normal.Y - contact.normal.Y) < 0.303f) && (Math.Abs(contactGeom.normal.Z - contact.normal.Z) < 0.065f)) && contactGeom.g1 != LandGeom && contactGeom.g2 != LandGeom) + { + if (contactGeom.normal.X == contact.normal.X && contactGeom.normal.Y == contact.normal.Y && contactGeom.normal.Z == contact.normal.Z) + { + if (Math.Abs(contact.depth - contactGeom.depth) < 0.272f) + { + result = true; + break; + } + } + //m_log.DebugFormat("[Collsion]: Depth {0}", Math.Abs(contact.depth - contactGeom.depth)); + //m_log.DebugFormat("[Collision]: <{0},{1},{2}>", Math.Abs(contactGeom.normal.X - contact.normal.X), Math.Abs(contactGeom.normal.Y - contact.normal.Y), Math.Abs(contactGeom.normal.Z - contact.normal.Z)); + } + + } + + //} + + } + } + return result; + } + + private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) + { + // obj1LocalID = 0; + //returncollisions = false; + obj2LocalID = 0; + //ctype = 0; + //cStartStop = 0; + if (!p2.SubscribedEvents() && !p1.SubscribedEvents()) + return; + + switch ((ActorTypes)p2.PhysicsActorType) + { + case ActorTypes.Agent: + cc2 = (OdeCharacter)p2; + + // obj1LocalID = cc2.m_localID; + switch ((ActorTypes)p1.PhysicsActorType) + { + case ActorTypes.Agent: + cc1 = (OdeCharacter)p1; + obj2LocalID = cc1.m_localID; + cc1.AddCollisionEvent(cc2.m_localID, contact); + //ctype = (int)CollisionCategories.Character; + + //if (cc1.CollidingObj) + //cStartStop = (int)StatusIndicators.Generic; + //else + //cStartStop = (int)StatusIndicators.Start; + + //returncollisions = true; + break; + case ActorTypes.Prim: + if (p1 is OdePrim) + { + cp1 = (OdePrim) p1; + obj2LocalID = cp1.m_localID; + cp1.AddCollisionEvent(cc2.m_localID, contact); + } + //ctype = (int)CollisionCategories.Geom; + + //if (cp1.CollidingObj) + //cStartStop = (int)StatusIndicators.Generic; + //else + //cStartStop = (int)StatusIndicators.Start; + + //returncollisions = true; + break; + + case ActorTypes.Ground: + case ActorTypes.Unknown: + obj2LocalID = 0; + //ctype = (int)CollisionCategories.Land; + //returncollisions = true; + break; + } + + cc2.AddCollisionEvent(obj2LocalID, contact); + break; + case ActorTypes.Prim: + + if (p2 is OdePrim) + { + cp2 = (OdePrim) p2; + + // obj1LocalID = cp2.m_localID; + switch ((ActorTypes) p1.PhysicsActorType) + { + case ActorTypes.Agent: + if (p1 is OdeCharacter) + { + cc1 = (OdeCharacter) p1; + obj2LocalID = cc1.m_localID; + cc1.AddCollisionEvent(cp2.m_localID, contact); + //ctype = (int)CollisionCategories.Character; + + //if (cc1.CollidingObj) + //cStartStop = (int)StatusIndicators.Generic; + //else + //cStartStop = (int)StatusIndicators.Start; + //returncollisions = true; + } + break; + case ActorTypes.Prim: + + if (p1 is OdePrim) + { + cp1 = (OdePrim) p1; + obj2LocalID = cp1.m_localID; + cp1.AddCollisionEvent(cp2.m_localID, contact); + //ctype = (int)CollisionCategories.Geom; + + //if (cp1.CollidingObj) + //cStartStop = (int)StatusIndicators.Generic; + //else + //cStartStop = (int)StatusIndicators.Start; + + //returncollisions = true; + } + break; + + case ActorTypes.Ground: + case ActorTypes.Unknown: + obj2LocalID = 0; + //ctype = (int)CollisionCategories.Land; + + //returncollisions = true; + break; + } + + cp2.AddCollisionEvent(obj2LocalID, contact); + } + break; + } + //if (returncollisions) + //{ + + //lock (m_storedCollisions) + //{ + //cDictKey = obj1LocalID.ToString() + obj2LocalID.ToString() + cStartStop.ToString() + ctype.ToString(); + //if (m_storedCollisions.ContainsKey(cDictKey)) + //{ + //sCollisionData objd = m_storedCollisions[cDictKey]; + //objd.NumberOfCollisions += 1; + //objd.lastframe = framecount; + //m_storedCollisions[cDictKey] = objd; + //} + //else + //{ + //sCollisionData objd = new sCollisionData(); + //objd.ColliderLocalId = obj1LocalID; + //objd.CollidedWithLocalId = obj2LocalID; + //objd.CollisionType = ctype; + //objd.NumberOfCollisions = 1; + //objd.lastframe = framecount; + //objd.StatusIndicator = cStartStop; + //m_storedCollisions.Add(cDictKey, objd); + //} + //} + // } + } + + public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount) + { + /* String name1 = null; + String name2 = null; + + if (!geom_name_map.TryGetValue(trimesh, out name1)) + { + name1 = "null"; + } + if (!geom_name_map.TryGetValue(refObject, out name2)) + { + name2 = "null"; + } + + m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2); + */ + return 1; + } + + public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex) + { + String name1 = null; + String name2 = null; + + if (!geom_name_map.TryGetValue(trimesh, out name1)) + { + name1 = "null"; + } + + if (!geom_name_map.TryGetValue(refObject, out name2)) + { + name2 = "null"; + } + + // m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex); + + d.Vector3 v0 = new d.Vector3(); + d.Vector3 v1 = new d.Vector3(); + d.Vector3 v2 = new d.Vector3(); + + d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2); + // m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z); + + return 1; + } + + /// + /// This is our collision testing routine in ODE + /// + /// + private void collision_optimized(float timeStep) + { + _perloopContact.Clear(); + + lock (_characters) + { + foreach (OdeCharacter chr in _characters) + { + // Reset the collision values to false + // since we don't know if we're colliding yet + + // For some reason this can happen. Don't ask... + // + if (chr == null) + continue; + + if (chr.Shell == IntPtr.Zero || chr.Body == IntPtr.Zero) + continue; + + chr.IsColliding = false; + chr.CollidingGround = false; + chr.CollidingObj = false; + + // test the avatar's geometry for collision with the space + // This will return near and the space that they are the closest to + // And we'll run this again against the avatar and the space segment + // This will return with a bunch of possible objects in the space segment + // and we'll run it again on all of them. + try + { + d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback); + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to space collide"); + } + //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y); + //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10) + //{ + //chr.Position.Z = terrainheight + 10.0f; + //forcedZ = true; + //} + } + } + + lock (_activeprims) + { + List removeprims = null; + foreach (OdePrim chr in _activeprims) + { + if (chr.Body != IntPtr.Zero && d.BodyIsEnabled(chr.Body) && (!chr.m_disabled)) + { + try + { + lock (chr) + { + if (space != IntPtr.Zero && chr.prim_geom != IntPtr.Zero && chr.m_taintremove == false) + { + d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback); + } + else + { + if (removeprims == null) + { + removeprims = new List(); + } + removeprims.Add(chr); + m_log.Debug("[PHYSICS]: unable to collide test active prim against space. The space was zero, the geom was zero or it was in the process of being removed. Removed it from the active prim list. This needs to be fixed!"); + } + } + } + catch (AccessViolationException) + { + m_log.Warn("[PHYSICS]: Unable to space collide"); + } + } + } + if (removeprims != null) + { + foreach (OdePrim chr in removeprims) + { + _activeprims.Remove(chr); + } + } + } + + _perloopContact.Clear(); + } + + #endregion + + public override void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) + { + m_worldOffset = offset; + WorldExtents = new Vector2(extents.X, extents.Y); + m_parentScene = pScene; + + } + + // Recovered for use by fly height. Kitto Flora + public float GetTerrainHeightAtXY(float x, float y) + { + + int offsetX = ((int)(x / (int)Constants.RegionSize)) * (int)Constants.RegionSize; + int offsetY = ((int)(y / (int)Constants.RegionSize)) * (int)Constants.RegionSize; + + IntPtr heightFieldGeom = IntPtr.Zero; + + if (RegionTerrain.TryGetValue(new Vector3(offsetX,offsetY,0), out heightFieldGeom)) + { + if (heightFieldGeom != IntPtr.Zero) + { + if (TerrainHeightFieldHeights.ContainsKey(heightFieldGeom)) + { + + int index; + + + if ((int)x > WorldExtents.X || (int)y > WorldExtents.Y || + (int)x < 0.001f || (int)y < 0.001f) + return 0; + + x = x - offsetX; + y = y - offsetY; + + index = (int)((int)x * ((int)Constants.RegionSize + 2) + (int)y); + + if (index < TerrainHeightFieldHeights[heightFieldGeom].Length) + { + //m_log.DebugFormat("x{0} y{1} = {2}", x, y, (float)TerrainHeightFieldHeights[heightFieldGeom][index]); + return (float)TerrainHeightFieldHeights[heightFieldGeom][index]; + } + + else + return 0f; + } + else + { + return 0f; + } + + } + else + { + return 0f; + } + + } + else + { + return 0f; + } + + + } +// End recovered. Kitto Flora + + public void addCollisionEventReporting(PhysicsActor obj) + { + lock (_collisionEventPrim) + { + if (!_collisionEventPrim.Contains(obj)) + _collisionEventPrim.Add(obj); + } + } + + public void remCollisionEventReporting(PhysicsActor obj) + { + lock (_collisionEventPrim) + { + if (!_collisionEventPrim.Contains(obj)) + _collisionEventPrim.Remove(obj); + } + } + + #region Add/Remove Entities + + public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) + { + Vector3 pos; + pos.X = position.X; + pos.Y = position.Y; + pos.Z = position.Z; + OdeCharacter newAv = new OdeCharacter(avName, this, pos, ode, size, avPIDD, avPIDP, avCapRadius, avStandupTensor, avDensity, avHeightFudgeFactor, avMovementDivisorWalk, avMovementDivisorRun); + newAv.Flying = isFlying; + newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; + + return newAv; + } + + public void AddCharacter(OdeCharacter chr) + { + lock (_characters) + { + if (!_characters.Contains(chr)) + { + _characters.Add(chr); + if (chr.bad) + m_log.DebugFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); + } + } + } + + public void RemoveCharacter(OdeCharacter chr) + { + lock (_characters) + { + if (_characters.Contains(chr)) + { + _characters.Remove(chr); + } + } + } + public void BadCharacter(OdeCharacter chr) + { + lock (_badCharacter) + { + if (!_badCharacter.Contains(chr)) + _badCharacter.Add(chr); + } + } + + public override void RemoveAvatar(PhysicsActor actor) + { + //m_log.Debug("[PHYSICS]:ODELOCK"); + ((OdeCharacter) actor).Destroy(); + + } + + private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, + IMesh mesh, PrimitiveBaseShape pbs, bool isphysical) + { + + Vector3 pos = position; + Vector3 siz = size; + Quaternion rot = rotation; + + OdePrim newPrim; + lock (OdeLock) + { + newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode); + + lock (_prims) + _prims.Add(newPrim); + } + + return newPrim; + } + + public void addActivePrim(OdePrim activatePrim) + { + // adds active prim.. (ones that should be iterated over in collisions_optimized + lock (_activeprims) + { + if (!_activeprims.Contains(activatePrim)) + _activeprims.Add(activatePrim); + //else + // m_log.Warn("[PHYSICS]: Double Entry in _activeprims detected, potential crash immenent"); + } + } + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation) //To be removed + { + return AddPrimShape(primName, pbs, position, size, rotation, false); + } + + public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position, + Vector3 size, Quaternion rotation, bool isPhysical) + { + PhysicsActor result; + IMesh mesh = null; + + if (needsMeshing(pbs)) + mesh = mesher.CreateMesh(primName, pbs, size, 32f, isPhysical); + + result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical); + + return result; + } + + public override float TimeDilation + { + get { return m_timeDilation; } + } + + public override bool SupportsNINJAJoints + { + get { return m_NINJA_physics_joints_enabled; } + } + + // internal utility function: must be called within a lock (OdeLock) + private void InternalAddActiveJoint(PhysicsJoint joint) + { + activeJoints.Add(joint); + SOPName_to_activeJoint.Add(joint.ObjectNameInScene, joint); + } + + // internal utility function: must be called within a lock (OdeLock) + private void InternalAddPendingJoint(OdePhysicsJoint joint) + { + pendingJoints.Add(joint); + SOPName_to_pendingJoint.Add(joint.ObjectNameInScene, joint); + } + + // internal utility function: must be called within a lock (OdeLock) + private void InternalRemovePendingJoint(PhysicsJoint joint) + { + pendingJoints.Remove(joint); + SOPName_to_pendingJoint.Remove(joint.ObjectNameInScene); + } + + // internal utility function: must be called within a lock (OdeLock) + private void InternalRemoveActiveJoint(PhysicsJoint joint) + { + activeJoints.Remove(joint); + SOPName_to_activeJoint.Remove(joint.ObjectNameInScene); + } + + public override void DumpJointInfo() + { + string hdr = "[NINJA] JOINTINFO: "; + foreach (PhysicsJoint j in pendingJoints) + { + m_log.Debug(hdr + " pending joint, Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); + } + m_log.Debug(hdr + pendingJoints.Count + " total pending joints"); + foreach (string jointName in SOPName_to_pendingJoint.Keys) + { + m_log.Debug(hdr + " pending joints dict contains Name: " + jointName); + } + m_log.Debug(hdr + SOPName_to_pendingJoint.Keys.Count + " total pending joints dict entries"); + foreach (PhysicsJoint j in activeJoints) + { + m_log.Debug(hdr + " active joint, Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); + } + m_log.Debug(hdr + activeJoints.Count + " total active joints"); + foreach (string jointName in SOPName_to_activeJoint.Keys) + { + m_log.Debug(hdr + " active joints dict contains Name: " + jointName); + } + m_log.Debug(hdr + SOPName_to_activeJoint.Keys.Count + " total active joints dict entries"); + + m_log.Debug(hdr + " Per-body joint connectivity information follows."); + m_log.Debug(hdr + joints_connecting_actor.Keys.Count + " bodies are connected by joints."); + foreach (string actorName in joints_connecting_actor.Keys) + { + m_log.Debug(hdr + " Actor " + actorName + " has the following joints connecting it"); + foreach (PhysicsJoint j in joints_connecting_actor[actorName]) + { + m_log.Debug(hdr + " * joint Name: " + j.ObjectNameInScene + " raw parms:" + j.RawParams); + } + m_log.Debug(hdr + joints_connecting_actor[actorName].Count + " connecting joints total for this actor"); + } + } + + public override void RequestJointDeletion(string ObjectNameInScene) + { + lock (externalJointRequestsLock) + { + if (!requestedJointsToBeDeleted.Contains(ObjectNameInScene)) // forbid same deletion request from entering twice to prevent spurious deletions processed asynchronously + { + requestedJointsToBeDeleted.Add(ObjectNameInScene); + } + } + } + + private void DeleteRequestedJoints() + { + List myRequestedJointsToBeDeleted; + lock (externalJointRequestsLock) + { + // make a local copy of the shared list for processing (threading issues) + myRequestedJointsToBeDeleted = new List(requestedJointsToBeDeleted); + } + + foreach (string jointName in myRequestedJointsToBeDeleted) + { + lock (OdeLock) + { + //m_log.Debug("[NINJA] trying to deleting requested joint " + jointName); + if (SOPName_to_activeJoint.ContainsKey(jointName) || SOPName_to_pendingJoint.ContainsKey(jointName)) + { + OdePhysicsJoint joint = null; + if (SOPName_to_activeJoint.ContainsKey(jointName)) + { + joint = SOPName_to_activeJoint[jointName] as OdePhysicsJoint; + InternalRemoveActiveJoint(joint); + } + else if (SOPName_to_pendingJoint.ContainsKey(jointName)) + { + joint = SOPName_to_pendingJoint[jointName] as OdePhysicsJoint; + InternalRemovePendingJoint(joint); + } + + if (joint != null) + { + //m_log.Debug("joint.BodyNames.Count is " + joint.BodyNames.Count + " and contents " + joint.BodyNames); + for (int iBodyName = 0; iBodyName < 2; iBodyName++) + { + string bodyName = joint.BodyNames[iBodyName]; + if (bodyName != "NULL") + { + joints_connecting_actor[bodyName].Remove(joint); + if (joints_connecting_actor[bodyName].Count == 0) + { + joints_connecting_actor.Remove(bodyName); + } + } + } + + DoJointDeactivated(joint); + if (joint.jointID != IntPtr.Zero) + { + d.JointDestroy(joint.jointID); + joint.jointID = IntPtr.Zero; + //DoJointErrorMessage(joint, "successfully destroyed joint " + jointName); + } + else + { + //m_log.Warn("[NINJA] Ignoring re-request to destroy joint " + jointName); + } + } + else + { + // DoJointErrorMessage(joint, "coult not find joint to destroy based on name " + jointName); + } + } + else + { + // DoJointErrorMessage(joint, "WARNING - joint removal failed, joint " + jointName); + } + } + } + + // remove processed joints from the shared list + lock (externalJointRequestsLock) + { + foreach (string jointName in myRequestedJointsToBeDeleted) + { + requestedJointsToBeDeleted.Remove(jointName); + } + } + } + + // for pending joints we don't know if their associated bodies exist yet or not. + // the joint is actually created during processing of the taints + private void CreateRequestedJoints() + { + List myRequestedJointsToBeCreated; + lock (externalJointRequestsLock) + { + // make a local copy of the shared list for processing (threading issues) + myRequestedJointsToBeCreated = new List(requestedJointsToBeCreated); + } + + foreach (PhysicsJoint joint in myRequestedJointsToBeCreated) + { + lock (OdeLock) + { + if (SOPName_to_pendingJoint.ContainsKey(joint.ObjectNameInScene) && SOPName_to_pendingJoint[joint.ObjectNameInScene] != null) + { + DoJointErrorMessage(joint, "WARNING: ignoring request to re-add already pending joint Name:" + joint.ObjectNameInScene + " type:" + joint.Type + " parms: " + joint.RawParams + " pos: " + joint.Position + " rot:" + joint.Rotation); + continue; + } + if (SOPName_to_activeJoint.ContainsKey(joint.ObjectNameInScene) && SOPName_to_activeJoint[joint.ObjectNameInScene] != null) + { + DoJointErrorMessage(joint, "WARNING: ignoring request to re-add already active joint Name:" + joint.ObjectNameInScene + " type:" + joint.Type + " parms: " + joint.RawParams + " pos: " + joint.Position + " rot:" + joint.Rotation); + continue; + } + + InternalAddPendingJoint(joint as OdePhysicsJoint); + + if (joint.BodyNames.Count >= 2) + { + for (int iBodyName = 0; iBodyName < 2; iBodyName++) + { + string bodyName = joint.BodyNames[iBodyName]; + if (bodyName != "NULL") + { + if (!joints_connecting_actor.ContainsKey(bodyName)) + { + joints_connecting_actor.Add(bodyName, new List()); + } + joints_connecting_actor[bodyName].Add(joint); + } + } + } + } + } + + // remove processed joints from shared list + lock (externalJointRequestsLock) + { + foreach (PhysicsJoint joint in myRequestedJointsToBeCreated) + { + requestedJointsToBeCreated.Remove(joint); + } + } + + } + + // public function to add an request for joint creation + // this joint will just be added to a waiting list that is NOT processed during the main + // Simulate() loop (to avoid deadlocks). After Simulate() is finished, we handle unprocessed joint requests. + + public override PhysicsJoint RequestJointCreation(string objectNameInScene, PhysicsJointType jointType, Vector3 position, + Quaternion rotation, string parms, List bodyNames, string trackedBodyName, Quaternion localRotation) + + { + + OdePhysicsJoint joint = new OdePhysicsJoint(); + joint.ObjectNameInScene = objectNameInScene; + joint.Type = jointType; + joint.Position = position; + joint.Rotation = rotation; + joint.RawParams = parms; + joint.BodyNames = new List(bodyNames); + joint.TrackedBodyName = trackedBodyName; + joint.LocalRotation = localRotation; + joint.jointID = IntPtr.Zero; + joint.ErrorMessageCount = 0; + + lock (externalJointRequestsLock) + { + if (!requestedJointsToBeCreated.Contains(joint)) // forbid same creation request from entering twice + { + requestedJointsToBeCreated.Add(joint); + } + } + return joint; + } + + private void RemoveAllJointsConnectedToActor(PhysicsActor actor) + { + //m_log.Debug("RemoveAllJointsConnectedToActor: start"); + if (actor.SOPName != null && joints_connecting_actor.ContainsKey(actor.SOPName) && joints_connecting_actor[actor.SOPName] != null) + { + + List jointsToRemove = new List(); + //TODO: merge these 2 loops (originally it was needed to avoid altering a list being iterated over, but it is no longer needed due to the joint request queue mechanism) + foreach (PhysicsJoint j in joints_connecting_actor[actor.SOPName]) + { + jointsToRemove.Add(j); + } + foreach (PhysicsJoint j in jointsToRemove) + { + //m_log.Debug("RemoveAllJointsConnectedToActor: about to request deletion of " + j.ObjectNameInScene); + RequestJointDeletion(j.ObjectNameInScene); + //m_log.Debug("RemoveAllJointsConnectedToActor: done request deletion of " + j.ObjectNameInScene); + j.TrackedBodyName = null; // *IMMEDIATELY* prevent any further movement of this joint (else a deleted actor might cause spurious tracking motion of the joint for a few frames, leading to the joint proxy object disappearing) + } + } + } + + public override void RemoveAllJointsConnectedToActorThreadLocked(PhysicsActor actor) + { + //m_log.Debug("RemoveAllJointsConnectedToActorThreadLocked: start"); + lock (OdeLock) + { + //m_log.Debug("RemoveAllJointsConnectedToActorThreadLocked: got lock"); + RemoveAllJointsConnectedToActor(actor); + } + } + + // normally called from within OnJointMoved, which is called from within a lock (OdeLock) + public override Vector3 GetJointAnchor(PhysicsJoint joint) + { + Debug.Assert(joint.IsInPhysicsEngine); + d.Vector3 pos = new d.Vector3(); + + if (!(joint is OdePhysicsJoint)) + { + DoJointErrorMessage(joint, "warning: non-ODE joint requesting anchor: " + joint.ObjectNameInScene); + } + else + { + OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint; + switch (odeJoint.Type) + { + case PhysicsJointType.Ball: + d.JointGetBallAnchor(odeJoint.jointID, out pos); + break; + case PhysicsJointType.Hinge: + d.JointGetHingeAnchor(odeJoint.jointID, out pos); + break; + } + } + return new Vector3(pos.X, pos.Y, pos.Z); + } + + // normally called from within OnJointMoved, which is called from within a lock (OdeLock) + // WARNING: ODE sometimes returns <0,0,0> as the joint axis! Therefore this function + // appears to be unreliable. Fortunately we can compute the joint axis ourselves by + // keeping track of the joint's original orientation relative to one of the involved bodies. + public override Vector3 GetJointAxis(PhysicsJoint joint) + { + Debug.Assert(joint.IsInPhysicsEngine); + d.Vector3 axis = new d.Vector3(); + + if (!(joint is OdePhysicsJoint)) + { + DoJointErrorMessage(joint, "warning: non-ODE joint requesting anchor: " + joint.ObjectNameInScene); + } + else + { + OdePhysicsJoint odeJoint = (OdePhysicsJoint)joint; + switch (odeJoint.Type) + { + case PhysicsJointType.Ball: + DoJointErrorMessage(joint, "warning - axis requested for ball joint: " + joint.ObjectNameInScene); + break; + case PhysicsJointType.Hinge: + d.JointGetHingeAxis(odeJoint.jointID, out axis); + break; + } + } + return new Vector3(axis.X, axis.Y, axis.Z); + } + + + public void remActivePrim(OdePrim deactivatePrim) + { + lock (_activeprims) + { + _activeprims.Remove(deactivatePrim); + } + } + + public override void RemovePrim(PhysicsActor prim) + { + if (prim is OdePrim) + { + lock (OdeLock) + { + OdePrim p = (OdePrim) prim; + + p.setPrimForRemoval(); + AddPhysicsActorTaint(prim); + //RemovePrimThreadLocked(p); + } + } + } + + /// + /// This is called from within simulate but outside the locked portion + /// We need to do our own locking here + /// Essentially, we need to remove the prim from our space segment, whatever segment it's in. + /// + /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory + /// that the space was using. + /// + /// + public void RemovePrimThreadLocked(OdePrim prim) + { +//Console.WriteLine("RemovePrimThreadLocked " + prim.m_primName); + lock (prim) + { + remCollisionEventReporting(prim); + lock (ode) + { + if (prim.prim_geom != IntPtr.Zero) + { + prim.ResetTaints(); + + if (prim.IsPhysical) + { + prim.disableBody(); + if (prim.childPrim) + { + prim.childPrim = false; + prim.Body = IntPtr.Zero; + prim.m_disabled = true; + prim.IsPhysical = false; + } + + + } + // we don't want to remove the main space + + // If the geometry is in the targetspace, remove it from the target space + //m_log.Warn(prim.m_targetSpace); + + //if (prim.m_targetSpace != IntPtr.Zero) + //{ + //if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom)) + //{ + + //if (d.GeomIsSpace(prim.m_targetSpace)) + //{ + //waitForSpaceUnlock(prim.m_targetSpace); + //d.SpaceRemove(prim.m_targetSpace, prim.prim_geom); + prim.m_targetSpace = IntPtr.Zero; + //} + //else + //{ + // m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + + //((OdePrim)prim).m_targetSpace.ToString()); + //} + + //} + //} + //m_log.Warn(prim.prim_geom); + try + { + if (prim.prim_geom != IntPtr.Zero) + { + d.GeomDestroy(prim.prim_geom); + prim.prim_geom = IntPtr.Zero; + } + else + { + m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene"); + } + } + catch (AccessViolationException) + { + m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed."); + } + lock (_prims) + _prims.Remove(prim); + + //If there are no more geometries in the sub-space, we don't need it in the main space anymore + //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0) + //{ + //if (prim.m_targetSpace != null) + //{ + //if (d.GeomIsSpace(prim.m_targetSpace)) + //{ + //waitForSpaceUnlock(prim.m_targetSpace); + //d.SpaceRemove(space, prim.m_targetSpace); + // free up memory used by the space. + //d.SpaceDestroy(prim.m_targetSpace); + //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position); + //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]); + //} + //else + //{ + //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" + + //((OdePrim) prim).m_targetSpace.ToString()); + //} + //} + //} + + if (SupportsNINJAJoints) + { + RemoveAllJointsConnectedToActorThreadLocked(prim); + } + } + } + } + } + + #endregion + + #region Space Separation Calculation + + /// + /// Takes a space pointer and zeros out the array we're using to hold the spaces + /// + /// + public void resetSpaceArrayItemToZero(IntPtr pSpace) + { + for (int x = 0; x < staticPrimspace.GetLength(0); x++) + { + for (int y = 0; y < staticPrimspace.GetLength(1); y++) + { + if (staticPrimspace[x, y] == pSpace) + staticPrimspace[x, y] = IntPtr.Zero; + } + } + } + + public void resetSpaceArrayItemToZero(int arrayitemX, int arrayitemY) + { + staticPrimspace[arrayitemX, arrayitemY] = IntPtr.Zero; + } + + /// + /// Called when a static prim moves. Allocates a space for the prim based on its position + /// + /// the pointer to the geom that moved + /// the position that the geom moved to + /// a pointer to the space it was in before it was moved. + /// a pointer to the new space it's in + public IntPtr recalculateSpaceForGeom(IntPtr geom, Vector3 pos, IntPtr currentspace) + { + // Called from setting the Position and Size of an ODEPrim so + // it's already in locked space. + + // we don't want to remove the main space + // we don't need to test physical here because this function should + // never be called if the prim is physical(active) + + // All physical prim end up in the root space + //Thread.Sleep(20); + if (currentspace != space) + { + //m_log.Info("[SPACE]: C:" + currentspace.ToString() + " g:" + geom.ToString()); + //if (currentspace == IntPtr.Zero) + //{ + //int adfadf = 0; + //} + if (d.SpaceQuery(currentspace, geom) && currentspace != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { + waitForSpaceUnlock(currentspace); + d.SpaceRemove(currentspace, geom); + } + else + { + m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + currentspace + + " Geom:" + geom); + } + } + else + { + IntPtr sGeomIsIn = d.GeomGetSpace(geom); + if (sGeomIsIn != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { + waitForSpaceUnlock(sGeomIsIn); + d.SpaceRemove(sGeomIsIn, geom); + } + else + { + m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + + sGeomIsIn + " Geom:" + geom); + } + } + } + + //If there are no more geometries in the sub-space, we don't need it in the main space anymore + if (d.SpaceGetNumGeoms(currentspace) == 0) + { + if (currentspace != IntPtr.Zero) + { + if (d.GeomIsSpace(currentspace)) + { + waitForSpaceUnlock(currentspace); + waitForSpaceUnlock(space); + d.SpaceRemove(space, currentspace); + // free up memory used by the space. + + //d.SpaceDestroy(currentspace); + resetSpaceArrayItemToZero(currentspace); + } + else + { + m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + + currentspace + " Geom:" + geom); + } + } + } + } + else + { + // this is a physical object that got disabled. ;.; + if (currentspace != IntPtr.Zero && geom != IntPtr.Zero) + { + if (d.SpaceQuery(currentspace, geom)) + { + if (d.GeomIsSpace(currentspace)) + { + waitForSpaceUnlock(currentspace); + d.SpaceRemove(currentspace, geom); + } + else + { + m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + + currentspace + " Geom:" + geom); + } + } + else + { + IntPtr sGeomIsIn = d.GeomGetSpace(geom); + if (sGeomIsIn != IntPtr.Zero) + { + if (d.GeomIsSpace(sGeomIsIn)) + { + waitForSpaceUnlock(sGeomIsIn); + d.SpaceRemove(sGeomIsIn, geom); + } + else + { + m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + + sGeomIsIn + " Geom:" + geom); + } + } + } + } + } + + // The routines in the Position and Size sections do the 'inserting' into the space, + // so all we have to do is make sure that the space that we're putting the prim into + // is in the 'main' space. + int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos); + IntPtr newspace = calculateSpaceForGeom(pos); + + if (newspace == IntPtr.Zero) + { + newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]); + d.HashSpaceSetLevels(newspace, smallHashspaceLow, smallHashspaceHigh); + } + + return newspace; + } + + /// + /// Creates a new space at X Y + /// + /// + /// + /// A pointer to the created space + public IntPtr createprimspace(int iprimspaceArrItemX, int iprimspaceArrItemY) + { + // creating a new space for prim and inserting it into main space. + staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero); + d.GeomSetCategoryBits(staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY], (int)CollisionCategories.Space); + waitForSpaceUnlock(space); + d.SpaceSetSublevel(space, 1); + d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]); + return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]; + } + + /// + /// Calculates the space the prim should be in by its position + /// + /// + /// a pointer to the space. This could be a new space or reused space. + public IntPtr calculateSpaceForGeom(Vector3 pos) + { + int[] xyspace = calculateSpaceArrayItemFromPos(pos); + //m_log.Info("[Physics]: Attempting to use arrayItem: " + xyspace[0].ToString() + "," + xyspace[1].ToString()); + return staticPrimspace[xyspace[0], xyspace[1]]; + } + + /// + /// Holds the space allocation logic + /// + /// + /// an array item based on the position + public int[] calculateSpaceArrayItemFromPos(Vector3 pos) + { + int[] returnint = new int[2]; + + returnint[0] = (int) (pos.X/metersInSpace); + + if (returnint[0] > ((int) (259f/metersInSpace))) + returnint[0] = ((int) (259f/metersInSpace)); + if (returnint[0] < 0) + returnint[0] = 0; + + returnint[1] = (int) (pos.Y/metersInSpace); + if (returnint[1] > ((int) (259f/metersInSpace))) + returnint[1] = ((int) (259f/metersInSpace)); + if (returnint[1] < 0) + returnint[1] = 0; + + return returnint; + } + + #endregion + + /// + /// Routine to figure out if we need to mesh this prim with our mesher + /// + /// + /// + public bool needsMeshing(PrimitiveBaseShape pbs) + { + // most of this is redundant now as the mesher will return null if it cant mesh a prim + // but we still need to check for sculptie meshing being enabled so this is the most + // convenient place to do it for now... + + // //if (pbs.PathCurve == (byte)Primitive.PathCurve.Circle && pbs.ProfileCurve == (byte)Primitive.ProfileCurve.Circle && pbs.PathScaleY <= 0.75f) + // //m_log.Debug("needsMeshing: " + " pathCurve: " + pbs.PathCurve.ToString() + " profileCurve: " + pbs.ProfileCurve.ToString() + " pathScaleY: " + Primitive.UnpackPathScale(pbs.PathScaleY).ToString()); + int iPropertiesNotSupportedDefault = 0; + + if (pbs.SculptEntry && !meshSculptedPrim) + { +#if SPAM + m_log.Warn("NonMesh"); +#endif + return false; + } + + // if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim + if (!forceSimplePrimMeshing) + { + if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight) + || (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 + && pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z)) + { + + if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0 + && pbs.ProfileHollow == 0 + && pbs.PathTwist == 0 && pbs.PathTwistBegin == 0 + && pbs.PathBegin == 0 && pbs.PathEnd == 0 + && pbs.PathTaperX == 0 && pbs.PathTaperY == 0 + && pbs.PathScaleX == 100 && pbs.PathScaleY == 100 + && pbs.PathShearX == 0 && pbs.PathShearY == 0) + { +#if SPAM + m_log.Warn("NonMesh"); +#endif + return false; + } + } + } + + if (pbs.ProfileHollow != 0) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0)) + iPropertiesNotSupportedDefault++; + + if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100)) + iPropertiesNotSupportedDefault++; + + if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0)) + iPropertiesNotSupportedDefault++; + + if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight) + iPropertiesNotSupportedDefault++; + + if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X)) + iPropertiesNotSupportedDefault++; + + if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1) + iPropertiesNotSupportedDefault++; + + // test for torus + if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square) + { + if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) + { + if (pbs.PathCurve == (byte)Extrusion.Straight) + { + iPropertiesNotSupportedDefault++; + } + + // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits + else if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) + { + if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2) + { + iPropertiesNotSupportedDefault++; + } + } + else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) + { + if (pbs.PathCurve == (byte)Extrusion.Straight) + { + iPropertiesNotSupportedDefault++; + } + else if (pbs.PathCurve == (byte)Extrusion.Curve1) + { + iPropertiesNotSupportedDefault++; + } + } + + + if (iPropertiesNotSupportedDefault == 0) + { +#if SPAM + m_log.Warn("NonMesh"); +#endif + return false; + } +#if SPAM + m_log.Debug("Mesh"); +#endif + return true; + } + + /// + /// Called after our prim properties are set Scale, position etc. + /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex + /// This assures us that we have no race conditions + /// + /// + public override void AddPhysicsActorTaint(PhysicsActor prim) + { + + if (prim is OdePrim) + { + OdePrim taintedprim = ((OdePrim) prim); + lock (_taintedPrimLock) + { + if (!(_taintedPrimH.Contains(taintedprim))) + { +//Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.m_primName); + _taintedPrimH.Add(taintedprim); // HashSet for searching + _taintedPrimL.Add(taintedprim); // List for ordered readout + } + } + return; + } + else if (prim is OdeCharacter) + { + OdeCharacter taintedchar = ((OdeCharacter)prim); + lock (_taintedActors) + { + if (!(_taintedActors.Contains(taintedchar))) + { + _taintedActors.Add(taintedchar); + if (taintedchar.bad) + m_log.DebugFormat("[PHYSICS]: Added BAD actor {0} to tainted actors", taintedchar.m_uuid); + } + } + } + } + + /// + /// This is our main simulate loop + /// It's thread locked by a Mutex in the scene. + /// It holds Collisions, it instructs ODE to step through the physical reactions + /// It moves the objects around in memory + /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup) + /// + /// + /// + public override float Simulate(float timeStep) + { + if (framecount >= int.MaxValue) + framecount = 0; + + //if (m_worldOffset != Vector3.Zero) + // return 0; + + framecount++; + + float fps = 0; + //m_log.Info(timeStep.ToString()); + step_time += timeStep; + + // If We're loaded down by something else, + // or debugging with the Visual Studio project on pause + // skip a few frames to catch up gracefully. + // without shooting the physicsactors all over the place + + if (step_time >= m_SkipFramesAtms) + { + // Instead of trying to catch up, it'll do 5 physics frames only + step_time = ODE_STEPSIZE; + m_physicsiterations = 5; + } + else + { + m_physicsiterations = 10; + } + + if (SupportsNINJAJoints) + { + DeleteRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks + CreateRequestedJoints(); // this must be outside of the lock (OdeLock) to avoid deadlocks + } + + lock (OdeLock) + { + // Process 10 frames if the sim is running normal.. + // process 5 frames if the sim is running slow + //try + //{ + //d.WorldSetQuickStepNumIterations(world, m_physicsiterations); + //} + //catch (StackOverflowException) + //{ + // m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim."); + // ode.drelease(world); + //base.TriggerPhysicsBasedRestart(); + //} + + int i = 0; + + // Figure out the Frames Per Second we're going at. + //(step_time == 0.004f, there's 250 of those per second. Times the step time/step size + + fps = (step_time / ODE_STEPSIZE) * 1000; + // HACK: Using a time dilation of 1.0 to debug rubberbanding issues + //m_timeDilation = Math.Min((step_time / ODE_STEPSIZE) / (0.09375f / ODE_STEPSIZE), 1.0f); + + step_time = 0.09375f; + + while (step_time > 0.0f) + { + //lock (ode) + //{ + //if (!ode.lockquery()) + //{ + // ode.dlock(world); + try + { + // Insert, remove Characters + bool processedtaints = false; + + lock (_taintedActors) + { + if (_taintedActors.Count > 0) + { + foreach (OdeCharacter character in _taintedActors) + { + + character.ProcessTaints(timeStep); + + processedtaints = true; + //character.m_collisionscore = 0; + } + + if (processedtaints) + _taintedActors.Clear(); + } + } + + // Modify other objects in the scene. + processedtaints = false; + + lock (_taintedPrimLock) + { + foreach (OdePrim prim in _taintedPrimL) + { + if (prim.m_taintremove) + { + //Console.WriteLine("Simulate calls RemovePrimThreadLocked"); + RemovePrimThreadLocked(prim); + } + else + { + //Console.WriteLine("Simulate calls ProcessTaints"); + prim.ProcessTaints(timeStep); + } + processedtaints = true; + prim.m_collisionscore = 0; + + // This loop can block up the Heartbeat for a very long time on large regions. + // We need to let the Watchdog know that the Heartbeat is not dead + // NOTE: This is currently commented out, but if things like OAR loading are + // timing the heartbeat out we will need to uncomment it + //Watchdog.UpdateThread(); + } + + if (SupportsNINJAJoints) + { + // Create pending joints, if possible + + // joints can only be processed after ALL bodies are processed (and exist in ODE), since creating + // a joint requires specifying the body id of both involved bodies + if (pendingJoints.Count > 0) + { + List successfullyProcessedPendingJoints = new List(); + //DoJointErrorMessage(joints_connecting_actor, "taint: " + pendingJoints.Count + " pending joints"); + foreach (PhysicsJoint joint in pendingJoints) + { + //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); + string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + List jointBodies = new List(); + bool allJointBodiesAreReady = true; + foreach (string jointParam in jointParams) + { + if (jointParam == "NULL") + { + //DoJointErrorMessage(joint, "attaching NULL joint to world"); + jointBodies.Add(IntPtr.Zero); + } + else + { + //DoJointErrorMessage(joint, "looking for prim name: " + jointParam); + bool foundPrim = false; + lock (_prims) + { + foreach (OdePrim prim in _prims) // FIXME: inefficient + { + if (prim.SOPName == jointParam) + { + //DoJointErrorMessage(joint, "found for prim name: " + jointParam); + if (prim.IsPhysical && prim.Body != IntPtr.Zero) + { + jointBodies.Add(prim.Body); + foundPrim = true; + break; + } + else + { + DoJointErrorMessage(joint, "prim name " + jointParam + + " exists but is not (yet) physical; deferring joint creation. " + + "IsPhysical property is " + prim.IsPhysical + + " and body is " + prim.Body); + foundPrim = false; + break; + } + } + } + } + if (foundPrim) + { + // all is fine + } + else + { + allJointBodiesAreReady = false; + break; + } + } + } + if (allJointBodiesAreReady) + { + //DoJointErrorMessage(joint, "allJointBodiesAreReady for " + joint.ObjectNameInScene + " with parms " + joint.RawParams); + if (jointBodies[0] == jointBodies[1]) + { + DoJointErrorMessage(joint, "ERROR: joint cannot be created; the joint bodies are the same, body1==body2. Raw body is " + jointBodies[0] + ". raw parms: " + joint.RawParams); + } + else + { + switch (joint.Type) + { + case PhysicsJointType.Ball: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating ball joint "); + odeJoint = d.JointCreateBall(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching ball joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting ball anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetBallAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + //DoJointErrorMessage(joint, "ODE joint setting OK"); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b0: "); + //DoJointErrorMessage(joint, "" + (jointBodies[0] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[0]) : "fixed environment")); + //DoJointErrorMessage(joint, "The ball joint's bodies are here: b1: "); + //DoJointErrorMessage(joint, "" + (jointBodies[1] != IntPtr.Zero ? "" + d.BodyGetPosition(jointBodies[1]) : "fixed environment")); + + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + case PhysicsJointType.Hinge: + { + IntPtr odeJoint; + //DoJointErrorMessage(joint, "ODE creating hinge joint "); + odeJoint = d.JointCreateHinge(world, IntPtr.Zero); + //DoJointErrorMessage(joint, "ODE attaching hinge joint: " + odeJoint + " with b1:" + jointBodies[0] + " b2:" + jointBodies[1]); + d.JointAttach(odeJoint, jointBodies[0], jointBodies[1]); + //DoJointErrorMessage(joint, "ODE setting hinge anchor: " + odeJoint + " to vec:" + joint.Position); + d.JointSetHingeAnchor(odeJoint, + joint.Position.X, + joint.Position.Y, + joint.Position.Z); + // We use the orientation of the x-axis of the joint's coordinate frame + // as the axis for the hinge. + + // Therefore, we must get the joint's coordinate frame based on the + // joint.Rotation field, which originates from the orientation of the + // joint's proxy object in the scene. + + // The joint's coordinate frame is defined as the transformation matrix + // that converts a vector from joint-local coordinates into world coordinates. + // World coordinates are defined as the XYZ coordinate system of the sim, + // as shown in the top status-bar of the viewer. + + // Once we have the joint's coordinate frame, we extract its X axis (AtAxis) + // and use that as the hinge axis. + + //joint.Rotation.Normalize(); + Matrix4 proxyFrame = Matrix4.CreateFromQuaternion(joint.Rotation); + + // Now extract the X axis of the joint's coordinate frame. + + // Do not try to use proxyFrame.AtAxis or you will become mired in the + // tar pit of transposed, inverted, and generally messed-up orientations. + // (In other words, Matrix4.AtAxis() is borked.) + // Vector3 jointAxis = proxyFrame.AtAxis; <--- this path leadeth to madness + + // Instead, compute the X axis of the coordinate frame by transforming + // the (1,0,0) vector. At least that works. + + //m_log.Debug("PHY: making axis: complete matrix is " + proxyFrame); + Vector3 jointAxis = Vector3.Transform(Vector3.UnitX, proxyFrame); + //m_log.Debug("PHY: making axis: hinge joint axis is " + jointAxis); + //DoJointErrorMessage(joint, "ODE setting hinge axis: " + odeJoint + " to vec:" + jointAxis); + d.JointSetHingeAxis(odeJoint, + jointAxis.X, + jointAxis.Y, + jointAxis.Z); + //d.JointSetHingeParam(odeJoint, (int)dParam.CFM, 0.1f); + if (joint is OdePhysicsJoint) + { + ((OdePhysicsJoint)joint).jointID = odeJoint; + } + else + { + DoJointErrorMessage(joint, "WARNING: non-ode joint in ODE!"); + } + } + break; + } + successfullyProcessedPendingJoints.Add(joint); + } + } + else + { + DoJointErrorMessage(joint, "joint could not yet be created; still pending"); + } + } + foreach (PhysicsJoint successfullyProcessedJoint in successfullyProcessedPendingJoints) + { + //DoJointErrorMessage(successfullyProcessedJoint, "finalizing succesfully procsssed joint " + successfullyProcessedJoint.ObjectNameInScene + " parms " + successfullyProcessedJoint.RawParams); + //DoJointErrorMessage(successfullyProcessedJoint, "removing from pending"); + InternalRemovePendingJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "adding to active"); + InternalAddActiveJoint(successfullyProcessedJoint); + //DoJointErrorMessage(successfullyProcessedJoint, "done"); + } + } + } + + if (processedtaints) +//Console.WriteLine("Simulate calls Clear of _taintedPrim list"); + _taintedPrimH.Clear(); + _taintedPrimL.Clear(); + } + + // Move characters + lock (_characters) + { + List defects = new List(); + foreach (OdeCharacter actor in _characters) + { + if (actor != null) + actor.Move(timeStep, defects); + } + if (0 != defects.Count) + { + foreach (OdeCharacter defect in defects) + { + RemoveCharacter(defect); + } + } + } + + // Move other active objects + lock (_activeprims) + { + foreach (OdePrim prim in _activeprims) + { + prim.m_collisionscore = 0; + prim.Move(timeStep); + } + } + + //if ((framecount % m_randomizeWater) == 0) + // randomizeWater(waterlevel); + + //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); + m_rayCastManager.ProcessQueuedRequests(); + + collision_optimized(timeStep); + + lock (_collisionEventPrim) + { + foreach (PhysicsActor obj in _collisionEventPrim) + { + if (obj == null) + continue; + + switch ((ActorTypes)obj.PhysicsActorType) + { + case ActorTypes.Agent: + OdeCharacter cobj = (OdeCharacter)obj; + cobj.AddCollisionFrameTime(100); + cobj.SendCollisions(); + break; + case ActorTypes.Prim: + OdePrim pobj = (OdePrim)obj; + pobj.SendCollisions(); + break; + } + } + } + + //if (m_global_contactcount > 5) + //{ + // m_log.DebugFormat("[PHYSICS]: Contacts:{0}", m_global_contactcount); + //} + + m_global_contactcount = 0; + + d.WorldQuickStep(world, ODE_STEPSIZE); + d.JointGroupEmpty(contactgroup); + //ode.dunlock(world); + } + catch (Exception e) + { + m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); + ode.dunlock(world); + } + + step_time -= ODE_STEPSIZE; + i++; + //} + //else + //{ + //fps = 0; + //} + //} + } + + lock (_characters) + { + foreach (OdeCharacter actor in _characters) + { + if (actor != null) + { + if (actor.bad) + m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); + actor.UpdatePositionAndVelocity(); + } + } + } + + lock (_badCharacter) + { + if (_badCharacter.Count > 0) + { + foreach (OdeCharacter chr in _badCharacter) + { + RemoveCharacter(chr); + } + _badCharacter.Clear(); + } + } + + lock (_activeprims) + { + //if (timeStep < 0.2f) + { + foreach (OdePrim actor in _activeprims) + { + if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag)) + { + actor.UpdatePositionAndVelocity(); + + if (SupportsNINJAJoints) + { + // If an actor moved, move its joint proxy objects as well. + // There seems to be an event PhysicsActor.OnPositionUpdate that could be used + // for this purpose but it is never called! So we just do the joint + // movement code here. + + if (actor.SOPName != null && + joints_connecting_actor.ContainsKey(actor.SOPName) && + joints_connecting_actor[actor.SOPName] != null && + joints_connecting_actor[actor.SOPName].Count > 0) + { + foreach (PhysicsJoint affectedJoint in joints_connecting_actor[actor.SOPName]) + { + if (affectedJoint.IsInPhysicsEngine) + { + DoJointMoved(affectedJoint); + } + else + { + DoJointErrorMessage(affectedJoint, "a body connected to a joint was moved, but the joint doesn't exist yet! this will lead to joint error. joint was: " + affectedJoint.ObjectNameInScene + " parms:" + affectedJoint.RawParams); + } + } + } + } + } + } + } + } + + //DumpJointInfo(); + + // Finished with all sim stepping. If requested, dump world state to file for debugging. + // TODO: This call to the export function is already inside lock (OdeLock) - but is an extra lock needed? + // TODO: This overwrites all dump files in-place. Should this be a growing logfile, or separate snapshots? + if (physics_logging && (physics_logging_interval>0) && (framecount % physics_logging_interval == 0)) + { + string fname = "state-" + world.ToString() + ".DIF"; // give each physics world a separate filename + string prefix = "world" + world.ToString(); // prefix for variable names in exported .DIF file + + if (physics_logging_append_existing_logfile) + { + string header = "-------------- START OF PHYSICS FRAME " + framecount.ToString() + " --------------"; + TextWriter fwriter = File.AppendText(fname); + fwriter.WriteLine(header); + fwriter.Close(); + } + d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); + } + } + + return fps; + } + + public override void GetResults() + { + } + + public override bool IsThreaded + { + // for now we won't be multithreaded + get { return (false); } + } + + #region ODE Specific Terrain Fixes + public float[] ResizeTerrain512NearestNeighbour(float[] heightMap) + { + float[] returnarr = new float[262144]; + float[,] resultarr = new float[(int)WorldExtents.X, (int)WorldExtents.Y]; + + // Filling out the array into its multi-dimensional components + for (int y = 0; y < WorldExtents.Y; y++) + { + for (int x = 0; x < WorldExtents.X; x++) + { + resultarr[y, x] = heightMap[y * (int)WorldExtents.Y + x]; + } + } + + // Resize using Nearest Neighbour + + // This particular way is quick but it only works on a multiple of the original + + // The idea behind this method can be described with the following diagrams + // second pass and third pass happen in the same loop really.. just separated + // them to show what this does. + + // First Pass + // ResultArr: + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + + // Second Pass + // ResultArr2: + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + + // Third pass fills in the blanks + // ResultArr2: + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + + // X,Y = . + // X+1,y = ^ + // X,Y+1 = * + // X+1,Y+1 = # + + // Filling in like this; + // .* + // ^# + // 1st . + // 2nd * + // 3rd ^ + // 4th # + // on single loop. + + float[,] resultarr2 = new float[512, 512]; + for (int y = 0; y < WorldExtents.Y; y++) + { + for (int x = 0; x < WorldExtents.X; x++) + { + resultarr2[y * 2, x * 2] = resultarr[y, x]; + + if (y < WorldExtents.Y) + { + resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x]; + } + if (x < WorldExtents.X) + { + resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x]; + } + if (x < WorldExtents.X && y < WorldExtents.Y) + { + resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x]; + } + } + } + + //Flatten out the array + int i = 0; + for (int y = 0; y < 512; y++) + { + for (int x = 0; x < 512; x++) + { + if (resultarr2[y, x] <= 0) + returnarr[i] = 0.0000001f; + else + returnarr[i] = resultarr2[y, x]; + + i++; + } + } + + return returnarr; + } + + public float[] ResizeTerrain512Interpolation(float[] heightMap) + { + float[] returnarr = new float[262144]; + float[,] resultarr = new float[512,512]; + + // Filling out the array into its multi-dimensional components + for (int y = 0; y < 256; y++) + { + for (int x = 0; x < 256; x++) + { + resultarr[y, x] = heightMap[y * 256 + x]; + } + } + + // Resize using interpolation + + // This particular way is quick but it only works on a multiple of the original + + // The idea behind this method can be described with the following diagrams + // second pass and third pass happen in the same loop really.. just separated + // them to show what this does. + + // First Pass + // ResultArr: + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + // 1,1,1,1,1,1 + + // Second Pass + // ResultArr2: + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + // ,,,,,,,,,, + // 1,,1,,1,,1,,1,,1, + + // Third pass fills in the blanks + // ResultArr2: + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + // 1,1,1,1,1,1,1,1,1,1,1,1 + + // X,Y = . + // X+1,y = ^ + // X,Y+1 = * + // X+1,Y+1 = # + + // Filling in like this; + // .* + // ^# + // 1st . + // 2nd * + // 3rd ^ + // 4th # + // on single loop. + + float[,] resultarr2 = new float[512,512]; + for (int y = 0; y < (int)Constants.RegionSize; y++) + { + for (int x = 0; x < (int)Constants.RegionSize; x++) + { + resultarr2[y*2, x*2] = resultarr[y, x]; + + if (y < (int)Constants.RegionSize) + { + if (y + 1 < (int)Constants.RegionSize) + { + if (x + 1 < (int)Constants.RegionSize) + { + resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] + + resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); + } + else + { + resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2); + } + } + else + { + resultarr2[(y*2) + 1, x*2] = resultarr[y, x]; + } + } + if (x < (int)Constants.RegionSize) + { + if (x + 1 < (int)Constants.RegionSize) + { + if (y + 1 < (int)Constants.RegionSize) + { + resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + + resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); + } + else + { + resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2); + } + } + else + { + resultarr2[y*2, (x*2) + 1] = resultarr[y, x]; + } + } + if (x < (int)Constants.RegionSize && y < (int)Constants.RegionSize) + { + if ((x + 1 < (int)Constants.RegionSize) && (y + 1 < (int)Constants.RegionSize)) + { + resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] + + resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4); + } + else + { + resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x]; + } + } + } + } + //Flatten out the array + int i = 0; + for (int y = 0; y < 512; y++) + { + for (int x = 0; x < 512; x++) + { + if (Single.IsNaN(resultarr2[y, x]) || Single.IsInfinity(resultarr2[y, x])) + { + m_log.Warn("[PHYSICS]: Non finite heightfield element detected. Setting it to 0"); + resultarr2[y, x] = 0; + } + returnarr[i] = resultarr2[y, x]; + i++; + } + } + + return returnarr; + } + + #endregion + + public override void SetTerrain(float[] heightMap) + { + if (m_worldOffset != Vector3.Zero && m_parentScene != null) + { + if (m_parentScene is OdeScene) + { + ((OdeScene)m_parentScene).SetTerrain(heightMap, m_worldOffset); + } + } + else + { + SetTerrain(heightMap, m_worldOffset); + } + } + + public void SetTerrain(float[] heightMap, Vector3 pOffset) + { + // this._heightmap[i] = (double)heightMap[i]; + // dbm (danx0r) -- creating a buffer zone of one extra sample all around + //_origheightmap = heightMap; + + float[] _heightmap; + + // zero out a heightmap array float array (single dimension [flattened])) + //if ((int)Constants.RegionSize == 256) + // _heightmap = new float[514 * 514]; + //else + + _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; + + uint heightmapWidth = Constants.RegionSize + 1; + uint heightmapHeight = Constants.RegionSize + 1; + + uint heightmapWidthSamples; + + uint heightmapHeightSamples; + + //if (((int)Constants.RegionSize) == 256) + //{ + // heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2; + // heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2; + // heightmapWidth++; + // heightmapHeight++; + //} + //else + //{ + + heightmapWidthSamples = (uint)Constants.RegionSize + 1; + heightmapHeightSamples = (uint)Constants.RegionSize + 1; + //} + + const float scale = 1.0f; + const float offset = 0.0f; + const float thickness = 0.2f; + const int wrap = 0; + + int regionsize = (int) Constants.RegionSize + 2; + //Double resolution + //if (((int)Constants.RegionSize) == 256) + // heightMap = ResizeTerrain512Interpolation(heightMap); + + + // if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256) + // regionsize = 512; + + float hfmin = 2000; + float hfmax = -2000; + + for (int x = 0; x < heightmapWidthSamples; x++) + { + for (int y = 0; y < heightmapHeightSamples; y++) + { + int xx = Util.Clip(x - 1, 0, regionsize - 1); + int yy = Util.Clip(y - 1, 0, regionsize - 1); + + + float val= heightMap[yy * (int)Constants.RegionSize + xx]; + _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; + + hfmin = (val < hfmin) ? val : hfmin; + hfmax = (val > hfmax) ? val : hfmax; + } + } + + + + + lock (OdeLock) + { + IntPtr GroundGeom = IntPtr.Zero; + if (RegionTerrain.TryGetValue(pOffset, out GroundGeom)) + { + RegionTerrain.Remove(pOffset); + if (GroundGeom != IntPtr.Zero) + { + if (TerrainHeightFieldHeights.ContainsKey(GroundGeom)) + { + TerrainHeightFieldHeights.Remove(GroundGeom); + } + d.SpaceRemove(space, GroundGeom); + d.GeomDestroy(GroundGeom); + } + + } + IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); + d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth + 1, heightmapHeight + 1, + (int)heightmapWidthSamples + 1, (int)heightmapHeightSamples + 1, scale, + offset, thickness, wrap); + d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); + GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); + if (GroundGeom != IntPtr.Zero) + { + d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); + d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); + + } + geom_name_map[GroundGeom] = "Terrain"; + + d.Matrix3 R = new d.Matrix3(); + + Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); + Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); + //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); + + q1 = q1 * q2; + //q1 = q1 * q3; + Vector3 v3; + float angle; + q1.GetAxisAngle(out v3, out angle); + + d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); + d.GeomSetRotation(GroundGeom, ref R); + d.GeomSetPosition(GroundGeom, (pOffset.X + ((int)Constants.RegionSize * 0.5f)) - 1, (pOffset.Y + ((int)Constants.RegionSize * 0.5f)) - 1, 0); + IntPtr testGround = IntPtr.Zero; + if (RegionTerrain.TryGetValue(pOffset, out testGround)) + { + RegionTerrain.Remove(pOffset); + } + RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); + TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); + + } + } + + public override void DeleteTerrain() + { + } + + public float GetWaterLevel() + { + return waterlevel; + } + + public override bool SupportsCombining() + { + return true; + } + + public override void UnCombine(PhysicsScene pScene) + { + IntPtr localGround = IntPtr.Zero; +// float[] localHeightfield; + bool proceed = false; + List geomDestroyList = new List(); + + lock (OdeLock) + { + if (RegionTerrain.TryGetValue(Vector3.Zero, out localGround)) + { + foreach (IntPtr geom in TerrainHeightFieldHeights.Keys) + { + if (geom == localGround) + { +// localHeightfield = TerrainHeightFieldHeights[geom]; + proceed = true; + } + else + { + geomDestroyList.Add(geom); + } + } + + if (proceed) + { + m_worldOffset = Vector3.Zero; + WorldExtents = new Vector2((int)Constants.RegionSize, (int)Constants.RegionSize); + m_parentScene = null; + + foreach (IntPtr g in geomDestroyList) + { + // removingHeightField needs to be done or the garbage collector will + // collect the terrain data before we tell ODE to destroy it causing + // memory corruption + if (TerrainHeightFieldHeights.ContainsKey(g)) + { +// float[] removingHeightField = TerrainHeightFieldHeights[g]; + TerrainHeightFieldHeights.Remove(g); + + if (RegionTerrain.ContainsKey(g)) + { + RegionTerrain.Remove(g); + } + + d.GeomDestroy(g); + //removingHeightField = new float[0]; + } + } + + } + else + { + m_log.Warn("[PHYSICS]: Couldn't proceed with UnCombine. Region has inconsistant data."); + + } + } + } + } + + public override void SetWaterLevel(float baseheight) + { + waterlevel = baseheight; + randomizeWater(waterlevel); + } + + public void randomizeWater(float baseheight) + { + const uint heightmapWidth = m_regionWidth + 2; + const uint heightmapHeight = m_regionHeight + 2; + const uint heightmapWidthSamples = m_regionWidth + 2; + const uint heightmapHeightSamples = m_regionHeight + 2; + const float scale = 1.0f; + const float offset = 0.0f; + const float thickness = 2.9f; + const int wrap = 0; + + for (int i = 0; i < (258 * 258); i++) + { + _watermap[i] = (baseheight-0.1f) + ((float)fluidRandomizer.Next(1,9) / 10f); + // m_log.Info((baseheight - 0.1f) + ((float)fluidRandomizer.Next(1, 9) / 10f)); + } + + lock (OdeLock) + { + if (WaterGeom != IntPtr.Zero) + { + d.SpaceRemove(space, WaterGeom); + } + IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); + d.GeomHeightfieldDataBuildSingle(HeightmapData, _watermap, 0, heightmapWidth, heightmapHeight, + (int)heightmapWidthSamples, (int)heightmapHeightSamples, scale, + offset, thickness, wrap); + d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight); + WaterGeom = d.CreateHeightfield(space, HeightmapData, 1); + if (WaterGeom != IntPtr.Zero) + { + d.GeomSetCategoryBits(WaterGeom, (int)(CollisionCategories.Water)); + d.GeomSetCollideBits(WaterGeom, (int)(CollisionCategories.Space)); + + } + geom_name_map[WaterGeom] = "Water"; + + d.Matrix3 R = new d.Matrix3(); + + Quaternion q1 = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), 1.5707f); + Quaternion q2 = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), 1.5707f); + //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1)); + + q1 = q1 * q2; + //q1 = q1 * q3; + Vector3 v3; + float angle; + q1.GetAxisAngle(out v3, out angle); + + d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); + d.GeomSetRotation(WaterGeom, ref R); + d.GeomSetPosition(WaterGeom, 128, 128, 0); + + } + + } + + public override void Dispose() + { + m_rayCastManager.Dispose(); + m_rayCastManager = null; + + lock (OdeLock) + { + lock (_prims) + { + foreach (OdePrim prm in _prims) + { + RemovePrim(prm); + } + } + + //foreach (OdeCharacter act in _characters) + //{ + //RemoveAvatar(act); + //} + d.WorldDestroy(world); + //d.CloseODE(); + } + } + public override Dictionary GetTopColliders() + { + Dictionary returncolliders = new Dictionary(); + int cnt = 0; + lock (_prims) + { + foreach (OdePrim prm in _prims) + { + if (prm.CollisionScore > 0) + { + returncolliders.Add(prm.m_localID, prm.CollisionScore); + cnt++; + prm.CollisionScore = 0f; + if (cnt > 25) + { + break; + } + } + } + } + return returncolliders; + } + + public override bool SupportsRayCast() + { + return true; + } + + public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod) + { + if (retMethod != null) + { + m_rayCastManager.QueueRequest(position, direction, length, retMethod); + } + } + +#if USE_DRAWSTUFF + // Keyboard callback + public void command(int cmd) + { + IntPtr geom; + d.Mass mass; + d.Vector3 sides = new d.Vector3(d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f, d.RandReal() * 0.5f + 0.1f); + + + + Char ch = Char.ToLower((Char)cmd); + switch ((Char)ch) + { + case 'w': + try + { + Vector3 rotate = (new Vector3(1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD)); + + xyz.X += rotate.X; xyz.Y += rotate.Y; xyz.Z += rotate.Z; + ds.SetViewpoint(ref xyz, ref hpr); + } + catch (ArgumentException) + { hpr.X = 0; } + break; + + case 'a': + hpr.X++; + ds.SetViewpoint(ref xyz, ref hpr); + break; + + case 's': + try + { + Vector3 rotate2 = (new Vector3(-1, 0, 0) * Quaternion.CreateFromEulers(hpr.Z * Utils.DEG_TO_RAD, hpr.Y * Utils.DEG_TO_RAD, hpr.X * Utils.DEG_TO_RAD)); + + xyz.X += rotate2.X; xyz.Y += rotate2.Y; xyz.Z += rotate2.Z; + ds.SetViewpoint(ref xyz, ref hpr); + } + catch (ArgumentException) + { hpr.X = 0; } + break; + case 'd': + hpr.X--; + ds.SetViewpoint(ref xyz, ref hpr); + break; + case 'r': + xyz.Z++; + ds.SetViewpoint(ref xyz, ref hpr); + break; + case 'f': + xyz.Z--; + ds.SetViewpoint(ref xyz, ref hpr); + break; + case 'e': + xyz.Y++; + ds.SetViewpoint(ref xyz, ref hpr); + break; + case 'q': + xyz.Y--; + ds.SetViewpoint(ref xyz, ref hpr); + break; + } + } + + public void step(int pause) + { + + ds.SetColor(1.0f, 1.0f, 0.0f); + ds.SetTexture(ds.Texture.Wood); + lock (_prims) + { + foreach (OdePrim prm in _prims) + { + //IntPtr body = d.GeomGetBody(prm.prim_geom); + if (prm.prim_geom != IntPtr.Zero) + { + d.Vector3 pos; + d.GeomCopyPosition(prm.prim_geom, out pos); + //d.BodyCopyPosition(body, out pos); + + d.Matrix3 R; + d.GeomCopyRotation(prm.prim_geom, out R); + //d.BodyCopyRotation(body, out R); + + + d.Vector3 sides = new d.Vector3(); + sides.X = prm.Size.X; + sides.Y = prm.Size.Y; + sides.Z = prm.Size.Z; + + ds.DrawBox(ref pos, ref R, ref sides); + } + } + } + ds.SetColor(1.0f, 0.0f, 0.0f); + lock (_characters) + { + foreach (OdeCharacter chr in _characters) + { + if (chr.Shell != IntPtr.Zero) + { + IntPtr body = d.GeomGetBody(chr.Shell); + + d.Vector3 pos; + d.GeomCopyPosition(chr.Shell, out pos); + //d.BodyCopyPosition(body, out pos); + + d.Matrix3 R; + d.GeomCopyRotation(chr.Shell, out R); + //d.BodyCopyRotation(body, out R); + + ds.DrawCapsule(ref pos, ref R, chr.Size.Z, 0.35f); + d.Vector3 sides = new d.Vector3(); + sides.X = 0.5f; + sides.Y = 0.5f; + sides.Z = 0.5f; + + ds.DrawBox(ref pos, ref R, ref sides); + } + } + } + } + + public void start(int unused) + { + ds.SetViewpoint(ref xyz, ref hpr); + } +#endif + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/ChOdePlugin/Tests/ODETestClass.cs new file mode 100644 index 0000000..69e2d03 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/Tests/ODETestClass.cs @@ -0,0 +1,122 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using Nini.Config; +using NUnit.Framework; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Physics.Manager; +using log4net; +using System.Reflection; + +namespace OpenSim.Region.Physics.OdePlugin +{ + [TestFixture] + public class ODETestClass + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private OdePlugin cbt; + private PhysicsScene ps; + private IMeshingPlugin imp; + + [SetUp] + public void Initialize() + { + // Loading ODEPlugin + cbt = new OdePlugin(); + // Loading Zero Mesher + imp = new ZeroMesherPlugin(); + // Getting Physics Scene + ps = cbt.GetScene("test"); + // Initializing Physics Scene. + ps.Initialise(imp.GetMesher(),null); + float[] _heightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize]; + for (int i = 0; i < ((int)Constants.RegionSize * (int)Constants.RegionSize); i++) + { + _heightmap[i] = 21f; + } + ps.SetTerrain(_heightmap); + } + + [TearDown] + public void Terminate() + { + ps.DeleteTerrain(); + ps.Dispose(); + + } + + [Test] + public void CreateAndDropPhysicalCube() + { + PrimitiveBaseShape newcube = PrimitiveBaseShape.CreateBox(); + Vector3 position = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 128f); + Vector3 size = new Vector3(0.5f, 0.5f, 0.5f); + Quaternion rot = Quaternion.Identity; + PhysicsActor prim = ps.AddPrimShape("CoolShape", newcube, position, size, rot, true); + OdePrim oprim = (OdePrim)prim; + OdeScene pscene = (OdeScene) ps; + + Assert.That(oprim.m_taintadd); + + prim.LocalID = 5; + + for (int i = 0; i < 58; i++) + { + ps.Simulate(0.133f); + + Assert.That(oprim.prim_geom != (IntPtr)0); + + Assert.That(oprim.m_targetSpace != (IntPtr)0); + + //Assert.That(oprim.m_targetSpace == pscene.space); + m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space); + + Assert.That(!oprim.m_taintadd); + m_log.Info("Prim Position (" + oprim.m_localID + "): " + prim.Position.ToString()); + + // Make sure we're above the ground + //Assert.That(prim.Position.Z > 20f); + //m_log.Info("PrimCollisionScore (" + oprim.m_localID + "): " + oprim.m_collisionscore); + + // Make sure we've got a Body + Assert.That(oprim.Body != (IntPtr)0); + //m_log.Info( + } + + // Make sure we're not somewhere above the ground + Assert.That(prim.Position.Z < 21.5f); + + ps.RemovePrim(prim); + Assert.That(oprim.m_taintremove); + ps.Simulate(0.133f); + Assert.That(oprim.Body == (IntPtr)0); + } + } +} diff --git a/OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs b/OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs new file mode 100644 index 0000000..87ca446 --- /dev/null +++ b/OpenSim/Region/Physics/ChOdePlugin/drawstuff.cs @@ -0,0 +1,98 @@ +/* + * Copyright ODE + * Ode.NET - .NET bindings for ODE + * Jason Perkins (starkos@industriousone.com) + * Licensed under the New BSD + * Part of the OpenDynamicsEngine +Open Dynamics Engine +Copyright (c) 2001-2007, Russell L. Smith. +All rights reserved. + +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 names of ODE's copyright owner 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 COPYRIGHT HOLDERS AND CONTRIBUTORS +"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 COPYRIGHT +OWNER OR 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.Runtime.InteropServices; +using Ode.NET; + +namespace Drawstuff.NET +{ +#if dDOUBLE + using dReal = System.Double; +#else + using dReal = System.Single; +#endif + + public static class ds + { + public const int VERSION = 2; + + public enum Texture + { + None, + Wood + } + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void CallbackFunction(int arg); + + [StructLayout(LayoutKind.Sequential)] + public struct Functions + { + public int version; + public CallbackFunction start; + public CallbackFunction step; + public CallbackFunction command; + public CallbackFunction stop; + public string path_to_textures; + } + + [DllImport("drawstuff", EntryPoint = "dsDrawBox")] + public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides); + + [DllImport("drawstuff", EntryPoint = "dsDrawCapsule")] + public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius); + + [DllImport("drawstuff", EntryPoint = "dsDrawConvex")] + public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons); + + [DllImport("drawstuff", EntryPoint = "dsSetColor")] + public static extern void SetColor(float red, float green, float blue); + + [DllImport("drawstuff", EntryPoint = "dsSetTexture")] + public static extern void SetTexture(Texture texture); + + [DllImport("drawstuff", EntryPoint = "dsSetViewpoint")] + public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr); + + [DllImport("drawstuff", EntryPoint = "dsSimulationLoop")] + public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn); + } +} diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index b99baa2..06ed8fb 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -1197,26 +1197,13 @@ namespace OpenSim.Region.Physics.OdePlugin public override PIDHoverType PIDHoverType { set { return; } } public override float PIDHoverTau { set { return; } } - public override Quaternion APIDTarget - { - set { return; } - } + public override Quaternion APIDTarget{ set { return; } } - public override bool APIDActive - { - set { return; } - } + public override bool APIDActive{ set { return; } } - public override float APIDStrength - { - set { return; } - } - - public override float APIDDamping - { - set { return; } - } + public override float APIDStrength{ set { return; } } + public override float APIDDamping{ set { return; } } public override void SubscribeEvents(int ms) diff --git a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs index 78b15be..39cdc0f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEDynamics.cs @@ -23,19 +23,6 @@ * 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. - * - * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. - * */ /* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces @@ -133,7 +120,7 @@ namespace OpenSim.Region.Physics.OdePlugin // private float m_VhoverEfficiency = 0f; private float m_VhoverTimescale = 0f; private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle. + private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. @@ -492,7 +479,7 @@ namespace OpenSim.Region.Physics.OdePlugin Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object m_dir *= rotq; // apply obj rotation to velocity vector - // add Gravity and Buoyancy + // add Gravity andBuoyancy // KF: So far I have found no good method to combine a script-requested // .Z velocity and gravity. Therefore only 0g will used script-requested // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. @@ -574,7 +561,6 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body */ -//if(frcount == 0) Console.WriteLine("MoveAngular "); // Get what the body is doing, this includes 'external' influences d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); @@ -650,7 +636,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Deflection section tba // Sum velocities - m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection + m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 688be83..3eb3b28 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -21,18 +21,6 @@ * 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. - * - * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. */ /* @@ -93,12 +81,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_PIDTau; private float PID_D = 35f; private float PID_G = 25f; - private bool m_usePID = false; - - private Quaternion m_APIDTarget = new Quaternion(); - private float m_APIDStrength = 0.5f; - private float m_APIDDamping = 0.5f; - private bool m_useAPID = false; + private bool m_usePID; // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), // and are for non-VEHICLES only. @@ -199,9 +182,6 @@ namespace OpenSim.Region.Physics.OdePlugin private ODEDynamics m_vehicle; internal int m_material = (int)Material.Wood; - - private int frcount = 0; // Used to limit dynamics debug output to - public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) @@ -1581,14 +1561,9 @@ Console.WriteLine(" JointCreateFixed"); float fy = 0; float fz = 0; - frcount++; // used to limit debug comment output - if (frcount > 100) - frcount = 0; if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. { -//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type + - // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); if (m_vehicle.Type != Vehicle.TYPE_NONE) { // 'VEHICLES' are dealt with in ODEDynamics.cs @@ -1596,6 +1571,7 @@ Console.WriteLine(" JointCreateFixed"); } else { +//Console.WriteLine("Move " + m_primName); if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 // NON-'VEHICLES' are dealt with here if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) @@ -1617,18 +1593,21 @@ Console.WriteLine(" JointCreateFixed"); //m_log.Info(m_collisionFlags.ToString()); - //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle. + //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. + // would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ?? // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up - // NB Prims in ODE are no subject to global gravity - fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass + // gravityz multiplier = 1 - m_buoyancy + fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; if (m_usePID) { -//if(frcount == 0) Console.WriteLine("PID " + m_primName); - // KF - this is for object MoveToTarget. - +//Console.WriteLine("PID " + m_primName); + // KF - this is for object move? eg. llSetPos() ? //if (!d.BodyIsEnabled(Body)) //d.BodySetForce(Body, 0f, 0f, 0f); + // If we're using the PID controller, then we have no gravity + //fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply... + fz = 0f; // no lock; for now it's only called from within Simulate() @@ -1763,7 +1742,7 @@ Console.WriteLine(" JointCreateFixed"); d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); d.BodySetLinearVel(Body, vel.X, vel.Y, 0); d.BodyAddForce(Body, 0, 0, fz); - //KF this prevents furthur motions return; + return; } else { @@ -1772,46 +1751,8 @@ Console.WriteLine(" JointCreateFixed"); // We're flying and colliding with something fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); } - } // end m_useHoverPID && !m_usePID - - if (m_useAPID) - { - // RotLookAt, apparently overrides all other rotation sources. Inputs: - // Quaternion m_APIDTarget - // float m_APIDStrength // From SL experiments, this is the time to get there - // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly - // Also in SL the mass of the object has no effect on time to get there. - // Factors: -//if(frcount == 0) Console.WriteLine("APID "); - // get present body rotation - float limit = 1.0f; - float scaler = 50f; // adjusts damping time - float RLAservo = 0f; - - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); - Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget; - float diff_angle; - Vector3 diff_axis; - rot_diff.GetAxisAngle(out diff_axis, out diff_angle); - diff_axis.Normalize(); - if(diff_angle > 0.01f) // diff_angle is always +ve - { -// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); - Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z); - rotforce = rotforce * rotq; - if(diff_angle > limit) diff_angle = limit; // cap the rotate rate -// RLAservo = timestep / m_APIDStrength * m_mass * scaler; - // rotforce = rotforce * RLAservo * diff_angle ; - // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); - RLAservo = timestep / m_APIDStrength * scaler; - rotforce = rotforce * RLAservo * diff_angle ; - d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); -//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); - } -//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); - } // end m_useAPID - + } + fx *= m_mass; fy *= m_mass; //fz *= m_mass; @@ -2673,7 +2614,7 @@ Console.WriteLine(" JointCreateFixed"); m_lastposition = _position; m_lastorientation = _orientation; - + l_position.X = vec.X; l_position.Y = vec.Y; l_position.Z = vec.Z; @@ -2681,10 +2622,6 @@ Console.WriteLine(" JointCreateFixed"); l_orientation.Y = ori.Y; l_orientation.Z = ori.Z; l_orientation.W = ori.W; - -// if(l_position.Y != m_lastposition.Y){ -// Console.WriteLine("UP&V {0} {1}", m_primName, l_position); -// } if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) { @@ -2885,17 +2822,20 @@ Console.WriteLine(" JointCreateFixed"); } public override bool PIDActive { set { m_usePID = value; } } public override float PIDTau { set { m_PIDTau = value; } } - - // For RotLookAt - public override Quaternion APIDTarget { set { m_APIDTarget = value; } } - public override bool APIDActive { set { m_useAPID = value; } } - public override float APIDStrength { set { m_APIDStrength = value; } } - public override float APIDDamping { set { m_APIDDamping = value; } } public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } public override bool PIDHoverActive { set { m_useHoverPID = value; } } public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } public override float PIDHoverTau { set { m_PIDHoverTau = value; } } + + public override Quaternion APIDTarget{ set { return; } } + + public override bool APIDActive{ set { return; } } + + public override float APIDStrength{ set { return; } } + + public override float APIDDamping{ set { return; } } + private void createAMotor(Vector3 axis) { -- cgit v1.1 From b53b87166940ca0fca4ae2190649e18102c886ec Mon Sep 17 00:00:00 2001 From: root Date: Tue, 22 Dec 2009 06:25:32 +0100 Subject: Add a data path for error messages --- OpenSim/Framework/Capabilities/Caps.cs | 21 +++++++++++++-------- .../Framework/Interfaces/IEntityInventory.cs | 2 ++ .../Region/Framework/Interfaces/IScriptModule.cs | 3 +++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 18 ++++++++++++------ .../Framework/Scenes/SceneObjectPartInventory.cs | 22 ++++++++++++++++++++++ OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 5 +++++ 6 files changed, 57 insertions(+), 14 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 1f1ac78..74c6ab0 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -46,7 +46,7 @@ namespace OpenSim.Framework.Capabilities public delegate UUID UpdateItem(UUID itemID, byte[] data); - public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data); + public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); public delegate void NewInventoryItem(UUID userID, InventoryItemBase item); @@ -54,7 +54,7 @@ namespace OpenSim.Framework.Capabilities public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data); - public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, + public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID, bool isScriptRunning, byte[] data); public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID, @@ -940,11 +940,13 @@ namespace OpenSim.Framework.Capabilities /// Prim containing item to update /// Signals whether the script to update is currently running /// New asset data - public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data) + public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors) { if (TaskScriptUpdatedCall != null) { - TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); + ArrayList e = TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data); + foreach (Object item in e) + errors.Add(item); } } @@ -1174,17 +1176,20 @@ namespace OpenSim.Framework.Capabilities // data, path, param)); string res = String.Empty; - LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete(); + LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete(); + ArrayList errors = new ArrayList(); handlerUpdateTaskScript = OnUpLoad; if (handlerUpdateTaskScript != null) { - handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data); + handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors); } - uploadComplete.item_id = inventoryItemID; - uploadComplete.task_id = primID; + uploadComplete.new_asset = inventoryItemID; + uploadComplete.compiled = errors.Count > 0 ? false : true; uploadComplete.state = "complete"; + uploadComplete.errors = new OSDArray(); + uploadComplete.errors.Array = errors; res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 89a45da..67395fa 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -26,6 +26,7 @@ */ using System.Collections.Generic; +using System.Collections; using OpenMetaverse; using OpenSim.Framework; @@ -71,6 +72,7 @@ namespace OpenSim.Region.Framework.Interfaces /// Start all the scripts contained in this entity's inventory /// void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); + ArrayList GetScriptErrors(UUID itemID); /// /// Stop all the scripts in this entity. diff --git a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs index 98efcbe..e90b300 100644 --- a/OpenSim/Region/Framework/Interfaces/IScriptModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IScriptModule.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces @@ -39,5 +40,7 @@ namespace OpenSim.Region.Framework.Interfaces bool PostScriptEvent(UUID itemID, string name, Object[] args); bool PostObjectEvent(UUID itemID, string name, Object[] args); + + ArrayList GetScriptErrors(UUID itemID); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 7ca779a..bce7d32 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Collections; using System.Reflection; using System.Text; using System.Timers; @@ -215,13 +216,13 @@ namespace OpenSim.Region.Framework.Scenes /// The prim which contains the item to update /// Indicates whether the script to update is currently running /// - public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId, + public ArrayList CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId, UUID primId, bool isScriptRunning, byte[] data) { if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); - return; + return new ArrayList(); } // Retrieve group @@ -234,7 +235,7 @@ namespace OpenSim.Region.Framework.Scenes "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist", itemId, primId); - return; + return new ArrayList(); } // Retrieve item @@ -247,7 +248,7 @@ namespace OpenSim.Region.Framework.Scenes + " but the item does not exist in this inventory", itemId, part.Name, part.UUID); - return; + return new ArrayList(); } AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data); @@ -264,29 +265,33 @@ namespace OpenSim.Region.Framework.Scenes part.GetProperties(remoteClient); // Trigger rerunning of script (use TriggerRezScript event, see RezScript) + ArrayList errors = new ArrayList(); + if (isScriptRunning) { // Needs to determine which engine was running it and use that // part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); + errors = part.Inventory.GetScriptErrors(item.ItemID); } else { remoteClient.SendAgentAlertMessage("Script saved", false); } + return errors; } /// /// CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[]) /// - public void CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId, + public ArrayList CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId, UUID primId, bool isScriptRunning, byte[] data) { ScenePresence avatar; if (TryGetAvatar(avatarId, out avatar)) { - CapsUpdateTaskInventoryScriptAsset( + return CapsUpdateTaskInventoryScriptAsset( avatar.ControllingClient, itemId, primId, isScriptRunning, data); } else @@ -295,6 +300,7 @@ namespace OpenSim.Region.Framework.Scenes "[PRIM INVENTORY]: " + "Avatar {0} cannot be found to update its prim item asset", avatarId); + return new ArrayList(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index cdd23bd..c3c6342 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -29,6 +29,7 @@ using System; using System.Xml; using System.IO; using System.Collections.Generic; +using System.Collections; using System.Reflection; using OpenMetaverse; using log4net; @@ -210,6 +211,27 @@ namespace OpenSim.Region.Framework.Scenes } } + public ArrayList GetScriptErrors(UUID itemID) + { + ArrayList ret = new ArrayList(); + + IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); + if (engines == null) // No engine at all + return ret; + + foreach (IScriptModule e in engines) + { + if (e != null) + { + ArrayList errors = e.GetScriptErrors(itemID); + foreach (Object line in errors) + ret.Add(line); + } + } + + return ret; + } + /// /// Stop all the scripts in this prim. /// diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 2a9a2db..31684ae 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1552,5 +1552,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine return true; } + + public ArrayList GetScriptErrors(UUID itemID) + { + return new ArrayList(); + } } } -- cgit v1.1 From bde26a8282cf7d3e173413a49a88f25a6bee0db1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 22 Dec 2009 06:43:03 +0100 Subject: Add missing file --- .../Capabilities/LLSDTaskScriptUploadComplete.cs | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs (limited to 'OpenSim') diff --git a/OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs b/OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs new file mode 100644 index 0000000..d308831 --- /dev/null +++ b/OpenSim/Framework/Capabilities/LLSDTaskScriptUploadComplete.cs @@ -0,0 +1,54 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; +using System; +using System.Collections; + +namespace OpenSim.Framework.Capabilities +{ + [OSDMap] + public class LLSDTaskScriptUploadComplete + { + /// + /// The task inventory item that was updated + /// + public UUID new_asset; + + /// + /// Was it compiled? + /// + public bool compiled; + + /// + /// State of the upload. So far have only even seen this set to "complete" + /// + public string state; + + public OSDArray errors; + } +} -- cgit v1.1 From b575bf25245102fd43d025081b249cb730b865ac Mon Sep 17 00:00:00 2001 From: CasperW Date: Wed, 23 Dec 2009 14:14:20 +0100 Subject: Added some null reference and deleted group checks to certain functions to fix region crash scenarios. --- .../Shared/Api/Implementation/LSL_Api.cs | 114 +++++++++++++++------ 1 file changed, 85 insertions(+), 29 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2da498a..84c2722 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -221,7 +221,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public List GetLinkParts(int linkType) { - List ret = new List(); + List ret = new List(); + if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) + return ret; ret.Add(m_host); switch (linkType) @@ -1136,7 +1138,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void llSetStatus(int status, int value) - { + { + if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) + return; m_host.AddScriptLPS(1); int statusrotationaxis = 0; @@ -1290,7 +1294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetScale(SceneObjectPart part, LSL_Vector scale) - { + { // TODO: this needs to trigger a persistance save as well if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; @@ -1349,7 +1353,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetColor(SceneObjectPart part, LSL_Vector color, int face) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; Color4 texcolor; if (face >= 0 && face < GetNumberOfSides(part)) @@ -1386,7 +1393,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetTexGen(SceneObjectPart part, int face,int style) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; MappingType textype; textype = MappingType.Default; @@ -1416,7 +1426,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetGlow(SceneObjectPart part, int face, float glow) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; if (face >= 0 && face < GetNumberOfSides(part)) { @@ -1441,7 +1454,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; Shininess sval = new Shininess(); @@ -1491,7 +1506,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetFullBright(SceneObjectPart part, int face, bool bright) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; if (face >= 0 && face < GetNumberOfSides(part)) { @@ -1558,7 +1576,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetAlpha(SceneObjectPart part, double alpha, int face) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; Color4 texcolor; if (face >= 0 && face < GetNumberOfSides(part)) @@ -1603,8 +1624,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, float wind, float tension, LSL_Vector Force) - { - if (part == null) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; if (flexi) @@ -1638,8 +1659,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) - { - if (part == null) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; if (light) @@ -1724,7 +1745,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetTexture(SceneObjectPart part, string texture, int face) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + UUID textureID=new UUID(); if (!UUID.TryParse(texture, out textureID)) @@ -1769,7 +1793,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; if (face >= 0 && face < GetNumberOfSides(part)) { @@ -1805,7 +1832,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; if (face >= 0 && face < GetNumberOfSides(part)) { @@ -1841,7 +1871,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void RotateTexture(SceneObjectPart part, double rotation, int face) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + Primitive.TextureEntry tex = part.Shape.Textures; if (face >= 0 && face < GetNumberOfSides(part)) { @@ -1911,7 +1944,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) LSL_Vector currentPos = llGetLocalPos(); @@ -2005,7 +2041,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetRot(SceneObjectPart part, Quaternion rot) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + part.UpdateRotation(rot); // Update rotation does not move the object in the physics scene if it's a linkset. @@ -6500,8 +6539,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) - { - ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); + { + ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return shapeBlock; if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && @@ -6570,7 +6611,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + ObjectShapePacket.ObjectDataBlock shapeBlock; shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); @@ -6618,7 +6662,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + ObjectShapePacket.ObjectDataBlock shapeBlock; shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); @@ -6659,7 +6706,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + ObjectShapePacket.ObjectDataBlock shapeBlock; shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); @@ -6779,7 +6829,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); UUID sculptId; @@ -6813,14 +6866,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void llSetPrimitiveParams(LSL_List rules) - { + { m_host.AddScriptLPS(1); SetPrimParams(m_host, rules); } public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) - { - m_host.AddScriptLPS(1); + { + m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); @@ -6829,7 +6882,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimParams(SceneObjectPart part, LSL_List rules) - { + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + return; + int idx = 0; while (idx < rules.Length) -- cgit v1.1 From a9f4d7a29c0f5b3ee10b46b9a27c5d10c7e71eb3 Mon Sep 17 00:00:00 2001 From: CasperW Date: Wed, 23 Dec 2009 17:34:08 +0100 Subject: Add a debugger tag to stop Visual Studio from breaking --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 8376846..c831c69 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1264,6 +1264,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine return UUID.Zero; } + [DebuggerNonUserCode] public void SetState(UUID itemID, string newState) { IScriptInstance instance = GetInstance(itemID); -- cgit v1.1 From 7f699fca9a34cd0f3525534bdbc04c8b8ee975fe Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 24 Dec 2009 18:18:14 +0100 Subject: Add the body to the LSL List Size property --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 38 +++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 1fc31c5..faf9c40 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -422,7 +422,8 @@ namespace OpenSim.Region.ScriptEngine.Shared public int Length { - get { + get + { if (m_data == null) m_data=new Object[0]; return m_data.Length; @@ -431,7 +432,40 @@ namespace OpenSim.Region.ScriptEngine.Shared public int Size { - get { return 0; } + get + { + if (m_data == null) + m_data=new Object[0]; + + int size = 0; + + foreach (Object o in m_data) + { + if (o is LSL_Types.LSLInteger) + size += 4; + else if (o is LSL_Types.LSLFloat) + size += 8; + else if (o is LSL_Types.LSLString) + size += ((LSL_Types.LSLString)o).m_string.Length; + else if (o is LSL_Types.key) + size += ((LSL_Types.key)o).value.Length; + else if (o is LSL_Types.Vector3) + size += 32; + else if (o is LSL_Types.Quaternion) + size += 64; + else if (o is int) + size += 4; + else if (o is string) + size += ((string)o).Length; + else if (o is float) + size += 8; + else if (o is double) + size += 16; + else + throw new Exception("Unknown type in List.Size: " + o.GetType().ToString()); + } + return size; + } } public object[] Data -- cgit v1.1 From e7439efc74a1cc0daedc51eb25ae66cd03db70b5 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 24 Dec 2009 19:19:44 -0500 Subject: Recover out-of-region objects during db load. --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 24 ++++++++++++++++++++++++ OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 4 +++- 3 files changed, 28 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index a7d34f5..7274a06 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.91CM"; + private const string VERSION_NUMBER = "0.6.92Ch"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b0fb8b3..998d598 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -222,6 +222,30 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted) { + // KF: Check for out-of-region, move inside and make static. + Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, + sceneObject.RootPart.GroupPosition.Y, + sceneObject.RootPart.GroupPosition.Z); + if (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || + npos.X > Constants.RegionSize || + npos.Y > Constants.RegionSize) + { + if (npos.X < 0.0) npos.X = 1.0f; + if (npos.Y < 0.0) npos.Y = 1.0f; + if (npos.Z < 0.0) npos.Z = 0.0f; + if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; + if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; + + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + part.GroupPosition = npos; + } + sceneObject.RootPart.Velocity = Vector3.Zero; + sceneObject.RootPart.AngularVelocity = Vector3.Zero; + sceneObject.RootPart.Acceleration = Vector3.Zero; + sceneObject.RootPart.Velocity = Vector3.Zero; + } + if (!alreadyPersisted) { sceneObject.ForceInventoryPersistence(); diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 983431d..0179240 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -215,6 +215,7 @@ namespace OpenSim.Region.Physics.OdePlugin parent_scene.GetTerrainHeightAtXY(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f)) + 0.5f); m_log.Warn("[PHYSICS]: Got nonFinite Object create Position"); } + _position = pos; m_taintposition = pos; PID_D = parent_scene.bodyPIDD; @@ -254,7 +255,8 @@ namespace OpenSim.Region.Physics.OdePlugin _parent_scene = parent_scene; m_targetSpace = (IntPtr)0; - if (pos.Z < 0) +// if (pos.Z < 0) + if (pos.Z < parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y)) m_isphysical = false; else { -- cgit v1.1 From b19e5643171d9a081426026c0e96c84c3e7f97b2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 25 Dec 2009 23:20:30 +0000 Subject: Restore version suffix. --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 7274a06..4844a66 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.92Ch"; + private const string VERSION_NUMBER = "0.6.92CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour { -- cgit v1.1 From 59f683066a60a99111cc032ee122dfe709c78440 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 25 Dec 2009 23:23:49 +0000 Subject: Set version back to core version (base) and suffix CM. Please DO NOT CHANGE THIS in the repo. This is the Caremninster repo and the number follows CORE. Always. --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 4844a66..f618047 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.92CM"; + private const string VERSION_NUMBER = "0.6.8CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour { -- cgit v1.1 From 43c303e27a93f07022ed0b151ca6945e34169ee9 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 26 Dec 2009 03:24:46 +0100 Subject: Make the GenericTableHandler work as intended --- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 9b8a001..4dfc324 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -37,7 +37,7 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Data.MySQL { - public class MySQLGenericTableHandler : MySqlFramework where T: struct + public class MySQLGenericTableHandler : MySqlFramework where T: class, new() { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -63,7 +63,7 @@ namespace OpenSim.Data.MySQL } Type t = typeof(T); - FieldInfo[] fields = t.GetFields(BindingFlags.NonPublic | + FieldInfo[] fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); @@ -165,7 +165,11 @@ namespace OpenSim.Data.MySQL new Dictionary(); foreach (string col in m_ColumnNames) + { data[col] = reader[col].ToString(); + if (data[col] == null) + data[col] = String.Empty; + } m_DataField.SetValue(row, data); } @@ -218,6 +222,8 @@ namespace OpenSim.Data.MySQL query = String.Format("replace into {0} (`", m_Realm) + String.Join("`,`", names.ToArray()) + "`) values ('" + String.Join("','", values.ToArray()) + "')"; + cmd.CommandText = query; + if (ExecuteNonQuery(cmd) > 0) return true; -- cgit v1.1 From 7371c7662a05d2c1dae1c110905817bb873cf934 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sat, 26 Dec 2009 18:14:12 +0100 Subject: Fix for landing points. Only one scenario is not fully covered by this change, and that is people who teleport from neighbouring regions, who won't get affected by the landing point. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 + .../Framework/Scenes/SceneCommunicationService.cs | 47 +++++++++++++++++----- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 25 ++++++++++-- 3 files changed, 59 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 265129c..37734f4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3460,6 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes } } // Honor parcel landing type and position. + /* ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); if (land != null) { @@ -3468,6 +3469,7 @@ namespace OpenSim.Region.Framework.Scenes agent.startpos = land.LandData.UserLocation; } } + */// This is now handled properly in ScenePresence.MakeRootAgent } m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index e649139..0a02d39 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -706,17 +706,42 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", - position, m_regionInfo.RegionName); - - // Teleport within the same region - if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); - - m_log.WarnFormat( - "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, avatar.Name, avatar.UUID, emergencyPos); - position = emergencyPos; + position, m_regionInfo.RegionName); + + // Teleport within the same region + if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); + + m_log.WarnFormat( + "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, avatar.Name, avatar.UUID, emergencyPos); + position = emergencyPos; + } + + Vector3 currentPos = avatar.AbsolutePosition; + ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y); + ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y); + if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0) + { + if (srcLand.LandData.LocalID == destLand.LandData.LocalID) + { + //TPing within the same parcel. If the landing point is restricted, block the TP. + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) + { + avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false); + position = currentPos; + } + } + else + { + //Tping to a different parcel. Respect the landing point on the destination parcel. + if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) + { + position = destLand.LandData.UserLocation; + } + } } // TODO: Get proper AVG Height diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a3ad7ca..c3bc96a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -836,9 +836,24 @@ namespace OpenSim.Region.Framework.Scenes { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); pos.Y = crossedBorder.BorderLine.Z - 1; + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } } - if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) { Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); @@ -973,9 +988,10 @@ namespace OpenSim.Region.Framework.Scenes public void Teleport(Vector3 pos) { bool isFlying = false; - if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; + if (m_physicsActor != null) + isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -986,7 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_appearance.AvatarHeight); } - SendTerseUpdateToAllClients(); + SendTerseUpdateToAllClients(); + } public void TeleportWithMomentum(Vector3 pos) -- cgit v1.1 From a6c93ce875c9e563de791002b309a3285266d597 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sat, 26 Dec 2009 22:55:18 +0100 Subject: Make sure that we're not bounds checking attachments. 'Cos otherwise your hair will end up on your bum. Seen that before? --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 998d598..34a92fe 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -226,9 +226,9 @@ namespace OpenSim.Region.Framework.Scenes Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, sceneObject.RootPart.GroupPosition.Y, sceneObject.RootPart.GroupPosition.Z); - if (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || + if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || npos.X > Constants.RegionSize || - npos.Y > Constants.RegionSize) + npos.Y > Constants.RegionSize)) { if (npos.X < 0.0) npos.X = 1.0f; if (npos.Y < 0.0) npos.Y = 1.0f; -- cgit v1.1 From a18f4964cf43095a12dd6c91f606a7f28b0af4df Mon Sep 17 00:00:00 2001 From: root Date: Sun, 27 Dec 2009 01:32:23 +0100 Subject: Correct some issues with the last commit --- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 58b95d7..b2bd5f6 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -205,7 +205,8 @@ namespace OpenSim.Data.MySQL foreach (FieldInfo fi in m_Fields.Values) { names.Add(fi.Name); - values.Add(fi.GetValue(row).ToString()); + values.Add("?" + fi.Name); + cmd.Parameters.AddWithValue(fi.Name, fi.GetValue(row).ToString()); } if (m_DataField != null) -- cgit v1.1 From 19a5e606b38372e882c13e27d6459ee703e07570 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sun, 27 Dec 2009 07:08:16 +0100 Subject: Convert some remaining legacy lock()s for m_parts in SceneObjectGroup to ReaderWriteLockSlim, hopefully fixes a native crash --- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 5a06bdb..65ce13a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -46,12 +46,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void ForceInventoryPersistence() { - lock (m_parts) + lockPartsForRead(true); + List values = new List(m_parts.Values); + lockPartsForRead(false); + foreach (SceneObjectPart part in values) { - foreach (SceneObjectPart part in m_parts.Values) - { - part.Inventory.ForceInventoryPersistence(); - } + part.Inventory.ForceInventoryPersistence(); } } @@ -75,14 +75,16 @@ namespace OpenSim.Region.Framework.Scenes /// Stop the scripts contained in all the prims in this group /// public void RemoveScriptInstances() - { - lock (m_parts) + { + lockPartsForRead(true); + List values = new List(m_parts.Values); + lockPartsForRead(false); + + foreach (SceneObjectPart part in values) { - foreach (SceneObjectPart part in m_parts.Values) - { - part.Inventory.RemoveScriptInstances(); - } + part.Inventory.RemoveScriptInstances(); } + } /// -- cgit v1.1 From d321d23afe62e0e00f774901be3e1d1d0eda8c15 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 27 Dec 2009 16:01:36 +0000 Subject: Fix the spelling :/ --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index aeb97eb..8a5f209 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4840,9 +4840,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP UserProfile.FirstLifeImage = Properties.FLImageID; UserProfile.Image = Properties.ImageID; UserProfile.ProfileUrl = Utils.BytesToString(Properties.ProfileURL); - Userprofile.Flags &= ~3; - Userprofile.Flags |= Properties.AllowPublish ? 1 : 0; - Userprofile.Flags |= Properties.MaturePublish ? 2 : 0; + UserProfile.Flags &= ~3; + UserProfile.Flags |= Properties.AllowPublish ? 1 : 0; + UserProfile.Flags |= Properties.MaturePublish ? 2 : 0; handlerUpdateAvatarProperties(this, UserProfile); } -- cgit v1.1 From 045a44b1afb8a72da922eaea7b4d0ca1833bc9dd Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 27 Dec 2009 16:07:13 +0000 Subject: One should not copy/paste so much :) --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 8a5f209..ba81d05 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4840,9 +4840,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP UserProfile.FirstLifeImage = Properties.FLImageID; UserProfile.Image = Properties.ImageID; UserProfile.ProfileUrl = Utils.BytesToString(Properties.ProfileURL); - UserProfile.Flags &= ~3; - UserProfile.Flags |= Properties.AllowPublish ? 1 : 0; - UserProfile.Flags |= Properties.MaturePublish ? 2 : 0; + UserProfile.UserFlags &= ~3; + UserProfile.UserFlags |= Properties.AllowPublish ? 1 : 0; + UserProfile.UserFlags |= Properties.MaturePublish ? 2 : 0; handlerUpdateAvatarProperties(this, UserProfile); } -- cgit v1.1 From 8ad8bd6282210c8ce0c00704edb3c55654ad2fc2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 27 Dec 2009 17:52:27 +0100 Subject: Fix up the new Sirikata cient view --- OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index e8d1889..4700bf2 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -449,7 +449,7 @@ namespace OpenSim.Client.Sirikata.ClientStack throw new System.NotImplementedException(); } - public void SendGenericMessage(string method, List message) + public void SendGenericMessage(string method, List message) { throw new System.NotImplementedException(); } -- cgit v1.1 From 06f639b8f345e075259d8b2ebfa96b9ed2174766 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 30 Dec 2009 00:27:01 +0100 Subject: Fix a timer list locking issue causing XMREngine deadlocks --- .../Shared/Api/Implementation/Plugins/Timer.cs | 32 ++++++++++++---------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs index eeb59d9..2fd33fe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs @@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins if (Timers.Count == 0) return; + Dictionary.ValueCollection tvals; lock (TimerListLock) { // Go through all timers - Dictionary.ValueCollection tvals = Timers.Values; - foreach (TimerClass ts in tvals) + tvals = Timers.Values; + } + + foreach (TimerClass ts in tvals) + { + // Time has passed? + if (ts.next < DateTime.Now.Ticks) { - // Time has passed? - if (ts.next < DateTime.Now.Ticks) - { - //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); - // Add it to queue - m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, - new EventParams("timer", new Object[0], - new DetectParams[0])); - // set next interval - - //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); - ts.next = DateTime.Now.Ticks + ts.interval; - } + //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); + // Add it to queue + m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, + new EventParams("timer", new Object[0], + new DetectParams[0])); + // set next interval + + //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); + ts.next = DateTime.Now.Ticks + ts.interval; } } } -- cgit v1.1 From 8f0d6d6b5c2a66681cc80f33d10b0635a1257b25 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 30 Dec 2009 00:36:16 +0000 Subject: Fix an omission in LSL that causes a viewer crash --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c9d6742..3a229c2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6363,6 +6363,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSLError("First parameter to llDialog needs to be a key"); return; } + if (buttons.Length < 1) + { + LSLError("No less than 1 button can be shown"); + return; + } if (buttons.Length > 12) { LSLError("No more than 12 buttons can be shown"); -- cgit v1.1 From cbe0841bc96d9ec834b06a0a012a50323698f719 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 30 Dec 2009 20:13:18 +0000 Subject: Revert "Merge branch 'master' into careminster" This reverts commit 596af3f600462fb1e467714e5b898c10aa3d838b. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 8 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 57 ++------------- .../RegionCombinerModule/RegionCombinerModule.cs | 82 ---------------------- 3 files changed, 4 insertions(+), 143 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 8f62855..e98f0e7 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -161,18 +161,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix); // Check control flags -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs bool heldForward = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS); bool heldBack = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); bool heldLeft = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); bool heldRight = ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG || (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG); -======= - bool heldForward = - (((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) || ((controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS)); - bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG; - bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS; - bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG; ->>>>>>> master:OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT; //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT; bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f05fe59..c3bc96a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -173,12 +173,8 @@ namespace OpenSim.Region.Framework.Scenes protected RegionInfo m_regionInfo; protected ulong crossingFromRegion; -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs private readonly Vector3[] Dir_Vectors = new Vector3[11]; private bool m_isNudging = false; -======= - private readonly Vector3[] Dir_Vectors = new Vector3[9]; ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs // Position of agent's camera in world (region cordinates) protected Vector3 m_CameraCenter; @@ -247,13 +243,9 @@ namespace OpenSim.Region.Framework.Scenes DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, -======= - DIR_CONTROL_FLAG_BACKWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG } @@ -735,43 +727,27 @@ namespace OpenSim.Region.Framework.Scenes Dir_Vectors[3] = -Vector3.UnitY; //RIGHT Dir_Vectors[4] = Vector3.UnitZ; //UP Dir_Vectors[5] = -Vector3.UnitZ; //DOWN -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge -======= - Dir_Vectors[8] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge - Dir_Vectors[6] = Vector3.UnitX*2; //FORWARD - Dir_Vectors[7] = -Vector3.UnitX; //BACK ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs } private Vector3[] GetWalkDirectionVectors() { -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs Vector3[] vector = new Vector3[11]; -======= - Vector3[] vector = new Vector3[9]; ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK vector[2] = Vector3.UnitY; //LEFT vector[3] = -Vector3.UnitY; //RIGHT vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE vector[8] = Vector3.UnitY; //LEFT_NUDGE vector[9] = -Vector3.UnitY; //RIGHT_NUDGE vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE -======= - vector[8] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_Nudge - vector[6] = (new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z) * 2); //FORWARD Nudge - vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK Nudge ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs return vector; } @@ -1387,18 +1363,12 @@ namespace OpenSim.Region.Framework.Scenes else dirVectors = Dir_Vectors; -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs bool[] isNudge = GetDirectionIsNudge(); -======= - // The fact that m_movementflag is a byte needs to be fixed - // it really should be a uint - uint nudgehack = 250; ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) { if (((uint)flags & (uint)DCF) != 0) @@ -1408,47 +1378,28 @@ namespace OpenSim.Region.Framework.Scenes try { agent_control_v3 += dirVectors[i]; -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs if (isNudge[i] == false) { Nudging = false; } -======= - //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs } catch (IndexOutOfRangeException) { // Why did I get this? } - if ((m_movementflag & (byte)(uint)DCF) == 0) + if ((m_movementflag & (uint)DCF) == 0) { - if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) - { - m_movementflag |= (byte)nudgehack; - } m_movementflag += (byte)(uint)DCF; update_movementflag = true; } } else { - if ((m_movementflag & (byte)(uint)DCF) != 0 || - ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) - && ((m_movementflag & (byte)nudgehack) == nudgehack)) - ) // This or is for Nudge forward + if ((m_movementflag & (uint)DCF) != 0) { - m_movementflag -= ((byte)(uint)DCF); - + m_movementflag -= (byte)(uint)DCF; update_movementflag = true; - /* - if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) - && ((m_movementflag & (byte)nudgehack) == nudgehack)) - { - m_log.Debug("Removed Hack flag"); - } - */ } else { @@ -1589,7 +1540,7 @@ namespace OpenSim.Region.Framework.Scenes } } - if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0)) + if (update_movementflag) Animator.UpdateMovementAnimations(); m_scene.EventManager.TriggerOnClientMovement(this); diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 1a99c83..92f060b 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -88,89 +88,7 @@ namespace OpenSim.Region.RegionCombinerModule public void RegionLoaded(Scene scene) { if (enabledYN) - { RegionLoadedDoWork(scene); - - scene.EventManager.OnNewPresence += NewPresence; - } - } - - private void NewPresence(ScenePresence presence) - { - if (presence.IsChildAgent) - { - byte[] throttleData; - - try - { - throttleData = presence.ControllingClient.GetThrottlesPacked(1); - } - catch (NotImplementedException) - { - return; - } - - if (throttleData == null) - return; - - if (throttleData.Length == 0) - return; - - if (throttleData.Length != 28) - return; - - byte[] adjData; - int pos = 0; - - if (!BitConverter.IsLittleEndian) - { - byte[] newData = new byte[7 * 4]; - Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4); - - for (int i = 0; i < 7; i++) - Array.Reverse(newData, i * 4, 4); - - adjData = newData; - } - else - { - adjData = throttleData; - } - - // 0.125f converts from bits to bytes - int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; - int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; - int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; - int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; - int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; - int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; - int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); - // State is a subcategory of task that we allocate a percentage to - - - //int total = resend + land + wind + cloud + task + texture + asset; - - byte[] data = new byte[7 * 4]; - int ii = 0; - - Buffer.BlockCopy(Utils.FloatToBytes(resend), 0, data, ii, 4); ii += 4; - Buffer.BlockCopy(Utils.FloatToBytes(land * 50), 0, data, ii, 4); ii += 4; - Buffer.BlockCopy(Utils.FloatToBytes(wind), 0, data, ii, 4); ii += 4; - Buffer.BlockCopy(Utils.FloatToBytes(cloud), 0, data, ii, 4); ii += 4; - Buffer.BlockCopy(Utils.FloatToBytes(task), 0, data, ii, 4); ii += 4; - Buffer.BlockCopy(Utils.FloatToBytes(texture), 0, data, ii, 4); ii += 4; - Buffer.BlockCopy(Utils.FloatToBytes(asset), 0, data, ii, 4); - - try - { - presence.ControllingClient.SetChildAgentThrottle(data); - } - catch (NotImplementedException) - { - return; - } - - } } private void RegionLoadedDoWork(Scene scene) -- cgit v1.1 From 5e103f2b2eb51c35b435f6850fc088f1f905d9dd Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 30 Dec 2009 20:26:22 +0000 Subject: Revert "Merge branch 'master' into careminster" This reverts commit d49d44923d1be38f6fff12706b156562c6060566. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 5 +---- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 ------------------ 2 files changed, 1 insertion(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 6c64484..e98f0e7 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -151,10 +151,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation const float PREJUMP_DELAY = 0.25f; #region Inputs - if (m_scenePresence.SitGround) - { - return "SIT_GROUND_CONSTRAINED"; - } + AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; PhysicsActor actor = m_scenePresence.PhysicsActor; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ee76cb6..c3bc96a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -129,7 +129,6 @@ namespace OpenSim.Region.Framework.Scenes private Vector3? m_forceToApply; private uint m_requestedSitTargetID; private UUID m_requestedSitTargetUUID; - public bool SitGround = false; private SendCourseLocationsMethod m_sendCourseLocationsMethod; @@ -1300,17 +1299,8 @@ namespace OpenSim.Region.Framework.Scenes if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) { -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); -======= - // TODO: This doesn't prevent the user from walking yet. - // Setting parent ID would fix this, if we knew what value - // to use. Or we could add a m_isSitting variable. - //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - SitGround = true; - ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs } // In the future, these values might need to go global. @@ -1550,11 +1540,7 @@ namespace OpenSim.Region.Framework.Scenes } } -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/ScenePresence.cs if (update_movementflag) -======= - if (update_movementflag && ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) == 0) && (m_parentID == 0) && !SitGround) ->>>>>>> master:OpenSim/Region/Framework/Scenes/ScenePresence.cs Animator.UpdateMovementAnimations(); m_scene.EventManager.TriggerOnClientMovement(this); @@ -1665,12 +1651,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void StandUp() { - if (SitGround) - SitGround = false; - if (m_parentID != 0) { - m_log.Debug("StandupCode Executed"); SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); if (part != null) { -- cgit v1.1 From 9602227eb6d26cf76d8c88ac86558218ca11e918 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 31 Dec 2009 06:19:22 +0100 Subject: Add a small delay in NewAgentConnection to fix an issue with Hippo (and possibly other cleints) getting their data mixed up. --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2091bf0..2e34d1c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3414,6 +3414,9 @@ namespace OpenSim.Region.Framework.Scenes CapsModule.AddCapsHandler(agent.AgentID); + if ((teleportFlags & ((uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.ViaLocation | (uint)TeleportFlags.ViaLandmark | (uint)TeleportFlags.Default)) != 0) + System.Threading.Thread.Sleep(2000); + if (!agent.child) { if (TestBorderCross(agent.startpos,Cardinals.E)) -- cgit v1.1 From 3f901d313bfd11070d5260f867c8a73c14f2d109 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 31 Dec 2009 16:07:36 -0500 Subject: Vehicle Linear parameter adjustments --- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 40 ++++++++++++--- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 12 +++-- OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 61 +++++++++++++---------- 3 files changed, 75 insertions(+), 38 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index 78b15be..ef2dccc 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -83,6 +83,12 @@ namespace OpenSim.Region.Physics.OdePlugin // private IntPtr m_jointGroup = IntPtr.Zero; // private IntPtr m_aMotor = IntPtr.Zero; + // Correction factors, to match Sl + private static float m_linearVelocityFactor = 0.9f; + private static float m_linearAttackFactor = 0.4f; + private static float m_linearDecayFactor = 0.5f; + private static float m_linearFrictionFactor = 1.2f; + // Vehicle properties private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind @@ -98,7 +104,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Linear properties private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time - private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL + private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL, for max limiting private Vector3 m_dir = Vector3.Zero; // velocity applied to body private Vector3 m_linearFrictionTimescale = Vector3.Zero; private float m_linearMotorDecayTimescale = 0; @@ -267,8 +273,9 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); + pValue *= m_linearVelocityFactor; + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, decayed by time + m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, for max limiting break; case Vehicle.LINEAR_MOTOR_OFFSET: // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -453,6 +460,17 @@ namespace OpenSim.Region.Physics.OdePlugin MoveAngular(pTimestep); }// end Step + internal void Halt() + { // Kill all motions, when non-physical + m_linearMotorDirection = Vector3.Zero; + m_linearMotorDirectionLASTSET = Vector3.Zero; + m_dir = Vector3.Zero; + m_lastLinearVelocityVector = Vector3.Zero; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorVelocity = Vector3.Zero; + m_lastAngularVelocity = Vector3.Zero; + } + private void MoveLinear(float pTimestep, OdeScene _pParentScene) { if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant @@ -460,9 +478,15 @@ namespace OpenSim.Region.Physics.OdePlugin if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // add drive to body - Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); - m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? - + float linfactor = m_linearMotorTimescale/pTimestep; + // Linear accel + Vector3 addAmount1 = (m_linearMotorDirection/linfactor) * 0.8f; + // Differential accel + Vector3 addAmount2 = ((m_linearMotorDirection - m_lastLinearVelocityVector)/linfactor) * 1.6f; + // SL correction + Vector3 addAmount = (addAmount1 + addAmount2) * m_linearAttackFactor; + m_lastLinearVelocityVector += addAmount; // lastLinearVelocityVector is the current body velocity vector +//if(frcount == 0) Console.WriteLine("AL {0} + AD {1} AS{2} V {3}", addAmount1, addAmount2, addAmount, m_lastLinearVelocityVector); // This will work temporarily, but we really need to compare speed on an axis // KF: Limit body velocity to applied velocity? if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) @@ -475,7 +499,7 @@ namespace OpenSim.Region.Physics.OdePlugin // decay applied velocity Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); //Console.WriteLine("decay: " + decayfraction); - m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f; + m_linearMotorDirection -= m_linearMotorDirection * decayfraction * m_linearDecayFactor; //Console.WriteLine("actual: " + m_linearMotorDirection); } else @@ -560,7 +584,7 @@ namespace OpenSim.Region.Physics.OdePlugin // apply friction Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); - m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; + m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount * m_linearFrictionFactor; } // end MoveLinear() private void MoveAngular(float pTimestep) diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 0179240..6e6b44f 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -2296,11 +2296,15 @@ Console.WriteLine(" JointCreateFixed"); public override bool IsPhysical { get { return m_isphysical; } - set { + set + { m_isphysical = value; - if (!m_isphysical) // Zero the remembered last velocity - m_lastVelocity = Vector3.Zero; - } + if (!m_isphysical) + { // Zero the remembered last velocity + m_lastVelocity = Vector3.Zero; + if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Halt(); + } + } } public void setPrimForRemoval() diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index f48649e..60786d4 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -229,7 +229,7 @@ namespace OpenSim.Region.Physics.OdePlugin public int bodyFramesAutoDisable = 20; - + protected DateTime m_lastframe = DateTime.UtcNow; private float[] _watermap; private bool m_filterCollisions = true; @@ -2639,13 +2639,20 @@ namespace OpenSim.Region.Physics.OdePlugin { if (framecount >= int.MaxValue) framecount = 0; - //if (m_worldOffset != Vector3.Zero) // return 0; framecount++; - - float fps = 0; + + DateTime now = DateTime.UtcNow; + TimeSpan SinceLastFrame = now - m_lastframe; + m_lastframe = now; + float realtime = (float)SinceLastFrame.TotalSeconds; +// Console.WriteLine("ts={0} rt={1}", timeStep, realtime); + timeStep = realtime; + + // float fps = 1.0f / realtime; + float fps = 0.0f; // number of ODE steps in this Simulate step //m_log.Info(timeStep.ToString()); step_time += timeStep; @@ -2691,11 +2698,11 @@ namespace OpenSim.Region.Physics.OdePlugin // Figure out the Frames Per Second we're going at. //(step_time == 0.004f, there's 250 of those per second. Times the step time/step size - fps = (step_time / ODE_STEPSIZE) * 1000; + // fps = (step_time / ODE_STEPSIZE) * 1000; // HACK: Using a time dilation of 1.0 to debug rubberbanding issues //m_timeDilation = Math.Min((step_time / ODE_STEPSIZE) / (0.09375f / ODE_STEPSIZE), 1.0f); - step_time = 0.09375f; + // step_time = 0.09375f; while (step_time > 0.0f) { @@ -2716,7 +2723,7 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (OdeCharacter character in _taintedActors) { - character.ProcessTaints(timeStep); + character.ProcessTaints(ODE_STEPSIZE); processedtaints = true; //character.m_collisionscore = 0; @@ -2725,7 +2732,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (processedtaints) _taintedActors.Clear(); } - } + } // end lock _taintedActors // Modify other objects in the scene. processedtaints = false; @@ -2742,7 +2749,7 @@ namespace OpenSim.Region.Physics.OdePlugin else { //Console.WriteLine("Simulate calls ProcessTaints"); - prim.ProcessTaints(timeStep); + prim.ProcessTaints(ODE_STEPSIZE); } processedtaints = true; prim.m_collisionscore = 0; @@ -2767,7 +2774,8 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (PhysicsJoint joint in pendingJoints) { //DoJointErrorMessage(joint, "taint: time to create joint with parms: " + joint.RawParams); - string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), System.StringSplitOptions.RemoveEmptyEntries); + string[] jointParams = joint.RawParams.Split(" ".ToCharArray(), + System.StringSplitOptions.RemoveEmptyEntries); List jointBodies = new List(); bool allJointBodiesAreReady = true; foreach (string jointParam in jointParams) @@ -2934,13 +2942,13 @@ namespace OpenSim.Region.Physics.OdePlugin //DoJointErrorMessage(successfullyProcessedJoint, "done"); } } - } + } // end SupportsNINJAJoints if (processedtaints) //Console.WriteLine("Simulate calls Clear of _taintedPrim list"); - _taintedPrimH.Clear(); + _taintedPrimH.Clear(); // ??? if this only ??? _taintedPrimL.Clear(); - } + } // end lock _taintedPrimLock // Move characters lock (_characters) @@ -2949,7 +2957,7 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (OdeCharacter actor in _characters) { if (actor != null) - actor.Move(timeStep, defects); + actor.Move(ODE_STEPSIZE, defects); } if (0 != defects.Count) { @@ -2958,7 +2966,7 @@ namespace OpenSim.Region.Physics.OdePlugin RemoveCharacter(defect); } } - } + } // end lock _characters // Move other active objects lock (_activeprims) @@ -2966,9 +2974,9 @@ namespace OpenSim.Region.Physics.OdePlugin foreach (OdePrim prim in _activeprims) { prim.m_collisionscore = 0; - prim.Move(timeStep); + prim.Move(ODE_STEPSIZE); } - } + } // end lock _activeprims //if ((framecount % m_randomizeWater) == 0) // randomizeWater(waterlevel); @@ -2976,7 +2984,7 @@ namespace OpenSim.Region.Physics.OdePlugin //int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests(); m_rayCastManager.ProcessQueuedRequests(); - collision_optimized(timeStep); + collision_optimized(ODE_STEPSIZE); lock (_collisionEventPrim) { @@ -2998,7 +3006,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; } } - } + } // end lock _collisionEventPrim //if (m_global_contactcount > 5) //{ @@ -3009,8 +3017,9 @@ namespace OpenSim.Region.Physics.OdePlugin d.WorldQuickStep(world, ODE_STEPSIZE); d.JointGroupEmpty(contactgroup); + fps++; //ode.dunlock(world); - } + } // end try catch (Exception e) { m_log.ErrorFormat("[PHYSICS]: {0}, {1}, {2}", e.Message, e.TargetSite, e); @@ -3025,7 +3034,7 @@ namespace OpenSim.Region.Physics.OdePlugin //fps = 0; //} //} - } + } // end while (step_time > 0.0f) lock (_characters) { @@ -3090,7 +3099,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } } - } + } // end lock _activeprims //DumpJointInfo(); @@ -3111,10 +3120,10 @@ namespace OpenSim.Region.Physics.OdePlugin } d.WorldExportDIF(world, fname, physics_logging_append_existing_logfile, prefix); } - } - - return fps; - } + } // end lock OdeLock + + return fps * 1000.0f; //NB This is a FRAME COUNT, not a time! AND is divide by 1000 in SimStatusReporter! + } // end Simulate public override void GetResults() { -- cgit v1.1 From 71fdc24f5c3d5805e185aac949e38f3c8058e03e Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 2 Jan 2010 21:21:31 +0100 Subject: Add virtual method StateChange to ScriptBaseClass --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs index a44abb0..b138da3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs @@ -128,6 +128,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_InitialValues = GetVars(); } + public virtual void StateChange(string newState) + { + } + public void Close() { // m_sponser.Close(); -- cgit v1.1 From 1121919b57e1495d0357d59e010a865b91757bfb Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 3 Jan 2010 22:02:36 +0000 Subject: Solve conflict --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ------- 1 file changed, 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index eda3d60..a14e3ad 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2910,13 +2910,6 @@ namespace OpenSim.Region.Framework.Scenes SetText(text); } - public void StopLookAt() - { - m_parentGroup.stopLookAt(); - - m_parentGroup.ScheduleGroupForTerseUpdate(); - } - public void StopMoveToTarget() { m_parentGroup.stopMoveToTarget(); -- cgit v1.1 From 53d3f46add698dd862c018e614778c1c19b0eda4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 4 Jan 2010 18:47:47 +0000 Subject: First stage port of the XInventoryService --- OpenSim/Data/IXInventoryData.cs | 82 ++++ OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 5 + OpenSim/Data/MySQL/MySQLXInventoryData.cs | 113 +++++ .../Services/InventoryService/XInventoryService.cs | 474 +++++++++++++++++++++ 4 files changed, 674 insertions(+) create mode 100644 OpenSim/Data/IXInventoryData.cs create mode 100644 OpenSim/Data/MySQL/MySQLXInventoryData.cs create mode 100644 OpenSim/Services/InventoryService/XInventoryService.cs (limited to 'OpenSim') diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs new file mode 100644 index 0000000..88174d9 --- /dev/null +++ b/OpenSim/Data/IXInventoryData.cs @@ -0,0 +1,82 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Data +{ + public class XInventoryFolder + { + public string folderName; + public int type; + public int version; + public UUID folderID; + public UUID agentID; + public UUID parentFolderID; + } + + public class XInventoryItem + { + public UUID assetID; + public int assetType; + public string inventoryName; + public string inventoryDescription; + public int inventoryNextPermissions; + public int inventoryCurrentPermissions; + public int invType; + public UUID creatorID; + public int inventoryBasePermissions; + public int inventoryEveryOnePermissions; + public int salePrice; + public int saleType; + public int creationDate; + public UUID groupID; + public bool groupOwned; + public int flags; + public UUID inventoryID; + public UUID avatarID; + public UUID parentFolderID; + public int inventoryGroupPermissions; + } + + public interface IXInventoryData + { + XInventoryFolder[] GetFolders(string[] fields, string[] vals); + XInventoryItem[] GetItems(string[] fields, string[] vals); + + bool StoreFolder(XInventoryFolder folder); + bool StoreItem(XInventoryItem item); + + bool DeleteFolders(string field, string val); + bool DeleteItems(string field, string val); + + bool MoveItem(string principalID, string id, string newParent); + } +} diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index b2bd5f6..fdb98eb 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -153,6 +153,11 @@ namespace OpenSim.Data.MySQL UUID.TryParse(reader[name].ToString(), out uuid); m_Fields[name].SetValue(row, uuid); } + else if (m_Fields[name].GetValue(row) is int) + { + int v = Convert.ToInt32(reader[name]); + m_Fields[name].SetValue(row, v); + } else { m_Fields[name].SetValue(row, reader[name]); diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs new file mode 100644 index 0000000..dd3e6ea --- /dev/null +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -0,0 +1,113 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Data; +using System.Reflection; +using System.Collections.Generic; +using log4net; +using MySql.Data.MySqlClient; +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Data.MySQL +{ + /// + /// A MySQL Interface for the Asset Server + /// + public class MySQLXInventoryData : IXInventoryData + { + private static readonly ILog m_log = LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private MySQLGenericTableHandler m_Folders; + private MySqlItemHandler m_Items; + + public MySQLXInventoryData(string conn, string realm) + { + m_Folders = new MySQLGenericTableHandler( + conn, "inventoryfolders", "InventoryStore"); + m_Items = new MySqlItemHandler( + conn, "inventoryitems", String.Empty); + } + + public XInventoryFolder[] GetFolders(string[] fields, string[] vals) + { + return m_Folders.Get(fields, vals); + } + + public XInventoryItem[] GetItems(string[] fields, string[] vals) + { + return m_Items.Get(fields, vals); + } + + public bool StoreFolder(XInventoryFolder folder) + { + return m_Folders.Store(folder); + } + + public bool StoreItem(XInventoryItem item) + { + return m_Items.Store(item); + } + + public bool DeleteFolders(string field, string val) + { + return m_Folders.Delete(field, val); + } + + public bool DeleteItems(string field, string val) + { + return m_Items.Delete(field, val); + } + + public bool MoveItem(string principalID, string id, string newParent) + { + return m_Items.MoveItem(principalID, id, newParent); + } + } + + public class MySqlItemHandler : MySQLGenericTableHandler + { + public MySqlItemHandler(string c, string t, string m) : + base(c, t, m) + { + } + + public bool MoveItem(string principalID, string id, string newParent) + { + MySqlCommand cmd = new MySqlCommand(); + + cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where agentID = ?AgentID and folderID = ?FolderID"); + cmd.Parameters.AddWithValue("?ParentFolderID", newParent); + cmd.Parameters.AddWithValue("?FolderID", id); + cmd.Parameters.AddWithValue("?AgentID", principalID); + + return ExecuteNonQuery(cmd) == 0 ? false : true; + } + } +} diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs new file mode 100644 index 0000000..1e7f206 --- /dev/null +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -0,0 +1,474 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using OpenMetaverse; +using log4net; +using Nini.Config; +using System.Reflection; +using OpenSim.Services.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Data; +using OpenSim.Framework; + +namespace OpenSim.Services.InventoryService +{ + public class XInventoryService : ServiceBase, IInventoryService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + protected IXInventoryData m_Database; + + public XInventoryService(IConfigSource config) : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + //string realm = "Inventory"; // OSG version doesn't use this + + // + // Try reading the [InventoryService] section first, if it exists + // + IConfig authConfig = config.Configs["InventoryService"]; + if (authConfig != null) + { + dllName = authConfig.GetString("StorageProvider", dllName); + connString = authConfig.GetString("ConnectionString", connString); + // realm = authConfig.GetString("Realm", realm); + } + + // + // Try reading the [DatabaseService] section, if it exists + // + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + if (dllName == String.Empty) + dllName = dbConfig.GetString("StorageProvider", String.Empty); + if (connString == String.Empty) + connString = dbConfig.GetString("ConnectionString", String.Empty); + } + + // + // We tried, but this doesn't exist. We can't proceed. + // + if (dllName == String.Empty) + throw new Exception("No StorageProvider configured"); + + m_Database = LoadPlugin(dllName, + new Object[] {connString, String.Empty}); + if (m_Database == null) + throw new Exception("Could not find a storage interface in the given module"); + } + + public bool CreateUserInventory(UUID principalID) + { + // This is braindeaad. We can't ever communicate that we fixed + // an existing inventory. Well, just return root folder status, + // but check sanity anyway. + // + bool result = false; + + InventoryFolderBase rootFolder = GetRootFolder(principalID); + + if (rootFolder == null) + { + rootFolder = ConvertToOpenSim(CreateFolder(principalID, UUID.Zero, (int)AssetType.Folder, "My Inventory")); + result = true; + } + + XInventoryFolder[] sysFolders = GetSystemFolders(principalID); + + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Animation) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Animation, "Animations"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Bodypart) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Bodypart, "Body Parts"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.CallingCard) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.CallingCard, "Calling Cards"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Clothing) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Clothing, "Clothing"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Gesture) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Gesture, "Gestures"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Landmark) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Landmark, "Landmarks"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.LostAndFoundFolder) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.LostAndFoundFolder, "Lost And Found"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Notecard) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Notecard, "Notecards"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Object) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Object, "Objects"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.SnapshotFolder) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.SnapshotFolder, "Photo Album"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.LSLText) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.LSLText, "Scripts"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Sound) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Sound, "Sounds"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.Texture) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.Texture, "Textures"); + if (!Array.Exists(sysFolders, delegate (XInventoryFolder f) { if (f.type == (int)AssetType.TrashFolder) return true; return false; })) + CreateFolder(principalID, rootFolder.ID, (int)AssetType.TrashFolder, "Trash"); + + return result; + } + + private XInventoryFolder CreateFolder(UUID principalID, UUID parentID, int type, string name) + { + XInventoryFolder newFolder = new XInventoryFolder(); + + newFolder.folderName = name; + newFolder.type = type; + newFolder.version = 1; + newFolder.folderID = UUID.Random(); + newFolder.agentID = principalID; + newFolder.parentFolderID = parentID; + + m_Database.StoreFolder(newFolder); + + return newFolder; + } + + private XInventoryFolder[] GetSystemFolders(UUID principalID) + { + XInventoryFolder[] allFolders = m_Database.GetFolders( + new string[] { "agentID" }, + new string[] { principalID.ToString() }); + + XInventoryFolder[] sysFolders = Array.FindAll( + allFolders, + delegate (XInventoryFolder f) + { + if (f.type > 0) + return true; + return false; + }); + + return sysFolders; + } + + public List GetInventorySkeleton(UUID principalID) + { + XInventoryFolder[] allFolders = m_Database.GetFolders( + new string[] { "agentID" }, + new string[] { principalID.ToString() }); + + if (allFolders.Length == 0) + return null; + + List folders = new List(); + + foreach (XInventoryFolder x in allFolders) + folders.Add(ConvertToOpenSim(x)); + + return folders; + } + + public InventoryFolderBase GetRootFolder(UUID principalID) + { + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "agentID", "parentFolderID"}, + new string[] { principalID.ToString(), UUID.Zero.ToString() }); + + if (folders.Length == 0) + return null; + + return ConvertToOpenSim(folders[0]); + } + + public InventoryFolderBase GetFolderForType(UUID principalID, AssetType type) + { + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "agentID", "type"}, + new string[] { principalID.ToString(), ((int)type).ToString() }); + + if (folders.Length == 0) + return null; + + return ConvertToOpenSim(folders[0]); + } + + public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) + { + InventoryCollection inventory = new InventoryCollection(); + inventory.UserID = principalID; + inventory.Folders = new List(); + inventory.Items = new List(); + + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "agentID", "parentFolderID"}, + new string[] { principalID.ToString(), UUID.Zero.ToString() }); + + foreach (XInventoryFolder x in folders) + inventory.Folders.Add(ConvertToOpenSim(x)); + + XInventoryItem[] items = m_Database.GetItems( + new string[] { "avatarID", "parentFolderID"}, + new string[] { principalID.ToString(), UUID.Zero.ToString() }); + + foreach (XInventoryItem i in items) + inventory.Items.Add(ConvertToOpenSim(i)); + + return inventory; + } + + public List GetFolderItems(UUID principalID, UUID folderID) + { + List invItems = new List(); + + XInventoryItem[] items = m_Database.GetItems( + new string[] { "avatarID", "parentFolderID"}, + new string[] { principalID.ToString(), UUID.Zero.ToString() }); + + foreach (XInventoryItem i in items) + invItems.Add(ConvertToOpenSim(i)); + + return invItems; + } + + public bool AddFolder(InventoryFolderBase folder) + { + XInventoryFolder xFolder = ConvertFromOpenSim(folder); + return m_Database.StoreFolder(xFolder); + } + + public bool UpdateFolder(InventoryFolderBase folder) + { + return AddFolder(folder); + } + + public bool MoveFolder(InventoryFolderBase folder) + { + XInventoryFolder[] x = m_Database.GetFolders( + new string[] { "folderID" }, + new string[] { folder.ID.ToString() }); + + if (x.Length == 0) + return false; + + x[0].parentFolderID = folder.ParentID; + + return m_Database.StoreFolder(x[0]); + } + + // We don't check the principal's ID here + // + public bool DeleteFolders(UUID principalID, List folderIDs) + { + foreach (UUID id in folderIDs) + { + InventoryFolderBase f = new InventoryFolderBase(); + f.ID = id; + PurgeFolder(f); + m_Database.DeleteFolders("folderID", id.ToString()); + } + + return true; + } + + public bool PurgeFolder(InventoryFolderBase folder) + { + XInventoryFolder[] subFolders = m_Database.GetFolders( + new string[] { "parentFolderID" }, + new string[] { folder.ID.ToString() }); + + foreach (XInventoryFolder x in subFolders) + PurgeFolder(ConvertToOpenSim(x)); + + m_Database.DeleteItems("parentFolderID", folder.ID.ToString()); + + return true; + } + + public bool AddItem(InventoryItemBase item) + { + return m_Database.StoreItem(ConvertFromOpenSim(item)); + } + + public bool UpdateItem(InventoryItemBase item) + { + return m_Database.StoreItem(ConvertFromOpenSim(item)); + } + + public bool MoveItems(UUID principalID, List items) + { + foreach (InventoryItemBase i in items) + { + m_Database.MoveItem(principalID.ToString(), i.ID.ToString(), + i.Folder.ToString()); + } + + return true; + } + + public bool DeleteItems(UUID principalID, List itemIDs) + { + foreach (UUID id in itemIDs) + m_Database.DeleteItems("inventoryID", id.ToString()); + + return true; + } + + public InventoryItemBase GetItem(InventoryItemBase item) + { + XInventoryItem[] items = m_Database.GetItems( + new string[] { "inventoryID" }, + new string[] { item.ID.ToString() }); + + if (items.Length == 0) + return null; + + return ConvertToOpenSim(items[0]); + } + + public InventoryFolderBase GetFolder(InventoryFolderBase folder) + { + XInventoryFolder[] folders = m_Database.GetFolders( + new string[] { "folderID"}, + new string[] { folder.ID.ToString() }); + + if (folders.Length == 0) + return null; + + return ConvertToOpenSim(folders[0]); + } + + public List GetActiveGestures(UUID userId) + { + return null; + } + + public int GetAssetPermissions(UUID userID, UUID assetID) + { + return 0; + } + + // CM never needed those. Left unimplemented. + // Obsolete in core + // + public InventoryCollection GetUserInventory(UUID userID) + { + return null; + } + public void GetUserInventory(UUID userID, InventoryReceiptCallback callback) + { + } + + // Unused. + // + public bool HasInventoryForUser(UUID userID) + { + return false; + } + + // CM Helpers + // + private InventoryFolderBase ConvertToOpenSim(XInventoryFolder folder) + { + InventoryFolderBase newFolder = new InventoryFolderBase(); + + newFolder.ParentID = folder.parentFolderID; + newFolder.Type = (short)folder.type; + newFolder.Version = (ushort)folder.version; + newFolder.Name = folder.folderName; + newFolder.Owner = folder.agentID; + newFolder.ID = folder.folderID; + + return newFolder; + } + + private XInventoryFolder ConvertFromOpenSim(InventoryFolderBase folder) + { + XInventoryFolder newFolder = new XInventoryFolder(); + + newFolder.parentFolderID = folder.ParentID; + newFolder.type = (int)folder.Type; + newFolder.version = (int)folder.Version; + newFolder.folderName = folder.Name; + newFolder.agentID = folder.Owner; + newFolder.folderID = folder.ID; + + return newFolder; + } + + private InventoryItemBase ConvertToOpenSim(XInventoryItem item) + { + InventoryItemBase newItem = new InventoryItemBase(); + + newItem.AssetID = item.assetID; + newItem.AssetType = item.assetType; + newItem.Name = item.inventoryName; + newItem.Owner = item.avatarID; + newItem.ID = item.inventoryID; + newItem.InvType = item.invType; + newItem.Folder = item.parentFolderID; + newItem.CreatorId = item.creatorID.ToString(); + newItem.Description = item.inventoryDescription; + newItem.NextPermissions = (uint)item.inventoryNextPermissions; + newItem.CurrentPermissions = (uint)item.inventoryCurrentPermissions; + newItem.BasePermissions = (uint)item.inventoryBasePermissions; + newItem.EveryOnePermissions = (uint)item.inventoryEveryOnePermissions; + newItem.GroupPermissions = (uint)item.inventoryGroupPermissions; + newItem.GroupID = item.groupID; + newItem.GroupOwned = item.groupOwned; + newItem.SalePrice = item.salePrice; + newItem.SaleType = (byte)item.saleType; + newItem.Flags = (uint)item.flags; + newItem.CreationDate = item.creationDate; + + return newItem; + } + + private XInventoryItem ConvertFromOpenSim(InventoryItemBase item) + { + XInventoryItem newItem = new XInventoryItem(); + + newItem.assetID = item.AssetID; + newItem.assetType = item.AssetType; + newItem.inventoryName = item.Name; + newItem.avatarID = item.Owner; + newItem.inventoryID = item.ID; + newItem.invType = item.InvType; + newItem.parentFolderID = item.Folder; + newItem.creatorID = item.CreatorIdAsUuid; + newItem.inventoryDescription = item.Description; + newItem.inventoryNextPermissions = (int)item.NextPermissions; + newItem.inventoryCurrentPermissions = (int)item.CurrentPermissions; + newItem.inventoryBasePermissions = (int)item.BasePermissions; + newItem.inventoryEveryOnePermissions = (int)item.EveryOnePermissions; + newItem.inventoryGroupPermissions = (int)item.GroupPermissions; + newItem.groupID = item.GroupID; + newItem.groupOwned = item.GroupOwned; + newItem.salePrice = item.SalePrice; + newItem.saleType = (int)item.SaleType; + newItem.flags = (int)item.Flags; + newItem.creationDate = item.CreationDate; + + return newItem; + } + } +} -- cgit v1.1 From 0907d5d69e10ba5be79a6d03366ce3cfa59c0bec Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 4 Jan 2010 20:52:44 +0000 Subject: Finish conversion if XInventoryService --- OpenSim/Data/IXInventoryData.cs | 4 +- OpenSim/Data/MySQL/MySQLXInventoryData.cs | 55 +++++++++++++++++--- .../Services/InventoryService/XInventoryService.cs | 58 +++++++++++++++++----- 3 files changed, 98 insertions(+), 19 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/IXInventoryData.cs b/OpenSim/Data/IXInventoryData.cs index 88174d9..cd9273e 100644 --- a/OpenSim/Data/IXInventoryData.cs +++ b/OpenSim/Data/IXInventoryData.cs @@ -77,6 +77,8 @@ namespace OpenSim.Data bool DeleteFolders(string field, string val); bool DeleteItems(string field, string val); - bool MoveItem(string principalID, string id, string newParent); + bool MoveItem(string id, string newParent); + XInventoryItem[] GetActiveGestures(UUID principalID); + int GetAssetPermissions(UUID principalID, UUID assetID); } } diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index dd3e6ea..0eebc9c 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -85,9 +85,19 @@ namespace OpenSim.Data.MySQL return m_Items.Delete(field, val); } - public bool MoveItem(string principalID, string id, string newParent) + public bool MoveItem(string id, string newParent) { - return m_Items.MoveItem(principalID, id, newParent); + return m_Items.MoveItem(id, newParent); + } + + public XInventoryItem[] GetActiveGestures(UUID principalID) + { + return m_Items.GetActiveGestures(principalID); + } + + public int GetAssetPermissions(UUID principalID, UUID assetID) + { + return m_Items.GetAssetPermissions(principalID, assetID); } } @@ -98,16 +108,49 @@ namespace OpenSim.Data.MySQL { } - public bool MoveItem(string principalID, string id, string newParent) + public bool MoveItem(string id, string newParent) { MySqlCommand cmd = new MySqlCommand(); - cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where agentID = ?AgentID and folderID = ?FolderID"); + cmd.CommandText = String.Format("update {0} set parentFolderID = ?ParentFolderID where inventoryID = ?InventoryID", m_Realm); cmd.Parameters.AddWithValue("?ParentFolderID", newParent); - cmd.Parameters.AddWithValue("?FolderID", id); - cmd.Parameters.AddWithValue("?AgentID", principalID); + cmd.Parameters.AddWithValue("?InventoryID", id); return ExecuteNonQuery(cmd) == 0 ? false : true; } + + public XInventoryItem[] GetActiveGestures(UUID principalID) + { + MySqlCommand cmd = new MySqlCommand(); + cmd.CommandText = String.Format("select * from inventoryitems where avatarId = ?uuid and assetType = ?type and flags = 1", m_Realm); + + cmd.Parameters.AddWithValue("?uuid", principalID.ToString()); + cmd.Parameters.AddWithValue("?type", (int)AssetType.Gesture); + + return DoQuery(cmd); + } + + public int GetAssetPermissions(UUID principalID, UUID assetID) + { + MySqlCommand cmd = new MySqlCommand(); + + cmd.CommandText = String.Format("select bit_or(inventoryCurrentPermissions) as inventoryCurrentPermissions from inventoryitems where avatarID = ?PrincipalID and assetID = ?AssetID group by assetID", m_Realm); + cmd.Parameters.AddWithValue("?PrincipalID", principalID.ToString()); + cmd.Parameters.AddWithValue("?AssetID", assetID.ToString()); + + IDataReader reader = ExecuteReader(cmd); + + int perms = 0; + + if (reader.Read()) + { + perms = Convert.ToInt32(reader["inventoryCurrentPermissions"]); + } + + reader.Close(); + CloseReaderCommand(cmd); + + return perms; + } } } diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 1e7f206..2c79c77 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -183,7 +183,10 @@ namespace OpenSim.Services.InventoryService List folders = new List(); foreach (XInventoryFolder x in allFolders) + { + m_log.DebugFormat("[INVENTORY]: Adding folder {0} to skeleton", x.folderName); folders.Add(ConvertToOpenSim(x)); + } return folders; } @@ -214,35 +217,48 @@ namespace OpenSim.Services.InventoryService public InventoryCollection GetFolderContent(UUID principalID, UUID folderID) { + // This method doesn't receive a valud principal id from the + // connector. So we disregard the principal and look + // by ID. + // + m_log.DebugFormat("[INVENTORY]: Fetch contents for folder {0}", folderID.ToString()); InventoryCollection inventory = new InventoryCollection(); inventory.UserID = principalID; inventory.Folders = new List(); inventory.Items = new List(); XInventoryFolder[] folders = m_Database.GetFolders( - new string[] { "agentID", "parentFolderID"}, - new string[] { principalID.ToString(), UUID.Zero.ToString() }); + new string[] { "parentFolderID"}, + new string[] { folderID.ToString() }); foreach (XInventoryFolder x in folders) + { + m_log.DebugFormat("[INVENTORY]: Adding folder {0} to response", x.folderName); inventory.Folders.Add(ConvertToOpenSim(x)); + } XInventoryItem[] items = m_Database.GetItems( - new string[] { "avatarID", "parentFolderID"}, - new string[] { principalID.ToString(), UUID.Zero.ToString() }); + new string[] { "parentFolderID"}, + new string[] { folderID.ToString() }); foreach (XInventoryItem i in items) + { + m_log.DebugFormat("[INVENTORY]: Adding item {0} to response", i.inventoryName); inventory.Items.Add(ConvertToOpenSim(i)); + } return inventory; } public List GetFolderItems(UUID principalID, UUID folderID) { + // Since we probably don't get a valid principal here, either ... + // List invItems = new List(); XInventoryItem[] items = m_Database.GetItems( - new string[] { "avatarID", "parentFolderID"}, - new string[] { principalID.ToString(), UUID.Zero.ToString() }); + new string[] { "parentFolderID"}, + new string[] { UUID.Zero.ToString() }); foreach (XInventoryItem i in items) invItems.Add(ConvertToOpenSim(i)); @@ -279,6 +295,8 @@ namespace OpenSim.Services.InventoryService // public bool DeleteFolders(UUID principalID, List folderIDs) { + // Ignore principal ID, it's bogus at connector level + // foreach (UUID id in folderIDs) { InventoryFolderBase f = new InventoryFolderBase(); @@ -297,7 +315,10 @@ namespace OpenSim.Services.InventoryService new string[] { folder.ID.ToString() }); foreach (XInventoryFolder x in subFolders) + { PurgeFolder(ConvertToOpenSim(x)); + m_Database.DeleteFolders("folderID", x.folderID.ToString()); + } m_Database.DeleteItems("parentFolderID", folder.ID.ToString()); @@ -316,10 +337,11 @@ namespace OpenSim.Services.InventoryService public bool MoveItems(UUID principalID, List items) { + // Principal is b0rked. *sigh* + // foreach (InventoryItemBase i in items) { - m_Database.MoveItem(principalID.ToString(), i.ID.ToString(), - i.Folder.ToString()); + m_Database.MoveItem(i.ID.ToString(), i.Folder.ToString()); } return true; @@ -327,6 +349,8 @@ namespace OpenSim.Services.InventoryService public bool DeleteItems(UUID principalID, List itemIDs) { + // Just use the ID... *facepalms* + // foreach (UUID id in itemIDs) m_Database.DeleteItems("inventoryID", id.ToString()); @@ -357,14 +381,24 @@ namespace OpenSim.Services.InventoryService return ConvertToOpenSim(folders[0]); } - public List GetActiveGestures(UUID userId) + public List GetActiveGestures(UUID principalID) { - return null; + XInventoryItem[] items = m_Database.GetActiveGestures(principalID); + + if (items.Length == 0) + return null; + + List ret = new List(); + + foreach (XInventoryItem x in items) + ret.Add(ConvertToOpenSim(x)); + + return ret; } - public int GetAssetPermissions(UUID userID, UUID assetID) + public int GetAssetPermissions(UUID principalID, UUID assetID) { - return 0; + return m_Database.GetAssetPermissions(principalID, assetID); } // CM never needed those. Left unimplemented. -- cgit v1.1 From 3724a38ab4694c75288cbf4ba848bd9894b5231d Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 5 Jan 2010 15:39:53 +0000 Subject: Allow estate managers (if estate_owner_is_god is set) to actually enter god mode. Allow god modification of objects if the object owner is the same god that wants to modify, this allows you to regain perms on your own objects after IAR import messed them up. --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index e837e9a..f66f01f 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -596,7 +596,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions return objectOwnerMask; // Estate users should be able to edit anything in the sim - if (IsEstateManager(user) && m_RegionOwnerIsGod && !IsAdministrator(objectOwner)) + if (IsEstateManager(user) && m_RegionOwnerIsGod && (!IsAdministrator(objectOwner)) || objectOwner == user) return objectOwnerMask; // Admin should be able to edit anything in the sim (including admin objects) @@ -888,6 +888,9 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; + if (IsEstateManager(user) && m_RegionOwnerIsGod) + return true; + return IsAdministrator(user); } -- cgit v1.1 From 71adb37fa87f0ad8fa42c8156529bf72814fde58 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 7 Jan 2010 23:58:19 -0500 Subject: Fix llRotBetween --- .../Shared/Api/Implementation/LSL_Api.cs | 56 +++++++++++++++++++++- 1 file changed, 54 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 76c79da..1469e7e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -722,6 +722,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { //A and B should both be normalized m_host.AddScriptLPS(1); + /* This method is more accurate than the SL one, and thus causes problems + for scripts that deal with the SL inaccuracy around 180-degrees -.- .._. + double dotProduct = LSL_Vector.Dot(a, b); LSL_Vector crossProduct = LSL_Vector.Cross(a, b); double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b); @@ -738,8 +741,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); return new LSL_Rotation((float)x, (float)y, (float)z, (float)w); - } - + */ + + // This method mimics the 180 errors found in SL + // See www.euclideanspace.com... angleBetween + LSL_Vector vec_a = a; + LSL_Vector vec_b = b; + + // Eliminate zero length + LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a); + LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b); + if (vec_a_mag < 0.00001 || + vec_b_mag < 0.00001) + { + return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); + } + + // Normalize + vec_a = llVecNorm(vec_a); + vec_b = llVecNorm(vec_b); + + // Calculate axis and rotation angle + LSL_Vector axis = vec_a % vec_b; + LSL_Float cos_theta = vec_a * vec_b; + + // Check if parallel + if (cos_theta > 0.99999) + { + return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); + } + + // Check if anti-parallel + else if (cos_theta < -0.99999) + { + LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a); + if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0); + return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0); + } + else // other rotation + { + LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f; + axis = llVecNorm(axis); + double x, y, z, s, t; + s = Math.Cos(theta); + t = Math.Sin(theta); + x = axis.x * t; + y = axis.y * t; + z = axis.z * t; + return new LSL_Rotation(x,y,z,s); + } + } + public void llWhisper(int channelID, string text) { m_host.AddScriptLPS(1); -- cgit v1.1 From a2aadb78a919323d62a5b4a44c0899b63641788b Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 8 Jan 2010 23:12:11 -0500 Subject: Maintain control() event stream --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index afd5f86..0eed284 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4792,6 +4792,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP (x.CameraLeftAxis != lastarg.CameraLeftAxis) || (x.CameraUpAxis != lastarg.CameraUpAxis) || (x.ControlFlags != lastarg.ControlFlags) || + (x.ControlFlags != 0) || (x.Far != lastarg.Far) || (x.Flags != lastarg.Flags) || (x.State != lastarg.State) || -- cgit v1.1 From a87d7a12967b50fe83ebbaa7b57e531eb93158a2 Mon Sep 17 00:00:00 2001 From: Careminster Staff Date: Wed, 13 Jan 2010 22:45:17 -0600 Subject: Adds Land Banning. --- .../CoreModules/World/Land/LandManagementModule.cs | 130 +++++++++++++-------- .../Region/CoreModules/World/Land/LandObject.cs | 48 ++++++-- 2 files changed, 120 insertions(+), 58 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 9b39b09..d9b36a5 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -264,20 +264,57 @@ namespace OpenSim.Region.CoreModules.World.Land return parcelsNear; } - public void SendYouAreBannedNotice(ScenePresence avatar) + public void KickUserOffOfParcel(ScenePresence avatar) { - if (AllowedForcefulBans) + if (avatar.GodLevel == 0) { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because you are banned. Please go away."); - - avatar.PhysicsActor.Position = avatar.lastKnownAllowedPosition; - avatar.PhysicsActor.Velocity = Vector3.Zero; + List parcelsNear = ParcelsNearPoint(avatar.AbsolutePosition); + foreach (ILandObject check in parcelsNear) + { + if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) + { + Vector3 target = check.LandData.UserLocation; + avatar.TeleportWithMomentum(target); + return; + } + } } - else + } + public void MoveUserOutOfParcel(ScenePresence avatar) + { + if (avatar.GodLevel == 0) { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim!"); + ILandObject land = m_scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + List parcelsNear = new List(); + + for (int x = -2; x <= 2; x += 2) + { + ILandObject check = GetLandObject(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y); + if (check != null) + { + if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) + { + Vector3 target = new Vector3(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); + avatar.TeleportWithMomentum(target); + avatar.Velocity = new Vector3(-avatar.Velocity.X - 5, avatar.Velocity.Y, avatar.Velocity.Z); + return; + } + } + } + for (int y = -2; y <= 2; y += 2) + { + ILandObject check = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y); + if (check != null) + { + if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) + { + Vector3 target = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y, avatar.AbsolutePosition.Z); + avatar.TeleportWithMomentum(target); + avatar.Velocity = new Vector3(avatar.Velocity.X, -avatar.Velocity.Y - 5, avatar.Velocity.Z); + return; + } + } + } } } @@ -297,16 +334,7 @@ namespace OpenSim.Region.CoreModules.World.Land { if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) { - SendYouAreBannedNotice(avatar); - } - else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) - { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!)."); - } - else - { - avatar.sentMessageAboutRestrictedParcelFlyingDown = true; + MoveUserOutOfParcel(avatar); } } else @@ -317,28 +345,47 @@ namespace OpenSim.Region.CoreModules.World.Land } } - public void SendOutNearestBanLine(IClientAPI avatar) + public void SendOutNearestBanLine(ScenePresence avatar) { - List avatars = m_scene.GetAvatars(); - foreach (ScenePresence presence in avatars) + ILandObject checkBan = null; + for (int x = -2; x <= 2; x += 2) { - if (presence.UUID == avatar.AgentId) + checkBan = GetLandObject(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y); + if (checkBan != null) { - List checkLandParcels = ParcelsNearPoint(presence.AbsolutePosition); - foreach (ILandObject checkBan in checkLandParcels) + if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) { - if (checkBan.IsBannedFromLand(avatar.AgentId)) + if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar); - return; //Only send one + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); + return; } - if (checkBan.IsRestrictedFromLand(avatar.AgentId)) + if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar); - return; //Only send one + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); + return; + } + } + } + } + for (int y = -2; y <= 2; y += 2) + { + checkBan = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y); + if (checkBan != null) + { + if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) + { + if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) + { + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); + return; + } + if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) + { + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); + return; } } - return; } } } @@ -385,25 +432,14 @@ namespace OpenSim.Region.CoreModules.World.Land if (clientAvatar != null) { SendLandUpdate(clientAvatar); - SendOutNearestBanLine(remote_client); + SendOutNearestBanLine(clientAvatar); ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); if (parcel != null) { if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) - { - EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, - m_scene.RegionInfo.RegionID); - //They are going under the safety line! - if (!parcel.IsBannedFromLand(clientAvatar.UUID)) - { - clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; - } - } - else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && parcel.IsBannedFromLand(clientAvatar.UUID)) { - SendYouAreBannedNotice(clientAvatar); + MoveUserOutOfParcel(clientAvatar); } } } @@ -451,7 +487,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (land != null) { - if (agentID == land.LandData.OwnerID) + if (m_scene.Permissions.CanEditParcel(agentID, land)) { land.UpdateAccessList(flags, entries, remote_client); } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 1fa8630..1c65965 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -267,11 +267,7 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsEitherBannedOrRestricted(UUID avatar) { - if (IsBannedFromLand(avatar)) - { - return true; - } - else if (IsRestrictedFromLand(avatar)) + if (IsRestrictedFromLand(avatar) || IsBannedFromLand(avatar)) { return true; } @@ -280,7 +276,8 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsBannedFromLand(UUID avatar) { - if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) + ScenePresence SP = m_scene.GetScenePresence(avatar); + if ((LandData.Flags & (uint)ParcelFlags.UseBanList) > 0) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); entry.AgentID = avatar; @@ -288,8 +285,22 @@ namespace OpenSim.Region.CoreModules.World.Land entry.Time = new DateTime(); if (LandData.ParcelAccessList.Contains(entry)) { - //They are banned, so lets send them a notice about this parcel - return true; + if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) > 0) + { + if (LandData.GroupID == SP.ControllingClient.ActiveGroupId) + { + return false; + } + else + { + //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel + return true; + } + } + else + { + return true; + } } } return false; @@ -297,7 +308,8 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsRestrictedFromLand(UUID avatar) { - if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) + ScenePresence SP = m_scene.GetScenePresence(avatar); + if ((LandData.Flags & (uint)ParcelFlags.UseAccessList) > 0) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); entry.AgentID = avatar; @@ -305,8 +317,22 @@ namespace OpenSim.Region.CoreModules.World.Land entry.Time = new DateTime(); if (!LandData.ParcelAccessList.Contains(entry)) { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel - return true; + if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) > 0) + { + if (LandData.GroupID == SP.ControllingClient.ActiveGroupId) + { + return false; + } + else + { + //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel + return true; + } + } + else + { + return true; + } } } return false; -- cgit v1.1 From 884410501e50f0abb09ef1339ac74e22c2dfd39f Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 15 Jan 2010 20:19:06 +0000 Subject: Allow renaming of items that contain no-mod items --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 18ec25f..dd4c14b 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1803,8 +1803,13 @@ namespace OpenSim.Region.Framework.Scenes } else { - item.BasePermissions = objectGroup.GetEffectivePermissions(); - item.CurrentPermissions = objectGroup.GetEffectivePermissions(); + uint ownerPerms = objectGroup.GetEffectivePermissions(); + if ((objectGroup.RootPart.OwnerMask & (uint)PermissionMask.Modify) != 0) + ownerPerms |= (uint)PermissionMask.Modify; + + item.BasePermissions = ownerPerms; + item.CurrentPermissions = ownerPerms; + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; item.GroupPermissions = objectGroup.RootPart.GroupMask; -- cgit v1.1 From 44d523518af31075c77653eacc7489220db4abaa Mon Sep 17 00:00:00 2001 From: Careminster Staff Date: Sun, 17 Jan 2010 19:23:36 -0600 Subject: Adds land ejection and freezing. Adds more checks to land banning. --- .../CoreModules/World/Land/LandManagementModule.cs | 442 +++++++++++++++++++-- 1 file changed, 419 insertions(+), 23 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index d9b36a5..23da1ae 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -81,6 +81,8 @@ namespace OpenSim.Region.CoreModules.World.Land private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; private bool m_allowedForcefulBans = true; + private string DefultGodParcelGroup; + private string DefultGodParcelName; // caches ExtendedLandData private Cache parcelInfoCache; @@ -153,6 +155,10 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelInfoRequest += ClientOnParcelInfoRequest; client.OnParcelDwellRequest += ClientOnParcelDwellRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; + client.OnParcelGodMark += ClientOnParcelGodMark; + client.OnSimWideDeletes += ClientOnSimWideDeletes; + client.OnParcelFreezeUser += ClientOnParcelFreezeUser; + client.OnParcelEjectUser += ClientOnParcelEjectUser; EntityBase presenceEntity; if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) @@ -264,22 +270,7 @@ namespace OpenSim.Region.CoreModules.World.Land return parcelsNear; } - public void KickUserOffOfParcel(ScenePresence avatar) - { - if (avatar.GodLevel == 0) - { - List parcelsNear = ParcelsNearPoint(avatar.AbsolutePosition); - foreach (ILandObject check in parcelsNear) - { - if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) - { - Vector3 target = check.LandData.UserLocation; - avatar.TeleportWithMomentum(target); - return; - } - } - } - } + public void MoveUserOutOfParcel(ScenePresence avatar) { if (avatar.GodLevel == 0) @@ -296,7 +287,6 @@ namespace OpenSim.Region.CoreModules.World.Land { Vector3 target = new Vector3(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); avatar.TeleportWithMomentum(target); - avatar.Velocity = new Vector3(-avatar.Velocity.X - 5, avatar.Velocity.Y, avatar.Velocity.Z); return; } } @@ -310,11 +300,73 @@ namespace OpenSim.Region.CoreModules.World.Land { Vector3 target = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y, avatar.AbsolutePosition.Z); avatar.TeleportWithMomentum(target); - avatar.Velocity = new Vector3(avatar.Velocity.X, -avatar.Velocity.Y - 5, avatar.Velocity.Z); return; } } } + List allParcels = new List(); + allParcels = AllParcels(); + if (allParcels.Count != 1) + { + foreach (ILandObject parcel in allParcels) + { + if (parcel.IsEitherBannedOrRestricted(avatar.UUID) != true) + { + Vector3 temptarget = parcel.LandData.UserLocation; + if (parcel.ContainsPoint((int)parcel.LandData.UserLocation.X, (int)parcel.LandData.UserLocation.Y)) + { + avatar.TeleportWithMomentum(temptarget); + return; + } + else + { + for (int x = 0; x <= Constants.RegionSize / 3; x += 3) + { + for (int y = 0; y <= Constants.RegionSize / 3; y += 3) + { + if (parcel.ContainsPoint(x, y)) + { + temptarget = new Vector3(x, y, avatar.AbsolutePosition.Z); + avatar.TeleportWithMomentum(temptarget); + return; + } + } + } + } + } + } + } + //Move to region side + if (avatar.AbsolutePosition.X > avatar.AbsolutePosition.Y) + { + if (avatar.AbsolutePosition.X > .5 * Constants.RegionSize) + { + Vector3 target = new Vector3(Constants.RegionSize, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); ; + avatar.TeleportWithMomentum(target); + return; + } + else + { + Vector3 target = new Vector3(0, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); ; + avatar.TeleportWithMomentum(target); + return; + } + } + else + { + if (avatar.AbsolutePosition.Y > .5 * Constants.RegionSize) + { + Vector3 target = new Vector3(avatar.AbsolutePosition.X, Constants.RegionSize, avatar.AbsolutePosition.Z); ; + avatar.TeleportWithMomentum(target); + return; + } + else + { + Vector3 target = new Vector3(avatar.AbsolutePosition.X, 0, avatar.AbsolutePosition.Z); ; + avatar.TeleportWithMomentum(target); + return; + } + } } } @@ -357,12 +409,12 @@ namespace OpenSim.Region.CoreModules.World.Land { if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, true, (int)ParcelResult.Multiple, avatar.ControllingClient); return; } if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, true, (int)ParcelResult.Multiple, avatar.ControllingClient); return; } } @@ -377,12 +429,12 @@ namespace OpenSim.Region.CoreModules.World.Land { if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, true, (int)ParcelResult.Multiple, avatar.ControllingClient); return; } if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, true, (int)ParcelResult.Multiple, avatar.ControllingClient); return; } } @@ -490,6 +542,18 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.CanEditParcel(agentID, land)) { land.UpdateAccessList(flags, entries, remote_client); + List presences = ((Scene)remote_client.Scene).GetAvatars(); + foreach (ScenePresence presence in presences) + { + land = GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); + if (land != null) + { + if (land.IsEitherBannedOrRestricted(presence.UUID)) + { + MoveUserOutOfParcel(presence); + } + } + } } } else @@ -1055,7 +1119,25 @@ namespace OpenSim.Region.CoreModules.World.Land m_landList.TryGetValue(localID, out land); } - if (land != null) land.UpdateLandProperties(args, remote_client); + if (land != null) + { + land.UpdateLandProperties(args, remote_client); + if ((args.ParcelFlags & (uint)(ParcelFlags.UseBanList | ParcelFlags.UseAccessList | ParcelFlags.UseAccessGroup | ParcelFlags.UsePassList)) != 0) + { + List presences = ((Scene)remote_client.Scene).GetAvatars(); + foreach (ScenePresence presence in presences) + { + land = GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); + if (land != null) + { + if (land.IsEitherBannedOrRestricted(presence.UUID)) + { + MoveUserOutOfParcel(presence); + } + } + } + } + } } public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) @@ -1473,5 +1555,319 @@ namespace OpenSim.Region.CoreModules.World.Land UpdateLandObject(localID, land.LandData); } + public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID) + { + ILandObject land = null; + List Land = ((Scene)client.Scene).LandChannel.AllParcels(); + foreach (ILandObject landObject in Land) + { + if (landObject.LandData.LocalID == landID) + { + land = landObject; + } + } + land.DeedToGroup(new UUID(DefultGodParcelGroup)); + land.LandData.Name = DefultGodParcelName; + land.SendLandUpdateToAvatarsOverMe(); + } + private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID) + { + ScenePresence SP; + ((Scene)client.Scene).TryGetAvatar(client.AgentId, out SP); + List returns = new List(); + if (SP.GodLevel != 0) + { + if (flags == 0) //All parcels, scripted or not + { + ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) + { + if (e.OwnerID == targetID) + { + returns.Add(e); + } + } + ); + } + if (flags == 4) //All parcels, scripted object + { + ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) + { + if (e.OwnerID == targetID) + { + if (e.scriptScore >= 0.01) + { + returns.Add(e); + } + } + } + ); + } + if (flags == 4) //not target parcel, scripted object + { + ((Scene)client.Scene).ForEachSOG(delegate(SceneObjectGroup e) + { + if (e.OwnerID == targetID) + { + ILandObject landobject = ((Scene)client.Scene).LandChannel.GetLandObject(e.AbsolutePosition.X, e.AbsolutePosition.Y); + if (landobject.LandData.OwnerID != e.OwnerID) + { + if (e.scriptScore >= 0.01) + { + returns.Add(e); + } + } + } + } + ); + } + foreach (SceneObjectGroup ol in returns) + { + ReturnObject(ol, client); + } + } + } + public void ReturnObject(SceneObjectGroup obj, IClientAPI client) + { + SceneObjectGroup[] objs = new SceneObjectGroup[1]; + objs[0] = obj; + ((Scene)client.Scene).returnObjects(objs, client.AgentId); + } + + Dictionary Timers = new Dictionary(); + + public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) + { + ScenePresence targetAvatar = null; + ((Scene)client.Scene).TryGetAvatar(target, out targetAvatar); + ScenePresence parcelManager = null; + ((Scene)client.Scene).TryGetAvatar(client.AgentId, out parcelManager); + System.Threading.Timer Timer; + + if (targetAvatar.GodLevel == 0) + { + ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); + if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land)) + return; + if (flags == 0) + { + targetAvatar.AllowMovement = false; + targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has frozen you for 30 seconds. You cannot move or interact with the world."); + parcelManager.ControllingClient.SendAlertMessage("Avatar Frozen."); + System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); + Timer = new System.Threading.Timer(timeCB, targetAvatar, 30000, 0); + Timers.Add(targetAvatar.UUID, Timer); + } + else + { + targetAvatar.AllowMovement = true; + targetAvatar.ControllingClient.SendAlertMessage(parcelManager.Firstname + " " + parcelManager.Lastname + " has unfrozen you."); + parcelManager.ControllingClient.SendAlertMessage("Avatar Unfrozen."); + Timers.TryGetValue(targetAvatar.UUID, out Timer); + Timers.Remove(targetAvatar.UUID); + Timer.Dispose(); + } + } + } + private void OnEndParcelFrozen(object avatar) + { + ScenePresence targetAvatar = (ScenePresence)avatar; + targetAvatar.AllowMovement = true; + System.Threading.Timer Timer; + Timers.TryGetValue(targetAvatar.UUID, out Timer); + Timers.Remove(targetAvatar.UUID); + targetAvatar.ControllingClient.SendAgentAlertMessage("The freeze has worn off; you may go about your business.", false); + } + + + public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) + { + ScenePresence targetAvatar = null; + ((Scene)client.Scene).TryGetAvatar(target, out targetAvatar); + ScenePresence parcelManager = null; + ((Scene)client.Scene).TryGetAvatar(client.AgentId, out parcelManager); + //Just eject + if (flags == 0) + { + if (targetAvatar.GodLevel == 0) + { + ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); + if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land)) + return; + + Vector3 position = new Vector3(0, 0, 0); + List allParcels = new List(); + allParcels = AllParcels(); + if (allParcels.Count != 1) + { + foreach (ILandObject parcel in allParcels) + { + if (parcel.LandData.GlobalID != land.LandData.GlobalID) + { + if (parcel.IsEitherBannedOrRestricted(targetAvatar.UUID) != true) + { + for (int x = 1; x <= Constants.RegionSize; x += 2) + { + for (int y = 1; y <= Constants.RegionSize; y += 2) + { + if (parcel.ContainsPoint(x, y)) + { + position = new Vector3(x, y, targetAvatar.AbsolutePosition.Z); + targetAvatar.TeleportWithMomentum(position); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); + return; + } + } + } + } + } + } + } + Vector3 targetVector; + if (targetAvatar.AbsolutePosition.X > targetAvatar.AbsolutePosition.Y) + { + if (targetAvatar.AbsolutePosition.X > .5 * Constants.RegionSize) + { + targetVector = new Vector3(Constants.RegionSize, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); + return; + } + else + { + targetVector = new Vector3(0, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); + return; + } + } + else + { + if (targetAvatar.AbsolutePosition.Y > .5 * Constants.RegionSize) + { + targetVector = new Vector3(targetAvatar.AbsolutePosition.X, Constants.RegionSize, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); + return; + } + else + { + targetVector = new Vector3(targetAvatar.AbsolutePosition.X, 0, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected."); + return; + } + } + } + } + //Eject and ban + if (flags == 1) + { + if (targetAvatar.GodLevel == 0) + { + ILandObject land = ((Scene)client.Scene).LandChannel.GetLandObject(targetAvatar.AbsolutePosition.X, targetAvatar.AbsolutePosition.Y); + if (!((Scene)client.Scene).Permissions.CanEditParcel(client.AgentId, land)) + return; + + Vector3 position = new Vector3(0, 0, 0); + List allParcels = new List(); + allParcels = AllParcels(); + if (allParcels.Count != 1) + { + foreach (ILandObject parcel in allParcels) + { + if (parcel.LandData.GlobalID != land.LandData.GlobalID) + { + if (parcel.IsEitherBannedOrRestricted(targetAvatar.UUID) != true) + { + for (int x = 1; x <= Constants.RegionSize; x += 2) + { + for (int y = 1; y <= Constants.RegionSize; y += 2) + { + if (parcel.ContainsPoint(x, y)) + { + position = new Vector3(x, y, targetAvatar.AbsolutePosition.Z); + targetAvatar.TeleportWithMomentum(position); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned."); + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = targetAvatar.UUID; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + land.LandData.ParcelAccessList.Add(entry); + return; + } + } + } + } + } + } + } + Vector3 targetVector; + if (targetAvatar.AbsolutePosition.X > targetAvatar.AbsolutePosition.Y) + { + if (targetAvatar.AbsolutePosition.X > .5 * Constants.RegionSize) + { + targetVector = new Vector3(Constants.RegionSize, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned."); + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = targetAvatar.UUID; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + land.LandData.ParcelAccessList.Add(entry); + return; + } + else + { + targetVector = new Vector3(0, targetAvatar.AbsolutePosition.Y, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned."); + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = targetAvatar.UUID; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + land.LandData.ParcelAccessList.Add(entry); + return; + } + } + else + { + if (targetAvatar.AbsolutePosition.Y > .5 * Constants.RegionSize) + { + targetVector = new Vector3(targetAvatar.AbsolutePosition.X, Constants.RegionSize, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned."); + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = targetAvatar.UUID; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + land.LandData.ParcelAccessList.Add(entry); + return; + } + else + { + targetVector = new Vector3(targetAvatar.AbsolutePosition.X, 0, targetAvatar.AbsolutePosition.Z); ; + targetAvatar.TeleportWithMomentum(targetVector); + targetAvatar.ControllingClient.SendAlertMessage("You have been ejected and banned by " + parcelManager.Firstname + " " + parcelManager.Lastname); + parcelManager.ControllingClient.SendAlertMessage("Avatar Ejected and Banned."); + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = targetAvatar.UUID; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + land.LandData.ParcelAccessList.Add(entry); + return; + } + } + } + } + } } } -- cgit v1.1 From f4e30664e6b327257db196512f0b6e304399214b Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Jan 2010 01:55:45 +0000 Subject: Fix a typo --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 23da1ae..6a0e8d1 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -81,8 +81,8 @@ namespace OpenSim.Region.CoreModules.World.Land private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; private bool m_allowedForcefulBans = true; - private string DefultGodParcelGroup; - private string DefultGodParcelName; + private string DefaultGodParcelGroup; + private string DefaultGodParcelName; // caches ExtendedLandData private Cache parcelInfoCache; @@ -1566,8 +1566,8 @@ namespace OpenSim.Region.CoreModules.World.Land land = landObject; } } - land.DeedToGroup(new UUID(DefultGodParcelGroup)); - land.LandData.Name = DefultGodParcelName; + land.DeedToGroup(new UUID(DefaultGodParcelGroup)); + land.LandData.Name = DefaultGodParcelName; land.SendLandUpdateToAvatarsOverMe(); } private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID) -- cgit v1.1 From 51bb31156502c391ac84aa207fce125a4299d755 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Jan 2010 02:53:31 +0000 Subject: Add chat banning. Staff patch --- .../Region/CoreModules/Avatar/Chat/ChatModule.cs | 51 +++++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index e3e8718..acc3a78 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -49,6 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat private int m_shoutdistance = 100; private int m_whisperdistance = 10; private List m_scenes = new List(); + private List FreezeCache = new List(); private string m_adminPrefix = ""; internal object m_syncy = new object(); @@ -172,7 +173,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat return; } - DeliverChatToAvatars(ChatSourceType.Agent, c); + if (FreezeCache.Contains(c.Sender.AgentId.ToString())) + { + if (c.Type != ChatTypeEnum.StartTyping || c.Type != ChatTypeEnum.StopTyping) + c.Sender.SendAgentAlertMessage("You may not talk as you are frozen.", false); + } + else + { + DeliverChatToAvatars(ChatSourceType.Agent, c); + } } public virtual void OnChatFromWorld(Object sender, OSChatMessage c) @@ -232,7 +241,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat s.ForEachScenePresence( delegate(ScenePresence presence) { - TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType); + ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); + if (Presencecheck != null) + { + if (Presencecheck.IsEitherBannedOrRestricted(c.SenderUUID) != true) + { + TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType); + } + } + } ); } @@ -322,5 +339,35 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID,(byte)src,(byte)ChatAudibleLevel.Fully); } + + Dictionary Timers = new Dictionary(); + public void ParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) + { + System.Threading.Timer Timer; + if (flags == 0) + { + FreezeCache.Add(target.ToString()); + System.Threading.TimerCallback timeCB = new System.Threading.TimerCallback(OnEndParcelFrozen); + Timer = new System.Threading.Timer(timeCB, target, 30000, 0); + Timers.Add(target, Timer); + } + else + { + FreezeCache.Remove(target.ToString()); + Timers.TryGetValue(target, out Timer); + Timers.Remove(target); + Timer.Dispose(); + } + } + + private void OnEndParcelFrozen(object avatar) + { + UUID target = (UUID)avatar; + FreezeCache.Remove(target.ToString()); + System.Threading.Timer Timer; + Timers.TryGetValue(target, out Timer); + Timers.Remove(target); + Timer.Dispose(); + } } } -- cgit v1.1 From d9c48e70a9a01f56135ede2cef9ec45c7dddf567 Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 18 Jan 2010 17:56:27 +0100 Subject: Fix a major security problem with osSetDynamicTexture which allowed the deletion of /any/ asset. --- .../Scripting/DynamicTexture/DynamicTextureModule.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index f51d0c2..679c871 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -358,11 +358,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture // tmptex.DefaultTexture.Fullbright = true; part.UpdateTexture(tmptex); - } - - if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) - { - scene.AssetService.Delete(oldID.ToString()); + } + + if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) + { + if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); + if (oldAsset != null) + { + if (oldAsset.Temporary == true) + { + scene.AssetService.Delete(oldID.ToString()); + } + } } } -- cgit v1.1 From 6772c9d2b6d05c985174f514aa8df2aacd33a201 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Jan 2010 17:35:49 +0000 Subject: Comment the asset deletion handler. It can be abused and is not currently needed. --- OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs b/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs index 3f33da6..f33bb90 100644 --- a/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs +++ b/OpenSim/Server/Handlers/Asset/AssetServerDeleteHandler.cs @@ -63,7 +63,7 @@ namespace OpenSim.Server.Handlers.Asset if (p.Length > 0) { - result = m_AssetService.Delete(p[0]); + // result = m_AssetService.Delete(p[0]); } XmlSerializer xs = new XmlSerializer(typeof(bool)); -- cgit v1.1 From 24056dc98ba94b32ac98cc0a3b1b85d5f8ef3de6 Mon Sep 17 00:00:00 2001 From: Careminster Staff Date: Mon, 18 Jan 2010 16:23:13 -0600 Subject: Adds example to OpenSim.ini.example for Admin Default Parcel settings --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 6a0e8d1..28669b9 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -81,7 +81,7 @@ namespace OpenSim.Region.CoreModules.World.Land private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; private bool m_allowedForcefulBans = true; - private string DefaultGodParcelGroup; + private UUID DefaultGodParcelGroup; private string DefaultGodParcelName; // caches ExtendedLandData @@ -96,6 +96,12 @@ namespace OpenSim.Region.CoreModules.World.Land public void Initialise(IConfigSource source) { + IConfig cnf = source.Configs["LandManagement"]; + if (cnf == null) + { + DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString())); + DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel"); + } } public void AddRegion(Scene scene) @@ -1566,7 +1572,7 @@ namespace OpenSim.Region.CoreModules.World.Land land = landObject; } } - land.DeedToGroup(new UUID(DefaultGodParcelGroup)); + land.DeedToGroup(DefaultGodParcelGroup); land.LandData.Name = DefaultGodParcelName; land.SendLandUpdateToAvatarsOverMe(); } -- cgit v1.1 From 496a8a4f7ca5422daa30913595b6b1a03fa8a59a Mon Sep 17 00:00:00 2001 From: CasperW Date: Wed, 20 Jan 2010 22:14:43 +0100 Subject: Fixed an issue with PayPrice sometimes being shared between multiple objects --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a7c14cf..4c97467 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.Framework.Scenes // TODO: This needs to be persisted in next XML version update! [XmlIgnore] - public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; + public int[] PayPrice = {-2,-2,-2,-2,-2}; [XmlIgnore] public PhysicsActor PhysActor; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 085d61f..a5aecd8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8946,12 +8946,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSLError("List must have at least 4 elements"); return; } - m_host.ParentGroup.RootPart.PayPrice[0]=price; - - m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; - m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; - m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; - m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; + int[] nPrice = new int[5]; + nPrice[0]=price; + nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0]; + nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1]; + nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2]; + nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3]; + m_host.ParentGroup.RootPart.PayPrice = nPrice; m_host.ParentGroup.HasGroupChanged = true; } -- cgit v1.1 From 66692f90e3b70ccdec8c148342578cd54acc4406 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 21 Jan 2010 14:39:11 -0500 Subject: ChODE Object Linear Motion update --- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 187 ++++++++++++---------- OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 2 +- 2 files changed, 102 insertions(+), 87 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index ef2dccc..9e145ec 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -82,13 +82,6 @@ namespace OpenSim.Region.Physics.OdePlugin private IntPtr m_body = IntPtr.Zero; // private IntPtr m_jointGroup = IntPtr.Zero; // private IntPtr m_aMotor = IntPtr.Zero; - - // Correction factors, to match Sl - private static float m_linearVelocityFactor = 0.9f; - private static float m_linearAttackFactor = 0.4f; - private static float m_linearDecayFactor = 0.5f; - private static float m_linearFrictionFactor = 1.2f; - // Vehicle properties private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind @@ -103,15 +96,15 @@ namespace OpenSim.Region.Physics.OdePlugin // LIMIT_ROLL_ONLY // Linear properties - private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time - private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL, for max limiting - private Vector3 m_dir = Vector3.Zero; // velocity applied to body - private Vector3 m_linearFrictionTimescale = Vector3.Zero; - private float m_linearMotorDecayTimescale = 0; - private float m_linearMotorTimescale = 0; - private Vector3 m_lastLinearVelocityVector = Vector3.Zero; - // private bool m_LinearMotorSetLastFrame = false; - // private Vector3 m_linearMotorOffset = Vector3.Zero; + private Vector3 m_linearMotorDirection = Vector3.Zero; // (was m_linearMotorDirectionLASTSET) the (local) Velocity + //requested by LSL + private float m_linearMotorTimescale = 0; // Motor Attack rate set by LSL + private float m_linearMotorDecayTimescale = 0; // Motor Decay rate set by LSL + private Vector3 m_linearFrictionTimescale = Vector3.Zero; // General Friction set by LSL + + private Vector3 m_lLinMotorDVel = Vector3.Zero; // decayed motor + private Vector3 m_lLinObjectVel = Vector3.Zero; // local frame object velocity + private Vector3 m_wLinObjectVel = Vector3.Zero; // world frame object velocity //Angular properties private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor @@ -241,7 +234,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; case Vehicle.LINEAR_MOTOR_DIRECTION: m_linearMotorDirection = new Vector3(pValue, pValue, pValue); - m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); + UpdateLinDecay(); break; case Vehicle.LINEAR_MOTOR_OFFSET: // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); @@ -273,9 +266,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.LINEAR_MOTOR_DIRECTION: - pValue *= m_linearVelocityFactor; - m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, decayed by time - m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, for max limiting + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, for max limiting + UpdateLinDecay(); break; case Vehicle.LINEAR_MOTOR_OFFSET: // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -304,7 +296,7 @@ namespace OpenSim.Region.Physics.OdePlugin case Vehicle.TYPE_SLED: m_linearFrictionTimescale = new Vector3(30, 1, 1000); m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); - m_linearMotorDirection = Vector3.Zero; +// m_lLinMotorVel = Vector3.Zero; m_linearMotorTimescale = 1000; m_linearMotorDecayTimescale = 120; m_angularMotorDirection = Vector3.Zero; @@ -330,7 +322,7 @@ namespace OpenSim.Region.Physics.OdePlugin case Vehicle.TYPE_CAR: m_linearFrictionTimescale = new Vector3(100, 2, 1000); m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); - m_linearMotorDirection = Vector3.Zero; +// m_lLinMotorVel = Vector3.Zero; m_linearMotorTimescale = 1; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; @@ -357,7 +349,7 @@ namespace OpenSim.Region.Physics.OdePlugin case Vehicle.TYPE_BOAT: m_linearFrictionTimescale = new Vector3(10, 3, 2); m_angularFrictionTimescale = new Vector3(10,10,10); - m_linearMotorDirection = Vector3.Zero; +// m_lLinMotorVel = Vector3.Zero; m_linearMotorTimescale = 5; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; @@ -385,7 +377,7 @@ namespace OpenSim.Region.Physics.OdePlugin case Vehicle.TYPE_AIRPLANE: m_linearFrictionTimescale = new Vector3(200, 10, 5); m_angularFrictionTimescale = new Vector3(20, 20, 20); - m_linearMotorDirection = Vector3.Zero; +// m_lLinMotorVel = Vector3.Zero; m_linearMotorTimescale = 2; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; @@ -412,7 +404,6 @@ namespace OpenSim.Region.Physics.OdePlugin case Vehicle.TYPE_BALLOON: m_linearFrictionTimescale = new Vector3(5, 5, 5); m_angularFrictionTimescale = new Vector3(10, 10, 10); - m_linearMotorDirection = Vector3.Zero; m_linearMotorTimescale = 5; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; @@ -453,7 +444,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) return; frcount++; // used to limit debug comment output - if (frcount > 100) + if (frcount > 24) frcount = 0; MoveLinear(pTimestep, pParentScene); @@ -463,63 +454,90 @@ namespace OpenSim.Region.Physics.OdePlugin internal void Halt() { // Kill all motions, when non-physical m_linearMotorDirection = Vector3.Zero; - m_linearMotorDirectionLASTSET = Vector3.Zero; - m_dir = Vector3.Zero; - m_lastLinearVelocityVector = Vector3.Zero; + m_lLinMotorDVel = Vector3.Zero; + m_lLinObjectVel = Vector3.Zero; + m_wLinObjectVel = Vector3.Zero; m_angularMotorDirection = Vector3.Zero; m_angularMotorVelocity = Vector3.Zero; m_lastAngularVelocity = Vector3.Zero; } + + private void UpdateLinDecay() + { + if (Math.Abs(m_linearMotorDirection.X) > Math.Abs(m_lLinMotorDVel.X)) m_lLinMotorDVel.X = m_linearMotorDirection.X; + if (Math.Abs(m_linearMotorDirection.Y) > Math.Abs(m_lLinMotorDVel.Y)) m_lLinMotorDVel.Y = m_linearMotorDirection.Y; + if (Math.Abs(m_linearMotorDirection.Z) > Math.Abs(m_lLinMotorDVel.Z)) m_lLinMotorDVel.Z = m_linearMotorDirection.Z; + } // else let the motor decay on its own private void MoveLinear(float pTimestep, OdeScene _pParentScene) { - if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant - { - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + Vector3 acceleration = new Vector3(0f, 0f, 0f); - // add drive to body - float linfactor = m_linearMotorTimescale/pTimestep; - // Linear accel - Vector3 addAmount1 = (m_linearMotorDirection/linfactor) * 0.8f; - // Differential accel - Vector3 addAmount2 = ((m_linearMotorDirection - m_lastLinearVelocityVector)/linfactor) * 1.6f; - // SL correction - Vector3 addAmount = (addAmount1 + addAmount2) * m_linearAttackFactor; - m_lastLinearVelocityVector += addAmount; // lastLinearVelocityVector is the current body velocity vector -//if(frcount == 0) Console.WriteLine("AL {0} + AD {1} AS{2} V {3}", addAmount1, addAmount2, addAmount, m_lastLinearVelocityVector); - // This will work temporarily, but we really need to compare speed on an axis - // KF: Limit body velocity to applied velocity? - if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) - m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; - if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) - m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; - if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) - m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; - - // decay applied velocity - Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); - //Console.WriteLine("decay: " + decayfraction); - m_linearMotorDirection -= m_linearMotorDirection * decayfraction * m_linearDecayFactor; - //Console.WriteLine("actual: " + m_linearMotorDirection); - } - else - { // requested is not significant - // if what remains of applied is small, zero it. - if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) - m_lastLinearVelocityVector = Vector3.Zero; - } - - - // convert requested object velocity to world-referenced vector - m_dir = m_lastLinearVelocityVector; d.Quaternion rot = d.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object - m_dir *= rotq; // apply obj rotation to velocity vector + Quaternion irotq = Quaternion.Inverse(rotq); + d.Vector3 velnow = d.BodyGetLinearVel(Body); // this is in world frame + Vector3 vel_now = new Vector3(velnow.X, velnow.Y, velnow.Z); + acceleration = vel_now - m_wLinObjectVel; + m_lLinObjectVel = vel_now * irotq; + + if (m_linearMotorDecayTimescale < 300.0f) //setting of 300 or more disables decay rate + { + if ( Vector3.Mag(m_lLinMotorDVel) < 1.0f) + { + float decayfactor = m_linearMotorDecayTimescale/pTimestep; + Vector3 decayAmount = (m_lLinMotorDVel/decayfactor); + m_lLinMotorDVel -= decayAmount; + } + else + { + float decayfactor = 3.0f - (0.57f * (float)Math.Log((double)(m_linearMotorDecayTimescale))); + Vector3 decel = Vector3.Normalize(m_lLinMotorDVel) * decayfactor * pTimestep; + m_lLinMotorDVel -= decel; + } + if (m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_lLinMotorDVel = Vector3.Zero; + } + else + { + if (Math.Abs(m_lLinMotorDVel.X) < Math.Abs(m_lLinObjectVel.X)) m_lLinObjectVel.X = m_lLinMotorDVel.X; + if (Math.Abs(m_lLinMotorDVel.Y) < Math.Abs(m_lLinObjectVel.Y)) m_lLinObjectVel.Y = m_lLinMotorDVel.Y; + if (Math.Abs(m_lLinMotorDVel.Z) < Math.Abs(m_lLinObjectVel.Z)) m_lLinObjectVel.Z = m_lLinMotorDVel.Z; + } + } - // add Gravity and Buoyancy - // KF: So far I have found no good method to combine a script-requested - // .Z velocity and gravity. Therefore only 0g will used script-requested - // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. + if ( (! m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! m_lLinObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + if (m_linearMotorTimescale < 300.0f) + { + Vector3 attack_error = m_lLinMotorDVel - m_lLinObjectVel; + float linfactor = m_linearMotorTimescale/pTimestep; + Vector3 attackAmount = (attack_error/linfactor) * 1.3f; + m_lLinObjectVel += attackAmount; + } + if (m_linearFrictionTimescale.X < 300.0f) + { + float fricfactor = m_linearFrictionTimescale.X / pTimestep; + float fricX = m_lLinObjectVel.X / fricfactor; + m_lLinObjectVel.X -= fricX; + } + if (m_linearFrictionTimescale.Y < 300.0f) + { + float fricfactor = m_linearFrictionTimescale.Y / pTimestep; + float fricY = m_lLinObjectVel.Y / fricfactor; + m_lLinObjectVel.Y -= fricY; + } + if (m_linearFrictionTimescale.Z < 300.0f) + { + float fricfactor = m_linearFrictionTimescale.Z / pTimestep; + float fricZ = m_lLinObjectVel.Z / fricfactor; + m_lLinObjectVel.Z -= fricZ; + } + } + m_wLinObjectVel = m_lLinObjectVel * rotq; + // Add Gravity and Buoyancy Vector3 grav = Vector3.Zero; if(m_VehicleBuoyancy < 1.0f) { @@ -528,10 +546,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.Mass objMass; d.BodyGetMass(Body, out objMass); // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); - // Preserve the current Z velocity - d.Vector3 vel_now = d.BodyGetLinearVel(Body); - m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity + grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); // Applied later as a force } // else its 1.0, no gravity. // Check if hovering @@ -567,24 +582,24 @@ namespace OpenSim.Region.Physics.OdePlugin { d.Mass objMass; d.BodyGetMass(Body, out objMass); - m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); + m_wLinObjectVel.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); //KF: m_VhoverEfficiency is not yet implemented } else { - m_dir.Z = 0f; + m_wLinObjectVel.Z = 0f; } } - + else + { // not hovering, Gravity rules + m_wLinObjectVel.Z = vel_now.Z; +//if(frcount == 0) Console.WriteLine(" Z {0} a.Z {1}", m_wLinObjectVel.Z, acceleration.Z); + } // Apply velocity - d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); + d.BodySetLinearVel(Body, m_wLinObjectVel.X, m_wLinObjectVel.Y, m_wLinObjectVel.Z); // apply gravity force d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); - - - // apply friction - Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); - m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount * m_linearFrictionFactor; +//if(frcount == 0) Console.WriteLine("Grav {0}", grav); } // end MoveLinear() private void MoveAngular(float pTimestep) @@ -633,7 +648,7 @@ namespace OpenSim.Region.Physics.OdePlugin if(m_verticalAttractionTimescale < 300) { - float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep); + float VAservo = 0.0167f / (m_verticalAttractionTimescale * pTimestep); // get present body rotation d.Quaternion rot = d.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index 60786d4..deb6164 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -229,7 +229,7 @@ namespace OpenSim.Region.Physics.OdePlugin public int bodyFramesAutoDisable = 20; - protected DateTime m_lastframe = DateTime.UtcNow; + private DateTime m_lastframe = DateTime.UtcNow; private float[] _watermap; private bool m_filterCollisions = true; -- cgit v1.1 From 1abb70cc73c997c08a416fecf689b83453f853d0 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 21 Jan 2010 19:31:02 -0500 Subject: Add glue for llSetVehicleFlags(), llRemoveVehicleFlags(). ChODE: Add associated methods. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 18 +++++++++++++++++- .../Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs | 10 ++++++++++ .../BulletDotNETPlugin/BulletDotNETCharacter.cs | 10 ++++++++++ .../Physics/BulletDotNETPlugin/BulletDotNETPrim.cs | 10 ++++++++++ .../Region/Physics/BulletXPlugin/BulletXPlugin.cs | 10 ++++++++++ OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 10 ++++++++++ OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 10 ++++++++++ OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 12 +++++++++++- OpenSim/Region/Physics/Manager/PhysicsActor.cs | 12 ++++++++++++ OpenSim/Region/Physics/OdePlugin/ODECharacter.cs | 10 ++++++++++ OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 10 ++++++++++ OpenSim/Region/Physics/POSPlugin/POSCharacter.cs | 10 ++++++++++ OpenSim/Region/Physics/POSPlugin/POSPrim.cs | 10 ++++++++++ OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs | 20 ++++++++++++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 16 ++++++++++++++-- 15 files changed, 174 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4c97467..04be9fc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2963,7 +2963,23 @@ namespace OpenSim.Region.Framework.Scenes PhysActor.VehicleRotationParam(param, rotation); } } - + + public void SetVehicleFlags(int flags) + { + if (PhysActor != null) + { + PhysActor.VehicleFlagsSet(flags); + } + } + + public void RemoveVehicleFlags(int flags) + { + if (PhysActor != null) + { + PhysActor.VehicleFlagsRemove(flags); + } + } + public void SetGroup(UUID groupID, IClientAPI client) { _groupID = groupID; diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs index 31366db..25b9099 100644 --- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs +++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsActor.cs @@ -184,7 +184,17 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs index a3344dd..120d040 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETCharacter.cs @@ -361,7 +361,17 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs index 9603ea4..f430def 100644 --- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs +++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETPrim.cs @@ -396,7 +396,17 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin { //TODO: } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { //TODO: GhostObject diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs index d5d146e..9113ebe 100644 --- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs +++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs @@ -984,7 +984,17 @@ namespace OpenSim.Region.Physics.BulletXPlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index aa0acb7..2eb519f 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -733,7 +733,17 @@ namespace OpenSim.Region.Physics.OdePlugin { } + + public override void VehicleFlagsSet(int flags) + { + } + + public override void VehicleFlagsRemove(int flags) + { + + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index 9e145ec..14d5caa 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -286,7 +286,17 @@ namespace OpenSim.Region.Physics.OdePlugin } }//end ProcessRotationVehicleParam + + internal void ProcessFlagsVehicleSet(int flags) + { + m_flags |= (VehicleFlag)flags; + } + internal void ProcessFlagsVehicleRemove(int flags) + { + m_flags &= ~((VehicleFlag)flags); + } + internal void ProcessTypeChange(Vehicle pType) { // Set Defaults For Type diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 6e6b44f..29a3dd9 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -2415,7 +2415,17 @@ Console.WriteLine(" JointCreateFixed"); { m_vehicle.ProcessRotationVehicleParam((Vehicle) param, rotation); } - + + public override void VehicleFlagsSet(int flags) + { + m_vehicle.ProcessFlagsVehicleSet(flags); + } + + public override void VehicleFlagsRemove(int flags) + { + m_vehicle.ProcessFlagsVehicleRemove(flags); + } + public override void SetVolumeDetect(int param) { lock (_parent_scene.OdeLock) diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs index 9c192ed..f43de48 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs @@ -208,6 +208,8 @@ namespace OpenSim.Region.Physics.Manager public abstract void VehicleFloatParam(int param, float value); public abstract void VehicleVectorParam(int param, Vector3 value); public abstract void VehicleRotationParam(int param, Quaternion rotation); + public abstract void VehicleFlagsSet(int flags); + public abstract void VehicleFlagsRemove(int flags); public abstract void SetVolumeDetect(int param); // Allows the detection of collisions with inherently non-physical prims. see llVolumeDetect for more @@ -351,7 +353,17 @@ namespace OpenSim.Region.Physics.Manager { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs index a38fccc..b713142 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs @@ -733,7 +733,17 @@ namespace OpenSim.Region.Physics.OdePlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index 567fd0e..010d97f 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -2352,6 +2352,16 @@ Console.WriteLine(" JointCreateFixed"); { m_vehicle.ProcessRotationVehicleParam((Vehicle) param, rotation); } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + + } public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs index 566b4e7..491e200 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSCharacter.cs @@ -181,7 +181,17 @@ namespace OpenSim.Region.Physics.POSPlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs index edccf47..f8d49f9 100644 --- a/OpenSim/Region/Physics/POSPlugin/POSPrim.cs +++ b/OpenSim/Region/Physics/POSPlugin/POSPrim.cs @@ -138,7 +138,17 @@ namespace OpenSim.Region.Physics.POSPlugin { } + + public override void VehicleFlagsSet(int flags) + { + } + + public override void VehicleFlagsRemove(int flags) + { + + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs index 24eb6b1..e54065c 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs @@ -370,7 +370,17 @@ namespace OpenSim.Region.Physics.PhysXPlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { @@ -774,7 +784,17 @@ namespace OpenSim.Region.Physics.PhysXPlugin { } + + public override void VehicleFlagsSet(int flags) + { + + } + + public override void VehicleFlagsRemove(int flags) + { + } + public override void SetVolumeDetect(int param) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a5aecd8..33218aa 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6315,13 +6315,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetVehicleFlags(int flags) { m_host.AddScriptLPS(1); - NotImplemented("llSetVehicleFlags"); + if (m_host.ParentGroup != null) + { + if (!m_host.ParentGroup.IsDeleted) + { + m_host.ParentGroup.RootPart.SetVehicleFlags(flags); + } + } } public void llRemoveVehicleFlags(int flags) { m_host.AddScriptLPS(1); - NotImplemented("llRemoveVehicleFlags"); + if (m_host.ParentGroup != null) + { + if (!m_host.ParentGroup.IsDeleted) + { + m_host.ParentGroup.RootPart.RemoveVehicleFlags(flags); + } + } } public void llSitTarget(LSL_Vector offset, LSL_Rotation rot) -- cgit v1.1 From e9c9a74e0ade505ee8d8d8e7790141f758a65f61 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 26 Jan 2010 15:12:41 +0000 Subject: Some merge fixups --- .../Avatar/InstantMessage/OfflineMessageModule.cs | 9 +++++---- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 4 ++-- .../Framework/Scenes/SceneObjectPartInventory.cs | 2 +- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 18 +++--------------- 4 files changed, 11 insertions(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 3e86848..8f289c0 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -180,11 +180,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private void RetrieveInstantMessages(IClientAPI client) { - if (m_RestURL != "") - { - m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); + if (m_RestURL == String.Empty) + return; + + m_log.DebugFormat("[OFFLINE MESSAGING] Retrieving stored messages for {0}", client.AgentId); - List msglist = SynchronousRestObjectPoster.BeginPostObject>( + List msglist = SynchronousRestObjectPoster.BeginPostObject>( "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); if (msglist != null) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index aea005e..8b58b3e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -74,7 +74,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Stop the scripts contained in all the prims in this group /// - public void RemoveScriptInstances() + public void RemoveScriptInstances(bool sceneObjectBeingDeleted) { lockPartsForRead(true); List values = new List(m_parts.Values); @@ -82,7 +82,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in values) { - part.Inventory.RemoveScriptInstances(); + part.Inventory.RemoveScriptInstances(sceneObjectBeingDeleted); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 1de0092..9661775 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -249,7 +249,7 @@ namespace OpenSim.Region.Framework.Scenes { if ((int)InventoryType.LSL == item.InvType) { - RemoveScriptInstance(item.ItemID); + RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); m_part.RemoveScriptEvents(item.ItemID); } } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 73850e1..35d57d8 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -885,12 +885,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance.ClearQueue(); instance.Stop(0); - SceneObjectPart part = - m_Scene.GetSceneObjectPart(localID); - - if (part != null) - part.RemoveScriptEvents(itemID); - // bool objectRemoved = false; lock (m_PrimObjects) @@ -923,18 +917,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine instance = null; -<<<<<<< HEAD:OpenSim/Region/ScriptEngine/XEngine/XEngine.cs ObjectRemoved handlerObjectRemoved = OnObjectRemoved; if (handlerObjectRemoved != null) + { + SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); handlerObjectRemoved(part.UUID); -======= - ObjectRemoved handlerObjectRemoved = OnObjectRemoved; - if (handlerObjectRemoved != null) - { - SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); - handlerObjectRemoved(part.UUID); - } ->>>>>>> master:OpenSim/Region/ScriptEngine/XEngine/XEngine.cs + } CleanAssemblies(); -- cgit v1.1 From 862caa72a80b597ccbf1ae82300af89f9103dbf9 Mon Sep 17 00:00:00 2001 From: Revolution Date: Wed, 27 Jan 2010 21:08:55 -0600 Subject: Fixes terrain editing. Changes ThrottleOutPacketType to task instead of land. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 33210d7..64e45d0 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -1098,7 +1098,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP LayerDataPacket layerpack = TerrainCompressor.CreateLandPacket(heightmap, patches); layerpack.Header.Reliable = true; - OutPacket(layerpack, ThrottleOutPacketType.Land); + OutPacket(layerpack, ThrottleOutPacketType.Task); } catch (Exception e) { -- cgit v1.1 From cfca9e1e811f6cdea6b7c3338f7f783a07f8e0ac Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Jan 2010 07:20:13 +0000 Subject: Revert "Updates all IRegionModules to the new style region modules." This reverts commit ec3c31e61e5e540f822891110df9bc978655bbaf. --- .../LoadRegions/LoadRegionsPlugin.cs | 4 +- OpenSim/Client/MXP/MXPModule.cs | 36 ++-- .../AssetTransaction/AssetTransactionModule.cs | 35 +--- .../Agent/Capabilities/CapabilitiesModule.cs | 2 +- .../Region/CoreModules/Agent/IPBan/IPBanModule.cs | 40 ++-- .../Agent/TextureDownload/TextureDownloadModule.cs | 33 +--- .../Agent/TextureSender/J2KDecoderModule.cs | 33 +--- .../Region/CoreModules/Agent/Xfer/XferModule.cs | 30 +-- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 29 +-- .../CoreModules/Avatar/Combat/CombatModule.cs | 32 +--- .../CoreModules/Avatar/Dialog/DialogModule.cs | 32 +--- .../CoreModules/Avatar/Friends/FriendsModule.cs | 54 ++---- .../CoreModules/Avatar/Gestures/GesturesModule.cs | 30 +-- .../Region/CoreModules/Avatar/Gods/GodsModule.cs | 28 +-- .../CoreModules/Avatar/Groups/GroupsModule.cs | 35 +--- .../Avatar/InstantMessage/InstantMessageModule.cs | 53 ++---- .../Avatar/InstantMessage/MessageTransferModule.cs | 54 ++---- .../Avatar/InstantMessage/MuteListModule.cs | 48 ++--- .../Avatar/InstantMessage/OfflineMessageModule.cs | 41 ++-- .../Avatar/InstantMessage/PresenceModule.cs | 61 ++---- .../Inventory/Archiver/InventoryArchiverModule.cs | 35 +--- .../Inventory/Transfer/InventoryTransferModule.cs | 63 ++---- .../Region/CoreModules/Avatar/Lure/LureModule.cs | 61 ++---- .../CoreModules/Avatar/ObjectCaps/ObjectAdd.cs | 55 ++---- .../Avatar/Profiles/AvatarProfilesModule.cs | 32 ++-- .../Framework/EventQueue/EventQueueGetModule.cs | 40 ++-- .../Framework/Monitoring/MonitorModule.cs | 103 ++++------ .../Hypergrid/HGStandaloneLoginModule.cs | 83 +++----- OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs | 31 ++- .../InterGrid/OpenGridProtocolModule.cs | 100 ++++------ .../DynamicTexture/DynamicTextureModule.cs | 60 ++---- .../Scripting/EMailModules/EmailModule.cs | 32 +--- .../Scripting/HttpRequest/ScriptsHttpRequests.cs | 36 ++-- .../CoreModules/Scripting/LSLHttp/UrlModule.cs | 2 - .../Scripting/LoadImageURL/LoadImageURLModule.cs | 37 ++-- .../Scripting/VectorRender/VectorRenderModule.cs | 41 ++-- .../Scripting/WorldComm/WorldCommModule.cs | 33 ++-- .../CoreModules/Scripting/XMLRPC/XMLRPCModule.cs | 51 +---- .../Asset/AssetServiceInConnectorModule.cs | 2 +- .../Grid/HypergridServiceInConnectorModule.cs | 2 +- .../Inventory/InventoryServiceInConnectorModule.cs | 2 +- .../Land/LandServiceInConnectorModule.cs | 2 +- .../Neighbour/NeighbourServiceInConnectorModule.cs | 2 +- .../SimulationServiceInConnectorModule.cs | 2 +- .../Interregion/LocalInterregionComms.cs | 4 +- .../Interregion/RESTInterregionComms.cs | 16 +- .../CoreModules/World/Archiver/ArchiverModule.cs | 1 - .../Region/CoreModules/World/Cloud/CloudModule.cs | 30 +-- .../World/Estate/EstateManagementModule.cs | 58 +++--- .../World/Permissions/PermissionsModule.cs | 212 ++++++++------------- .../Region/CoreModules/World/Sound/SoundModule.cs | 33 +--- OpenSim/Region/CoreModules/World/Sun/SunModule.cs | 96 +++++----- .../World/Vegetation/VegetationModule.cs | 27 +-- .../Region/CoreModules/World/Wind/WindModule.cs | 45 ++--- .../CoreModules/World/WorldMap/MapImageModule.cs | 30 +-- .../CoreModules/World/WorldMap/MapSearchModule.cs | 35 +--- OpenSim/Region/DataSnapshot/DataSnapshotManager.cs | 55 +++--- .../Region/Framework/Interfaces/ICloudModule.cs | 2 +- .../Region/Framework/Interfaces/IEmailModule.cs | 2 +- .../Region/Framework/Interfaces/IEstateModule.cs | 2 +- OpenSim/Region/Framework/Interfaces/ISunModule.cs | 2 +- OpenSim/Region/Framework/Interfaces/IWindModule.cs | 2 +- .../InternetRelayClientView/IRCStackModule.cs | 32 +--- .../Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 72 ++----- .../ContentManagementModule.cs | 47 ++--- .../Scripting/Minimodule/MRMModule.cs | 64 +++---- .../RegionReadyModule/RegionReadyModule.cs | 6 +- .../ScriptModuleComms/ScriptModuleCommsModule.cs | 1 - .../XmlRpcRouterModule/XmlRpcGridRouterModule.cs | 28 +-- .../XmlRpcRouterModule/XmlRpcRouterModule.cs | 30 +-- .../FreeswitchServiceInConnectorModule.cs | 2 +- .../SvnSerialiser/SvnBackupModule.cs | 28 +-- .../Region/OptionalModules/World/NPC/NPCModule.cs | 28 +-- .../World/TreePopulator/TreePopulatorModule.cs | 41 ++-- OpenSim/Region/UserStatistics/WebStatsModule.cs | 33 ++-- OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs | 9 +- 76 files changed, 879 insertions(+), 1811 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs index 64863c5..6fd3d30 100644 --- a/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs +++ b/OpenSim/ApplicationPlugins/LoadRegions/LoadRegionsPlugin.cs @@ -99,7 +99,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions regionLoader.SetIniConfigSource(m_openSim.ConfigSource.Source); RegionInfo[] regionsToLoad = regionLoader.LoadRegions(); - /*m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); + m_log.Info("[LOADREGIONSPLUGIN]: Loading specific shared modules..."); m_log.Info("[LOADREGIONSPLUGIN]: DynamicTextureModule..."); m_openSim.ModuleLoader.LoadDefaultSharedModule(new DynamicTextureModule()); m_log.Info("[LOADREGIONSPLUGIN]: InstantMessageModule..."); @@ -111,7 +111,7 @@ namespace OpenSim.ApplicationPlugins.LoadRegions m_log.Info("[LOADREGIONSPLUGIN]: AssetTransactionModule..."); m_openSim.ModuleLoader.LoadDefaultSharedModule(new AssetTransactionModule()); m_log.Info("[LOADREGIONSPLUGIN]: Done."); - */ + if (!CheckRegionsForSanity(regionsToLoad)) { m_log.Error("[LOADREGIONS]: Halting startup due to conflicts in region configurations"); diff --git a/OpenSim/Client/MXP/MXPModule.cs b/OpenSim/Client/MXP/MXPModule.cs index 47417ab..0b442cc 100644 --- a/OpenSim/Client/MXP/MXPModule.cs +++ b/OpenSim/Client/MXP/MXPModule.cs @@ -31,7 +31,6 @@ using System.Reflection; using System.Text; using System.Timers; using log4net; -using Mono.Addins; using MXP; using Nini.Config; using OpenMetaverse; @@ -45,8 +44,7 @@ namespace OpenSim.Client.MXP /** * MXP Client Module which adds MXP support to client / region communication. */ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MXPModule : ISharedRegionModule + public class MXPModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -59,23 +57,15 @@ namespace OpenSim.Client.MXP private readonly Dictionary m_scenes = new Dictionary(); private bool m_shutdown; - public void Initialise(IConfigSource source) - { - m_config = source; - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) m_scenes.Add(scene.RegionInfo.RegionID, scene); + + m_config = source; } - public void RegionLoaded(Scene scene) + public void PostInitialise() { if (m_config.Configs["MXP"] != null) { @@ -86,7 +76,7 @@ namespace OpenSim.Client.MXP m_port = con.GetInt("Port", m_port); - m_server = new MXPPacketServer(m_port, m_scenes, m_config.Configs["StandAlone"].GetBoolean("accounts_authenticate", true)); + m_server = new MXPPacketServer(m_port, m_scenes,m_config.Configs["StandAlone"].GetBoolean("accounts_authenticate",true)); m_ticker = new Timer(100); m_ticker.AutoReset = false; @@ -99,14 +89,6 @@ namespace OpenSim.Client.MXP } } - public void RemoveRegion(Scene scene) - { - } - - public void PostInitialise() - { - } - void ticker_Elapsed(object sender, ElapsedEventArgs e) { try @@ -139,5 +121,11 @@ namespace OpenSim.Client.MXP { get { return "MXP ClientStack Module"; } } + + public bool IsSharedModule + { + get { return true; } + } + } } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 7012037..1077f4a 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,8 +35,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class AssetTransactionModule : ISharedRegionModule, IAgentAssetTransactions + public class AssetTransactionModule : IRegionModule, IAgentAssetTransactions { private readonly Dictionary RegisteredScenes = new Dictionary(); private bool m_dumpAssetsToFile = false; @@ -61,14 +59,9 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction //m_log.Debug("creating AgentAssetTransactionModule"); } - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { @@ -86,23 +79,6 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction m_scene = scene; } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) - RegisteredScenes.Remove(scene.RegionInfo.RegionID); - scene.UnregisterModuleInterface(this); - scene.EventManager.OnNewClient -= NewClient; - } - public void PostInitialise() { } @@ -116,6 +92,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction get { return "AgentTransactionModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion public void NewClient(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs b/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs index 886173f..2a1355b 100644 --- a/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Capabilities/CapabilitiesModule.cs @@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Agent.Capabilities public void RemoveRegion(Scene scene) { - scene.UnregisterModuleInterface(this); + m_scene.UnregisterModuleInterface(this); } public void PostInitialise() {} diff --git a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs index f7f2eff..bfe2a71 100644 --- a/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs +++ b/OpenSim/Region/CoreModules/Agent/IPBan/IPBanModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.IO; using System.Text; -using Mono.Addins; using Nini.Config; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; @@ -37,27 +36,21 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Agent.IPBan { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class IPBanModule : ISharedRegionModule + public class IPBanModule : IRegionModule { - #region Implementation of ISharedRegionModule + #region Implementation of IRegionModule private List m_bans = new List(); - private Dictionary SceneBanners = new Dictionary(); - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { - } - - public void AddRegion(Scene scene) - { - SceneBanners.Add(scene, new SceneBanner(scene, m_bans)); + new SceneBanner(scene, m_bans); lock (m_bans) { foreach (EstateBan ban in scene.RegionInfo.EstateSettings.EstateBans) { - if (!String.IsNullOrEmpty(ban.BannedHostIPMask)) + if (!String.IsNullOrEmpty(ban.BannedHostIPMask)) m_bans.Add(ban.BannedHostIPMask); if (!String.IsNullOrEmpty(ban.BannedHostNameMask)) m_bans.Add(ban.BannedHostNameMask); @@ -65,12 +58,7 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan } } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) + public void PostInitialise() { if (File.Exists("bans.txt")) { @@ -82,18 +70,9 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan } } - public void RemoveRegion(Scene scene) - { - if(SceneBanners.ContainsKey(scene)) - SceneBanners.Remove(scene); - } - - public void PostInitialise() - { - } - public void Close() { + } public string Name @@ -101,6 +80,11 @@ namespace OpenSim.Region.CoreModules.Agent.IPBan get { return "IPBanModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion /// diff --git a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs index c4d84cb..71ff28c 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureDownload/TextureDownloadModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Reflection; using System.Threading; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -42,8 +41,7 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Agent.TextureDownload { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class TextureDownloadModule : INonSharedRegionModule + public class TextureDownloadModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -67,14 +65,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureDownload { } - #region INonSharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { + if (m_scene == null) { //m_log.Debug("Creating Texture download module"); @@ -95,23 +90,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureDownload } } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) + public void PostInitialise() { } - public void RemoveRegion(Scene scene) - { - if(m_scenes.Contains(scene)) - m_scenes.Remove(scene); - scene.EventManager.OnNewClient -= NewClient; - scene.EventManager.OnRemovePresence -= EventManager_OnRemovePresence; - } - public void Close() { } @@ -121,6 +103,11 @@ namespace OpenSim.Region.CoreModules.Agent.TextureDownload get { return "TextureDownloadModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion /// diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index ff87493..7ac8bed 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs @@ -32,7 +32,6 @@ using System.Reflection; using System.Text; using System.Threading; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -46,8 +45,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender { public delegate void J2KDecodeDelegate(UUID assetID); - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class J2KDecoderModule : ISharedRegionModule, IJ2KDecoder + public class J2KDecoderModule : IRegionModule, IJ2KDecoder { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -60,19 +58,16 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender /// Reference to a scene (doesn't matter which one as long as it can load the cache module) private Scene m_scene; - #region ISharedRegionModule + #region IRegionModule public string Name { get { return "J2KDecoderModule"; } } - - public J2KDecoderModule() - { - } + public bool IsSharedModule { get { return true; } } - public void Initialise(IConfigSource source) + public J2KDecoderModule() { } - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { if (m_scene == null) m_scene = scene; @@ -80,30 +75,16 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender scene.RegisterModuleInterface(this); } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - m_cache = m_scene.RequestModuleInterface(); - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } - public void PostInitialise() { + m_cache = m_scene.RequestModuleInterface(); } public void Close() { } - #endregion + #endregion IRegionModule #region IJ2KDecoder diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index d062361..ef7dce8 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,8 +35,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Agent.Xfer { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class XferModule : INonSharedRegionModule, IXfer + public class XferModule : IRegionModule, IXfer { private Scene m_scene; private Dictionary Requests = new Dictionary(); @@ -54,13 +52,9 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer public DateTime timeStamp; } - #region INonSharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { m_scene = scene; m_scene.EventManager.OnNewClient += NewClient; @@ -68,21 +62,10 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer m_scene.RegisterModuleInterface(this); } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) + public void PostInitialise() { } - public void RemoveRegion(Scene scene) - { - scene.EventManager.OnNewClient -= NewClient; - scene.UnregisterModuleInterface(this); - } - public void Close() { } @@ -92,6 +75,11 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer get { return "XferModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion #region IXfer Members diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 6bbbd56..35c59aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -28,7 +28,6 @@ using System; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,8 +38,7 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class AvatarFactoryModule : IAvatarFactory, ISharedRegionModule + public class AvatarFactoryModule : IAvatarFactory, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene = null; @@ -77,16 +75,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return appearance; } - public void Initialise(IConfigSource source) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += NewClient; @@ -95,18 +84,9 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory { m_scene = scene; } - } - public void RegionLoaded(Scene scene) - { } - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - scene.EventManager.OnNewClient -= NewClient; - } - public void PostInitialise() { } @@ -120,6 +100,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory get { return "Default Avatar Factory"; } } + public bool IsSharedModule + { + get { return false; } + } + public void NewClient(IClientAPI client) { client.OnAvatarNowWearing += AvatarIsWearing; diff --git a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs index b7d12aa..61b6d65 100644 --- a/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Combat/CombatModule.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; -using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -35,8 +34,7 @@ using OpenMetaverse; namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class CombatModule : ISharedRegionModule + public class CombatModule : IRegionModule { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -55,17 +53,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule /// /// /// - public void Initialise(IConfigSource config) - { - - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { lock (m_scenel) { @@ -83,17 +71,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.EventManager.OnAvatarKilled -= KillAvatar; - scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; - m_scenel.Remove(scene.RegionInfo.RegionHandle); - } - public void PostInitialise() { } @@ -107,6 +84,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Combat.CombatModule get { return "CombatModule"; } } + public bool IsSharedModule + { + get { return true; } + } + private void KillAvatar(uint killerObjectLocalID, ScenePresence DeadAvatar) { if (killerObjectLocalID == 0) diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index ecffc7a..72ec869 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -25,11 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,46 +37,28 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Dialog { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class DialogModule : ISharedRegionModule, IDialogModule + public class DialogModule : IRegionModule, IDialogModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; - public void Initialise(IConfigSource source) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; m_scene.RegisterModuleInterface(this); - + m_scene.AddCommand( this, "alert", "alert ", "Send an alert to a user", HandleAlertConsoleCommand); m_scene.AddCommand( this, "alert general", "alert general ", "Send an alert to everyone", HandleAlertConsoleCommand); } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } - - public void PostInitialise() { } + + public void PostInitialise() {} public void Close() {} public string Name { get { return "Dialog Module"; } } + public bool IsSharedModule { get { return false; } } public void SendAlertToUser(IClientAPI client, string message) { diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 7254180..086d4fe 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -31,7 +31,6 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -82,8 +81,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends - Terminate Friendship messages (single) */ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class FriendsModule : ISharedRegionModule, IFriendsModule + public class FriendsModule : IRegionModule, IFriendsModule { private class Transaction { @@ -113,23 +111,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private IGridService m_gridServices = null; - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - - } - - public void PostInitialise() - { - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { lock (m_scenes) { @@ -144,9 +128,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (!m_scenes.ContainsKey(scene.RegionInfo.RegionHandle)) m_scenes[scene.RegionInfo.RegionHandle] = scene; } - + scene.RegisterModuleInterface(this); - + scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; @@ -154,34 +138,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends scene.EventManager.OnClientClosed += ClientClosed; } - public void RegionLoaded(Scene scene) + public void PostInitialise() { if (m_scenes.Count > 0) { - m_TransferModule = scene.RequestModuleInterface(); - m_gridServices = scene.GridService; + m_TransferModule = m_initialScene.RequestModuleInterface(); + m_gridServices = m_initialScene.GridService; } if (m_TransferModule == null) m_log.Error("[FRIENDS]: Unable to find a message transfer module, friendship offers will not work"); } - public void RemoveRegion(Scene scene) - { - MainServer.Instance.RemoveXmlRPCHandler("presence_update_bulk"); - MainServer.Instance.RemoveXmlRPCHandler("terminate_friend"); - - if (m_scenes.ContainsKey(scene.RegionInfo.RegionHandle)) - m_scenes.Remove(scene.RegionInfo.RegionHandle); - - scene.UnregisterModuleInterface(this); - - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; - scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; - scene.EventManager.OnMakeChildAgent -= MakeChildAgent; - scene.EventManager.OnClientClosed -= ClientClosed; - } - public void Close() { } @@ -191,6 +158,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends get { return "FriendsModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion #region IInterregionFriendsComms diff --git a/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs b/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs index c306f94..8ce5092 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gestures/GesturesModule.cs @@ -25,10 +25,8 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,41 +37,23 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Gestures { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GesturesModule : INonSharedRegionModule + public class GesturesModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; - public void Initialise(IConfigSource source) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; + m_scene.EventManager.OnNewClient += OnNewClient; } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if(m_scene == scene) - m_scene = null; - scene.EventManager.OnNewClient -= OnNewClient; - } + public void PostInitialise() {} public void Close() {} public string Name { get { return "Gestures Module"; } } + public bool IsSharedModule { get { return false; } } private void OnNewClient(IClientAPI client) { diff --git a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs index 3914f2e..50171a3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Gods/GodsModule.cs @@ -25,9 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Collections.Generic; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,8 +34,7 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Gods { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GodsModule : INonSharedRegionModule, IGodsModule + public class GodsModule : IRegionModule, IGodsModule { /// Special UUID for actions that apply to all agents private static readonly UUID ALL_AGENTS = new UUID("44e87126-e794-4ded-05b3-7c42da3d5cdb"); @@ -45,34 +42,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Gods protected Scene m_scene; protected IDialogModule m_dialogModule; - public void Initialise(IConfigSource source) - { - - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; m_dialogModule = m_scene.RequestModuleInterface(); m_scene.RegisterModuleInterface(this); } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } + public void PostInitialise() {} public void Close() {} public string Name { get { return "Gods Module"; } } + public bool IsSharedModule { get { return false; } } public void RequestGodlikePowers( UUID agentID, UUID sessionID, UUID token, bool godLike, IClientAPI controllingClient) diff --git a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs index 7ff8d30..31363e5 100644 --- a/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Groups/GroupsModule.cs @@ -25,11 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,8 +36,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Groups { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsModule : ISharedRegionModule + public class GroupsModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -58,9 +55,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups private static GroupMembershipData osGroup = new GroupMembershipData(); - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { IConfig groupsConfig = config.Configs["Groups"]; @@ -79,15 +76,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups if (groupsConfig.GetString("Module", "Default") != "Default") return; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { lock (m_SceneList) { if (!m_SceneList.Contains(scene)) @@ -110,19 +99,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (m_SceneList.Contains(scene)) - m_SceneList.Remove(scene); - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnClientClosed -= OnClientClosed; - scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; - } - public void PostInitialise() { } @@ -147,6 +123,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Groups get { return "GroupsModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion private void OnNewClient(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index e1bde4b..9a68749 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -24,12 +24,9 @@ * (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.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,8 +36,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class InstantMessageModule : ISharedRegionModule + public class InstantMessageModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -51,11 +47,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private readonly List m_scenes = new List(); - #region ISharedRegionModule Members + #region IRegionModule Members private IMessageTransferModule m_TransferModule = null; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { if (config.Configs["Messaging"] != null) { @@ -66,15 +62,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } m_enabled = true; - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { lock (m_scenes) { if (!m_scenes.Contains(scene)) @@ -86,27 +74,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } - public void RegionLoaded(Scene scene) - { - if (!m_enabled) - return; - - m_TransferModule = - m_scenes[0].RequestModuleInterface(); - - if (m_TransferModule == null) - m_log.Error("[INSTANT MESSAGE]: No message transfer module, " + - "IM will not work!"); - } - - public void RemoveRegion(Scene scene) - { - if (m_scenes.Contains(scene)) - m_scenes.Remove(scene); - scene.EventManager.OnClientConnect -= OnClientConnect; - scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; - } - void OnClientConnect(IClientCore client) { IClientIM clientIM; @@ -118,6 +85,15 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage public void PostInitialise() { + if (!m_enabled) + return; + + m_TransferModule = + m_scenes[0].RequestModuleInterface(); + + if (m_TransferModule == null) + m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ + "IM will not work!"); } public void Close() @@ -129,6 +105,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage get { return "InstantMessageModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion public void OnInstantMessage(IClientAPI client, GridInstantMessage im) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 16bdfdd..e5159b3 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Net; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -41,8 +40,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MessageTransferModule : ISharedRegionModule, IMessageTransferModule + public class MessageTransferModule : IRegionModule, IMessageTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -52,9 +50,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage protected Dictionary m_UserRegionMap = new Dictionary(); public event UndeliveredMessage OnUndeliveredMessage; - private bool m_enabled = true; - public virtual void Initialise(IConfigSource config) + public virtual void Initialise(Scene scene, IConfigSource config) { IConfig cnf = config.Configs["Messaging"]; if (cnf != null && cnf.GetString( @@ -62,49 +59,27 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage "MessageTransferModule") { m_log.Debug("[MESSAGE TRANSFER]: Disabled by configuration"); - m_enabled = false; + return; } cnf = config.Configs["Startup"]; if (cnf != null) m_Gridmode = cnf.GetBoolean("gridmode", false); - } - public Type ReplaceableInterface - { - get { return null; } - } + // m_Enabled = true; - public void AddRegion(Scene scene) - { - if (m_enabled) + lock (m_Scenes) { - lock (m_Scenes) + if (m_Scenes.Count == 0) { - if (m_Scenes.Count == 0) - { - MainServer.Instance.AddXmlRPCHandler( - "grid_instant_message", processXMLRPCGridInstantMessage); - } - - m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); - scene.RegisterModuleInterface(this); - m_Scenes.Add(scene); + MainServer.Instance.AddXmlRPCHandler( + "grid_instant_message", processXMLRPCGridInstantMessage); } - } - } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (m_Scenes.Contains(scene)) - m_Scenes.Remove(scene); - MainServer.Instance.RemoveXmlRPCHandler( - "grid_instant_message"); - scene.UnregisterModuleInterface(this); + m_log.Debug("[MESSAGE TRANSFER]: Message transfer module active"); + scene.RegisterModuleInterface(this); + m_Scenes.Add(scene); + } } public virtual void PostInitialise() @@ -120,6 +95,11 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage get { return "MessageTransferModule"; } } + public virtual bool IsSharedModule + { + get { return true; } + } + public virtual void SendInstantMessage(GridInstantMessage im, MessageResultNotification result) { UUID toAgentID = new UUID(im.toAgentID); diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs index 3570495..2d4a635 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MuteListModule.cs @@ -28,7 +28,6 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -40,8 +39,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.MuteList { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MuteListModule : ISharedRegionModule + public class MuteListModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -49,7 +47,7 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList private List m_SceneList = new List(); private string m_RestURL = String.Empty; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { if (!enabled) return; @@ -68,24 +66,19 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList enabled = false; return; } - m_RestURL = cnf.GetString("MuteListURL", ""); - if (m_RestURL == "") - { - m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); - enabled = false; - return; - } - } - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { lock (m_SceneList) { + if (m_SceneList.Count == 0) + { + m_RestURL = cnf.GetString("MuteListURL", ""); + if (m_RestURL == "") + { + m_log.Error("[MUTE LIST] Module was enabled, but no URL is given, disabling"); + enabled = false; + return; + } + } if (!m_SceneList.Contains(scene)) m_SceneList.Add(scene); @@ -93,18 +86,6 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList } } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (m_SceneList.Contains(scene)) - m_SceneList.Remove(scene); - - scene.EventManager.OnNewClient -= OnNewClient; - } - public void PostInitialise() { if (!enabled) @@ -121,6 +102,11 @@ namespace OpenSim.Region.CoreModules.Avatar.MuteList get { return "MuteListModule"; } } + public bool IsSharedModule + { + get { return true; } + } + public void Close() { } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 8f289c0..0727fa9 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -28,7 +28,6 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -41,8 +40,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class OfflineMessageModule : ISharedRegionModule + public class OfflineMessageModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -51,7 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private string m_RestURL = String.Empty; private bool m_ForwardOfflineGroupMessages = true; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { if (!enabled) return; @@ -85,23 +83,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return; } } - } - } - - public Type ReplaceableInterface - { - get { return null; } - } + if (!m_SceneList.Contains(scene)) + m_SceneList.Add(scene); - public void AddRegion(Scene scene) - { - if (!m_SceneList.Contains(scene)) - m_SceneList.Add(scene); - - scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnNewClient += OnNewClient; + } } - public void RegionLoaded(Scene scene) + public void PostInitialise() { if (!enabled) return; @@ -131,22 +120,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage m_log.Debug("[OFFLINE MESSAGING] Offline messages enabled"); } - public void RemoveRegion(Scene scene) - { - if (m_SceneList.Contains(scene)) - m_SceneList.Remove(scene); - scene.EventManager.OnNewClient -= OnNewClient; - } - - public void PostInitialise() - { - } - public string Name { get { return "OfflineMessageModule"; } } + public bool IsSharedModule + { + get { return true; } + } + public void Close() { } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs index f5498f4..f5ab454 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/PresenceModule.cs @@ -24,14 +24,11 @@ * (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.Net; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -42,8 +39,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class PresenceModule : ISharedRegionModule, IPresenceModule + public class PresenceModule : IRegionModule, IPresenceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -63,7 +59,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage public event PresenceChange OnPresenceChange; public event BulkPresenceData OnBulkPresenceData; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { lock (m_Scenes) { @@ -82,38 +78,28 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage m_Gridmode = cnf.GetBoolean("gridmode", false); m_Enabled = true; - } - } - } - public Type ReplaceableInterface - { - get { return null; } - } + m_initialScene = scene; + } - public void AddRegion(Scene scene) - { - if (m_Enabled) - { - m_initialScene = scene; if (m_Gridmode) NotifyMessageServerOfStartup(scene); m_Scenes.Add(scene); + } - scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; - scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; - } + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnSetRootAgentScene += OnSetRootAgentScene; + scene.EventManager.OnMakeChildAgent += OnMakeChildAgent; } - public void RegionLoaded(Scene scene) + public void PostInitialise() { } - public void RemoveRegion(Scene scene) + public void Close() { if (!m_Gridmode || !m_Enabled) return; @@ -130,28 +116,21 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } - NotifyMessageServerOfShutdown(scene); - if(m_Scenes.Contains(scene)) - m_Scenes.Remove(scene); - - scene.UnregisterModuleInterface(this); - - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnSetRootAgentScene -= OnSetRootAgentScene; - scene.EventManager.OnMakeChildAgent -= OnMakeChildAgent; - } - - public void PostInitialise() - { + lock (m_Scenes) + { + foreach (Scene scene in m_Scenes) + NotifyMessageServerOfShutdown(scene); + } } - public void Close() + public string Name { + get { return "PresenceModule"; } } - public string Name + public bool IsSharedModule { - get { return "PresenceModule"; } + get { return true; } } public void RequestBulkPresenceData(UUID[] users) diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs index a04ab22..ecd60bd 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Archiver/InventoryArchiverModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -42,11 +41,10 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] /// /// This module loads and saves OpenSimulator inventory archives /// - public class InventoryArchiverModule : ISharedRegionModule, IInventoryArchiverModule + public class InventoryArchiverModule : IRegionModule, IInventoryArchiverModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -84,28 +82,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver DisablePresenceChecks = disablePresenceChecks; } - public void Initialise(IConfigSource source) - { - - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { if (m_scenes.Count == 0) { scene.RegisterModuleInterface(this); OnInventoryArchiveSaved += SaveInvConsoleCommandCompleted; - + scene.AddCommand( this, "load iar", "load iar []", - "Load user inventory archive.", HandleLoadInvConsoleCommand); - + "Load user inventory archive.", HandleLoadInvConsoleCommand); + scene.AddCommand( this, "save iar", "save iar []", @@ -113,21 +101,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Archiver m_aScene = scene; } - + m_scenes[scene.RegionInfo.RegionID] = scene; } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - if(m_scenes.ContainsKey(scene.RegionInfo.RegionID)) - m_scenes.Remove(scene.RegionInfo.RegionID); - } - public void PostInitialise() {} public void Close() {} diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index abf440e..b60b32b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -40,8 +39,7 @@ using OpenSim.Services.Interfaces; namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class InventoryTransferModule : IInventoryTransferModule, ISharedRegionModule + public class InventoryTransferModule : IInventoryTransferModule, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -52,11 +50,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer new Dictionary(); private IMessageTransferModule m_TransferModule = null; - private bool m_enabled = true; - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { if (config.Configs["Messaging"] != null) { @@ -65,61 +62,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer if (config.Configs["Messaging"].GetString( "InventoryTransferModule", "InventoryTransferModule") != "InventoryTransferModule") - m_enabled = false; + return; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { - if (m_enabled) + if (!m_Scenelist.Contains(scene)) { - if (!m_Scenelist.Contains(scene)) - { - m_Scenelist.Add(scene); + m_Scenelist.Add(scene); - scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnClientClosed += ClientLoggedOut; - scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - } + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnClientClosed += ClientLoggedOut; + scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; } } - public void RegionLoaded(Scene scene) + public void PostInitialise() { - if (m_enabled) + if (m_Scenelist.Count > 0) { - if (m_Scenelist.Count > 0) - { - m_TransferModule = m_Scenelist[0].RequestModuleInterface(); - if (m_TransferModule == null) - m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); - } + m_TransferModule = m_Scenelist[0].RequestModuleInterface(); + if (m_TransferModule == null) + m_log.Error("[INVENTORY TRANSFER] No Message transfer module found, transfers will be local only"); } } - public void RemoveRegion(Scene scene) - { - if (m_Scenelist.Contains(scene)) - m_Scenelist.Remove(scene); - - scene.UnregisterModuleInterface(this); - - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnClientClosed -= ClientLoggedOut; - scene.EventManager.OnIncomingInstantMessage -= OnGridInstantMessage; - } - - public void PostInitialise() - { - } - public void Close() { } diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs index 973d27f..261bd6c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/LureModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,72 +37,36 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Lure { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class LureModule : ISharedRegionModule + public class LureModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly List m_scenes = new List(); - private bool m_enabled = true; - private IMessageTransferModule m_TransferModule = null; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { if (config.Configs["Messaging"] != null) { if (config.Configs["Messaging"].GetString( "LureModule", "LureModule") != "LureModule") - m_enabled = false; + return; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { - if (m_enabled) + lock (m_scenes) { - lock (m_scenes) + if (!m_scenes.Contains(scene)) { - if (!m_scenes.Contains(scene)) - { - m_scenes.Add(scene); - scene.EventManager.OnNewClient += OnNewClient; - scene.EventManager.OnIncomingInstantMessage += - OnGridInstantMessage; - } + m_scenes.Add(scene); + scene.EventManager.OnNewClient += OnNewClient; + scene.EventManager.OnIncomingInstantMessage += + OnGridInstantMessage; } } } - public void RegionLoaded(Scene scene) - { - if (m_enabled) - { - m_TransferModule = - m_scenes[0].RequestModuleInterface(); - - if (m_TransferModule == null) - m_log.Error("[INSTANT MESSAGE]: No message transfer module, " + - "lures will not work!"); - } - } - - public void RemoveRegion(Scene scene) - { - if (m_scenes.Contains(scene)) - m_scenes.Remove(scene); - scene.EventManager.OnNewClient -= OnNewClient; - scene.EventManager.OnIncomingInstantMessage -= - OnGridInstantMessage; - } - void OnNewClient(IClientAPI client) { client.OnInstantMessage += OnInstantMessage; @@ -113,6 +76,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure public void PostInitialise() { + m_TransferModule = + m_scenes[0].RequestModuleInterface(); + + if (m_TransferModule == null) + m_log.Error("[INSTANT MESSAGE]: No message transfer module, "+ + "lures will not work!"); } public void Close() diff --git a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs index 748b42c..63a93aa 100644 --- a/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs +++ b/OpenSim/Region/CoreModules/Avatar/ObjectCaps/ObjectAdd.cs @@ -29,7 +29,6 @@ using System; using System.Collections; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -42,54 +41,24 @@ using Caps=OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class ObjectAdd : ISharedRegionModule + public class ObjectAdd : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource pSource) + public void Initialise(Scene pScene, IConfigSource pSource) { - - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { - m_scene = scene; + m_scene = pScene; m_scene.EventManager.OnRegisterCaps += RegisterCaps; } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.EventManager.OnRegisterCaps -= RegisterCaps; - } - public void PostInitialise() { } - public void Close() - { - - } - - public string Name - { - get { return "ObjectAddModule"; } - } - public void RegisterCaps(UUID agentID, Caps caps) { UUID capuuid = UUID.Random(); @@ -379,6 +348,22 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps Array.Reverse(resultbytes); return String.Format("{0}",Convert.ToBase64String(resultbytes)); } + + public void Close() + { + + } + + public string Name + { + get { return "ObjectAddModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + #endregion } } diff --git a/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs b/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs index 7fcb0e1..8cf58c6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Profiles/AvatarProfilesModule.cs @@ -30,7 +30,6 @@ using System.Collections; using System.Globalization; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,17 +38,20 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Profiles { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class AvatarProfilesModule : INonSharedRegionModule + public class AvatarProfilesModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; private IProfileModule m_profileModule = null; private bool m_enabled = true; - #region INonSharedRegionModule Members + public AvatarProfilesModule() + { + } - public void Initialise(IConfigSource config) + #region IRegionModule Members + + public void Initialise(Scene scene, IConfigSource config) { IConfig profileConfig = config.Configs["Profile"]; if (profileConfig != null) @@ -60,31 +62,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Profiles return; } } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { m_scene = scene; m_scene.EventManager.OnNewClient += NewClient; } - public void RegionLoaded(Scene scene) + public void PostInitialise() { if (!m_enabled) return; m_profileModule = m_scene.RequestModuleInterface(); } - public void RemoveRegion(Scene scene) - { - scene.EventManager.OnNewClient -= NewClient; - } - public void Close() { } @@ -94,6 +83,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Profiles get { return "AvatarProfilesModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion public void NewClient(IClientAPI client) diff --git a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs index 1ee6f0d..0c6cb1b 100644 --- a/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EventQueue/EventQueueGetModule.cs @@ -32,7 +32,6 @@ using System.Net; using System.Reflection; using System.Threading; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Packets; @@ -53,13 +52,11 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue public OSDMap body; } - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class EventQueueGetModule : IEventQueue, INonSharedRegionModule + public class EventQueueGetModule : IEventQueue, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene = null; private IConfigSource m_gConfig; - private IConfig m_startupConfig; bool enabledYN = false; private Dictionary m_ids = new Dictionary(); @@ -68,31 +65,23 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue private Dictionary m_QueueUUIDAvatarMapping = new Dictionary(); private Dictionary m_AvatarQueueUUIDMapping = new Dictionary(); - #region INonSharedRegionModule methods - public virtual void Initialise(IConfigSource config) + #region IRegionModule methods + public virtual void Initialise(Scene scene, IConfigSource config) { m_gConfig = config; - m_startupConfig = m_gConfig.Configs["Startup"]; - } + IConfig startupConfig = m_gConfig.Configs["Startup"]; - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { - ReadConfigAndPopulate(scene, m_startupConfig, "Startup"); + ReadConfigAndPopulate(scene, startupConfig, "Startup"); if (enabledYN) { m_scene = scene; scene.RegisterModuleInterface(this); - + // Register fallback handler // Why does EQG Fail on region crossings! - + //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); scene.EventManager.OnNewClient += OnNewClient; @@ -110,19 +99,16 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue { m_gConfig = null; } + } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) + private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p) { + enabledYN = startupConfig.GetBoolean("EventQueue", true); } - private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string p) + public void PostInitialise() { - enabledYN = startupConfig.GetBoolean("EventQueue", true); } public virtual void Close() @@ -134,6 +120,10 @@ namespace OpenSim.Region.CoreModules.Framework.EventQueue get { return "EventQueueGetModule"; } } + public bool IsSharedModule + { + get { return false; } + } #endregion /// diff --git a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs index 0135d33..f15f8f6 100644 --- a/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Monitoring/MonitorModule.cs @@ -25,12 +25,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -41,8 +39,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Framework.Monitoring { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MonitorModule : INonSharedRegionModule + public class MonitorModule : IRegionModule { private Scene m_scene; private readonly List m_monitors = new List(); @@ -65,19 +62,9 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring } } - #region Implementation of INonSharedRegionModule + #region Implementation of IRegionModule - public void Initialise(IConfigSource source) - { - - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; @@ -90,51 +77,6 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring MainServer.Instance.AddHTTPHandler("/monitorstats/" + m_scene.RegionInfo.RegionID + "/", StatsPage); } - public void RegionLoaded(Scene scene) - { - m_monitors.Add(new AgentCountMonitor(m_scene)); - m_monitors.Add(new ChildAgentCountMonitor(m_scene)); - m_monitors.Add(new GCMemoryMonitor()); - m_monitors.Add(new ObjectCountMonitor(m_scene)); - m_monitors.Add(new PhysicsFrameMonitor(m_scene)); - m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); - m_monitors.Add(new PWSMemoryMonitor()); - m_monitors.Add(new ThreadCountMonitor()); - m_monitors.Add(new TotalFrameMonitor(m_scene)); - m_monitors.Add(new EventFrameMonitor(m_scene)); - m_monitors.Add(new LandFrameMonitor(m_scene)); - m_monitors.Add(new LastFrameTimeMonitor(m_scene)); - - m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); - - foreach (IAlert alert in m_alerts) - { - alert.OnTriggerAlert += OnTriggerAlert; - } - } - - public void RemoveRegion(Scene scene) - { - MainServer.Instance.RemoveHTTPHandler("", "/monitorstats/" + m_scene.RegionInfo.RegionID + "/"); - m_monitors.Clear(); - - foreach (IAlert alert in m_alerts) - { - alert.OnTriggerAlert -= OnTriggerAlert; - } - m_alerts.Clear(); - } - - public void Close() - { - - } - - public string Name - { - get { return "Region Health Monitoring Module"; } - } - public Hashtable StatsPage(Hashtable request) { // If request was for a specific monitor @@ -190,10 +132,49 @@ namespace OpenSim.Region.CoreModules.Framework.Monitoring return ereply; } + public void PostInitialise() + { + m_monitors.Add(new AgentCountMonitor(m_scene)); + m_monitors.Add(new ChildAgentCountMonitor(m_scene)); + m_monitors.Add(new GCMemoryMonitor()); + m_monitors.Add(new ObjectCountMonitor(m_scene)); + m_monitors.Add(new PhysicsFrameMonitor(m_scene)); + m_monitors.Add(new PhysicsUpdateFrameMonitor(m_scene)); + m_monitors.Add(new PWSMemoryMonitor()); + m_monitors.Add(new ThreadCountMonitor()); + m_monitors.Add(new TotalFrameMonitor(m_scene)); + m_monitors.Add(new EventFrameMonitor(m_scene)); + m_monitors.Add(new LandFrameMonitor(m_scene)); + m_monitors.Add(new LastFrameTimeMonitor(m_scene)); + + m_alerts.Add(new DeadlockAlert(m_monitors.Find(x => x is LastFrameTimeMonitor) as LastFrameTimeMonitor)); + + foreach (IAlert alert in m_alerts) + { + alert.OnTriggerAlert += OnTriggerAlert; + } + } + void OnTriggerAlert(System.Type reporter, string reason, bool fatal) { m_log.Error("[Monitor] " + reporter.Name + " for " + m_scene.RegionInfo.RegionName + " reports " + reason + " (Fatal: " + fatal + ")"); } + + public void Close() + { + + } + + public string Name + { + get { return "Region Health Monitoring Module"; } + } + + public bool IsSharedModule + { + get { return false; } + } + #endregion } } diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs index f9c594b..0b54746 100644 --- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs +++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -32,7 +32,6 @@ using System.Net; using System.Reflection; using System.Text.RegularExpressions; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using Nwc.XmlRpc; @@ -47,8 +46,7 @@ using OpenSim.Region.Framework.Interfaces; namespace OpenSim.Region.CoreModules.Hypergrid { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class HGStandaloneLoginModule : ISharedRegionModule, ILoginServiceToRegionsConnector + public class HGStandaloneLoginModule : IRegionModule, ILoginServiceToRegionsConnector { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -58,58 +56,47 @@ namespace OpenSim.Region.CoreModules.Hypergrid protected bool m_enabled = false; // Module is only enabled if running in standalone mode protected HGLoginAuthService m_loginService; - private bool authenticate = true; - private string welcomeMessage = "Welcome to OpenSim"; - private IConfig startupConfig; - private IConfig standaloneConfig; - - #region ISharedRegionModule Members - - public void Initialise(IConfigSource source) - { - startupConfig = source.Configs["Startup"]; - standaloneConfig = source.Configs["StandAlone"]; - if (standaloneConfig != null) - { - authenticate = standaloneConfig.GetBoolean("accounts_authenticate", true); - welcomeMessage = standaloneConfig.GetString("welcome_message"); - } - m_enabled = !startupConfig.GetBoolean("gridmode", false); - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { - } + #region IRegionModule Members - public void RegionLoaded(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { if (m_firstScene == null) { m_firstScene = scene; + IConfig startupConfig = source.Configs["Startup"]; + if (startupConfig != null) + { + m_enabled = !startupConfig.GetBoolean("gridmode", false); + } + if (m_enabled) { m_log.Debug("[HGLogin]: HGlogin module enabled"); + bool authenticate = true; + string welcomeMessage = "Welcome to OpenSim"; + IConfig standaloneConfig = source.Configs["StandAlone"]; + if (standaloneConfig != null) + { + authenticate = standaloneConfig.GetBoolean("accounts_authenticate", true); + welcomeMessage = standaloneConfig.GetString("welcome_message"); + } //TODO: fix casting. LibraryRootFolder rootFolder = m_firstScene.CommsManager.UserProfileCacheService.LibraryRoot as LibraryRootFolder; - + IHttpServer httpServer = MainServer.Instance; //TODO: fix the casting of the user service, maybe by registering the userManagerBase with scenes, or refactoring so we just need a IUserService reference - m_loginService + m_loginService = new HGLoginAuthService( - (UserManagerBase)m_firstScene.CommsManager.UserAdminService, - welcomeMessage, - m_firstScene.CommsManager.InterServiceInventoryService, - m_firstScene.CommsManager.NetworkServersInfo, - authenticate, - rootFolder, + (UserManagerBase)m_firstScene.CommsManager.UserAdminService, + welcomeMessage, + m_firstScene.CommsManager.InterServiceInventoryService, + m_firstScene.CommsManager.NetworkServersInfo, + authenticate, + rootFolder, this); httpServer.AddXmlRPCHandler("hg_login", m_loginService.XmlRpcLoginMethod); @@ -126,19 +113,6 @@ namespace OpenSim.Region.CoreModules.Hypergrid } } - public void RemoveRegion(Scene scene) - { - if (scene == m_firstScene) - { - IHttpServer httpServer = MainServer.Instance; - httpServer.RemoveXmlRPCHandler("hg_login"); - httpServer.RemoveXmlRPCHandler("check_auth_session"); - httpServer.RemoveXmlRPCHandler("get_avatar_appearance"); - httpServer.RemoveXmlRPCHandler("update_avatar_appearance"); - } - m_scenes.Remove(scene); - } - public void PostInitialise() { @@ -154,6 +128,11 @@ namespace OpenSim.Region.CoreModules.Hypergrid get { return "HGStandaloneLoginModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion protected void AddScene(Scene scene) diff --git a/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs b/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs index 4534024..0f2ba32 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OGSRadmin.cs @@ -32,7 +32,6 @@ using System.Net; using System.Reflection; using System.Text; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -43,8 +42,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.InterGrid { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class OGSRadmin : ISharedRegionModule + public class OGSRadmin : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly List m_scenes = new List(); @@ -58,6 +56,7 @@ namespace OpenSim.Region.CoreModules.InterGrid get { return "OGS Supporting RAdmin"; } } + public void Initialise(IConfigSource source) { m_settings = source; @@ -68,11 +67,6 @@ namespace OpenSim.Region.CoreModules.InterGrid } - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) { lock (m_scenes) @@ -83,11 +77,15 @@ namespace OpenSim.Region.CoreModules.InterGrid { lock (m_scenes) m_scenes.Remove(scene); - MainServer.Instance.RemoveXmlRPCHandler("grid_message"); } public void RegionLoaded(Scene scene) { + + } + + public void PostInitialise() + { if (m_settings.Configs["Startup"].GetBoolean("gridmode", false)) { m_com = m_scenes[0].CommsManager; @@ -95,8 +93,21 @@ namespace OpenSim.Region.CoreModules.InterGrid } } - public void PostInitialise() + #endregion + + #region IRegionModule + + public void Initialise(Scene scene, IConfigSource source) + { + m_settings = source; + + lock (m_scenes) + m_scenes.Add(scene); + } + + public bool IsSharedModule { + get { return true; } } #endregion diff --git a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs index 8bb0fa9..10a3232 100644 --- a/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs +++ b/OpenSim/Region/CoreModules/InterGrid/OpenGridProtocolModule.cs @@ -35,7 +35,6 @@ using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Web; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -76,9 +75,8 @@ namespace OpenSim.Region.CoreModules.InterGrid public bool visible_to_parent; public string teleported_into_region; } - - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class OpenGridProtocolModule : ISharedRegionModule + + public class OpenGridProtocolModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_scene = new List(); @@ -94,22 +92,21 @@ namespace OpenSim.Region.CoreModules.InterGrid private bool httpSSL = false; private uint httpsslport = 0; private bool GridMode = false; - private bool m_enabled = false; - private IConfig cfg = null; - private IConfig httpcfg = null; - private IConfig startupcfg = null; - - #region ISharedRegionModule Members - public void Initialise(IConfigSource config) + #region IRegionModule Members + + public void Initialise(Scene scene, IConfigSource config) { + bool enabled = false; + IConfig cfg = null; + IConfig httpcfg = null; + IConfig startupcfg = null; try { cfg = config.Configs["OpenGridProtocol"]; - } - catch (NullReferenceException) + } catch (NullReferenceException) { - m_enabled = false; + enabled = false; } try @@ -131,15 +128,15 @@ namespace OpenSim.Region.CoreModules.InterGrid if (startupcfg != null) { - GridMode = m_enabled = startupcfg.GetBoolean("gridmode", false); + GridMode = enabled = startupcfg.GetBoolean("gridmode", false); } if (cfg != null) { - m_enabled = cfg.GetBoolean("ogp_enabled", false); + enabled = cfg.GetBoolean("ogp_enabled", false); LastNameSuffix = cfg.GetString("ogp_lastname_suffix", "_EXTERNAL"); FirstNamePrefix = cfg.GetString("ogp_firstname_prefix", ""); - if (m_enabled) + if (enabled) { m_log.Warn("[OGP]: Open Grid Protocol is on, Listening for Clients on /agent/"); lock (m_scene) @@ -168,61 +165,35 @@ namespace OpenSim.Region.CoreModules.InterGrid } } + // can't pick the region 'agent' because it would conflict with our agent domain handler + // a zero length region name would conflict with are base region seed cap + if (!SceneListDuplicateCheck(scene.RegionInfo.RegionName) && scene.RegionInfo.RegionName.ToLower() != "agent" && scene.RegionInfo.RegionName.Length > 0) + { + MainServer.Instance.AddLLSDHandler( + "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()), + ProcessRegionDomainSeed); + } + + if (!m_scene.Contains(scene)) + m_scene.Add(scene); } } } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { - if (m_enabled) + lock (m_scene) { - lock (m_scene) + if (m_scene.Count == 1) { - if (m_scene.Count == 1) + if (httpcfg != null) { - if (httpcfg != null) - { - httpSSL = httpcfg.GetBoolean("http_listener_ssl", false); - httpsCN = httpcfg.GetString("http_listener_cn", scene.RegionInfo.ExternalHostName); - if (httpsCN.Length == 0) - httpsCN = scene.RegionInfo.ExternalHostName; - httpsslport = (uint)httpcfg.GetInt("http_listener_sslport", ((int)scene.RegionInfo.HttpPort + 1)); - } + httpSSL = httpcfg.GetBoolean("http_listener_ssl", false); + httpsCN = httpcfg.GetString("http_listener_cn", scene.RegionInfo.ExternalHostName); + if (httpsCN.Length == 0) + httpsCN = scene.RegionInfo.ExternalHostName; + httpsslport = (uint)httpcfg.GetInt("http_listener_sslport",((int)scene.RegionInfo.HttpPort + 1)); } } - // can't pick the region 'agent' because it would conflict with our agent domain handler - // a zero length region name would conflict with are base region seed cap - if (!SceneListDuplicateCheck(scene.RegionInfo.RegionName) && scene.RegionInfo.RegionName.ToLower() != "agent" && scene.RegionInfo.RegionName.Length > 0) - { - MainServer.Instance.AddLLSDHandler( - "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()), - ProcessRegionDomainSeed); - } - - if (!m_scene.Contains(scene)) - m_scene.Add(scene); } } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - MainServer.Instance.RemoveLLSDHandler( - "/" + HttpUtility.UrlPathEncode(scene.RegionInfo.RegionName.ToLower()), - ProcessRegionDomainSeed); - - if (m_scene.Contains(scene)) - m_scene.Remove(scene); - } public void PostInitialise() { @@ -238,6 +209,11 @@ namespace OpenSim.Region.CoreModules.InterGrid get { return "OpenGridProtocolModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion public OSD ProcessRegionDomainSeed(string path, OSD request, string endpoint) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 40b7159..679c871 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -41,8 +40,7 @@ using System.Reflection; namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class DynamicTextureModule : ISharedRegionModule, IDynamicTextureManager + public class DynamicTextureModule : IRegionModule, IDynamicTextureManager { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -212,14 +210,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture #endregion - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) { @@ -228,24 +221,6 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) - { - RegisteredScenes.Remove(scene.RegionInfo.RegionID); - scene.UnregisterModuleInterface(this); - } - } - public void PostInitialise() { } @@ -259,6 +234,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture get { return "DynamicTextureModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion #region Nested type: DynamicTextureUpdater @@ -378,18 +358,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture // tmptex.DefaultTexture.Fullbright = true; part.UpdateTexture(tmptex); - } - - if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) - { - if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); - if (oldAsset != null) - { - if (oldAsset.Temporary == true) - { - scene.AssetService.Delete(oldID.ToString()); - } - } + } + + if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) + { + if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); + if (oldAsset != null) + { + if (oldAsset.Temporary == true) + { + scene.AssetService.Delete(oldID.ToString()); + } + } } } diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index d6ed468..83f004d 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -32,7 +32,6 @@ using System.Text.RegularExpressions; using DotNetOpenMail; using DotNetOpenMail.SmtpAuth; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -41,7 +40,6 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.EmailModules { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EmailModule : IEmailModule { // @@ -96,7 +94,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules } } - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { m_Config = config; IConfig SMTPConfig; @@ -138,16 +136,7 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules m_Enabled = false; return; } - m_log.Info("[EMAIL] Activated DefaultEmailModule"); - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { // It's a go! if (m_Enabled) { @@ -166,20 +155,8 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules m_Scenes.Add(scene.RegionInfo.RegionHandle, scene); } } - } - } - - public void RegionLoaded(Scene scene) - { - } - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - - if (m_Scenes.ContainsKey(scene.RegionInfo.RegionHandle)) - { - m_Scenes.Remove(scene.RegionInfo.RegionHandle); + m_log.Info("[EMAIL] Activated DefaultEmailModule"); } } @@ -196,6 +173,11 @@ namespace OpenSim.Region.CoreModules.Scripting.EmailModules get { return "DefaultEmailModule"; } } + public bool IsSharedModule + { + get { return true; } + } + /// /// Delay function using thread in seconds /// diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index e331b8d..d78931a 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -31,7 +31,6 @@ using System.IO; using System.Net; using System.Text; using System.Threading; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -85,8 +84,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class HttpRequestModule : ISharedRegionModule, IHttpRequestModule + public class HttpRequestModule : IRegionModule, IHttpRequestModule { private object HttpListLock = new object(); private int httpTimeout = 30000; @@ -231,35 +229,18 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest #endregion - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); - m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); - - m_pendingRequests = new Dictionary(); - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { m_scene = scene; m_scene.RegisterModuleInterface(this); - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void RegionLoaded(Scene scene) - { - } + m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); + m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); + m_pendingRequests = new Dictionary(); } public void PostInitialise() @@ -275,6 +256,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest get { return m_name; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion } diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 6ce55a9..9b565ed 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -126,8 +126,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp public void RemoveRegion(Scene scene) { - scene.UnregisterModuleInterface(this); - scene.EventManager.OnScriptReset -= OnScriptReset; } public void Close() diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index 35ce2cb..c23cea5 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -29,7 +29,6 @@ using System; using System.Drawing; using System.IO; using System.Net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -40,8 +39,7 @@ using System.Reflection; namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class LoadImageURLModule : ISharedRegionModule, IDynamicTextureRender + public class LoadImageURLModule : IRegionModule, IDynamicTextureRender { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -99,28 +97,20 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL #endregion - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) - { - m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); - m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource config) { if (m_scene == null) { m_scene = scene; } + + m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); + m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) + public void PostInitialise() { m_textureManager = m_scene.RequestModuleInterface(); if (m_textureManager != null) @@ -129,14 +119,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL } } - public void RemoveRegion(Scene scene) - { - } - - public void PostInitialise() - { - } - public void Close() { } @@ -146,6 +128,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL get { return m_name; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion private void MakeHttpRequest(string url, UUID requestID) diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 71b01a1..d57a8e5 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -31,7 +31,6 @@ using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -44,8 +43,7 @@ using System.Reflection; namespace OpenSim.Region.CoreModules.Scripting.VectorRender { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class VectorRenderModule : ISharedRegionModule, IDynamicTextureRender + public class VectorRenderModule : IRegionModule, IDynamicTextureRender { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -112,10 +110,15 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender #endregion - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { + if (m_scene == null) + { + m_scene = scene; + } + if (m_graph == null) { Bitmap bitmap = new Bitmap(1024, 1024, PixelFormat.Format32bppArgb); @@ -130,20 +133,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender m_log.DebugFormat("[VECTORRENDERMODULE]: using font \"{0}\" for text rendering.", m_fontName); } - public void AddRegion(Scene scene) - { - if (m_scene == null) - { - m_scene = scene; - } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) + public void PostInitialise() { m_textureManager = m_scene.RequestModuleInterface(); if (m_textureManager != null) @@ -152,14 +142,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } } - public void RemoveRegion(Scene scene) - { - } - - public void PostInitialise() - { - } - public void Close() { } @@ -169,6 +151,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender get { return m_name; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion private void Draw(string data, UUID id, string extraParams) diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index d935c56..93aa88c 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -28,7 +28,6 @@ using System; using System.Collections; using System.Collections.Generic; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -86,8 +85,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.WorldComm { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class WorldCommModule : ISharedRegionModule, IWorldComm + public class WorldCommModule : IRegionModule, IWorldComm { // private static readonly ILog m_log = // LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -100,9 +98,9 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm private int m_saydistance = 30; private int m_shoutdistance = 100; - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { // wrap this in a try block so that defaults will work if // the config file doesn't specify otherwise. @@ -122,6 +120,7 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if (maxlisteners < 1) maxlisteners = int.MaxValue; if (maxhandles < 1) maxhandles = int.MaxValue; +<<<<<<< HEAD:OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs m_listenerManager = new ListenerManager(maxlisteners, maxhandles); m_pendingQ = new Queue(); m_pending = Queue.Synchronized(m_pendingQ); @@ -133,26 +132,19 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm public void AddRegion(Scene scene) { +======= +>>>>>>> ec3c31e... Updates all IRegionModules to the new style region modules.:OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs m_scene = scene; m_scene.RegisterModuleInterface(this); + m_listenerManager = new ListenerManager(maxlisteners, maxhandles); m_scene.EventManager.OnChatFromClient += DeliverClientMessage; m_scene.EventManager.OnChatBroadcast += DeliverClientMessage; + m_pendingQ = new Queue(); + m_pending = Queue.Synchronized(m_pendingQ); } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) + public void PostInitialise() { - scene.UnregisterModuleInterface(this); - scene.EventManager.OnChatFromClient -= DeliverClientMessage; - scene.EventManager.OnChatBroadcast -= DeliverClientMessage; } public void Close() @@ -164,6 +156,11 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm get { return "WorldCommModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion #region IWorldComm Members diff --git a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs index a9147fb6..27b64bf 100644 --- a/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/XMLRPC/XMLRPCModule.cs @@ -32,7 +32,6 @@ using System.Net; using System.Reflection; using System.Threading; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenMetaverse; @@ -77,8 +76,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class XMLRPCModule : ISharedRegionModule, IXMLRPC + public class XMLRPCModule : IRegionModule, IXMLRPC { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -96,9 +94,9 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC private int RemoteReplyScriptWait = 300; private object XMLRPCListLock = new object(); - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { // We need to create these early because the scripts might be calling // But since this gets called for every region, we need to make sure they @@ -118,14 +116,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC { } } - } - - public void PostInitialise() - { - } - public void AddRegion(Scene scene) - { if (!m_scenes.Contains(scene)) { m_scenes.Add(scene); @@ -134,12 +125,7 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC } } - public Type ReplaceableInterface - { - get { return null; } - } - private Dictionary m_HttpServers = new Dictionary(); - public void RegionLoaded(Scene scene) + public void PostInitialise() { if (IsEnabled()) { @@ -147,31 +133,9 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC // Attach xmlrpc handlers m_log.Info("[REMOTE_DATA]: " + "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); - BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort); + BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); httpServer.Start(); - m_HttpServers.Add(scene, httpServer); - } - } - - public void RemoveRegion(Scene scene) - { - if (m_scenes.Contains(scene)) - m_scenes.Remove(scene); - scene.UnregisterModuleInterface(this); - if (IsEnabled()) - { - // Start http server - // Attach xmlrpc handlers - if (m_HttpServers.ContainsKey(scene)) - { - BaseHttpServer httpServer; - m_HttpServers.TryGetValue(scene, out httpServer); - m_log.Info("[REMOTE_DATA]: " + - "Stopping XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); - httpServer.RemoveXmlRPCHandler("llRemoteData"); - httpServer.Stop(); - } } } @@ -184,6 +148,11 @@ namespace OpenSim.Region.CoreModules.Scripting.XMLRPC get { return m_name; } } + public bool IsSharedModule + { + get { return true; } + } + public int Port { get { return m_remoteDataPort; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs index d3e2db7..879cc70 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Asset/AssetServiceInConnectorModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Asset private IConfigSource m_Config; bool m_Registered = false; - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs index a895a3f..b12d778 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Grid/HypergridServiceInConnectorModule.cs @@ -51,7 +51,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Grid bool m_Registered = false; HypergridServiceInConnector m_HypergridHandler; - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs index 4c74725..54c6d89 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Inventory/InventoryServiceInConnectorModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Inventory private IConfigSource m_Config; bool m_Registered = false; - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index dcc6dec..bce160a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land private IConfigSource m_Config; private List m_Scenes = new List(); - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs index a5c5ef6..8a90370 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Neighbour/NeighbourServiceInConnectorModule.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Neighbour private IConfigSource m_Config; private List m_Scenes = new List(); - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs index c2cea16..f28a318 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Simulation/SimulationServiceInConnectorModule.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Simulation private IConfigSource m_Config; bool m_Registered = false; - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs index 71d7993..d68c683 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/LocalInterregionComms.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion #endregion /* Events */ - #region ISharedRegionModule + #region IRegionModule public void Initialise(IConfigSource config) { @@ -136,7 +136,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion } } - #endregion + #endregion /* IRegionModule */ #region IInterregionComms diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs index ca07a28..0357c60 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Interregion/RESTInterregionComms.cs @@ -66,7 +66,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion protected bool m_safemode; protected IPAddress m_thisIP; - #region ISharedRegionModule + #region IRegionModule public virtual void Initialise(IConfigSource config) { @@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion MainServer.Instance.AddHTTPHandler("/object/", ObjectHandler); } - #endregion + #endregion /* IRegionModule */ #region IInterregionComms @@ -435,12 +435,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Interregion } OSDMap resp = new OSDMap(2); - string reason = String.Empty; - uint teleportFlags = 0; - if (args.ContainsKey("teleport_flags")) - { - teleportFlags = args["teleport_flags"].AsUInteger(); - } + string reason = String.Empty; + uint teleportFlags = 0; + if (args.ContainsKey("teleport_flags")) + { + teleportFlags = args["teleport_flags"].AsUInteger(); + } // This is the meaning of POST agent m_regionClient.AdjustUserInformation(aCircuit); diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index c738b65..fc8d4e1 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -81,7 +81,6 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void RemoveRegion(Scene scene) { - scene.UnregisterModuleInterface(this); } public void Close() diff --git a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs index a2cfce6..5fa3dc2 100644 --- a/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs +++ b/OpenSim/Region/CoreModules/World/Cloud/CloudModule.cs @@ -27,7 +27,6 @@ using System; using System.Collections.Generic; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -36,7 +35,6 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class CloudModule : ICloudModule { // private static readonly log4net.ILog m_log @@ -50,7 +48,7 @@ namespace OpenSim.Region.CoreModules private float m_cloudDensity = 1.0F; private float[] cloudCover = new float[16 * 16]; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { IConfig cloudConfig = config.Configs["Cloud"]; @@ -60,17 +58,10 @@ namespace OpenSim.Region.CoreModules m_cloudDensity = cloudConfig.GetFloat("density", 0.5F); m_frameUpdateRate = cloudConfig.GetInt("cloud_update_rate", 1000); } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { if (m_enabled) { + m_scene = scene; scene.EventManager.OnNewClient += CloudsToClient; @@ -80,18 +71,9 @@ namespace OpenSim.Region.CoreModules GenerateCloudCover(); m_ready = true; - } - } - public void RegionLoaded(Scene scene) - { - } + } - public void RemoveRegion(Scene scene) - { - scene.EventManager.OnNewClient -= CloudsToClient; - scene.UnregisterModuleInterface(this); - scene.EventManager.OnFrame -= CloudUpdate; } public void PostInitialise() @@ -114,6 +96,12 @@ namespace OpenSim.Region.CoreModules get { return "CloudModule"; } } + public bool IsSharedModule + { + get { return false; } + } + + public float CloudCover(int x, int y, int z) { float cover = 0f; diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 39836ae..695cced 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -30,7 +30,6 @@ using System.IO; using System.Reflection; using System.Security; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -39,7 +38,6 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.World.Estate { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class EstateManagementModule : IEstateModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -900,16 +898,7 @@ namespace OpenSim.Region.CoreModules.World.Estate #region IRegionModule Members - public void Initialise(IConfigSource source) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; m_scene.RegisterModuleInterface(this); @@ -931,29 +920,6 @@ namespace OpenSim.Region.CoreModules.World.Estate consoleSetTerrainHeights); } - public void RegionLoaded(Scene scene) - { - // Sets up the sun module based on the saved Estate and Region Settings - // DO NOT REMOVE or the sun will stop working - TriggerEstateToolsSunUpdate(); - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - scene.EventManager.OnNewClient -= EventManager_OnNewClient; - scene.EventManager.OnRequestChangeWaterHeight -= changeWaterHeight; - } - - public void Close() - { - } - - public string Name - { - get { return "EstateManagementModule"; } - } - #region Console Commands public void consoleSetTerrainTexture(string module, string[] args) @@ -1040,6 +1006,28 @@ namespace OpenSim.Region.CoreModules.World.Estate } #endregion + + public void PostInitialise() + { + // Sets up the sun module based no the saved Estate and Region Settings + // DO NOT REMOVE or the sun will stop working + TriggerEstateToolsSunUpdate(); + } + + public void Close() + { + } + + public string Name + { + get { return "EstateManagementModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + #endregion #region Other Functions diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 5b15065..1533462 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -90,8 +89,7 @@ enum GroupPowers : long namespace OpenSim.Region.CoreModules.World.Permissions { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class PermissionsModule : INonSharedRegionModule + public class PermissionsModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -151,10 +149,12 @@ namespace OpenSim.Region.CoreModules.World.Permissions #endregion - #region INonSharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { + m_scene = scene; + IConfig myConfig = config.Configs["Startup"]; string permissionModules = myConfig.GetString("permissionmodules", "DefaultPermissionsModule"); @@ -179,57 +179,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (m_bypassPermissions) m_log.Info("[PERMISSIONS]: serviceside_object_permissions = false in ini file so disabling all region service permission checks"); else - m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); - - string grant = myConfig.GetString("GrantLSL",""); - if (grant.Length > 0) { - foreach (string uuidl in grant.Split(',')) { - string uuid = uuidl.Trim(" \t".ToCharArray()); - GrantLSL.Add(uuid, true); - } - } - - grant = myConfig.GetString("GrantCS",""); - if (grant.Length > 0) { - foreach (string uuidl in grant.Split(',')) { - string uuid = uuidl.Trim(" \t".ToCharArray()); - GrantCS.Add(uuid, true); - } - } - - grant = myConfig.GetString("GrantVB",""); - if (grant.Length > 0) { - foreach (string uuidl in grant.Split(',')) { - string uuid = uuidl.Trim(" \t".ToCharArray()); - GrantVB.Add(uuid, true); - } - } - - grant = myConfig.GetString("GrantJS", ""); - if (grant.Length > 0) - { - foreach (string uuidl in grant.Split(',')) - { - string uuid = uuidl.Trim(" \t".ToCharArray()); - GrantJS.Add(uuid, true); - } - } - - grant = myConfig.GetString("GrantYP", ""); - if (grant.Length > 0) - { - foreach (string uuidl in grant.Split(',')) - { - string uuid = uuidl.Trim(" \t".ToCharArray()); - GrantYP.Add(uuid, true); - } - } - - } - - public void AddRegion(Scene scene) - { - m_scene = scene; + m_log.Debug("[PERMISSIONS]: Enabling all region service permission checks"); //Register functions with Scene External Checks! m_scene.Permissions.OnBypassPermissions += BypassPermissions; @@ -262,23 +212,23 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnLinkObject += CanLinkObject; //NOT YET IMPLEMENTED m_scene.Permissions.OnDelinkObject += CanDelinkObject; //NOT YET IMPLEMENTED m_scene.Permissions.OnBuyLand += CanBuyLand; //NOT YET IMPLEMENTED - + m_scene.Permissions.OnViewNotecard += CanViewNotecard; //NOT YET IMPLEMENTED m_scene.Permissions.OnViewScript += CanViewScript; //NOT YET IMPLEMENTED m_scene.Permissions.OnEditNotecard += CanEditNotecard; //NOT YET IMPLEMENTED m_scene.Permissions.OnEditScript += CanEditScript; //NOT YET IMPLEMENTED - + m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; //NOT IMPLEMENTED HERE m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnResetScript += CanResetScript; - + m_scene.Permissions.OnCreateUserInventory += CanCreateUserInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnCopyUserInventory += CanCopyUserInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnEditUserInventory += CanEditUserInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED - + m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED m_scene.Permissions.OnUseObjectReturn += CanUseObjectReturn; //NOT YET IMPLEMENTED @@ -296,87 +246,52 @@ namespace OpenSim.Region.CoreModules.World.Permissions "debug permissions ", "Enable permissions debugging", HandleDebugPermissions); - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - m_friendsModule = m_scene.RequestModuleInterface(); + + + string grant = myConfig.GetString("GrantLSL",""); + if (grant.Length > 0) { + foreach (string uuidl in grant.Split(',')) { + string uuid = uuidl.Trim(" \t".ToCharArray()); + GrantLSL.Add(uuid, true); + } + } - if (m_friendsModule == null) - m_log.Error("[PERMISSIONS]: Friends module not found, friend permissions will not work"); - else - m_log.Info("[PERMISSIONS]: Friends module found, friend permissions enabled"); - } + grant = myConfig.GetString("GrantCS",""); + if (grant.Length > 0) { + foreach (string uuidl in grant.Split(',')) { + string uuid = uuidl.Trim(" \t".ToCharArray()); + GrantCS.Add(uuid, true); + } + } - public void RemoveRegion(Scene scene) - { - scene.Permissions.OnBypassPermissions -= BypassPermissions; - scene.Permissions.OnSetBypassPermissions -= SetBypassPermissions; - scene.Permissions.OnPropagatePermissions -= PropagatePermissions; - scene.Permissions.OnGenerateClientFlags -= GenerateClientFlags; - scene.Permissions.OnAbandonParcel -= CanAbandonParcel; - scene.Permissions.OnReclaimParcel -= CanReclaimParcel; - scene.Permissions.OnDeedParcel -= CanDeedParcel; - scene.Permissions.OnDeedObject -= CanDeedObject; - scene.Permissions.OnIsGod -= IsGod; - scene.Permissions.OnDuplicateObject -= CanDuplicateObject; - scene.Permissions.OnDeleteObject -= CanDeleteObject; //MAYBE FULLY IMPLEMENTED - scene.Permissions.OnEditObject -= CanEditObject; //MAYBE FULLY IMPLEMENTED - scene.Permissions.OnEditParcel -= CanEditParcel; //MAYBE FULLY IMPLEMENTED - scene.Permissions.OnInstantMessage -= CanInstantMessage; - scene.Permissions.OnInventoryTransfer -= CanInventoryTransfer; //NOT YET IMPLEMENTED - scene.Permissions.OnIssueEstateCommand -= CanIssueEstateCommand; //FULLY IMPLEMENTED - scene.Permissions.OnMoveObject -= CanMoveObject; //MAYBE FULLY IMPLEMENTED - scene.Permissions.OnObjectEntry -= CanObjectEntry; - scene.Permissions.OnReturnObject -= CanReturnObject; //NOT YET IMPLEMENTED - scene.Permissions.OnRezObject -= CanRezObject; //MAYBE FULLY IMPLEMENTED - scene.Permissions.OnRunConsoleCommand -= CanRunConsoleCommand; - scene.Permissions.OnRunScript -= CanRunScript; //NOT YET IMPLEMENTED - scene.Permissions.OnCompileScript -= CanCompileScript; - scene.Permissions.OnSellParcel -= CanSellParcel; - scene.Permissions.OnTakeObject -= CanTakeObject; - scene.Permissions.OnTakeCopyObject -= CanTakeCopyObject; - scene.Permissions.OnTerraformLand -= CanTerraformLand; - scene.Permissions.OnLinkObject -= CanLinkObject; //NOT YET IMPLEMENTED - scene.Permissions.OnDelinkObject -= CanDelinkObject; //NOT YET IMPLEMENTED - scene.Permissions.OnBuyLand -= CanBuyLand; //NOT YET IMPLEMENTED - - scene.Permissions.OnViewNotecard -= CanViewNotecard; //NOT YET IMPLEMENTED - scene.Permissions.OnViewScript -= CanViewScript; //NOT YET IMPLEMENTED - scene.Permissions.OnEditNotecard -= CanEditNotecard; //NOT YET IMPLEMENTED - scene.Permissions.OnEditScript -= CanEditScript; //NOT YET IMPLEMENTED - - scene.Permissions.OnCreateObjectInventory -= CanCreateObjectInventory; //NOT IMPLEMENTED HERE - scene.Permissions.OnEditObjectInventory -= CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED - scene.Permissions.OnCopyObjectInventory -= CanCopyObjectInventory; //NOT YET IMPLEMENTED - scene.Permissions.OnDeleteObjectInventory -= CanDeleteObjectInventory; //NOT YET IMPLEMENTED - scene.Permissions.OnResetScript -= CanResetScript; - - scene.Permissions.OnCreateUserInventory -= CanCreateUserInventory; //NOT YET IMPLEMENTED - scene.Permissions.OnCopyUserInventory -= CanCopyUserInventory; //NOT YET IMPLEMENTED - scene.Permissions.OnEditUserInventory -= CanEditUserInventory; //NOT YET IMPLEMENTED - scene.Permissions.OnDeleteUserInventory -= CanDeleteUserInventory; //NOT YET IMPLEMENTED - - scene.Permissions.OnTeleport -= CanTeleport; //NOT YET IMPLEMENTED - scene.Permissions.OnUseObjectReturn -= CanUseObjectReturn; //NOT YET IMPLEMENTED - } + grant = myConfig.GetString("GrantVB",""); + if (grant.Length > 0) { + foreach (string uuidl in grant.Split(',')) { + string uuid = uuidl.Trim(" \t".ToCharArray()); + GrantVB.Add(uuid, true); + } + } - public void PostInitialise() - { - } + grant = myConfig.GetString("GrantJS", ""); + if (grant.Length > 0) + { + foreach (string uuidl in grant.Split(',')) + { + string uuid = uuidl.Trim(" \t".ToCharArray()); + GrantJS.Add(uuid, true); + } + } - public void Close() - { - } + grant = myConfig.GetString("GrantYP", ""); + if (grant.Length > 0) + { + foreach (string uuidl in grant.Split(',')) + { + string uuid = uuidl.Trim(" \t".ToCharArray()); + GrantYP.Add(uuid, true); + } + } - public string Name - { - get { return "PermissionsModule"; } } public void HandleBypassPermissions(string module, string[] args) @@ -449,6 +364,31 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_log.InfoFormat("[PERMISSIONS] Set permissions debugging to {0} in {1}", m_debugPermissions, m_scene.RegionInfo.RegionName); } } + + public void PostInitialise() + { + m_friendsModule = m_scene.RequestModuleInterface(); + + if (m_friendsModule == null) + m_log.Error("[PERMISSIONS]: Friends module not found, friend permissions will not work"); + else + m_log.Info("[PERMISSIONS]: Friends module found, friend permissions enabled"); + } + + public void Close() + { + } + + public string Name + { + get { return "PermissionsModule"; } + } + + public bool IsSharedModule + { + get { return false; } + } + #endregion #region Helper Functions diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index ed7bfe1..37f1f2e 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -26,7 +26,6 @@ */ using System; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -35,44 +34,26 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.World.Sound { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SoundModule : INonSharedRegionModule, ISoundModule + public class SoundModule : IRegionModule, ISoundModule { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; - public void Initialise(IConfigSource source) - { - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; - + m_scene.EventManager.OnNewClient += OnNewClient; - + m_scene.RegisterModuleInterface(this); } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.EventManager.OnNewClient -= OnNewClient; - scene.UnregisterModuleInterface(this); - } + public void PostInitialise() {} public void Close() {} public string Name { get { return "Sound Module"; } } - + public bool IsSharedModule { get { return false; } } + private void OnNewClient(IClientAPI client) { client.OnSoundTrigger += TriggerSound; diff --git a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs index 948c47c..0712a7f 100644 --- a/OpenSim/Region/CoreModules/World/Sun/SunModule.cs +++ b/OpenSim/Region/CoreModules/World/Sun/SunModule.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -38,7 +37,6 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class SunModule : ISunModule { /// @@ -280,12 +278,27 @@ namespace OpenSim.Region.CoreModules return GetCurrentSunHour() + 6.0f; } - #region INonSharedRegionModule Methods + #region IRegion Methods // Called immediately after the module is loaded for a given region // i.e. Immediately after instance creation. - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { + m_scene = scene; + m_frame = 0; + + // This one puts an entry in the main help screen + m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); + + // This one enables the ability to type just "sun" without any parameters + m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand); + foreach (KeyValuePair kvp in GetParamList()) + { + m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand); + } + + + TimeZone local = TimeZone.CurrentTimeZone; TicksUTCOffset = local.GetUtcOffset(local.ToLocalTime(DateTime.Now)).Ticks; m_log.Debug("[SUN]: localtime offset is " + TicksUTCOffset); @@ -333,43 +346,7 @@ namespace OpenSim.Region.CoreModules // m_latitude = d_latitude; // m_longitude = d_longitude; } - } - - public void Close() - { - ready = false; - - // Remove our hooks - m_scene.EventManager.OnFrame -= SunUpdate; - m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; - m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; - m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; - } - - public string Name - { - get { return "SunModule"; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { - m_scene = scene; - m_frame = 0; - - // This one puts an entry in the main help screen - m_scene.AddCommand(this, String.Empty, "sun", "Usage: sun [param] [value] - Get or Update Sun module paramater", null); - // This one enables the ability to type just "sun" without any parameters - m_scene.AddCommand(this, "sun", "", "", HandleSunConsoleCommand); - foreach (KeyValuePair kvp in GetParamList()) - { - m_scene.AddCommand(this, String.Format("sun {0}", kvp.Key), String.Format("{0} - {1}", kvp.Key, kvp.Value), "", HandleSunConsoleCommand); - } switch (m_RegionMode) { case "T1": @@ -377,8 +354,8 @@ namespace OpenSim.Region.CoreModules case "SL": // Time taken to complete a cycle (day and season) - SecondsPerSunCycle = (uint)(m_DayLengthHours * 60 * 60); - SecondsPerYear = (uint)(SecondsPerSunCycle * m_YearLengthDays); + SecondsPerSunCycle = (uint) (m_DayLengthHours * 60 * 60); + SecondsPerYear = (uint) (SecondsPerSunCycle*m_YearLengthDays); // Ration of real-to-virtual time @@ -387,17 +364,17 @@ namespace OpenSim.Region.CoreModules // Speed of rotation needed to complete a cycle in the // designated period (day and season) - SunSpeed = m_SunCycle / SecondsPerSunCycle; - SeasonSpeed = m_SeasonalCycle / SecondsPerYear; + SunSpeed = m_SunCycle/SecondsPerSunCycle; + SeasonSpeed = m_SeasonalCycle/SecondsPerYear; // Horizon translation - HorizonShift = m_HorizonShift; // Z axis translation + HorizonShift = m_HorizonShift; // Z axis translation // HoursToRadians = (SunCycle/24)*VWTimeRatio; // Insert our event handling hooks - scene.EventManager.OnFrame += SunUpdate; + scene.EventManager.OnFrame += SunUpdate; scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; scene.EventManager.OnEstateToolsSunUpdate += EstateToolsSunUpdate; scene.EventManager.OnGetCurrentTimeAsLindenSunHour += GetCurrentTimeAsLindenSunHour; @@ -414,21 +391,34 @@ namespace OpenSim.Region.CoreModules } scene.RegisterModuleInterface(this); + } - public void RegionLoaded(Scene scene) + + public void PostInitialise() { } - public void RemoveRegion(Scene scene) + public void Close() { - scene.RegisterModuleInterface(this); - scene.EventManager.OnFrame -= SunUpdate; - scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; - scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; - scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; + ready = false; + + // Remove our hooks + m_scene.EventManager.OnFrame -= SunUpdate; + m_scene.EventManager.OnAvatarEnteringNewParcel -= AvatarEnteringParcel; + m_scene.EventManager.OnEstateToolsSunUpdate -= EstateToolsSunUpdate; + m_scene.EventManager.OnGetCurrentTimeAsLindenSunHour -= GetCurrentTimeAsLindenSunHour; + } + + public string Name + { + get { return "SunModule"; } } + public bool IsSharedModule + { + get { return false; } + } #endregion #region EventManager Events diff --git a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs index 0b487ed..c2ad7b8 100644 --- a/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs +++ b/OpenSim/Region/CoreModules/World/Vegetation/VegetationModule.cs @@ -28,7 +28,6 @@ using System; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -37,8 +36,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Avatar.Vegetation { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class VegetationModule : INonSharedRegionModule, IVegetationModule + public class VegetationModule : IRegionModule, IVegetationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -47,34 +45,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Vegetation protected static readonly PCode[] creationCapabilities = new PCode[] { PCode.Grass, PCode.NewTree, PCode.Tree }; public PCode[] CreationCapabilities { get { return creationCapabilities; } } - public void Initialise(IConfigSource source) - { - } - - public void AddRegion(Scene scene) + public void Initialise(Scene scene, IConfigSource source) { m_scene = scene; m_scene.RegisterModuleInterface(this); } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } public void PostInitialise() {} public void Close() {} public string Name { get { return "Vegetation Module"; } } - + public bool IsSharedModule { get { return false; } } + public SceneObjectGroup AddTree( UUID uuid, UUID groupID, Vector3 scale, Quaternion rotation, Vector3 position, Tree treeType, bool newTree) { diff --git a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs index cd3706d..3283c1f 100644 --- a/OpenSim/Region/CoreModules/World/Wind/WindModule.cs +++ b/OpenSim/Region/CoreModules/World/Wind/WindModule.cs @@ -55,19 +55,17 @@ namespace OpenSim.Region.CoreModules private IWindModelPlugin m_activeWindPlugin = null; private const string m_dWindPluginName = "SimpleRandomWind"; - private string m_desiredWindPlugin = "SimpleRandomWind"; private Dictionary m_availableWindPlugins = new Dictionary(); // Simplified windSpeeds based on the fact that the client protocal tracks at a resolution of 16m private Vector2[] windSpeeds = new Vector2[16 * 16]; - private IConfig windConfig; #region IRegion Methods - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { - windConfig = config.Configs["Wind"]; - m_desiredWindPlugin = m_dWindPluginName; + IConfig windConfig = config.Configs["Wind"]; + string desiredWindPlugin = m_dWindPluginName; if (windConfig != null) { @@ -78,18 +76,10 @@ namespace OpenSim.Region.CoreModules // Determine which wind model plugin is desired if (windConfig.Contains("wind_plugin")) { - m_desiredWindPlugin = windConfig.GetString("wind_plugin"); + desiredWindPlugin = windConfig.GetString("wind_plugin"); } } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { if (m_enabled) { m_log.InfoFormat("[WIND] Enabled with an update rate of {0} frames.", m_frameUpdateRate); @@ -105,30 +95,30 @@ namespace OpenSim.Region.CoreModules } // Check for desired plugin - if (m_availableWindPlugins.ContainsKey(m_desiredWindPlugin)) + if (m_availableWindPlugins.ContainsKey(desiredWindPlugin)) { - m_activeWindPlugin = m_availableWindPlugins[m_desiredWindPlugin]; + m_activeWindPlugin = m_availableWindPlugins[desiredWindPlugin]; - m_log.InfoFormat("[WIND] {0} plugin found, initializing.", m_desiredWindPlugin); + m_log.InfoFormat("[WIND] {0} plugin found, initializing.", desiredWindPlugin); if (windConfig != null) { m_activeWindPlugin.Initialise(); m_activeWindPlugin.WindConfig(m_scene, windConfig); } - } + } // if the plug-in wasn't found, default to no wind. if (m_activeWindPlugin == null) { - m_log.ErrorFormat("[WIND] Could not find specified wind plug-in: {0}", m_desiredWindPlugin); + m_log.ErrorFormat("[WIND] Could not find specified wind plug-in: {0}", desiredWindPlugin); m_log.ErrorFormat("[WIND] Defaulting to no wind."); } // This one puts an entry in the main help screen m_scene.AddCommand(this, String.Empty, "wind", "Usage: wind [value] - Get or Update Wind paramaters", null); - + // This one enables the ability to type just the base command without any parameters m_scene.AddCommand(this, "wind", "", "", HandleConsoleCommand); @@ -137,7 +127,7 @@ namespace OpenSim.Region.CoreModules { m_scene.AddCommand(this, String.Format("wind base wind_plugin {0}", windPlugin.Name), String.Format("{0} - {1}", windPlugin.Name, windPlugin.Description), "", HandleConsoleBaseCommand); m_scene.AddCommand(this, String.Format("wind base wind_update_rate"), "Change the wind update rate.", "", HandleConsoleBaseCommand); - + foreach (KeyValuePair kvp in windPlugin.WindParams()) { m_scene.AddCommand(this, String.Format("wind {0} {1}", windPlugin.Name, kvp.Key), String.Format("{0} : {1} - {2}", windPlugin.Name, kvp.Key, kvp.Value), "", HandleConsoleParamCommand); @@ -159,17 +149,11 @@ namespace OpenSim.Region.CoreModules m_ready = true; } - } - public void RegionLoaded(Scene scene) - { } - public void RemoveRegion(Scene scene) + public void PostInitialise() { - scene.EventManager.OnFrame -= WindUpdate; - scene.EventManager.OnMakeRootAgent -= OnAgentEnteredRegion; - scene.UnregisterModuleInterface(this); } public void Close() @@ -198,6 +182,11 @@ namespace OpenSim.Region.CoreModules get { return "WindModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs index 6bda1e9..285d36a 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapImageModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Drawing; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.Imaging; @@ -60,8 +59,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap public face[] trns; } - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MapImageModule : IMapImageGenerator, INonSharedRegionModule + public class MapImageModule : IMapImageGenerator, IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -130,38 +128,25 @@ namespace OpenSim.Region.CoreModules.World.WorldMap #endregion - #region INonSharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { + m_scene = scene; m_config = source; IConfig startupConfig = m_config.Configs["Startup"]; if (startupConfig.GetString("MapImageModule", "MapImageModule") != "MapImageModule") return; - } - public void AddRegion(Scene scene) - { - m_scene = scene; m_scene.RegisterModuleInterface(this); } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) + public void PostInitialise() { } - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } - public void Close() { } @@ -171,6 +156,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap get { return "MapImageModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion // TODO: unused: diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index dd33673..be46fa5 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -24,12 +24,9 @@ * (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.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -41,8 +38,7 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.CoreModules.World.WorldMap { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MapSearchModule : ISharedRegionModule + public class MapSearchModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -50,12 +46,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap Scene m_scene = null; // only need one for communication with GridService List m_scenes = new List(); - #region ISharedRegionModule Members - public void Initialise(IConfigSource source) - { - } - - public void AddRegion(Scene scene) + #region IRegionModule Members + public void Initialise(Scene scene, IConfigSource source) { if (m_scene == null) { @@ -66,22 +58,6 @@ namespace OpenSim.Region.CoreModules.World.WorldMap scene.EventManager.OnNewClient += OnNewClient; } - public Type ReplaceableInterface - { - get { return null; } - } - - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if(m_scenes.Contains(scene)) - m_scenes.Remove(scene); - scene.EventManager.OnNewClient -= OnNewClient; - } - public void PostInitialise() { } @@ -97,6 +73,11 @@ namespace OpenSim.Region.CoreModules.World.WorldMap get { return "MapSearchModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion private void OnNewClient(IClientAPI client) diff --git a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs index b0cefc3..4df9094 100644 --- a/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs +++ b/OpenSim/Region/DataSnapshot/DataSnapshotManager.cs @@ -33,7 +33,6 @@ using System.Net; using System.Reflection; using System.Xml; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -44,8 +43,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.DataSnapshot { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class DataSnapshotManager : ISharedRegionModule, IDataSnapshot + public class DataSnapshotManager : IRegionModule, IDataSnapshot { #region Class members //Information from config @@ -91,7 +89,7 @@ namespace OpenSim.Region.DataSnapshot #region IRegionModule - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { if (!m_configLoaded) { @@ -142,29 +140,24 @@ namespace OpenSim.Region.DataSnapshot return; } } - } - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void AddRegion(Scene scene) - { - if (m_enabled) - { - //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer - new DataRequestHandler(scene, this); + if (m_enabled) + { + //Hand it the first scene, assuming that all scenes have the same BaseHTTPServer + new DataRequestHandler(scene, this); - m_hostname = scene.RegionInfo.ExternalHostName; - m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); + m_hostname = scene.RegionInfo.ExternalHostName; + m_snapStore = new SnapshotStore(m_snapsDir, m_gridinfo, m_listener_port, m_hostname); - MakeEverythingStale(); + MakeEverythingStale(); - if (m_dataServices != "" && m_dataServices != "noservices") - NotifyDataServices(m_dataServices, "online"); + if (m_dataServices != "" && m_dataServices != "noservices") + NotifyDataServices(m_dataServices, "online"); + } + } + if (m_enabled) + { m_log.Info("[DATASNAPSHOT]: Scene added to module."); m_snapStore.AddScene(scene); @@ -198,25 +191,20 @@ namespace OpenSim.Region.DataSnapshot } else { - m_log.Info("[DATASNAPSHOT]: Data snapshot disabled, not adding scene to module (or anything else)."); + m_log.Warn("[DATASNAPSHOT]: Data snapshot disabled, not adding scene to module (or anything else)."); } } - public void RegionLoaded(Scene scene) + public void Close() { + if (m_enabled && m_dataServices != "" && m_dataServices != "noservices") + NotifyDataServices(m_dataServices, "offline"); } - public void RemoveRegion(Scene scene) - { - if (m_scenes.Contains(scene)) - m_scenes.Remove(scene); - m_snapStore.RemoveScene(scene); - } - public void Close() + public bool IsSharedModule { - if (m_enabled && m_dataServices != "" && m_dataServices != "noservices") - NotifyDataServices(m_dataServices, "offline"); + get { return true; } } public string Name @@ -226,6 +214,7 @@ namespace OpenSim.Region.DataSnapshot public void PostInitialise() { + } #endregion diff --git a/OpenSim/Region/Framework/Interfaces/ICloudModule.cs b/OpenSim/Region/Framework/Interfaces/ICloudModule.cs index 879114b..f8a5bad 100644 --- a/OpenSim/Region/Framework/Interfaces/ICloudModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ICloudModule.cs @@ -28,7 +28,7 @@ namespace OpenSim.Region.Framework.Interfaces { - public interface ICloudModule : INonSharedRegionModule + public interface ICloudModule : IRegionModule { /// /// Retrieves the cloud density at the given region coordinates diff --git a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs index bdad0b4..3a2c423 100644 --- a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces public int numLeft; } - public interface IEmailModule : ISharedRegionModule + public interface IEmailModule : IRegionModule { void SendEmail(UUID objectID, string address, string subject, string body); Email GetNextEmail(UUID objectID, string sender, string subject); diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index 347818c..890fa31 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public interface IEstateModule : INonSharedRegionModule + public interface IEstateModule : IRegionModule { uint GetRegionFlags(); bool IsManager(UUID avatarID); diff --git a/OpenSim/Region/Framework/Interfaces/ISunModule.cs b/OpenSim/Region/Framework/Interfaces/ISunModule.cs index 8231716..819ae11 100644 --- a/OpenSim/Region/Framework/Interfaces/ISunModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISunModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public interface ISunModule : INonSharedRegionModule + public interface ISunModule : IRegionModule { double GetSunParameter(string param); diff --git a/OpenSim/Region/Framework/Interfaces/IWindModule.cs b/OpenSim/Region/Framework/Interfaces/IWindModule.cs index 4a26a71..10ecc32 100644 --- a/OpenSim/Region/Framework/Interfaces/IWindModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IWindModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public interface IWindModule : INonSharedRegionModule + public interface IWindModule : IRegionModule { /// diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs index ec040db..cfe1278 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/IRCStackModule.cs @@ -25,11 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Net; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -37,23 +35,24 @@ using OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server; namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class IRCStackModule : INonSharedRegionModule + public class IRCStackModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IRCServer m_server; // private Scene m_scene; - private int portNo; - #region Implementation of ISharedRegionModule + #region Implementation of IRegionModule - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { if (null != source.Configs["IRCd"] && source.Configs["IRCd"].GetBoolean("Enabled",false)) { - portNo = source.Configs["IRCd"].GetInt("Port",6666); + int portNo = source.Configs["IRCd"].GetInt("Port",6666); +// m_scene = scene; + m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene); + m_server.OnNewIRCClient += m_server_OnNewIRCClient; } } @@ -69,20 +68,9 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView m_log.Info("[IRCd] Added user to Scene"); } - public void AddRegion(Scene scene) - { - if (portNo != null) - { - m_server = new IRCServer(IPAddress.Parse("0.0.0.0"), portNo, scene); - m_server.OnNewIRCClient += m_server_OnNewIRCClient; - } - } - public void RegionLoaded(Scene scene) + public void PostInitialise() { - } - public void RemoveRegion(Scene scene) - { } public void Close() @@ -95,9 +83,9 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView get { return "IRCClientStackModule"; } } - public Type ReplaceableInterface + public bool IsSharedModule { - get { return null; } + get { return false; } } #endregion diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 23ae307..b04b076 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -38,7 +38,6 @@ using System.Collections.Generic; using System.Reflection; using OpenMetaverse; using log4net; -using Mono.Addins; using Nini.Config; using Nwc.XmlRpc; using OpenSim.Framework; @@ -54,8 +53,7 @@ using System.Text.RegularExpressions; namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class FreeSwitchVoiceModule : ISharedRegionModule, IVoiceModule + public class FreeSwitchVoiceModule : IRegionModule, IVoiceModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -110,8 +108,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice private IConfig m_config; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { + m_scene = scene; m_config = config.Configs["FreeSwitchVoice"]; if (null == m_config) @@ -225,21 +224,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return; } } - } - public void AddRegion(Scene scene) - { - m_scene = scene; - if (m_pluginEnabled) + if (m_pluginEnabled) { // we need to capture scene in an anonymous method // here as we need it later in the callbacks scene.EventManager.OnRegisterCaps += delegate(UUID agentID, Caps caps) - { - OnRegisterCaps(scene, agentID, caps); - }; - - + { + OnRegisterCaps(scene, agentID, caps); + }; + + try { @@ -259,53 +254,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); } } - + } + } + + public void PostInitialise() + { if (m_pluginEnabled) { m_log.Info("[FreeSwitchVoice] registering IVoiceModule with the scene"); - + // register the voice interface for this module, so the script engine can call us m_scene.RegisterModuleInterface(this); } } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (UseProxy) - { - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/", m_freeSwitchAPIPrefix)); - } - else - { - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix)); - - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix)); - - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix)); - - MainServer.Instance.RemoveHTTPHandler("", String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix)); - } - scene.EventManager.OnRegisterCaps -= delegate(UUID agentID, Caps caps) - { - OnRegisterCaps(scene, agentID, caps); - }; - scene.UnregisterModuleInterface(this); - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void PostInitialise() - { - } - public void Close() { } @@ -314,6 +277,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice { get { return "FreeSwitchVoiceModule"; } } + + public bool IsSharedModule + { + get { return true; } + } // // implementation of IVoiceModule, called by osSetParcelSIPAddress script function diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs index 6769d59..3d1c346 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementModule.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * @@ -38,7 +38,6 @@ using System.Threading; using OpenMetaverse; -using Mono.Addins; using Nini.Config; using OpenSim; @@ -51,8 +50,7 @@ using log4net; namespace OpenSim.Region.OptionalModules.ContentManagement { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class ContentManagementModule : ISharedRegionModule + public class ContentManagementModule : IRegionModule { #region Static Fields @@ -62,20 +60,22 @@ namespace OpenSim.Region.OptionalModules.ContentManagement #region Fields - private bool initialised = false; - private CMController m_control = null; - private bool m_enabled = false; - private CMModel m_model = null; - private bool m_posted = false; - private CMView m_view = null; - private string databaseDir = "./"; - private string database = "FileSystemDatabase"; - private int channel = 345; + bool initialised = false; + CMController m_control = null; + bool m_enabled = false; + CMModel m_model = null; + bool m_posted = false; + CMView m_view = null; #endregion Fields #region Public Properties + public bool IsSharedModule + { + get { return true; } + } + public string Name { get { return "ContentManagementModule"; } @@ -89,8 +89,11 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { } - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { + string databaseDir = "./"; + string database = "FileSystemDatabase"; + int channel = 345; try { if (source.Configs["CMS"] == null) @@ -112,15 +115,13 @@ namespace OpenSim.Region.OptionalModules.ContentManagement m_log.ErrorFormat("[Content Management]: Exception thrown while reading parameters from configuration file. Message: " + e); m_enabled = false; } - } - public void AddRegion(Scene scene) - { if (!m_enabled) { m_log.Info("[Content Management]: Content Management System is not Enabled."); return; } + lock (this) { if (!initialised) //only init once @@ -141,18 +142,6 @@ namespace OpenSim.Region.OptionalModules.ContentManagement } } } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } public void PostInitialise() { diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs index f24bcdc..4521f8e 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/MRMModule.cs @@ -38,7 +38,6 @@ using System.Security.Policy; using System.Text; using log4net; using Microsoft.CSharp; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenSim.Framework; @@ -47,8 +46,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Scripting.Minimodule { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class MRMModule : INonSharedRegionModule, IMRMModule + public class MRMModule : IRegionModule, IMRMModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; @@ -64,14 +62,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule private IConfig m_config; - private bool m_hidden = true; - public void RegisterExtension(T instance) { m_extensions[typeof (T)] = instance; } - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { if (source.Configs["MRM"] != null) { @@ -80,10 +76,19 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule if (source.Configs["MRM"].GetBoolean("Enabled", false)) { m_log.Info("[MRM] Enabling MRM Module"); - + m_scene = scene; + // when hidden, we don't listen for client initiated script events // only making the MRM engine available for region modules - m_hidden = source.Configs["MRM"].GetBoolean("Hidden", false); + if (!source.Configs["MRM"].GetBoolean("Hidden", false)) + { + scene.EventManager.OnRezScript += EventManager_OnRezScript; + scene.EventManager.OnStopScript += EventManager_OnStopScript; + } + + scene.EventManager.OnFrame += EventManager_OnFrame; + + scene.RegisterModuleInterface(this); } else { @@ -96,39 +101,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule } } - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { - m_scene = scene; - if (!m_hidden) - { - scene.EventManager.OnRezScript += EventManager_OnRezScript; - scene.EventManager.OnStopScript += EventManager_OnStopScript; - } - scene.EventManager.OnFrame += EventManager_OnFrame; - - scene.RegisterModuleInterface(this); - } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - if (!m_hidden) - { - scene.EventManager.OnRezScript -= EventManager_OnRezScript; - scene.EventManager.OnStopScript -= EventManager_OnStopScript; - } - scene.EventManager.OnFrame -= EventManager_OnFrame; - - scene.UnregisterModuleInterface(this); - } - void EventManager_OnStopScript(uint localID, UUID itemID) { if (m_scripts.ContainsKey(itemID)) @@ -330,6 +302,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule mmb.InitMiniModule(world, host, itemID); } + public void PostInitialise() + { + + } + public void Close() { foreach (KeyValuePair pair in m_scripts) @@ -343,6 +320,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule get { return "MiniRegionModule"; } } + public bool IsSharedModule + { + get { return false; } + } + /// /// Stolen from ScriptEngine Common /// diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index 999756a..c653e98 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -100,10 +100,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady if (!m_enabled) return; - scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; - scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; + m_scene.EventManager.OnEmptyScriptCompileQueue -= OnEmptyScriptCompileQueue; + m_scene.EventManager.OnOarFileLoaded -= OnOarFileLoaded; - scene = null; + m_scene = null; } public void Close() diff --git a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs index df01938..44c9ada 100644 --- a/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/ScriptModuleComms/ScriptModuleCommsModule.cs @@ -58,7 +58,6 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms public void RemoveRegion(Scene scene) { - scene.UnregisterModuleInterface(this); } public void RegionLoaded(Scene scene) diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs index f2a0e53..d18ac0a 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcGridRouterModule.cs @@ -30,7 +30,6 @@ using System.Collections.Generic; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -50,8 +49,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule public string uri; } - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class XmlRpcGridRouter : INonSharedRegionModule, IXmlRpcRouter + public class XmlRpcGridRouter : IRegionModule, IXmlRpcRouter { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -61,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule private bool m_Enabled = false; private string m_ServerURI = String.Empty; - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { IConfig startupConfig = config.Configs["Startup"]; if (startupConfig == null) @@ -77,26 +75,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule return; } + scene.RegisterModuleInterface(this); m_Enabled = true; } } - public void AddRegion(Scene scene) + public void PostInitialise() { - scene.RegisterModuleInterface(this); - } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } - - public Type ReplaceableInterface - { - get { return null; } } public void Close() @@ -108,6 +93,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcGridRouterModule get { return "XmlRpcGridRouterModule"; } } + public bool IsSharedModule + { + get { return false; } + } + public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { if (!m_Channels.ContainsKey(itemID)) diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index 4d39345..32659c8 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -29,7 +29,6 @@ using System; using System.Reflection; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; @@ -40,12 +39,11 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class XmlRpcRouter : INonSharedRegionModule, IXmlRpcRouter + public class XmlRpcRouter : IRegionModule, IXmlRpcRouter { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_enabled = false; - public void Initialise(IConfigSource config) + + public void Initialise(Scene scene, IConfigSource config) { IConfig startupConfig = config.Configs["Startup"]; if (startupConfig == null) @@ -54,25 +52,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule if (startupConfig.GetString("XmlRpcRouterModule", "XmlRpcRouterModule") == "XmlRpcRouterModule") { - m_enabled = true; + scene.RegisterModuleInterface(this); } } - public void AddRegion(Scene scene) - { - scene.RegisterModuleInterface(this); - } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } - public Type ReplaceableInterface + public void PostInitialise() { - get { return null; } } public void Close() @@ -84,6 +69,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule get { return "XmlRpcRouterModule"; } } + public bool IsSharedModule + { + get { return false; } + } + public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] {uri}); diff --git a/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs b/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs index 801f1f8..97fa63c 100644 --- a/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/ServiceConnectorsIn/Freeswitch/FreeswitchServiceInConnectorModule.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Freeswitch private IConfigSource m_Config; bool m_Registered = false; - #region ISharedRegionModule interface + #region IRegionModule interface public void Initialise(IConfigSource config) { diff --git a/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs b/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs index fa5878d..3490a8b 100644 --- a/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs +++ b/OpenSim/Region/OptionalModules/SvnSerialiser/SvnBackupModule.cs @@ -31,7 +31,6 @@ using System.IO; using System.Reflection; using System.Timers; using log4net; -using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.World.Serialiser; @@ -43,8 +42,7 @@ using Slash = System.IO.Path; namespace OpenSim.Region.Modules.SvnSerialiser { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SvnBackupModule : ISharedRegionModule + public class SvnBackupModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -202,9 +200,9 @@ namespace OpenSim.Region.Modules.SvnSerialiser #endregion - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { m_scenes = new List(); m_timer = new Timer(); @@ -227,10 +225,7 @@ namespace OpenSim.Region.Modules.SvnSerialiser catch (Exception) { } - } - public void AddRegion(Scene scene) - { lock (m_scenes) { m_scenes.Add(scene); @@ -241,18 +236,6 @@ namespace OpenSim.Region.Modules.SvnSerialiser scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; } } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - } - - public Type ReplaceableInterface - { - get { return null; } - } public void PostInitialise() { @@ -294,6 +277,11 @@ namespace OpenSim.Region.Modules.SvnSerialiser get { return "SvnBackupModule"; } } + public bool IsSharedModule + { + get { return true; } + } + #endregion private void EventManager_OnPluginConsole(string[] args) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs index 521d01a..ac39a53 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs @@ -25,11 +25,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; using System.Collections.Generic; using System.Threading; using OpenMetaverse; -using Mono.Addins; using Nini.Config; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -39,8 +37,7 @@ using Timer=System.Timers.Timer; namespace OpenSim.Region.OptionalModules.World.NPC { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class NPCModule : ISharedRegionModule, INPCModule + public class NPCModule : IRegionModule, INPCModule { // private const bool m_enabled = false; @@ -137,13 +134,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC } - public void Initialise(IConfigSource source) + public void Initialise(Scene scene, IConfigSource source) { m_createMutex = new Mutex(false); m_timer = new Timer(500); m_timer.Elapsed += m_timer_Elapsed; m_timer.Start(); + + scene.RegisterModuleInterface(this); } void m_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) @@ -174,19 +173,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC } } - public void AddRegion(Scene scene) - { - scene.RegisterModuleInterface(this); - } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - } - public void PostInitialise() { } @@ -200,9 +186,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC get { return "NPCModule"; } } - public Type ReplaceableInterface + public bool IsSharedModule { - get { return null; } - } + get { return true; } + } } } diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index b59d07a..e3fbb6e 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -31,7 +31,6 @@ using System.Reflection; using System.Timers; using OpenMetaverse; using log4net; -using Mono.Addins; using Nini.Config; using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.InterfaceCommander; @@ -47,8 +46,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator /// /// Version 2.02 - Still hacky /// - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class TreePopulatorModule : INonSharedRegionModule, ICommandableModule, IVegetationModule + public class TreePopulatorModule : IRegionModule, ICommandableModule, IVegetationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private readonly Commander m_commander = new Commander("tree"); @@ -170,10 +168,15 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator #endregion - #region ISharedRegionModule Members + #region IRegionModule Members - public void Initialise(IConfigSource config) + public void Initialise(Scene scene, IConfigSource config) { + + m_scene = scene; + m_scene.RegisterModuleInterface(this); + m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; + // ini file settings try { @@ -193,18 +196,12 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator m_log.Debug("[TREES]: ini failure for update_rate - using default"); } - m_log.Debug("[TREES]: Initialised tree module"); - } - - public void AddRegion(Scene scene) - { - m_scene = scene; - m_scene.RegisterModuleInterface(this); - m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; InstallCommands(); + + m_log.Debug("[TREES]: Initialised tree module"); } - public void RegionLoaded(Scene scene) + public void PostInitialise() { ReloadCopse(); if (m_copse.Count > 0) @@ -214,17 +211,6 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator activeizeTreeze(true); } - public void RemoveRegion(Scene scene) - { - scene.UnregisterModuleInterface(this); - scene.EventManager.OnPluginConsole -= EventManager_OnPluginConsole; - } - - public Type ReplaceableInterface - { - get { return null; } - } - public void Close() { } @@ -234,6 +220,11 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator get { return "TreePopulatorModule"; } } + public bool IsSharedModule + { + get { return false; } + } + #endregion //-------------------------------------------------------------- diff --git a/OpenSim/Region/UserStatistics/WebStatsModule.cs b/OpenSim/Region/UserStatistics/WebStatsModule.cs index 9b53d06..a03cc4c 100644 --- a/OpenSim/Region/UserStatistics/WebStatsModule.cs +++ b/OpenSim/Region/UserStatistics/WebStatsModule.cs @@ -34,7 +34,6 @@ using System.Reflection; using System.Text; using System.Threading; using log4net; -using Mono.Addins; using Nini.Config; using OpenMetaverse; using OpenMetaverse.StructuredData; @@ -53,8 +52,7 @@ using OSDMap = OpenMetaverse.StructuredData.OSDMap; namespace OpenSim.Region.UserStatistics { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class WebStatsModule : ISharedRegionModule + public class WebStatsModule : IRegionModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -72,7 +70,7 @@ namespace OpenSim.Region.UserStatistics private string m_loglines = String.Empty; private volatile int lastHit = 12000; - public virtual void Initialise(IConfigSource config) + public virtual void Initialise(Scene scene, IConfigSource config) { IConfig cnfg; try @@ -84,17 +82,11 @@ namespace OpenSim.Region.UserStatistics { enabled = false; } - } - - public Type ReplaceableInterface - { - get { return null; } - } - - public void AddRegion(Scene scene) - { + if (!enabled) + { return; + } lock (m_scene) { @@ -138,7 +130,7 @@ namespace OpenSim.Region.UserStatistics MainServer.Instance.AddHTTPHandler("/SStats/", HandleStatsRequest); MainServer.Instance.AddHTTPHandler("/CAPS/VS/", HandleUnknownCAPSRequest); } - + m_scene.Add(scene); if (m_simstatsCounters.ContainsKey(scene.RegionInfo.RegionID)) m_simstatsCounters.Remove(scene.RegionInfo.RegionID); @@ -148,14 +140,6 @@ namespace OpenSim.Region.UserStatistics } } - public void RegionLoaded(Scene scene) - { - } - - public void RemoveRegion(Scene scene) - { - } - public void ReceiveClassicSimStatsPacket(SimStats stats) { if (!enabled) @@ -324,6 +308,11 @@ namespace OpenSim.Region.UserStatistics get { return "ViewerStatsModule"; } } + public bool IsSharedModule + { + get { return true; } + } + public void OnRegisterCaps(UUID agentID, Caps caps) { m_log.DebugFormat("[VC]: OnRegisterCaps: agentID {0} caps {1}", agentID, caps); diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index 20f2bca..b13e8dd 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -161,11 +161,10 @@ namespace OpenSim.Tests.Common.Setup capsModule.Initialise(new IniConfigSource()); testScene.AddRegionModule(capsModule.Name, capsModule); capsModule.AddRegion(testScene); - - INonSharedRegionModule godsModule = new GodsModule(); - godsModule.Initialise(new IniConfigSource()); - testScene.AddRegionModule(godsModule.Name, godsModule); - godsModule.AddRegion(testScene); + + IRegionModule godsModule = new GodsModule(); + godsModule.Initialise(testScene, new IniConfigSource()); + testScene.AddModule(godsModule.Name, godsModule); realServices = realServices.ToLower(); // IConfigSource config = new IniConfigSource(); -- cgit v1.1 From 44c86cedcf8ddba1ca4c9e3ff4f1e39ceb59be06 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Jan 2010 07:42:45 +0000 Subject: Resolve one more conflict I overlooked --- .../CoreModules/Scripting/WorldComm/WorldCommModule.cs | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs index 93aa88c..60df2e7 100644 --- a/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs @@ -120,20 +120,6 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm if (maxlisteners < 1) maxlisteners = int.MaxValue; if (maxhandles < 1) maxhandles = int.MaxValue; -<<<<<<< HEAD:OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs - m_listenerManager = new ListenerManager(maxlisteners, maxhandles); - m_pendingQ = new Queue(); - m_pending = Queue.Synchronized(m_pendingQ); - } - - public void PostInitialise() - { - } - - public void AddRegion(Scene scene) - { -======= ->>>>>>> ec3c31e... Updates all IRegionModules to the new style region modules.:OpenSim/Region/CoreModules/Scripting/WorldComm/WorldCommModule.cs m_scene = scene; m_scene.RegisterModuleInterface(this); m_listenerManager = new ListenerManager(maxlisteners, maxhandles); -- cgit v1.1 From 9e37d246240db077fe7a4e1389f5220d72d6542c Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Jan 2010 11:47:45 +0000 Subject: Prevent empty ObjectProperties packets being sent --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 64e45d0..1496f5c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3885,6 +3885,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_propertiesPacketTimer.Stop(); + if (m_propertiesBlocks.Count == 0) + return; + proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[m_propertiesBlocks.Count]; int index = 0; -- cgit v1.1 From 0c5850237ec68158743117933d2ddd6e7df62c28 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Jan 2010 16:50:00 +0000 Subject: Small fix for a spurious exception --- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index e4296ef..1cff0eb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -76,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (EntityBase e in m_presence.Scene.Entities) { - if (e is SceneObjectGroup) + if (e != null && e is SceneObjectGroup) m_pendingObjects.Enqueue((SceneObjectGroup)e); } } -- cgit v1.1 From 6478617c932e87bf091266dba2db4d73fcdd046f Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 2 Feb 2010 03:49:00 +0000 Subject: Revert "improve locking of m_items in SceneObjectPartInventory" This reverts commit 968b9e160d70568fbdea5b190d1386e9431316e3. --- .../Framework/Scenes/SceneObjectPartInventory.cs | 218 ++++++++------------- 1 file changed, 85 insertions(+), 133 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 87c1a95..b37e1a2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -44,8 +44,6 @@ namespace OpenSim.Region.Framework.Scenes { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); - private string m_inventoryFileName = String.Empty; private int m_inventoryFileNameSerial = 0; @@ -272,12 +270,8 @@ namespace OpenSim.Region.Framework.Scenes if (stateSource == 1 && // Prim crossing m_part.ParentGroup.Scene.m_trustBinaries) { - lock (m_items) - { - m_items[item.ItemID].PermsMask = 0; - m_items[item.ItemID].PermsGranter = UUID.Zero; - } - + m_items[item.ItemID].PermsMask = 0; + m_items[item.ItemID].PermsGranter = UUID.Zero; m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); m_part.ParentGroup.AddActiveScriptCount(1); @@ -285,38 +279,33 @@ namespace OpenSim.Region.Framework.Scenes return; } - m_part.ParentGroup.Scene.AssetService.Get( - item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset) - { - if (null == asset) - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", - item.Name, item.ItemID, m_part.AbsolutePosition, - m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); - } - else - { - if (m_part.ParentGroup.m_savedScriptState != null) - RestoreSavedScriptState(item.OldItemID, item.ItemID); - - lock (m_items) - { - m_items[item.ItemID].PermsMask = 0; - m_items[item.ItemID].PermsGranter = UUID.Zero; - } - - string script = Utils.BytesToString(asset.Data); - m_part.ParentGroup.Scene.EventManager.TriggerRezScript( - m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); - m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); - } - } - ); + m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset) + { + if (null == asset) + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", + item.Name, item.ItemID, m_part.AbsolutePosition, + m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); + } + else + { + if (m_part.ParentGroup.m_savedScriptState != null) + RestoreSavedScriptState(item.OldItemID, item.ItemID); + m_items[item.ItemID].PermsMask = 0; + m_items[item.ItemID].PermsGranter = UUID.Zero; + string script = Utils.BytesToString(asset.Data); + m_part.ParentGroup.Scene.EventManager.TriggerRezScript( + m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); + m_part.ParentGroup.AddActiveScriptCount(1); + m_part.ScheduleFullUpdate(); + } + }); } - } + } + + static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); private void RestoreSavedScriptState(UUID oldID, UUID newID) { @@ -408,15 +397,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) { - bool scriptPresent = false; - - lock (m_items) - { - if (m_items.ContainsKey(itemId)) - scriptPresent = true; - } - - if (scriptPresent) + if (m_items.ContainsKey(itemId)) { if (!sceneObjectBeingDeleted) m_part.RemoveScriptEvents(itemId); @@ -488,13 +469,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) { - List il; - - lock (m_items) - { - il = new List(m_items.Values); - } - + List il = new List(m_items.Values); foreach (TaskInventoryItem i in il) { if (i.Name == item.Name) @@ -576,9 +551,7 @@ namespace OpenSim.Region.Framework.Scenes public TaskInventoryItem GetInventoryItem(UUID itemId) { TaskInventoryItem item; - - lock (m_items) - m_items.TryGetValue(itemId, out item); + m_items.TryGetValue(itemId, out item); return item; } @@ -904,61 +877,54 @@ namespace OpenSim.Region.Framework.Scenes { uint mask=0x7fffffff; - lock (m_items) + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) + if (item.InvType != (int)InventoryType.Object) { - if (item.InvType != (int)InventoryType.Object) - { - if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) - mask &= ~((uint)PermissionMask.Copy >> 13); - if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) - mask &= ~((uint)PermissionMask.Transfer >> 13); - if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) - mask &= ~((uint)PermissionMask.Modify >> 13); - } - else - { - if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) - mask &= ~((uint)PermissionMask.Copy >> 13); - if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) - mask &= ~((uint)PermissionMask.Transfer >> 13); - if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) - mask &= ~((uint)PermissionMask.Modify >> 13); - } - - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) - mask &= ~(uint)PermissionMask.Copy; - if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) - mask &= ~(uint)PermissionMask.Transfer; - if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) - mask &= ~(uint)PermissionMask.Modify; + if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) + mask &= ~((uint)PermissionMask.Copy >> 13); + if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) + mask &= ~((uint)PermissionMask.Transfer >> 13); + if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) + mask &= ~((uint)PermissionMask.Modify >> 13); + } + else + { + if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) + mask &= ~((uint)PermissionMask.Copy >> 13); + if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) + mask &= ~((uint)PermissionMask.Transfer >> 13); + if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) + mask &= ~((uint)PermissionMask.Modify >> 13); } + + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + mask &= ~(uint)PermissionMask.Copy; + if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) + mask &= ~(uint)PermissionMask.Transfer; + if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) + mask &= ~(uint)PermissionMask.Modify; } - return mask; } public void ApplyNextOwnerPermissions() { - lock (m_items) + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) { - if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) - { - if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Copy; - if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; - if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) - item.CurrentPermissions &= ~(uint)PermissionMask.Modify; - item.CurrentPermissions |= 8; - } - item.CurrentPermissions &= item.NextPermissions; - item.BasePermissions &= item.NextPermissions; - item.EveryonePermissions &= item.NextPermissions; + if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) + item.CurrentPermissions &= ~(uint)PermissionMask.Copy; + if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) + item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; + if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) + item.CurrentPermissions &= ~(uint)PermissionMask.Modify; + item.CurrentPermissions |= 8; } + item.CurrentPermissions &= item.NextPermissions; + item.BasePermissions &= item.NextPermissions; + item.EveryonePermissions &= item.NextPermissions; } m_part.TriggerScriptChangedEvent(Changed.OWNER); @@ -966,29 +932,22 @@ namespace OpenSim.Region.Framework.Scenes public void ApplyGodPermissions(uint perms) { - lock (m_items) + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) - { - item.CurrentPermissions = perms; - item.BasePermissions = perms; - } + item.CurrentPermissions = perms; + item.BasePermissions = perms; } } public bool ContainsScripts() { - lock (m_items) + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) + if (item.InvType == (int)InventoryType.LSL) { - if (item.InvType == (int)InventoryType.LSL) - { - return true; - } + return true; } } - return false; } @@ -996,11 +955,8 @@ namespace OpenSim.Region.Framework.Scenes { List ret = new List(); - lock (m_items) - { - foreach (TaskInventoryItem item in m_items.Values) - ret.Add(item.ItemID); - } + foreach (TaskInventoryItem item in m_items.Values) + ret.Add(item.ItemID); return ret; } @@ -1013,30 +969,26 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) // No engine at all return ret; - lock (m_items) + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) + if (item.InvType == (int)InventoryType.LSL) { - if (item.InvType == (int)InventoryType.LSL) + foreach (IScriptModule e in engines) { - foreach (IScriptModule e in engines) + if (e != null) { - if (e != null) + string n = e.GetXMLState(item.ItemID); + if (n != String.Empty) { - string n = e.GetXMLState(item.ItemID); - if (n != String.Empty) - { - if (!ret.ContainsKey(item.ItemID)) - ret[item.ItemID] = n; - break; - } + if (!ret.ContainsKey(item.ItemID)) + ret[item.ItemID] = n; + break; } } } } } - return ret; } } -} \ No newline at end of file +} -- cgit v1.1 From 8c2061029331e323b5c1c0414bbda417cb6c4674 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 2 Feb 2010 13:28:42 -0500 Subject: AngMotor update 1 --- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 203 ++++++++++++++-------- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 19 +- 2 files changed, 143 insertions(+), 79 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index 14d5caa..c03e381 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -108,13 +108,14 @@ namespace OpenSim.Region.Physics.OdePlugin //Angular properties private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor - private int m_angularMotorApply = 0; // application frame counter - private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity - private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate - private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate - private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate + + private float m_angularMotorTimescale = 0; // motor angular Attack rate set by LSL + private float m_angularMotorDecayTimescale = 0; // motor angular Decay rate set by LSL + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular Friction set by LSL + + private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor +// private Vector3 m_angObjectVel = Vector3.Zero; // current body angular velocity private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body - // private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body //Deflection properties // private float m_angularDeflectionEfficiency = 0; @@ -227,7 +228,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; case Vehicle.ANGULAR_MOTOR_DIRECTION: m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - m_angularMotorApply = 10; + UpdateAngDecay(); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); @@ -260,7 +261,7 @@ namespace OpenSim.Region.Physics.OdePlugin if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; - m_angularMotorApply = 10; + UpdateAngDecay(); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); @@ -310,6 +311,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorTimescale = 1000; m_linearMotorDecayTimescale = 120; m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; m_angularMotorTimescale = 1000; m_angularMotorDecayTimescale = 120; m_VhoverHeight = 0; @@ -336,6 +338,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorTimescale = 1; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; m_angularMotorTimescale = 1; m_angularMotorDecayTimescale = 0.8f; m_VhoverHeight = 0; @@ -363,6 +366,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorTimescale = 5; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; m_angularMotorTimescale = 4; m_angularMotorDecayTimescale = 4; m_VhoverHeight = 0; @@ -391,6 +395,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorTimescale = 2; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; m_angularMotorTimescale = 4; m_angularMotorDecayTimescale = 4; m_VhoverHeight = 0; @@ -417,6 +422,7 @@ namespace OpenSim.Region.Physics.OdePlugin m_linearMotorTimescale = 5; m_linearMotorDecayTimescale = 60; m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; m_angularMotorTimescale = 6; m_angularMotorDecayTimescale = 10; m_VhoverHeight = 5; @@ -468,8 +474,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_lLinObjectVel = Vector3.Zero; m_wLinObjectVel = Vector3.Zero; m_angularMotorDirection = Vector3.Zero; - m_angularMotorVelocity = Vector3.Zero; - m_lastAngularVelocity = Vector3.Zero; + m_lastAngularVelocity = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; } private void UpdateLinDecay() @@ -611,54 +617,62 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); //if(frcount == 0) Console.WriteLine("Grav {0}", grav); } // end MoveLinear() + + private void UpdateAngDecay() + { + if (Math.Abs(m_angularMotorDirection.X) > Math.Abs(m_angularMotorDVel.X)) m_angularMotorDVel.X = m_angularMotorDirection.X; + if (Math.Abs(m_angularMotorDirection.Y) > Math.Abs(m_angularMotorDVel.Y)) m_angularMotorDVel.Y = m_angularMotorDirection.Y; + if (Math.Abs(m_angularMotorDirection.Z) > Math.Abs(m_angularMotorDVel.Z)) m_angularMotorDVel.Z = m_angularMotorDirection.Z; + } // else let the motor decay on its own private void MoveAngular(float pTimestep) { /* - private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor - private int m_angularMotorApply = 0; // application frame counter - private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down) - private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate - private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate - private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate - private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + + private float m_angularMotorTimescale = 0; // motor angular Attack rate set by LSL + private float m_angularMotorDecayTimescale = 0; // motor angular Decay rate set by LSL + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular Friction set by LSL + + private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor + private Vector3 m_angObjectVel = Vector3.Zero; // what was last applied to body */ //if(frcount == 0) Console.WriteLine("MoveAngular "); +//#### // Get what the body is doing, this includes 'external' influences - d.Vector3 angularVelocity = d.BodyGetAngularVel(Body); - // Vector3 angularVelocity = Vector3.Zero; + d.Vector3 angularObjectVel = d.BodyGetAngularVel(Body); + Vector3 angObjectVel = new Vector3(angularObjectVel.X, angularObjectVel.Y, angularObjectVel.Z); +//if(frcount == 0) Console.WriteLine("V0 = {0}", angObjectVel); +// Vector3 FrAaccel = m_lastAngularVelocity - angObjectVel; +// Vector3 initavel = angObjectVel; + // Decay Angular Motor + if (m_angularMotorDecayTimescale < 300.0f) + { + float decayfactor = m_angularMotorDecayTimescale/pTimestep; + Vector3 decayAmount = (m_angularMotorDVel/decayfactor); + m_angularMotorDVel -= decayAmount; - if (m_angularMotorApply > 0) - { - // ramp up to new value - // current velocity += error / ( time to get there / step interval ) - // requested speed - last motor speed - m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep); - m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep); - m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep); - - m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected - // velocity may still be acheived. - } - else - { - // no motor recently applied, keep the body velocity - /* m_angularMotorVelocity.X = angularVelocity.X; - m_angularMotorVelocity.Y = angularVelocity.Y; - m_angularMotorVelocity.Z = angularVelocity.Z; */ - - // and decay the velocity - m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep); - } // end motor section - + if (m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_angularMotorDVel = Vector3.Zero; + } + else + { + if (Math.Abs(m_angularMotorDVel.X) < Math.Abs(angObjectVel.X)) angObjectVel.X = m_angularMotorDVel.X; + if (Math.Abs(m_angularMotorDVel.Y) < Math.Abs(angObjectVel.Y)) angObjectVel.Y = m_angularMotorDVel.Y; + if (Math.Abs(m_angularMotorDVel.Z) < Math.Abs(angObjectVel.Z)) angObjectVel.Z = m_angularMotorDVel.Z; + } + } // end decay angular motor +//if(frcount == 0) Console.WriteLine("MotorDvel {0} Obj {1}", m_angularMotorDVel, angObjectVel); +//if(frcount == 0) Console.WriteLine("VA = {0}", angObjectVel); // Vertical attractor section Vector3 vertattr = Vector3.Zero; if(m_verticalAttractionTimescale < 300) { - float VAservo = 0.0167f / (m_verticalAttractionTimescale * pTimestep); + float VAservo = 1.0f / (m_verticalAttractionTimescale * pTimestep); // get present body rotation d.Quaternion rot = d.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); @@ -670,38 +684,88 @@ namespace OpenSim.Region.Physics.OdePlugin // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. + if (verterr.Z < 0.0f) - { + { // Defelction from vertical exceeds 90-degrees. This method will ensure stable return to + // vertical, BUT for some reason a z-rotation is imparted to the object. TBI. +//Console.WriteLine("InvertFlip"); verterr.X = 2.0f - verterr.X; verterr.Y = 2.0f - verterr.Y; } - // Error is 0 (no error) to +/- 2 (max error) - // scale it by VAservo - verterr = verterr * VAservo; + verterr *= 0.5f; + // verterror is 0 (no error) to +/- 1 (max error at 180-deg tilt) + + if ((!angObjectVel.ApproxEquals(Vector3.Zero, 0.001f)) || (verterr.Z < 0.49f)) + { +//if(frcount == 0) + // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so + // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. + vertattr.X = verterr.Y; + vertattr.Y = - verterr.X; + vertattr.Z = 0f; //if(frcount == 0) Console.WriteLine("VAerr=" + verterr); - - // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so - // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. - vertattr.X = verterr.Y; - vertattr.Y = - verterr.X; - vertattr.Z = 0f; - - // scaling appears better usingsquare-law - float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency); - vertattr.X += bounce * angularVelocity.X; - vertattr.Y += bounce * angularVelocity.Y; - + + // scaling appears better usingsquare-law + float damped = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; + float bounce = 1.0f - damped; + // 0 = crit damp, 1 = bouncy + float oavz = angObjectVel.Z; // retain z velocity + angObjectVel = (angObjectVel + (vertattr * VAservo * 0.0333f)) * bounce; // The time-scaled correction, which sums, therefore is bouncy + angObjectVel = angObjectVel + (vertattr * VAservo * 0.0667f * damped); // damped, good @ < 90. + angObjectVel.Z = oavz; +//if(frcount == 0) Console.WriteLine("VA+"); +//Console.WriteLine("VAttr {0} OAvel {1}", vertattr, angObjectVel); + } + else + { + // else error is very small + angObjectVel.X = 0f; + angObjectVel.Y = 0f; +//if(frcount == 0) Console.WriteLine("VA0"); + } } // else vertical attractor is off +//if(frcount == 0) Console.WriteLine("V1 = {0}", angObjectVel); + + if ( (! m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! angObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) + { // if motor or object have motion + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + + if (m_angularMotorTimescale < 300.0f) + { + Vector3 attack_error = m_angularMotorDVel - angObjectVel; + float angfactor = m_angularMotorTimescale/pTimestep; + Vector3 attackAmount = (attack_error/angfactor); + angObjectVel += attackAmount; +//if(frcount == 0) Console.WriteLine("Accel {0} Attk {1}",FrAaccel, attackAmount); +//if(frcount == 0) Console.WriteLine("V2+= {0}", angObjectVel); + } + + if (m_angularFrictionTimescale.X < 300.0f) + { + float fricfactor = m_angularFrictionTimescale.X / pTimestep; + angObjectVel.X -= angObjectVel.X / fricfactor; + } + if (m_angularFrictionTimescale.Y < 300.0f) + { + float fricfactor = m_angularFrictionTimescale.Y / pTimestep; + angObjectVel.Y -= angObjectVel.Y / fricfactor; + } + if (m_angularFrictionTimescale.Z < 300.0f) + { + float fricfactor = m_angularFrictionTimescale.Z / pTimestep; + angObjectVel.Z -= angObjectVel.Z / fricfactor; + Console.WriteLine("z fric"); + } + } // else no signif. motion - // m_lastVertAttractor = vertattr; - +//if(frcount == 0) Console.WriteLine("Dmotor {0} Obj {1}", m_angularMotorDVel, angObjectVel); // Bank section tba // Deflection section tba +//if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); - // Sum velocities - m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection - - if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f)) + m_lastAngularVelocity = angObjectVel; +/* + if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.0001f)) { if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); } @@ -709,13 +773,12 @@ namespace OpenSim.Region.Physics.OdePlugin { m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. } - - // apply friction - Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); - m_lastAngularVelocity -= m_lastAngularVelocity * decayamount; - + */ // Apply to the body +// Vector3 aInc = m_lastAngularVelocity - initavel; +//if(frcount == 0) Console.WriteLine("Inc {0}", aInc); d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); +//if(frcount == 0) Console.WriteLine("V4 = {0}", m_lastAngularVelocity); } //end MoveAngular } diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 29a3dd9..8502aef 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -2593,14 +2593,14 @@ Console.WriteLine(" JointCreateFixed"); { get { - Vector3 pv = Vector3.Zero; +/* Vector3 pv = Vector3.Zero; if (_zeroFlag) return pv; m_lastUpdateSent = false; if (m_rotationalVelocity.ApproxEquals(pv, 0.2f)) return pv; - +*/ return m_rotationalVelocity; } set @@ -2827,14 +2827,15 @@ Console.WriteLine(" JointCreateFixed"); _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); - if (_velocity.ApproxEquals(pv, 0.5f)) - { - m_rotationalVelocity = pv; - } - else - { +// if (_velocity.ApproxEquals(pv, 0.5f)) ???? Disregard rotational vel if lin vel is < 0.5 ????? +// { +// m_rotationalVelocity = pv;/ + +// } +// else +// { m_rotationalVelocity = new Vector3(rotvel.X, rotvel.Y, rotvel.Z); - } +// } //m_log.Debug("ODE: " + m_rotationalVelocity.ToString()); _orientation.X = ori.X; -- cgit v1.1 From 48134af6162249885740bad80a6b1bbb618bbc6e Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Wed, 3 Feb 2010 16:20:13 -0500 Subject: Motor angular decay fix. --- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index c03e381..4eb3313 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -646,12 +646,15 @@ namespace OpenSim.Region.Physics.OdePlugin //if(frcount == 0) Console.WriteLine("V0 = {0}", angObjectVel); // Vector3 FrAaccel = m_lastAngularVelocity - angObjectVel; // Vector3 initavel = angObjectVel; - // Decay Angular Motor + // Decay Angular Motor 1. In SL this also depends on attack rate! decay ~= 23/Attack. + float atk_decayfactor = 23.0f / (m_angularMotorTimescale * pTimestep); + m_angularMotorDVel -= m_angularMotorDVel / atk_decayfactor; + // Decay Angular Motor 2. if (m_angularMotorDecayTimescale < 300.0f) { - float decayfactor = m_angularMotorDecayTimescale/pTimestep; - Vector3 decayAmount = (m_angularMotorDVel/decayfactor); - m_angularMotorDVel -= decayAmount; + float decayfactor = m_angularMotorDecayTimescale/pTimestep; // df = Dec / pts + Vector3 decayAmount = (m_angularMotorDVel/decayfactor); // v-da = v-Dvel / df = v-Dvel * pts / Dec + m_angularMotorDVel -= decayAmount; // v-Dvel = v-Dvel - (v-Dvel / df = v-Dvel * pts / Dec) if (m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) { -- cgit v1.1 From ae9362636e1a95c32f7bcf1225e939b44c37a4a0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Feb 2010 17:00:16 +0000 Subject: Line endings cleanup --- .../Framework/Scenes/SceneCommunicationService.cs | 72 +++++++++++----------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 6a3c386..545183b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -699,42 +699,42 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", - position, m_regionInfo.RegionName); - - // Teleport within the same region - if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); - - m_log.WarnFormat( - "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, avatar.Name, avatar.UUID, emergencyPos); - position = emergencyPos; - } - - Vector3 currentPos = avatar.AbsolutePosition; - ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y); - ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y); - if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0) - { - if (srcLand.LandData.LocalID == destLand.LandData.LocalID) - { - //TPing within the same parcel. If the landing point is restricted, block the TP. - //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) - { - avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false); - position = currentPos; - } - } - else - { - //Tping to a different parcel. Respect the landing point on the destination parcel. - if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) - { - position = destLand.LandData.UserLocation; - } - } + position, m_regionInfo.RegionName); + + // Teleport within the same region + if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); + + m_log.WarnFormat( + "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, avatar.Name, avatar.UUID, emergencyPos); + position = emergencyPos; + } + + Vector3 currentPos = avatar.AbsolutePosition; + ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y); + ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y); + if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0) + { + if (srcLand.LandData.LocalID == destLand.LandData.LocalID) + { + //TPing within the same parcel. If the landing point is restricted, block the TP. + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) + { + avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false); + position = currentPos; + } + } + else + { + //Tping to a different parcel. Respect the landing point on the destination parcel. + if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) + { + position = destLand.LandData.UserLocation; + } + } } // TODO: Get proper AVG Height -- cgit v1.1 From 044979066cf66e4dcd2c8f4be90337555dc0b34d Mon Sep 17 00:00:00 2001 From: CasperW Date: Fri, 5 Feb 2010 00:53:32 +0100 Subject: Fix two inconsistencies with LightShare --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs | 6 +++++- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index d4250c1..99973b4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -244,6 +244,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Types.Vector3 iV; switch (rule) { + case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: + idx++; + wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); + break; case (int)ScriptBaseClass.WL_AMBIENT: idx++; iQ = rules.GetQuaternionItem(idx); @@ -300,7 +304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: idx++; iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); break; case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: idx++; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs index 7b67fa3..522c020 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Constants.cs @@ -70,7 +70,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int WL_CLOUD_SCROLL_Y = 32; public const int WL_CLOUD_SCROLL_Y_LOCK = 33; public const int WL_CLOUD_SCROLL_X_LOCK = 34; - public const int WL_DRAW_CLASSIC_CLOUDS = 35; + public const int WL_DRAW_CLASSIC_CLOUDS = 35; + public const int WL_SUN_MOON_POSITION = 36; } } -- cgit v1.1 From 0ad8046582354139f289f58f56b9b19a8bde7f38 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Feb 2010 22:44:17 +0000 Subject: Resolve a merge issue --- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 165 +++++++++++++++------------- 1 file changed, 86 insertions(+), 79 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index f4485df..f84beb6 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -715,88 +715,93 @@ namespace OpenSim.Data.MySQL { RegionMeta7WindlightData nWP = new RegionMeta7WindlightData(); nWP.OnSave += StoreRegionWindlightSettings; - lock (m_Connection) + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - + dbcon.Open(); + string command = "select * from `regionwindlight` where region_id = ?regionID"; - MySqlCommand cmd = new MySqlCommand(command); + using(MySqlCommand cmd = new MySqlCommand(command)) + { + cmd.Connection = dbcon; - cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); + cmd.Parameters.AddWithValue("?regionID", regionUUID.ToString()); - IDataReader result = ExecuteReader(cmd); - if (!result.Read()) - { - //No result, so store our default windlight profile and return it - nWP.regionID = regionUUID; - StoreRegionWindlightSettings(nWP); - return nWP; - } - else - { - UUID.TryParse(result["region_id"].ToString(), out nWP.regionID); - nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); - nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); - nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); - nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); - nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); - nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); - nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); - nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); - nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); - nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); - nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); - nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); - nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); - nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); - nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); - nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); - nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); - UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); - nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); - nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); - nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); - nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); - nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); - nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); - nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); - nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); - nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); - nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); - nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); - nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); - nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); - nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); - nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); - nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); - nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); - nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); - nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); - nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); - nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); - nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); - nWP.eastAngle = Convert.ToSingle(result["east_angle"]); - nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); - nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); - nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); - nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); - nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); - nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); - nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); - nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); - nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); - nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); - nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); - nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); - nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); - nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); - nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); - nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); - nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); - nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); - nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); - nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); - nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + IDataReader result = ExecuteReader(cmd); + if (!result.Read()) + { + //No result, so store our default windlight profile and return it + nWP.regionID = regionUUID; + StoreRegionWindlightSettings(nWP); + return nWP; + } + else + { + UUID.TryParse(result["region_id"].ToString(), out nWP.regionID); + nWP.waterColor.X = Convert.ToSingle(result["water_color_r"]); + nWP.waterColor.Y = Convert.ToSingle(result["water_color_g"]); + nWP.waterColor.Z = Convert.ToSingle(result["water_color_b"]); + nWP.waterFogDensityExponent = Convert.ToSingle(result["water_fog_density_exponent"]); + nWP.underwaterFogModifier = Convert.ToSingle(result["underwater_fog_modifier"]); + nWP.reflectionWaveletScale.X = Convert.ToSingle(result["reflection_wavelet_scale_1"]); + nWP.reflectionWaveletScale.Y = Convert.ToSingle(result["reflection_wavelet_scale_2"]); + nWP.reflectionWaveletScale.Z = Convert.ToSingle(result["reflection_wavelet_scale_3"]); + nWP.fresnelScale = Convert.ToSingle(result["fresnel_scale"]); + nWP.fresnelOffset = Convert.ToSingle(result["fresnel_offset"]); + nWP.refractScaleAbove = Convert.ToSingle(result["refract_scale_above"]); + nWP.refractScaleBelow = Convert.ToSingle(result["refract_scale_below"]); + nWP.blurMultiplier = Convert.ToSingle(result["blur_multiplier"]); + nWP.bigWaveDirection.X = Convert.ToSingle(result["big_wave_direction_x"]); + nWP.bigWaveDirection.Y = Convert.ToSingle(result["big_wave_direction_y"]); + nWP.littleWaveDirection.X = Convert.ToSingle(result["little_wave_direction_x"]); + nWP.littleWaveDirection.Y = Convert.ToSingle(result["little_wave_direction_y"]); + UUID.TryParse(result["normal_map_texture"].ToString(), out nWP.normalMapTexture); + nWP.horizon.X = Convert.ToSingle(result["horizon_r"]); + nWP.horizon.Y = Convert.ToSingle(result["horizon_g"]); + nWP.horizon.Z = Convert.ToSingle(result["horizon_b"]); + nWP.horizon.W = Convert.ToSingle(result["horizon_i"]); + nWP.hazeHorizon = Convert.ToSingle(result["haze_horizon"]); + nWP.blueDensity.X = Convert.ToSingle(result["blue_density_r"]); + nWP.blueDensity.Y = Convert.ToSingle(result["blue_density_g"]); + nWP.blueDensity.Z = Convert.ToSingle(result["blue_density_b"]); + nWP.blueDensity.W = Convert.ToSingle(result["blue_density_i"]); + nWP.hazeDensity = Convert.ToSingle(result["haze_density"]); + nWP.densityMultiplier = Convert.ToSingle(result["density_multiplier"]); + nWP.distanceMultiplier = Convert.ToSingle(result["distance_multiplier"]); + nWP.maxAltitude = Convert.ToUInt16(result["max_altitude"]); + nWP.sunMoonColor.X = Convert.ToSingle(result["sun_moon_color_r"]); + nWP.sunMoonColor.Y = Convert.ToSingle(result["sun_moon_color_g"]); + nWP.sunMoonColor.Z = Convert.ToSingle(result["sun_moon_color_b"]); + nWP.sunMoonColor.W = Convert.ToSingle(result["sun_moon_color_i"]); + nWP.sunMoonPosition = Convert.ToSingle(result["sun_moon_position"]); + nWP.ambient.X = Convert.ToSingle(result["ambient_r"]); + nWP.ambient.Y = Convert.ToSingle(result["ambient_g"]); + nWP.ambient.Z = Convert.ToSingle(result["ambient_b"]); + nWP.ambient.W = Convert.ToSingle(result["ambient_i"]); + nWP.eastAngle = Convert.ToSingle(result["east_angle"]); + nWP.sunGlowFocus = Convert.ToSingle(result["sun_glow_focus"]); + nWP.sunGlowSize = Convert.ToSingle(result["sun_glow_size"]); + nWP.sceneGamma = Convert.ToSingle(result["scene_gamma"]); + nWP.starBrightness = Convert.ToSingle(result["star_brightness"]); + nWP.cloudColor.X = Convert.ToSingle(result["cloud_color_r"]); + nWP.cloudColor.Y = Convert.ToSingle(result["cloud_color_g"]); + nWP.cloudColor.Z = Convert.ToSingle(result["cloud_color_b"]); + nWP.cloudColor.W = Convert.ToSingle(result["cloud_color_i"]); + nWP.cloudXYDensity.X = Convert.ToSingle(result["cloud_x"]); + nWP.cloudXYDensity.Y = Convert.ToSingle(result["cloud_y"]); + nWP.cloudXYDensity.Z = Convert.ToSingle(result["cloud_density"]); + nWP.cloudCoverage = Convert.ToSingle(result["cloud_coverage"]); + nWP.cloudScale = Convert.ToSingle(result["cloud_scale"]); + nWP.cloudDetailXYDensity.X = Convert.ToSingle(result["cloud_detail_x"]); + nWP.cloudDetailXYDensity.Y = Convert.ToSingle(result["cloud_detail_y"]); + nWP.cloudDetailXYDensity.Z = Convert.ToSingle(result["cloud_detail_density"]); + nWP.cloudScrollX = Convert.ToSingle(result["cloud_scroll_x"]); + nWP.cloudScrollXLock = Convert.ToBoolean(result["cloud_scroll_x_lock"]); + nWP.cloudScrollY = Convert.ToSingle(result["cloud_scroll_y"]); + nWP.cloudScrollYLock = Convert.ToBoolean(result["cloud_scroll_y_lock"]); + nWP.drawClassicClouds = Convert.ToBoolean(result["draw_classic_clouds"]); + } } } return nWP; @@ -842,9 +847,11 @@ namespace OpenSim.Data.MySQL public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) { - lock (m_Connection) + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { - using (MySqlCommand cmd = m_Connection.CreateCommand()) + dbcon.Open(); + + using (MySqlCommand cmd = dbcon.CreateCommand()) { cmd.CommandText = "REPLACE INTO `regionwindlight` (`region_id`, `water_color_r`, `water_color_g`, "; cmd.CommandText += "`water_color_b`, `water_fog_density_exponent`, `underwater_fog_modifier`, "; -- cgit v1.1 From 9568718addfd8e5d4094a456127ca469987f1f7a Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 12 Feb 2010 15:56:21 -0500 Subject: Angular motor adjustments --- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 48 ++++++++++++----------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index 4eb3313..55d6945 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -224,6 +224,8 @@ namespace OpenSim.Region.Physics.OdePlugin // These are vector properties but the engine lets you use a single float value to // set all of the components to the same value case Vehicle.ANGULAR_FRICTION_TIMESCALE: + if (pValue > 30f) pValue = 30f; + if (pValue < 0.1f) pValue = 0.1f; m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); break; case Vehicle.ANGULAR_MOTOR_DIRECTION: @@ -250,6 +252,12 @@ namespace OpenSim.Region.Physics.OdePlugin switch (pParam) { case Vehicle.ANGULAR_FRICTION_TIMESCALE: + if (pValue.X > 30f) pValue.X = 30f; + if (pValue.X < 0.1f) pValue.X = 0.1f; + if (pValue.Y > 30f) pValue.Y = 30f; + if (pValue.Y < 0.1f) pValue.Y = 0.1f; + if (pValue.Z > 30f) pValue.Z = 30f; + if (pValue.Z < 0.1f) pValue.Z = 0.1f; m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.ANGULAR_MOTOR_DIRECTION: @@ -306,7 +314,7 @@ namespace OpenSim.Region.Physics.OdePlugin { case Vehicle.TYPE_SLED: m_linearFrictionTimescale = new Vector3(30, 1, 1000); - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_angularFrictionTimescale = new Vector3(30, 30, 30); // m_lLinMotorVel = Vector3.Zero; m_linearMotorTimescale = 1000; m_linearMotorDecayTimescale = 120; @@ -333,7 +341,7 @@ namespace OpenSim.Region.Physics.OdePlugin break; case Vehicle.TYPE_CAR: m_linearFrictionTimescale = new Vector3(100, 2, 1000); - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); + m_angularFrictionTimescale = new Vector3(30, 30, 30); // was 1000, but sl max frict time is 30. // m_lLinMotorVel = Vector3.Zero; m_linearMotorTimescale = 1; m_linearMotorDecayTimescale = 60; @@ -548,6 +556,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_linearFrictionTimescale.Z < 300.0f) { float fricfactor = m_linearFrictionTimescale.Z / pTimestep; +//if(frcount == 0) Console.WriteLine("Zfric={0}", fricfactor); float fricZ = m_lLinObjectVel.Z / fricfactor; m_lLinObjectVel.Z -= fricZ; } @@ -639,7 +648,6 @@ namespace OpenSim.Region.Physics.OdePlugin */ //if(frcount == 0) Console.WriteLine("MoveAngular "); -//#### // Get what the body is doing, this includes 'external' influences d.Vector3 angularObjectVel = d.BodyGetAngularVel(Body); Vector3 angObjectVel = new Vector3(angularObjectVel.X, angularObjectVel.Y, angularObjectVel.Z); @@ -652,9 +660,18 @@ namespace OpenSim.Region.Physics.OdePlugin // Decay Angular Motor 2. if (m_angularMotorDecayTimescale < 300.0f) { - float decayfactor = m_angularMotorDecayTimescale/pTimestep; // df = Dec / pts - Vector3 decayAmount = (m_angularMotorDVel/decayfactor); // v-da = v-Dvel / df = v-Dvel * pts / Dec - m_angularMotorDVel -= decayAmount; // v-Dvel = v-Dvel - (v-Dvel / df = v-Dvel * pts / Dec) +//#### + if ( Vector3.Mag(m_angularMotorDVel) < 1.0f) + { + float decayfactor = (m_angularMotorDecayTimescale)/pTimestep; + Vector3 decayAmount = (m_angularMotorDVel/decayfactor); + m_angularMotorDVel -= decayAmount; + } + else + { + Vector3 decel = Vector3.Normalize(m_angularMotorDVel) * pTimestep / m_angularMotorDecayTimescale; + m_angularMotorDVel -= decel; + } if (m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) { @@ -743,22 +760,9 @@ namespace OpenSim.Region.Physics.OdePlugin //if(frcount == 0) Console.WriteLine("V2+= {0}", angObjectVel); } - if (m_angularFrictionTimescale.X < 300.0f) - { - float fricfactor = m_angularFrictionTimescale.X / pTimestep; - angObjectVel.X -= angObjectVel.X / fricfactor; - } - if (m_angularFrictionTimescale.Y < 300.0f) - { - float fricfactor = m_angularFrictionTimescale.Y / pTimestep; - angObjectVel.Y -= angObjectVel.Y / fricfactor; - } - if (m_angularFrictionTimescale.Z < 300.0f) - { - float fricfactor = m_angularFrictionTimescale.Z / pTimestep; - angObjectVel.Z -= angObjectVel.Z / fricfactor; - Console.WriteLine("z fric"); - } + angObjectVel.X -= angObjectVel.X / (m_angularFrictionTimescale.X * 0.7f / pTimestep); + angObjectVel.Y -= angObjectVel.Y / (m_angularFrictionTimescale.Y * 0.7f / pTimestep); + angObjectVel.Z -= angObjectVel.Z / (m_angularFrictionTimescale.Z * 0.7f / pTimestep); } // else no signif. motion //if(frcount == 0) Console.WriteLine("Dmotor {0} Obj {1}", m_angularMotorDVel, angObjectVel); -- cgit v1.1 From ce3e2655752fb56d9f18bf7cc0686e97c06f16da Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 14 Feb 2010 23:58:54 +0000 Subject: Plug a small hole --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 7b852a2..b2b061e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -585,6 +585,9 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[AGENT INVENTORY]: Failed to find item " + oldItemID.ToString()); return; } + + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + return; } AssetBase asset = AssetService.Get(item.AssetID.ToString()); -- cgit v1.1 From 94c417c90c9e4d91ea0c09fc5a3ac2541e09655d Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 15 Feb 2010 06:10:04 +0100 Subject: Implement missing llGetPrimitiveParams parameters --- .../Shared/Api/Implementation/LSL_Api.cs | 170 +++++++++++++++++---- 1 file changed, 138 insertions(+), 32 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e4ccce8..9db8ca0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7674,25 +7674,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case (int)ScriptBaseClass.PRIM_BUMP_SHINY: - // TODO-------------- - if (remain < 1) - return res; - - face=(int)rules.GetLSLIntegerItem(idx++); - - res.Add(new LSL_Integer(0)); - res.Add(new LSL_Integer(0)); + case (int)ScriptBaseClass.PRIM_BUMP_SHINY: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + int shiny; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + Shininess shinyness = tex.GetFace((uint)face).Shiny; + if (shinyness == Shininess.High) + { + shiny = ScriptBaseClass.PRIM_SHINY_HIGH; + } + else if (shinyness == Shininess.Medium) + { + shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; + } + else if (shinyness == Shininess.Low) + { + shiny = ScriptBaseClass.PRIM_SHINY_LOW; + } + else + { + shiny = ScriptBaseClass.PRIM_SHINY_NONE; + } + res.Add(new LSL_Integer(shiny)); + res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); + } + } + else + { + Shininess shinyness = tex.GetFace((uint)face).Shiny; + if (shinyness == Shininess.High) + { + shiny = ScriptBaseClass.PRIM_SHINY_HIGH; + } + else if (shinyness == Shininess.Medium) + { + shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; + } + else if (shinyness == Shininess.Low) + { + shiny = ScriptBaseClass.PRIM_SHINY_LOW; + } + else + { + shiny = ScriptBaseClass.PRIM_SHINY_NONE; + } + res.Add(new LSL_Integer(shiny)); + res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); + } break; - case (int)ScriptBaseClass.PRIM_FULLBRIGHT: - // TODO-------------- - if (remain < 1) - return res; - - face=(int)rules.GetLSLIntegerItem(idx++); - - res.Add(new LSL_Integer(0)); + case (int)ScriptBaseClass.PRIM_FULLBRIGHT: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + int fullbright; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + if (tex.GetFace((uint)face).Fullbright == true) + { + fullbright = ScriptBaseClass.TRUE; + } + else + { + fullbright = ScriptBaseClass.FALSE; + } + res.Add(new LSL_Integer(fullbright)); + } + } + else + { + if (tex.GetFace((uint)face).Fullbright == true) + { + fullbright = ScriptBaseClass.TRUE; + } + else + { + fullbright = ScriptBaseClass.FALSE; + } + res.Add(new LSL_Integer(fullbright)); + } break; case (int)ScriptBaseClass.PRIM_FLEXIBLE: @@ -7713,14 +7784,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PRIM_TEXGEN: - // TODO-------------- - // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) - if (remain < 1) - return res; - - face=(int)rules.GetLSLIntegerItem(idx++); - - res.Add(new LSL_Integer(0)); + // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } + } + } + else + { + if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } + } break; case (int)ScriptBaseClass.PRIM_POINT_LIGHT: @@ -7738,14 +7832,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Float(shape.LightFalloff)); // falloff break; - case (int)ScriptBaseClass.PRIM_GLOW: - // TODO-------------- - if (remain < 1) + case (int)ScriptBaseClass.PRIM_GLOW: + if (remain < 1) return res; - - face=(int)rules.GetLSLIntegerItem(idx++); - - res.Add(new LSL_Float(0)); + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + float primglow; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + primglow = tex.GetFace((uint)face).Glow; + res.Add(new LSL_Float(primglow)); + } + } + else + { + primglow = tex.GetFace((uint)face).Glow; + res.Add(new LSL_Float(primglow)); + } break; } } -- cgit v1.1 From af2d20c5fa0403c6cae1008eda3179acc4694d7f Mon Sep 17 00:00:00 2001 From: CasperW Date: Mon, 15 Feb 2010 22:22:36 +0100 Subject: Fix an inconsistency in llSetPayPrice between SL and OS behaviour --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9db8ca0..824073b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8968,9 +8968,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (quick_pay_buttons.Data.Length < 4) - { - LSLError("List must have at least 4 elements"); - return; + { + int x; + for (x=quick_pay_buttons.Data.Length; x<= 4; x++) + { + quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE); + } } int[] nPrice = new int[5]; nPrice[0]=price; -- cgit v1.1 From d6eff8ebcffc1231ea533c83764aa3b39d4e5750 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Feb 2010 23:14:57 +0000 Subject: Change a condition to actually make linden land reclaim work --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 28669b9..9be94ce 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -97,7 +97,7 @@ namespace OpenSim.Region.CoreModules.World.Land public void Initialise(IConfigSource source) { IConfig cnf = source.Configs["LandManagement"]; - if (cnf == null) + if (cnf != null) { DefaultGodParcelGroup = new UUID(cnf.GetString("DefaultAdministratorGroupUUID", UUID.Zero.ToString())); DefaultGodParcelName = cnf.GetString("DefaultAdministratorParcelName", "Default Parcel"); -- cgit v1.1 From efd481085135f60d8f6d3e4615591a26ec3f05f6 Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 25 Feb 2010 12:04:51 +0100 Subject: Disable blocking teleports within the same parcel for now; it's not implemented correctly. Will review soon. --- OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 9ceab19..5f84252 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -722,8 +722,10 @@ namespace OpenSim.Region.Framework.Scenes //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) { - avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false); - position = currentPos; + //Disabling this behaviour for now pending review. ~CasperW + + //avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false); + //position = currentPos; } } else -- cgit v1.1 From e99341d7df66f73286b8a440991358cbca1a8399 Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 25 Feb 2010 12:07:56 +0100 Subject: llDie() should not work on attachments (results in an incosistent attachment state) --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 824073b..7a6739b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1118,7 +1118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public virtual void llDie() { m_host.AddScriptLPS(1); - throw new SelfDeleteException(); + if (!m_host.IsAttachment) throw new SelfDeleteException(); } public LSL_Float llGround(LSL_Vector offset) -- cgit v1.1 From 7f61de8f57d9f01e532dc37a5ef81153ba40fc24 Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 25 Feb 2010 14:14:53 +0100 Subject: Allow particles and texture anims to be persisted to XML. This behaviour is expected. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 11682d9..0d19589 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -518,14 +518,12 @@ namespace OpenSim.Region.Framework.Scenes set { m_scriptAccessPin = (int)value; } } - [XmlIgnore] public Byte[] TextureAnimation { get { return m_TextureAnimation; } set { m_TextureAnimation = value; } } - [XmlIgnore] public Byte[] ParticleSystem { get { return m_particleSystem; } -- cgit v1.1 From 393a7828584a0bf8564dd351015238365e51b984 Mon Sep 17 00:00:00 2001 From: CasperW Date: Thu, 25 Feb 2010 18:05:30 +0100 Subject: Fix the crashed session notification from the userserver. --- .../Framework/Communications/Services/LoginService.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index 71b38ed..824cc57 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs @@ -88,15 +88,7 @@ namespace OpenSim.Framework.Communications.Services m_welcomeMessage = welcomeMess; } } - - /// - /// If the user is already logged in, try to notify the region that the user they've got is dead. - /// - /// - public virtual void LogOffUser(UserProfileData theUser, string message) - { - } - + /// /// Called when we receive the client's initial XMLRPC login_to_simulator request message /// @@ -1056,7 +1048,13 @@ namespace OpenSim.Framework.Communications.Services protected abstract RegionInfo RequestClosestRegion(string region); protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle); - protected abstract RegionInfo GetRegionInfo(UUID homeRegionId); + protected abstract RegionInfo GetRegionInfo(UUID homeRegionId); + + /// + /// If the user is already logged in, try to notify the region that the user they've got is dead. + /// + /// + public abstract void LogOffUser(UserProfileData theUser, string message); /// /// Prepare a login to the given region. This involves both telling the region to expect a connection -- cgit v1.1 From 84b0a23e193b220d61b5a67e90df32138441c1e8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Mar 2010 10:38:03 +0000 Subject: Remove a superfluous array creation --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index e87b1f4..1ea52c5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -416,7 +416,6 @@ namespace OpenSim.Region.ScriptEngine.Shared public list(params object[] args) { - m_data = new object[args.Length]; m_data = args; } -- cgit v1.1 From 62dd83f473fefb3ff2a7b64728a40337ae0e395e Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Mar 2010 10:38:03 +0000 Subject: Remove a superfluous array creation --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index e87b1f4..1ea52c5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -416,7 +416,6 @@ namespace OpenSim.Region.ScriptEngine.Shared public list(params object[] args) { - m_data = new object[args.Length]; m_data = args; } -- cgit v1.1 From 87590491b52e8ca0211274c17a83482534f845f3 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 4 Mar 2010 16:33:26 -0500 Subject: Fix Physics angular reference frame. --- .../Physics/ChOdePlugin/ODEDynamics.c_comments | 630 --------------------- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 33 +- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 76 ++- 3 files changed, 84 insertions(+), 655 deletions(-) delete mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments deleted file mode 100644 index 1060aa6..0000000 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.c_comments +++ /dev/null @@ -1,630 +0,0 @@ -/* - * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. - * - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using log4net; -using OpenMetaverse; -using Ode.NET; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.OdePlugin -{ - public class ODEDynamics - { - public Vehicle Type - { - get { return m_type; } - } - - public IntPtr Body - { - get { return m_body; } - } - - private int frcount = 0; // Used to limit dynamics debug output to - // every 100th frame - - // private OdeScene m_parentScene = null; - private IntPtr m_body = IntPtr.Zero; - private IntPtr m_jointGroup = IntPtr.Zero; - private IntPtr m_aMotor = IntPtr.Zero; - - - // Vehicle properties - private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind - // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier - private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: - // HOVER_TERRAIN_ONLY - // HOVER_GLOBAL_HEIGHT - // NO_DEFLECTION_UP - // HOVER_WATER_ONLY - // HOVER_UP_ONLY - // LIMIT_MOTOR_UP - // LIMIT_ROLL_ONLY - - // Linear properties - private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time - private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL - private Vector3 m_dir = Vector3.Zero; // velocity applied to body - private Vector3 m_linearFrictionTimescale = Vector3.Zero; - private float m_linearMotorDecayTimescale = 0; - private float m_linearMotorTimescale = 0; - private Vector3 m_lastLinearVelocityVector = Vector3.Zero; - // private bool m_LinearMotorSetLastFrame = false; - // private Vector3 m_linearMotorOffset = Vector3.Zero; - - //Angular properties - private Vector3 m_angularMotorDirection = Vector3.Zero; - private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero; - private Vector3 m_angularFrictionTimescale = Vector3.Zero; - private float m_angularMotorDecayTimescale = 0; - private float m_angularMotorTimescale = 0; - private Vector3 m_lastAngularVelocityVector = Vector3.Zero; - - //Deflection properties - // private float m_angularDeflectionEfficiency = 0; - // private float m_angularDeflectionTimescale = 0; - // private float m_linearDeflectionEfficiency = 0; - // private float m_linearDeflectionTimescale = 0; - - //Banking properties - // private float m_bankingEfficiency = 0; - // private float m_bankingMix = 0; - // private float m_bankingTimescale = 0; - - //Hover and Buoyancy properties - private float m_VhoverHeight = 0f; - private float m_VhoverEfficiency = 0f; - private float m_VhoverTimescale = 0f; - private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle. - // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) - // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. - // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. - - //Attractor properties - private float m_verticalAttractionEfficiency = 0; - private float m_verticalAttractionTimescale = 0; - - - - - - internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) - { - switch (pParam) - { - case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: - if (pValue < 0.01f) pValue = 0.01f; - // m_angularDeflectionEfficiency = pValue; - break; - case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - // m_angularDeflectionTimescale = pValue; - break; - case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_angularMotorDecayTimescale = pValue; - break; - case Vehicle.ANGULAR_MOTOR_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_angularMotorTimescale = pValue; - break; - case Vehicle.BANKING_EFFICIENCY: - if (pValue < 0.01f) pValue = 0.01f; - // m_bankingEfficiency = pValue; - break; - case Vehicle.BANKING_MIX: - if (pValue < 0.01f) pValue = 0.01f; - // m_bankingMix = pValue; - break; - case Vehicle.BANKING_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - // m_bankingTimescale = pValue; - break; - case Vehicle.BUOYANCY: - if (pValue < -1f) pValue = -1f; - if (pValue > 1f) pValue = 1f; - m_VehicleBuoyancy = pValue; - break; - case Vehicle.HOVER_EFFICIENCY: - if (pValue < 0f) pValue = 0f; - if (pValue > 1f) pValue = 1f; - m_VhoverEfficiency = pValue; - break; - case Vehicle.HOVER_HEIGHT: - m_VhoverHeight = pValue; - break; - case Vehicle.HOVER_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_VhoverTimescale = pValue; - break; - case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: - if (pValue < 0.01f) pValue = 0.01f; - // m_linearDeflectionEfficiency = pValue; - break; - case Vehicle.LINEAR_DEFLECTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - // m_linearDeflectionTimescale = pValue; - break; - case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_linearMotorDecayTimescale = pValue; - break; - case Vehicle.LINEAR_MOTOR_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_linearMotorTimescale = pValue; - break; - case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: - if (pValue < 0.0f) pValue = 0.0f; - if (pValue > 1.0f) pValue = 1.0f; - m_verticalAttractionEfficiency = pValue; - break; - case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_verticalAttractionTimescale = pValue; - break; - - // These are vector properties but the engine lets you use a single float value to - // set all of the components to the same value - case Vehicle.ANGULAR_FRICTION_TIMESCALE: - m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); - break; - case Vehicle.ANGULAR_MOTOR_DIRECTION: - m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); - break; - case Vehicle.LINEAR_FRICTION_TIMESCALE: - m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); - break; - case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue, pValue, pValue); - m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue); - break; - case Vehicle.LINEAR_MOTOR_OFFSET: - // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); - break; - - } - - }//end ProcessFloatVehicleParam - - internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue) - { - switch (pParam) - { - case Vehicle.ANGULAR_FRICTION_TIMESCALE: - m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.ANGULAR_MOTOR_DIRECTION: - m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.LINEAR_FRICTION_TIMESCALE: - m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.LINEAR_MOTOR_OFFSET: - // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - } - - }//end ProcessVectorVehicleParam - - internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) - { - switch (pParam) - { - case Vehicle.REFERENCE_FRAME: - // m_referenceFrame = pValue; - break; - } - - }//end ProcessRotationVehicleParam - - internal void ProcessTypeChange(Vehicle pType) - { -Console.WriteLine("ProcessTypeChange to " + pType); - - // Set Defaults For Type - m_type = pType; - switch (pType) - { - case Vehicle.TYPE_SLED: - m_linearFrictionTimescale = new Vector3(30, 1, 1000); - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 1000; - m_linearMotorDecayTimescale = 120; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 1000; - m_angularMotorDecayTimescale = 120; - m_VhoverHeight = 0; - m_VhoverEfficiency = 1; - m_VhoverTimescale = 10; - m_VehicleBuoyancy = 0; - // m_linearDeflectionEfficiency = 1; - // m_linearDeflectionTimescale = 1; - // m_angularDeflectionEfficiency = 1; - // m_angularDeflectionTimescale = 1000; - // m_bankingEfficiency = 0; - // m_bankingMix = 1; - // m_bankingTimescale = 10; - // m_referenceFrame = Quaternion.Identity; - m_flags &= - ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - break; - case Vehicle.TYPE_CAR: - m_linearFrictionTimescale = new Vector3(100, 2, 1000); - m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 1; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 1; - m_angularMotorDecayTimescale = 0.8f; - m_VhoverHeight = 0; - m_VhoverEfficiency = 0; - m_VhoverTimescale = 1000; - m_VehicleBuoyancy = 0; - // // m_linearDeflectionEfficiency = 1; - // // m_linearDeflectionTimescale = 2; - // // m_angularDeflectionEfficiency = 0; - // m_angularDeflectionTimescale = 10; - m_verticalAttractionEfficiency = 1; - m_verticalAttractionTimescale = 10; - // m_bankingEfficiency = -0.2f; - // m_bankingMix = 1; - // m_bankingTimescale = 1; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | - VehicleFlag.LIMIT_MOTOR_UP); - break; - case Vehicle.TYPE_BOAT: - m_linearFrictionTimescale = new Vector3(10, 3, 2); - m_angularFrictionTimescale = new Vector3(10,10,10); - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 5; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 4; - m_angularMotorDecayTimescale = 4; - m_VhoverHeight = 0; - m_VhoverEfficiency = 0.5f; - m_VhoverTimescale = 2; - m_VehicleBuoyancy = 1; - // m_linearDeflectionEfficiency = 0.5f; - // m_linearDeflectionTimescale = 3; - // m_angularDeflectionEfficiency = 0.5f; - // m_angularDeflectionTimescale = 5; - m_verticalAttractionEfficiency = 0.5f; - m_verticalAttractionTimescale = 5; - // m_bankingEfficiency = -0.3f; - // m_bankingMix = 0.8f; - // m_bankingTimescale = 1; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | - VehicleFlag.LIMIT_MOTOR_UP); - break; - case Vehicle.TYPE_AIRPLANE: - m_linearFrictionTimescale = new Vector3(200, 10, 5); - m_angularFrictionTimescale = new Vector3(20, 20, 20); - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 2; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 4; - m_angularMotorDecayTimescale = 4; - m_VhoverHeight = 0; - m_VhoverEfficiency = 0.5f; - m_VhoverTimescale = 1000; - m_VehicleBuoyancy = 0; - // m_linearDeflectionEfficiency = 0.5f; - // m_linearDeflectionTimescale = 3; - // m_angularDeflectionEfficiency = 1; - // m_angularDeflectionTimescale = 2; - m_verticalAttractionEfficiency = 0.9f; - m_verticalAttractionTimescale = 2; - // m_bankingEfficiency = 1; - // m_bankingMix = 0.7f; - // m_bankingTimescale = 2; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); - break; - case Vehicle.TYPE_BALLOON: - m_linearFrictionTimescale = new Vector3(5, 5, 5); - m_angularFrictionTimescale = new Vector3(10, 10, 10); - m_linearMotorDirection = Vector3.Zero; - m_linearMotorTimescale = 5; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorTimescale = 6; - m_angularMotorDecayTimescale = 10; - m_VhoverHeight = 5; - m_VhoverEfficiency = 0.8f; - m_VhoverTimescale = 10; - m_VehicleBuoyancy = 1; - // m_linearDeflectionEfficiency = 0; - // m_linearDeflectionTimescale = 5; - // m_angularDeflectionEfficiency = 0; - // m_angularDeflectionTimescale = 5; - m_verticalAttractionEfficiency = 1; - m_verticalAttractionTimescale = 1000; - // m_bankingEfficiency = 0; - // m_bankingMix = 0.7f; - // m_bankingTimescale = 5; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); - break; - - } - }//end SetDefaultsForType - - internal void Enable(IntPtr pBody, OdeScene pParentScene) - { -//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy); - if (m_type == Vehicle.TYPE_NONE) - return; - - m_body = pBody; - //KF: This used to set up the linear and angular joints - } - - internal void Step(float pTimestep, OdeScene pParentScene) - { - if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) - return; - frcount++; // used to limit debug comment output - if (frcount > 100) - frcount = 0; - - MoveLinear(pTimestep, pParentScene); - MoveAngular(pTimestep); - }// end Step - - private void MoveLinear(float pTimestep, OdeScene _pParentScene) - { - if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant - { - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); - - // add drive to body - Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep); - m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector? - - // This will work temporarily, but we really need to compare speed on an axis - // KF: Limit body velocity to applied velocity? - if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X)) - m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X; - if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y)) - m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y; - if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z)) - m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z; - - // decay applied velocity - Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep))); - //Console.WriteLine("decay: " + decayfraction); - m_linearMotorDirection -= m_linearMotorDirection * decayfraction; - //Console.WriteLine("actual: " + m_linearMotorDirection); - } - else - { // requested is not significant - // if what remains of applied is small, zero it. - if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f)) - m_lastLinearVelocityVector = Vector3.Zero; - } - - - // convert requested object velocity to world-referenced vector - m_dir = m_lastLinearVelocityVector; - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object - m_dir *= rotq; // apply obj rotation to velocity vector - - // add Gravity andBuoyancy - // KF: So far I have found no good method to combine a script-requested - // .Z velocity and gravity. Therefore only 0g will used script-requested - // .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only. - Vector3 grav = Vector3.Zero; - if(m_VehicleBuoyancy < 1.0f) - { - // There is some gravity, make a gravity force vector - // that is applied after object velocity. - d.Mass objMass; - d.BodyGetMass(Body, out objMass); - // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); - // Preserve the current Z velocity - d.Vector3 vel_now = d.BodyGetLinearVel(Body); - m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity - } // else its 1.0, no gravity. - - // Check if hovering - if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) - { - // We should hover, get the target height - d.Vector3 pos = d.BodyGetPosition(Body); - if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) - { - m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; - } - else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) - { - m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; - } - else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) - { - m_VhoverTargetHeight = m_VhoverHeight; - } - - if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) - { - // If body is aready heigher, use its height as target height - if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; - } - -// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped -// m_VhoverTimescale = 0f; // time to acheive height -// pTimestep is time since last frame,in secs - float herr0 = pos.Z - m_VhoverTargetHeight; -//if(frcount == 0) Console.WriteLine("herr0=" + herr0); - // Replace Vertical speed with correction figure if significant - if(Math.Abs(herr0) > 0.01f ) - { - d.Mass objMass; - d.BodyGetMass(Body, out objMass); - m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); - // m_VhoverEfficiency is not yet implemented - } - else - { - m_dir.Z = 0f; - } - } - - // Apply velocity - d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z); -//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z); - // apply gravity force - d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); -//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z); - - - // apply friction - Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep); - m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount; - } // end MoveLinear() - - private void MoveAngular(float pTimestep) - { - - // m_angularMotorDirection is the latest value from the script, and is decayed here - // m_angularMotorDirectionLASTSET is the latest value from the script - // m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here - - if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) - { - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); - // ramp up to new value - Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep); - m_lastAngularVelocityVector += (addAmount * 10f); -//if(frcount == 0) Console.WriteLine("add: " + addAmount); - - // limit applied value to what was set by script - // This will work temporarily, but we really need to compare speed on an axis - if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X)) - m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X; - if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y)) - m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y; - if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z)) - m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z; - - // decay the requested value - Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep))); - //Console.WriteLine("decay: " + decayfraction); - m_angularMotorDirection -= m_angularMotorDirection * decayfraction; - //Console.WriteLine("actual: " + m_linearMotorDirection); - } - // KF: m_lastAngularVelocityVector is rotational speed in rad/sec ? - - // Vertical attractor section - -// d.Mass objMass; -// d.BodyGetMass(Body, out objMass); -// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep); - float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep); - // get present body rotation - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); - // make a vector pointing up - Vector3 verterr = Vector3.Zero; - verterr.Z = 1.0f; - // rotate it to Body Angle - verterr = verterr * rotq; - // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. - // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go - // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. - if (verterr.Z < 0.0f) - { - verterr.X = 2.0f - verterr.X; - verterr.Y = 2.0f - verterr.Y; - } - // Error is 0 (no error) to +/- 2 (max error) - // scale it by servo - verterr = verterr * servo; - - // rotate to object frame - // verterr = verterr * rotq; - - // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so - // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. - m_lastAngularVelocityVector.X += verterr.Y; - m_lastAngularVelocityVector.Y -= verterr.X; -/* -if(frcount == 0) - { -// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector); - Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}", - Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency)); - } - */ - d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z); - // apply friction - Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep); - m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount; - - } //end MoveAngular - } -} diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs index 55d6945..b3b09e6 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs @@ -116,6 +116,8 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor // private Vector3 m_angObjectVel = Vector3.Zero; // current body angular velocity private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + + private Vector3 m_angularLock = Vector3.One; //Deflection properties // private float m_angularDeflectionEfficiency = 0; @@ -296,6 +298,11 @@ namespace OpenSim.Region.Physics.OdePlugin }//end ProcessRotationVehicleParam + internal void SetAngularLock(Vector3 pValue) + { + m_angularLock = pValue; + } + internal void ProcessFlagsVehicleSet(int flags) { m_flags |= (VehicleFlag)flags; @@ -649,8 +656,13 @@ namespace OpenSim.Region.Physics.OdePlugin //if(frcount == 0) Console.WriteLine("MoveAngular "); // Get what the body is doing, this includes 'external' influences + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object + Quaternion irotq = Quaternion.Inverse(rotq); d.Vector3 angularObjectVel = d.BodyGetAngularVel(Body); Vector3 angObjectVel = new Vector3(angularObjectVel.X, angularObjectVel.Y, angularObjectVel.Z); + angObjectVel = angObjectVel * irotq; // ============ Converts to LOCAL rotation + //if(frcount == 0) Console.WriteLine("V0 = {0}", angObjectVel); // Vector3 FrAaccel = m_lastAngularVelocity - angObjectVel; // Vector3 initavel = angObjectVel; @@ -694,8 +706,8 @@ namespace OpenSim.Region.Physics.OdePlugin { float VAservo = 1.0f / (m_verticalAttractionTimescale * pTimestep); // get present body rotation - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); +// d.Quaternion rot = d.BodyGetQuaternion(Body); +// Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // make a vector pointing up Vector3 verterr = Vector3.Zero; verterr.Z = 1.0f; @@ -706,7 +718,7 @@ namespace OpenSim.Region.Physics.OdePlugin // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. if (verterr.Z < 0.0f) - { // Defelction from vertical exceeds 90-degrees. This method will ensure stable return to + { // Deflection from vertical exceeds 90-degrees. This method will ensure stable return to // vertical, BUT for some reason a z-rotation is imparted to the object. TBI. //Console.WriteLine("InvertFlip"); verterr.X = 2.0f - verterr.X; @@ -781,9 +793,22 @@ namespace OpenSim.Region.Physics.OdePlugin m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. } */ +//if(frcount == 0) Console.WriteLine("angularLock {0}", m_angularLock); + + if (!m_angularLock.ApproxEquals(Vector3.One, 0.003f)) + { + if (m_angularLock.X == 0) + m_lastAngularVelocity.X = 0f; + if (m_angularLock.Y == 0) + m_lastAngularVelocity.Y = 0f; + if (m_angularLock.Z == 0) + m_lastAngularVelocity.Z = 0f; + } // Apply to the body // Vector3 aInc = m_lastAngularVelocity - initavel; -//if(frcount == 0) Console.WriteLine("Inc {0}", aInc); +//if(frcount == 0) Console.WriteLine("Inc {0}", aInc); + m_lastAngularVelocity = m_lastAngularVelocity * rotq; // ================ Converts to WORLD rotation + d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); //if(frcount == 0) Console.WriteLine("V4 = {0}", m_lastAngularVelocity); diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 8502aef..fb6cb55 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -85,8 +85,10 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_taintVelocity; private Vector3 m_taintTorque; private Quaternion m_taintrot; - private Vector3 m_angularlock = Vector3.One; - private Vector3 m_taintAngularLock = Vector3.One; + private Vector3 m_angularlock = Vector3.One; // Current setting + private Vector3 m_taintAngularLock = Vector3.One; // Request from LSL + + private IntPtr Amotor = IntPtr.Zero; private Vector3 m_PIDTarget; @@ -405,10 +407,10 @@ namespace OpenSim.Region.Physics.OdePlugin m_disabled = false; // The body doesn't already have a finite rotation mode set here - if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0.0f)) && _parent == null) + /* ### if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0.0f)) && _parent == null) { createAMotor(m_angularlock); - } + } */ if (m_vehicle.Type != Vehicle.TYPE_NONE) { m_vehicle.Enable(Body, _parent_scene); @@ -958,8 +960,10 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_taintCollidesWater != m_collidesWater) changefloatonwater(timestep); - + + // ##* if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) +//Console.WriteLine("ALchange req {0} is {1}", m_taintAngularLock, m_angularlock); changeAngularLock(timestep); } @@ -970,15 +974,21 @@ namespace OpenSim.Region.Physics.OdePlugin } - private void changeAngularLock(float timestep) + private void changeAngularLock(float timestep) // ##* { // do we have a Physical object? - if (Body != IntPtr.Zero) - { +// if (Body != IntPtr.Zero) +// { //Check that we have a Parent //If we have a parent then we're not authorative here if (_parent == null) { +//Console.WriteLine("Alock changed to {0}", m_taintAngularLock); + m_angularlock = m_taintAngularLock; + m_vehicle.SetAngularLock(m_angularlock); + + +/* if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f)) { //d.BodySetFiniteRotationMode(Body, 0); @@ -997,7 +1007,9 @@ namespace OpenSim.Region.Physics.OdePlugin } // Store this for later in case we get turned into a separate body m_angularlock = m_taintAngularLock; - + m_vehicle.SetAngularLock(m_angularlock); + } */ + } } private void changelink(float timestep) @@ -1140,10 +1152,10 @@ namespace OpenSim.Region.Physics.OdePlugin prm.m_disabled = false; // The body doesn't already have a finite rotation mode set here - if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) + /* ### if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) { prm.createAMotor(m_angularlock); - } + } */ prm.Body = Body; _parent_scene.addActivePrim(prm); } @@ -1183,10 +1195,10 @@ namespace OpenSim.Region.Physics.OdePlugin m_disabled = false; // The body doesn't already have a finite rotation mode set here - if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) + /* ### if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) { createAMotor(m_angularlock); - } + } */ d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); _parent_scene.addActivePrim(this); @@ -1600,14 +1612,17 @@ Console.WriteLine(" JointCreateFixed"); { if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 // NON-'VEHICLES' are dealt with here - if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f)) + // m_angularlock = <1,1,1> means no lock. a 0 on axis means locked. + +// NB this may be wrong - may lock global axis! Should be LOCAL axis! + if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.One, 0.003f)) { d.Vector3 avel2 = d.BodyGetAngularVel(Body); - if (m_angularlock.X == 1) + if (m_angularlock.X == 0) avel2.X = 0; - if (m_angularlock.Y == 1) + if (m_angularlock.Y == 0) avel2.Y = 0; - if (m_angularlock.Z == 1) + if (m_angularlock.Z == 0) avel2.Z = 0; d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); } @@ -1808,6 +1823,17 @@ Console.WriteLine(" JointCreateFixed"); // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); RLAservo = timestep / m_APIDStrength * scaler; rotforce = rotforce * RLAservo * diff_angle ; + + if (m_angularlock.X == 0) + rotforce.X = 0; + if (m_angularlock.Y == 0) + rotforce.Y = 0; + if (m_angularlock.Z == 0) + rotforce.Z = 0; + + + + d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); //Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); } @@ -1878,11 +1904,11 @@ Console.WriteLine(" JointCreateFixed"); { // KF: If this is a root prim do BodySet d.BodySetQuaternion(Body, ref myrot); - if (m_isphysical) + /* ### if (m_isphysical) { if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) createAMotor(m_angularlock); - } + } */ } else { @@ -2508,7 +2534,14 @@ Console.WriteLine(" JointCreateFixed"); } } } - +/* + public Vector3 AngularLock + { + get { return m_angularlock; } + set { } + } + +*/ public override float CollisionScore { get { return m_collisionscore; } @@ -2914,8 +2947,9 @@ Console.WriteLine(" JointCreateFixed"); public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } public override float PIDHoverTau { set { m_PIDHoverTau = value; } } - private void createAMotor(Vector3 axis) + private void createAMotor(Vector3 axis) // ##* { +Console.WriteLine(" createAMotor called! ----------------------------"); if (Body == IntPtr.Zero) return; -- cgit v1.1 From 83929c69e35d156d99be46a6ee50b0d3fe5c9f25 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 6 Mar 2010 00:56:55 -0600 Subject: - implementing server 1.38 functions Signed-off-by: Melanie --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 ++ .../Shared/Api/Implementation/LSL_Api.cs | 99 +++++++++++++++++++--- .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 4 + .../Shared/Api/Runtime/LSL_Constants.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 20 +++++ 5 files changed, 119 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5c283bc..a85a4b3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4680,5 +4680,10 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[Physics] " + ex); } } + + public Color4 GetTextColor() + { + return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index aa876ec..a373046 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5406,12 +5406,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate) { m_host.AddScriptLPS(1); + + SetTextureAnim(m_host, mode, face, sizex, sizey, start, length, rate); + } + + public void llSetLinkTextureAnim(int linknumber, int mode, int face, int sizex, int sizey, double start, double length, double rate) + { + m_host.AddScriptLPS(1); + + List parts = GetLinkParts(linknumber); + + foreach (var part in parts) + { + SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); + } + } + + private void SetTextureAnim(SceneObjectPart part, int mode, int face, int sizex, int sizey, double start, double length, double rate) + { + Primitive.TextureAnimation pTexAnim = new Primitive.TextureAnimation(); pTexAnim.Flags = (Primitive.TextureAnimMode)mode; //ALL_SIDES if (face == ScriptBaseClass.ALL_SIDES) - face = 255; + face = 255; pTexAnim.Face = (uint)face; pTexAnim.Length = (float)length; @@ -5420,9 +5439,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api pTexAnim.SizeY = (uint)sizey; pTexAnim.Start = (float)start; - m_host.AddTextureAnimation(pTexAnim); - m_host.SendFullUpdateToAllClients(); - m_host.ParentGroup.HasGroupChanged = true; + part.AddTextureAnimation(pTexAnim); + part.SendFullUpdateToAllClients(); + part.ParentGroup.HasGroupChanged = true; } public void llTriggerSoundLimited(string sound, double volume, LSL_Vector top_north_east, @@ -5819,13 +5838,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return ps; } + public void llLinkParticleSystem(int linknumber, LSL_List rules) + { + m_host.AddScriptLPS(1); + + List parts = GetLinkParts(linknumber); + + foreach (var part in parts) + { + SetParticleSystem(part, rules); + } + } + public void llParticleSystem(LSL_List rules) { m_host.AddScriptLPS(1); + SetParticleSystem(m_host, rules); + } + + private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { + + if (rules.Length == 0) { - m_host.RemoveParticleSystem(); - m_host.ParentGroup.HasGroupChanged = true; + part.RemoveParticleSystem(); + part.ParentGroup.HasGroupChanged = true; } else { @@ -5936,7 +5973,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - prules.Target = m_host.UUID; + prules.Target = part.UUID; } break; @@ -5962,10 +5999,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } prules.CRC = 1; - m_host.AddNewParticleSystem(prules); - m_host.ParentGroup.HasGroupChanged = true; + part.AddNewParticleSystem(prules); + part.ParentGroup.HasGroupChanged = true; } - m_host.SendFullUpdateToAllClients(); + part.SendFullUpdateToAllClients(); } public void llGroundRepel(double height, int water, double tau) @@ -6759,6 +6796,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetPrimParams(part, rules); } + public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) + { + llSetLinkPrimitiveParams(linknumber, rules); + } + protected void SetPrimParams(SceneObjectPart part, LSL_List rules) { int idx = 0; @@ -7115,6 +7157,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int style = rules.GetLSLIntegerItem(idx++); SetTexGen(part, face, style); break; + case (int)ScriptBaseClass.PRIM_TEXT: + if (remain < 3) + return; + string primText = rules.GetLSLStringItem(idx++); + LSL_Vector primTextColor = rules.GetVector3Item(idx++); + LSL_Float primTextAlpha = rules.GetLSLFloatItem(idx++); + Vector3 av3 = new Vector3(Util.Clip((float)primTextColor.x, 0.0f, 1.0f), + Util.Clip((float)primTextColor.y, 0.0f, 1.0f), + Util.Clip((float)primTextColor.z, 0.0f, 1.0f)); + part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); + + break; } } } @@ -7358,6 +7412,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return GetLinkPrimitiveParams(m_host, rules); } + public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) + { + m_host.AddScriptLPS(1); + + List parts = GetLinkParts(linknumber); + + LSL_List res = new LSL_List(); + + foreach (var part in parts) + { + LSL_List partRes = GetLinkPrimitiveParams(part, rules); + res += partRes; + } + + return res; + } + public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) { LSL_List res = new LSL_List(); @@ -7635,6 +7706,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Float(0)); break; + case (int)ScriptBaseClass.PRIM_TEXT: + Color4 textColor = part.GetTextColor(); + res.Add(part.Text); + res.Add(new LSL_Vector(textColor.R, + textColor.G, + textColor.B)); + res.Add(new LSL_Float(textColor.A)); + break; } } return res; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index a74e8da..7ab04a3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -135,6 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Key llGetLinkKey(int linknum); LSL_String llGetLinkName(int linknum); LSL_Integer llGetLinkNumber(); + LSL_List llGetLinkPrimitiveParams(int linknum, LSL_List rules); LSL_Integer llGetListEntryType(LSL_List src, int index); LSL_Integer llGetListLength(LSL_List src); LSL_Vector llGetLocalPos(); @@ -206,6 +207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llInstantMessage(string user, string message); LSL_String llIntegerToBase64(int number); LSL_String llKey2Name(string id); + void llLinkParticleSystem(int linknum, LSL_List rules); LSL_String llList2CSV(LSL_List src); LSL_Float llList2Float(LSL_List src, int index); LSL_Integer llList2Integer(LSL_List src, int index); @@ -322,6 +324,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetLinkColor(int linknumber, LSL_Vector color, int face); void llSetLinkPrimitiveParams(int linknumber, LSL_List rules); void llSetLinkTexture(int linknumber, string texture, int face); + void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate); void llSetLocalRot(LSL_Rotation rot); void llSetObjectDesc(string desc); void llSetObjectName(string name); @@ -330,6 +333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void llSetPayPrice(int price, LSL_List quick_pay_buttons); void llSetPos(LSL_Vector pos); void llSetPrimitiveParams(LSL_List rules); + void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); void llSetPrimURL(string url); void llSetRemoteScriptAccessPin(int pin); void llSetRot(LSL_Rotation rot); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 7cf82b2..ee35fa4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -313,6 +313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int PRIM_CAST_SHADOWS = 24; // Not implemented, here for completeness sake public const int PRIM_POINT_LIGHT = 23; // Huh? public const int PRIM_GLOW = 25; + public const int PRIM_TEXT = 26; public const int PRIM_TEXGEN_DEFAULT = 0; public const int PRIM_TEXGEN_PLANAR = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index a28e97b..3339995 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -674,6 +674,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llGetPrimitiveParams(rules); } + public LSL_List llGetLinkPrimitiveParams(int linknum, LSL_List rules) + { + return m_LSL_Functions.llGetLinkPrimitiveParams(linknum, rules); + } + public LSL_Integer llGetRegionAgentCount() { return m_LSL_Functions.llGetRegionAgentCount(); @@ -889,6 +894,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase return m_LSL_Functions.llKey2Name(id); } + public void llLinkParticleSystem(int linknum, LSL_List rules) + { + m_LSL_Functions.llLinkParticleSystem(linknum, rules); + } + public LSL_String llList2CSV(LSL_List src) { return m_LSL_Functions.llList2CSV(src); @@ -1468,6 +1478,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetLinkTexture(linknumber, texture, face); } + public void llSetLinkTextureAnim(int linknum, int mode, int face, int sizex, int sizey, double start, double length, double rate) + { + m_LSL_Functions.llSetLinkTextureAnim(linknum, mode, face, sizex, sizey, start, length, rate); + } + public void llSetLocalRot(LSL_Rotation rot) { m_LSL_Functions.llSetLocalRot(rot); @@ -1508,6 +1523,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llSetPrimitiveParams(rules); } + public void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules) + { + m_LSL_Functions.llSetLinkPrimitiveParamsFast(linknum, rules); + } + public void llSetPrimURL(string url) { m_LSL_Functions.llSetPrimURL(url); -- cgit v1.1 From 3d053b194a641c64158045720e2d82735bdfaec5 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 7 Mar 2010 16:05:24 +0000 Subject: Small consistency change --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a373046..3b2c9b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5873,7 +5873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api for (int i = 0; i < rules.Length; i += 2) { - switch (Convert.ToInt32(rules.Data[i])) + switch (rules.GetLSLIntegerItem(i)) { case (int)ScriptBaseClass.PSYS_PART_FLAGS: prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); -- cgit v1.1 From c8c608acc8509ebc1651b4c2dd9094cbe64dcfb8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 7 Mar 2010 16:05:24 +0000 Subject: Small consistency change --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3154f9e..180fba9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6065,7 +6065,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api for (int i = 0; i < rules.Length; i += 2) { - switch (Convert.ToInt32(rules.Data[i])) + switch (rules.GetLSLIntegerItem(i)) { case (int)ScriptBaseClass.PSYS_PART_FLAGS: prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); -- cgit v1.1 From 49baf090cd1164b11b07fb372dff1d7b8b48c264 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 7 Mar 2010 16:05:24 +0000 Subject: Small consistency change --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4661488..aa2c8b3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6067,7 +6067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api for (int i = 0; i < rules.Length; i += 2) { - switch (Convert.ToInt32(rules.Data[i])) + switch (rules.GetLSLIntegerItem(i)) { case (int)ScriptBaseClass.PSYS_PART_FLAGS: prules.PartDataFlags = (Primitive.ParticleSystem.ParticleDataFlags)(uint)rules.GetLSLIntegerItem(i + 1); @@ -10191,4 +10191,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } -} \ No newline at end of file +} -- cgit v1.1 From 5caae0293ab0f69cced21923c36db230698c7970 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 3 Mar 2010 22:14:06 +0000 Subject: Fix bug where approximately half the time, attachments would rez only their root prim until right clicked (or otherwise updated). The root cause of this problem was that multiple ObjectUpdates were being sent on attachment which differed enough to confuse the client. Sometimes these would eliminate each other and sometimes not, depending on whether the scheduler looked at the queued updates. The solution here is to only schedule the ObjectUpdate once the attachment code has done all it needs to do. Backport from head. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 44 ++++++++++++--- OpenSim/Region/Framework/Scenes/Scene.cs | 40 +++++++++++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 62 ++++++++++++++-------- .../Region/Framework/Scenes/SceneObjectGroup.cs | 35 +++++++++--- 4 files changed, 138 insertions(+), 43 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index c6cee75..5b21332 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2339,9 +2339,18 @@ namespace OpenSim.Region.Framework.Scenes EventManager.TriggerOnAttach(localID, itemID, avatarID); } - public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, - uint AttachmentPt) + /// + /// Called when the client receives a request to rez a single attachment on to the avatar from inventory + /// (RezSingleAttachmentFromInv packet). + /// + /// + /// + /// + /// + public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { + m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name); + SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt); if (att == null) @@ -2353,9 +2362,20 @@ namespace OpenSim.Region.Framework.Scenes return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt); } - public UUID RezSingleAttachment(SceneObjectGroup att, - IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + /// + /// Update the user inventory to reflect an attachment + /// + /// + /// + /// + /// + /// + public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { + m_log.DebugFormat( + "[USER INVENTORY]: Updating inventory of {0} to show attachment of {1} (item ID {2})", + remoteClient.Name, att.Name, itemID); + if (!att.IsDeleted) AttachmentPt = att.RootPart.AttachmentPoint; @@ -2394,8 +2414,19 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent); } + /// + /// This registers the item as attached in a user's inventory + /// + /// + /// + /// + /// public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) { +// m_log.DebugFormat( +// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", +// att.Name, remoteClient.Name, AttachmentPt, itemID); + if (UUID.Zero == itemID) { m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID."); @@ -2423,10 +2454,7 @@ namespace OpenSim.Region.Framework.Scenes presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); if (m_AvatarFactory != null) - { m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); - } - } } @@ -2509,6 +2537,7 @@ namespace OpenSim.Region.Framework.Scenes { sog.SetOwnerId(ownerID); sog.SetGroup(groupID, remoteClient); + sog.ScheduleGroupForFullUpdate(); foreach (SceneObjectPart child in sog.Children.Values) child.Inventory.ChangeInventoryOwner(ownerID); @@ -2530,6 +2559,7 @@ namespace OpenSim.Region.Framework.Scenes sog.SetOwnerId(groupID); sog.ApplyNextOwnerPermissions(); } + } foreach (uint localID in localIDs) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 41fd1e1..7796b8d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1813,14 +1813,22 @@ namespace OpenSim.Region.Framework.Scenes //m_log.DebugFormat( // "[SCENE]: Scene.AddNewPrim() pcode {0} called for {1} in {2}", shape.PCode, ownerID, RegionInfo.RegionName); + SceneObjectGroup sceneObject = null; + // If an entity creator has been registered for this prim type then use that if (m_entityCreators.ContainsKey((PCode)shape.PCode)) - return m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape); + { + sceneObject = m_entityCreators[(PCode)shape.PCode].CreateEntity(ownerID, groupID, pos, rot, shape); + } + else + { + // Otherwise, use this default creation code; + sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); + AddNewSceneObject(sceneObject, true); + sceneObject.SetGroup(groupID, null); + } - // Otherwise, use this default creation code; - SceneObjectGroup sceneObject = new SceneObjectGroup(ownerID, pos, rot, shape); - AddNewSceneObject(sceneObject, true); - sceneObject.SetGroup(groupID, null); + sceneObject.ScheduleGroupForFullUpdate(); return sceneObject; } @@ -1848,7 +1856,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Add a newly created object to the scene + /// Add a newly created object to the scene. Updates are also sent to viewers. /// /// /// @@ -1857,8 +1865,25 @@ namespace OpenSim.Region.Framework.Scenes /// public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) { - return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup); + return AddNewSceneObject(sceneObject, attachToBackup, true); } + + /// + /// Add a newly created object to the scene + /// + /// + /// + /// If true, the object is made persistent into the scene. + /// If false, the object will not persist over server restarts + /// + /// + /// If true, updates for the new scene object are sent to all viewers in range. + /// If false, it is left to the caller to schedule the update + /// + public bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) + { + return m_sceneGraph.AddNewSceneObject(sceneObject, attachToBackup, sendClientUpdates); + } /// /// Delete every object from the scene @@ -3322,7 +3347,6 @@ namespace OpenSim.Region.Framework.Scenes } else m_log.Debug("[SCENE]: Unable to register with InterregionCommsIn"); - } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 321cc45..d31b45e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -228,7 +228,7 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.HasGroupChanged = true; } - return AddSceneObject(sceneObject, attachToBackup); + return AddSceneObject(sceneObject, attachToBackup, true); } /// @@ -243,12 +243,12 @@ namespace OpenSim.Region.Framework.Scenes /// /// true if the object was added, false if an object with the same uuid was already in the scene /// - protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) + protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { // Ensure that we persist this new scene object sceneObject.HasGroupChanged = true; - return AddSceneObject(sceneObject, attachToBackup); + return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); } /// @@ -260,12 +260,19 @@ namespace OpenSim.Region.Framework.Scenes /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// - /// true if the object was added, false if an object with the same uuid was already in the scene + /// + /// If true, updates for the new scene object are sent to all viewers in range. + /// If false, it is left to the caller to schedule the update + /// + /// + /// true if the object was added, false if an object with the same uuid was already in the scene /// - protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup) + protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; + + bool alreadyExisted = false; if (m_parentScene.m_clampPrimSize) { @@ -286,6 +293,9 @@ namespace OpenSim.Region.Framework.Scenes sceneObject.AttachToScene(m_parentScene); + if (sendClientUpdates) + sceneObject.ScheduleGroupForFullUpdate(); + lock (sceneObject) { if (!Entities.ContainsKey(sceneObject.UUID)) @@ -309,12 +319,14 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } } - - return true; + } + else + { + alreadyExisted = true; } } - return false; + return alreadyExisted; } /// @@ -521,26 +533,34 @@ namespace OpenSim.Region.Framework.Scenes itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, false, false, remoteClient.AgentId, true); +// m_log.DebugFormat( +// "[SCENE GRAPH]: Retrieved single object {0} for attachment to {1} on point {2}", +// objatt.Name, remoteClient.Name, AttachmentPt); + if (objatt != null) { bool tainted = false; if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; - if (AttachObject( - remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false)) - { - objatt.ScheduleGroupForFullUpdate(); - if (tainted) - objatt.HasGroupChanged = true; - - // Fire after attach, so we don't get messy perms dialogs - // 3 == AttachedRez - objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); + AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); + //objatt.ScheduleGroupForFullUpdate(); - // Do this last so that event listeners have access to all the effects of the attachment - m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); - } + if (tainted) + objatt.HasGroupChanged = true; + + // Fire after attach, so we don't get messy perms dialogs + // 3 == AttachedRez + objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); + + // Do this last so that event listeners have access to all the effects of the attachment + m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); + } + else + { + m_log.WarnFormat( + "[SCENE GRAPH]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", + itemID, remoteClient.Name, AttachmentPt); } return objatt; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c5a6171..c14b39a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -567,8 +567,10 @@ namespace OpenSim.Region.Framework.Scenes } ApplyPhysics(m_scene.m_physicalPrim); - - ScheduleGroupForFullUpdate(); + + // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled + // for the same object with very different properties. The caller must schedule the update. + //ScheduleGroupForFullUpdate(); } public Vector3 GroupScale() @@ -956,10 +958,11 @@ namespace OpenSim.Region.Framework.Scenes // don't attach attachments to child agents if (avatar.IsChildAgent) return; +// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name); + DetachFromBackup(); // Remove from database and parcel prim count - // m_scene.DeleteFromStorage(UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); @@ -985,7 +988,6 @@ namespace OpenSim.Region.Framework.Scenes SetAttachmentPoint(Convert.ToByte(attachmentpoint)); avatar.AddAttachment(this); - m_log.Debug("[SOG]: Added attachment " + UUID + " to avatar " + avatar.UUID); if (!silent) { @@ -1002,6 +1004,12 @@ namespace OpenSim.Region.Framework.Scenes ScheduleGroupForFullUpdate(); } } + else + { + m_log.WarnFormat( + "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", + UUID, agentID, Scene.RegionInfo.RegionName); + } } public byte GetAttachmentPoint() @@ -1986,6 +1994,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleFullUpdateToAvatar(ScenePresence presence) { +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); + RootPart.AddFullUpdateToAvatar(presence); lock (m_parts) @@ -2000,6 +2010,8 @@ namespace OpenSim.Region.Framework.Scenes public void ScheduleTerseUpdateToAvatar(ScenePresence presence) { +// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1} just to avatar {2}", Name, UUID, presence.Name); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) @@ -2014,6 +2026,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { +// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID); + checkAtTargets(); RootPart.ScheduleFullUpdate(); @@ -2032,6 +2046,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForTerseUpdate() { +// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); + lock (m_parts) { foreach (SceneObjectPart part in m_parts.Values) @@ -2045,9 +2061,11 @@ namespace OpenSim.Region.Framework.Scenes /// Immediately send a full update for this scene object. /// public void SendGroupFullUpdate() - { + { if (IsDeleted) return; + +// m_log.DebugFormat("[SOG]: Sending immediate full group update for {0} {1}", Name, UUID); RootPart.SendFullUpdateToAllClients(); @@ -2064,7 +2082,7 @@ namespace OpenSim.Region.Framework.Scenes /// /// Immediately send an update for this scene object's root prim only. /// This is for updates regarding the object as a whole, and none of its parts in particular. - /// Note: this may not be cused by opensim (it probably should) but it's used by + /// Note: this may not be used by opensim (it probably should) but it's used by /// external modules. /// public void SendGroupRootTerseUpdate() @@ -2079,6 +2097,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_scene == null) // Need to check here as it's null during object creation return; + m_scene.SceneGraph.AddToUpdateList(this); } @@ -3557,7 +3576,9 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChanged = true; } - ScheduleGroupForFullUpdate(); + // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled + // for the same object with very different properties. The caller must schedule the update. + //ScheduleGroupForFullUpdate(); } public void TriggerScriptChangedEvent(Changed val) -- cgit v1.1 From 06e351f1ef83217ac5f9ab479120cd23a68a6012 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Mar 2010 22:28:52 +0000 Subject: Revert "Adds land ejection and freezing. Adds more checks to land banning." This reverts commit 44d523518af31075c77653eacc7489220db4abaa. --- .../CoreModules/World/Land/LandManagementModule.cs | 128 ++++----------------- 1 file changed, 25 insertions(+), 103 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index ef3e722..33d16d5 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -161,10 +161,6 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelInfoRequest += ClientOnParcelInfoRequest; client.OnParcelDwellRequest += ClientOnParcelDwellRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; - client.OnParcelGodMark += ClientOnParcelGodMark; - client.OnSimWideDeletes += ClientOnSimWideDeletes; - client.OnParcelFreezeUser += ClientOnParcelFreezeUser; - client.OnParcelEjectUser += ClientOnParcelEjectUser; EntityBase presenceEntity; if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) @@ -273,7 +269,22 @@ namespace OpenSim.Region.CoreModules.World.Land return parcelsNear; } - + public void KickUserOffOfParcel(ScenePresence avatar) + { + if (avatar.GodLevel == 0) + { + List parcelsNear = ParcelsNearPoint(avatar.AbsolutePosition); + foreach (ILandObject check in parcelsNear) + { + if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) + { + Vector3 target = check.LandData.UserLocation; + avatar.TeleportWithMomentum(target); + return; + } + } + } + } public void MoveUserOutOfParcel(ScenePresence avatar) { if (avatar.GodLevel == 0) @@ -290,6 +301,7 @@ namespace OpenSim.Region.CoreModules.World.Land { Vector3 target = new Vector3(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); avatar.TeleportWithMomentum(target); + avatar.Velocity = new Vector3(-avatar.Velocity.X - 5, avatar.Velocity.Y, avatar.Velocity.Z); return; } } @@ -303,73 +315,11 @@ namespace OpenSim.Region.CoreModules.World.Land { Vector3 target = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y, avatar.AbsolutePosition.Z); avatar.TeleportWithMomentum(target); + avatar.Velocity = new Vector3(avatar.Velocity.X, -avatar.Velocity.Y - 5, avatar.Velocity.Z); return; } } } - List allParcels = new List(); - allParcels = AllParcels(); - if (allParcels.Count != 1) - { - foreach (ILandObject parcel in allParcels) - { - if (parcel.IsEitherBannedOrRestricted(avatar.UUID) != true) - { - Vector3 temptarget = parcel.LandData.UserLocation; - if (parcel.ContainsPoint((int)parcel.LandData.UserLocation.X, (int)parcel.LandData.UserLocation.Y)) - { - avatar.TeleportWithMomentum(temptarget); - return; - } - else - { - for (int x = 0; x <= Constants.RegionSize / 3; x += 3) - { - for (int y = 0; y <= Constants.RegionSize / 3; y += 3) - { - if (parcel.ContainsPoint(x, y)) - { - temptarget = new Vector3(x, y, avatar.AbsolutePosition.Z); - avatar.TeleportWithMomentum(temptarget); - return; - } - } - } - } - } - } - } - //Move to region side - if (avatar.AbsolutePosition.X > avatar.AbsolutePosition.Y) - { - if (avatar.AbsolutePosition.X > .5 * Constants.RegionSize) - { - Vector3 target = new Vector3(Constants.RegionSize, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); ; - avatar.TeleportWithMomentum(target); - return; - } - else - { - Vector3 target = new Vector3(0, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); ; - avatar.TeleportWithMomentum(target); - return; - } - } - else - { - if (avatar.AbsolutePosition.Y > .5 * Constants.RegionSize) - { - Vector3 target = new Vector3(avatar.AbsolutePosition.X, Constants.RegionSize, avatar.AbsolutePosition.Z); ; - avatar.TeleportWithMomentum(target); - return; - } - else - { - Vector3 target = new Vector3(avatar.AbsolutePosition.X, 0, avatar.AbsolutePosition.Z); ; - avatar.TeleportWithMomentum(target); - return; - } - } } } @@ -412,12 +362,12 @@ namespace OpenSim.Region.CoreModules.World.Land { if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, true, (int)ParcelResult.Multiple, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); return; } if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, true, (int)ParcelResult.Multiple, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); return; } } @@ -432,12 +382,12 @@ namespace OpenSim.Region.CoreModules.World.Land { if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, true, (int)ParcelResult.Multiple, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); return; } if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, true, (int)ParcelResult.Multiple, avatar.ControllingClient); + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); return; } } @@ -545,18 +495,6 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.CanEditParcel(agentID, land)) { land.UpdateAccessList(flags, entries, remote_client); - List presences = ((Scene)remote_client.Scene).GetAvatars(); - foreach (ScenePresence presence in presences) - { - land = GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); - if (land != null) - { - if (land.IsEitherBannedOrRestricted(presence.UUID)) - { - MoveUserOutOfParcel(presence); - } - } - } } } else @@ -1122,25 +1060,7 @@ namespace OpenSim.Region.CoreModules.World.Land m_landList.TryGetValue(localID, out land); } - if (land != null) - { - land.UpdateLandProperties(args, remote_client); - if ((args.ParcelFlags & (uint)(ParcelFlags.UseBanList | ParcelFlags.UseAccessList | ParcelFlags.UseAccessGroup | ParcelFlags.UsePassList)) != 0) - { - List presences = ((Scene)remote_client.Scene).GetAvatars(); - foreach (ScenePresence presence in presences) - { - land = GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); - if (land != null) - { - if (land.IsEitherBannedOrRestricted(presence.UUID)) - { - MoveUserOutOfParcel(presence); - } - } - } - } - } + if (land != null) land.UpdateLandProperties(args, remote_client); } public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) @@ -1552,6 +1472,7 @@ namespace OpenSim.Region.CoreModules.World.Land UpdateLandObject(localID, land.LandData); } + public void ClientOnParcelGodMark(IClientAPI client, UUID god, int landID) { ILandObject land = null; @@ -1567,6 +1488,7 @@ namespace OpenSim.Region.CoreModules.World.Land land.LandData.Name = DefaultGodParcelName; land.SendLandUpdateToAvatarsOverMe(); } + private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID) { ScenePresence SP; -- cgit v1.1 From 80b5a95bb8f640efaf61eee810341f5951dfda6a Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Mar 2010 22:29:02 +0000 Subject: Revert "Adds Land Banning." This reverts commit a87d7a12967b50fe83ebbaa7b57e531eb93158a2. --- .../CoreModules/World/Land/LandManagementModule.cs | 130 ++++++++------------- .../Region/CoreModules/World/Land/LandObject.cs | 48 ++------ 2 files changed, 58 insertions(+), 120 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 33d16d5..8c3d17d 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -269,57 +269,20 @@ namespace OpenSim.Region.CoreModules.World.Land return parcelsNear; } - public void KickUserOffOfParcel(ScenePresence avatar) + public void SendYouAreBannedNotice(ScenePresence avatar) { - if (avatar.GodLevel == 0) + if (AllowedForcefulBans) { - List parcelsNear = ParcelsNearPoint(avatar.AbsolutePosition); - foreach (ILandObject check in parcelsNear) - { - if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) - { - Vector3 target = check.LandData.UserLocation; - avatar.TeleportWithMomentum(target); - return; - } - } + avatar.ControllingClient.SendAlertMessage( + "You are not allowed on this parcel because you are banned. Please go away."); + + avatar.PhysicsActor.Position = avatar.lastKnownAllowedPosition; + avatar.PhysicsActor.Velocity = Vector3.Zero; } - } - public void MoveUserOutOfParcel(ScenePresence avatar) - { - if (avatar.GodLevel == 0) + else { - ILandObject land = m_scene.LandChannel.GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); - List parcelsNear = new List(); - - for (int x = -2; x <= 2; x += 2) - { - ILandObject check = GetLandObject(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y); - if (check != null) - { - if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) - { - Vector3 target = new Vector3(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); - avatar.TeleportWithMomentum(target); - avatar.Velocity = new Vector3(-avatar.Velocity.X - 5, avatar.Velocity.Y, avatar.Velocity.Z); - return; - } - } - } - for (int y = -2; y <= 2; y += 2) - { - ILandObject check = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y); - if (check != null) - { - if (check.IsEitherBannedOrRestricted(avatar.UUID) != true) - { - Vector3 target = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y, avatar.AbsolutePosition.Z); - avatar.TeleportWithMomentum(target); - avatar.Velocity = new Vector3(avatar.Velocity.X, -avatar.Velocity.Y - 5, avatar.Velocity.Z); - return; - } - } - } + avatar.ControllingClient.SendAlertMessage( + "You are not allowed on this parcel because you are banned; however, the grid administrator has disabled ban lines globally. Please obey the land owner's requests or you can be banned from the entire sim!"); } } @@ -339,7 +302,16 @@ namespace OpenSim.Region.CoreModules.World.Land { if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) { - MoveUserOutOfParcel(avatar); + SendYouAreBannedNotice(avatar); + } + else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) + { + avatar.ControllingClient.SendAlertMessage( + "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!)."); + } + else + { + avatar.sentMessageAboutRestrictedParcelFlyingDown = true; } } else @@ -350,47 +322,28 @@ namespace OpenSim.Region.CoreModules.World.Land } } - public void SendOutNearestBanLine(ScenePresence avatar) + public void SendOutNearestBanLine(IClientAPI avatar) { - ILandObject checkBan = null; - for (int x = -2; x <= 2; x += 2) - { - checkBan = GetLandObject(avatar.AbsolutePosition.X + x, avatar.AbsolutePosition.Y); - if (checkBan != null) - { - if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) - { - if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) - { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); - return; - } - if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) - { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); - return; - } - } - } - } - for (int y = -2; y <= 2; y += 2) + List avatars = m_scene.GetAvatars(); + foreach (ScenePresence presence in avatars) { - checkBan = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y + y); - if (checkBan != null) + if (presence.UUID == avatar.AgentId) { - if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) + List checkLandParcels = ParcelsNearPoint(presence.AbsolutePosition); + foreach (ILandObject checkBan in checkLandParcels) { - if (checkBan.IsRestrictedFromLand(avatar.ControllingClient.AgentId)) + if (checkBan.IsBannedFromLand(avatar.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar.ControllingClient); - return; + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar); + return; //Only send one } - if (checkBan.IsBannedFromLand(avatar.ControllingClient.AgentId)) + if (checkBan.IsRestrictedFromLand(avatar.AgentId)) { - checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar.ControllingClient); - return; + checkBan.SendLandProperties((int)ParcelPropertiesStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar); + return; //Only send one } } + return; } } } @@ -437,14 +390,25 @@ namespace OpenSim.Region.CoreModules.World.Land if (clientAvatar != null) { SendLandUpdate(clientAvatar); - SendOutNearestBanLine(clientAvatar); + SendOutNearestBanLine(remote_client); ILandObject parcel = GetLandObject(clientAvatar.AbsolutePosition.X, clientAvatar.AbsolutePosition.Y); if (parcel != null) { if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && + clientAvatar.sentMessageAboutRestrictedParcelFlyingDown) + { + EventManagerOnAvatarEnteringNewParcel(clientAvatar, parcel.LandData.LocalID, + m_scene.RegionInfo.RegionID); + //They are going under the safety line! + if (!parcel.IsBannedFromLand(clientAvatar.UUID)) + { + clientAvatar.sentMessageAboutRestrictedParcelFlyingDown = false; + } + } + else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && parcel.IsBannedFromLand(clientAvatar.UUID)) { - MoveUserOutOfParcel(clientAvatar); + SendYouAreBannedNotice(clientAvatar); } } } @@ -492,7 +456,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (land != null) { - if (m_scene.Permissions.CanEditParcel(agentID, land)) + if (agentID == land.LandData.OwnerID) { land.UpdateAccessList(flags, entries, remote_client); } diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 1c65965..1fa8630 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -267,7 +267,11 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsEitherBannedOrRestricted(UUID avatar) { - if (IsRestrictedFromLand(avatar) || IsBannedFromLand(avatar)) + if (IsBannedFromLand(avatar)) + { + return true; + } + else if (IsRestrictedFromLand(avatar)) { return true; } @@ -276,8 +280,7 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsBannedFromLand(UUID avatar) { - ScenePresence SP = m_scene.GetScenePresence(avatar); - if ((LandData.Flags & (uint)ParcelFlags.UseBanList) > 0) + if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); entry.AgentID = avatar; @@ -285,22 +288,8 @@ namespace OpenSim.Region.CoreModules.World.Land entry.Time = new DateTime(); if (LandData.ParcelAccessList.Contains(entry)) { - if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) > 0) - { - if (LandData.GroupID == SP.ControllingClient.ActiveGroupId) - { - return false; - } - else - { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel - return true; - } - } - else - { - return true; - } + //They are banned, so lets send them a notice about this parcel + return true; } } return false; @@ -308,8 +297,7 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsRestrictedFromLand(UUID avatar) { - ScenePresence SP = m_scene.GetScenePresence(avatar); - if ((LandData.Flags & (uint)ParcelFlags.UseAccessList) > 0) + if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); entry.AgentID = avatar; @@ -317,22 +305,8 @@ namespace OpenSim.Region.CoreModules.World.Land entry.Time = new DateTime(); if (!LandData.ParcelAccessList.Contains(entry)) { - if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) > 0) - { - if (LandData.GroupID == SP.ControllingClient.ActiveGroupId) - { - return false; - } - else - { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel - return true; - } - } - else - { - return true; - } + //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel + return true; } } return false; -- cgit v1.1 From fce9e499e4682edf6db7b4f9c5546524b4a25197 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Mar 2010 01:19:45 -0600 Subject: - parcel blocking, region crossing blocking, teleport blocking --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 1 + .../Sirikata/ClientStack/SirikataClientView.cs | 1 + .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 1 + OpenSim/Framework/IClientAPI.cs | 1 + .../Region/ClientStack/LindenUDP/LLClientView.cs | 4 + .../CoreModules/World/Land/LandManagementModule.cs | 93 ++++++++- .../Region/CoreModules/World/Land/LandObject.cs | 9 +- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 229 +++++++++++++++++++++ .../Server/IRCClientView.cs | 1 + .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 1 + OpenSim/Tests/Common/Mock/TestClient.cs | 1 + 12 files changed, 333 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 7b9faa9..f8cfe44 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -598,6 +598,7 @@ namespace OpenSim.Client.MXP.ClientStack public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index b7ead6e..3bf73d6 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -244,6 +244,7 @@ namespace OpenSim.Client.Sirikata.ClientStack public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index d51277b..894fdac 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -247,6 +247,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack public event Action OnRegionHandShakeReply = delegate { }; public event GenericCall2 OnRequestWearables = delegate { }; public event GenericCall1 OnCompleteMovementToRegion = delegate { }; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate = delegate { }; public event AgentRequestSit OnAgentRequestSit = delegate { }; public event AgentSit OnAgentSit = delegate { }; diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 7219bf8..3126e57 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -881,6 +881,7 @@ namespace OpenSim.Framework event Action OnRegionHandShakeReply; event GenericCall2 OnRequestWearables; event GenericCall1 OnCompleteMovementToRegion; + event UpdateAgent OnPreAgentUpdate; event UpdateAgent OnAgentUpdate; event AgentRequestSit OnAgentRequestSit; event AgentSit OnAgentSit; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 2c8d88b..ea73abb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -127,6 +127,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event ObjectDeselect OnObjectDetach; public event ObjectDrop OnObjectDrop; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; @@ -4880,7 +4881,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP UpdateAgent handlerAgentUpdate = OnAgentUpdate; lastarg = arg; // save this set of arguments for nexttime if (handlerAgentUpdate != null) + { + OnPreAgentUpdate(this, arg); OnAgentUpdate(this, arg); + } handlerAgentUpdate = null; } diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 8c3d17d..e0cdb36 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Reflection; using log4net; using Nini.Config; @@ -86,6 +87,7 @@ namespace OpenSim.Region.CoreModules.World.Land // caches ExtendedLandData private Cache parcelInfoCache; + private Vector3? forcedPosition = null; #region INonSharedRegionModule Members @@ -144,6 +146,13 @@ namespace OpenSim.Region.CoreModules.World.Land { } + private bool OnVerifyUserConnection(ScenePresence scenePresence, out string reason) + { + ILandObject nearestParcel = m_scene.GetNearestAllowedParcel(scenePresence.UUID, scenePresence.AbsolutePosition.X, scenePresence.AbsolutePosition.Y); + reason = "You are not allowed to enter this sim."; + return nearestParcel != null; + } + void EventManagerOnNewClient(IClientAPI client) { //Register some client events @@ -161,6 +170,7 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelInfoRequest += ClientOnParcelInfoRequest; client.OnParcelDwellRequest += ClientOnParcelDwellRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; + client.OnPreAgentUpdate += ClientOnPreAgentUpdate; EntityBase presenceEntity; if (m_scene.Entities.TryGetValue(client.AgentId, out presenceEntity) && presenceEntity is ScenePresence) @@ -170,6 +180,40 @@ namespace OpenSim.Region.CoreModules.World.Land } } + void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) + { + //If we are forcing a position for them to go + if( forcedPosition != null ) + { + ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId); + + //Putting the user into flying, both keeps the avatar in fligth when it bumps into something and stopped from going another direction AND + //When the avatar walks into a ban line on the ground, it prevents getting stuck + agentData.ControlFlags = (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; + + + //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines + if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) < .2) + { + Debug.WriteLine(string.Format("Stopping force position because {0} is close enough to position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition)); + forcedPosition = null; + } + //if we are far away, teleport + else if(Vector3.Distance(clientAvatar.AbsolutePosition,forcedPosition.Value) > 3 ) + { + Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}",forcedPosition.Value,clientAvatar.AbsolutePosition)); + clientAvatar.Teleport(forcedPosition.Value); + forcedPosition = null; + } + else + { + //Forces them toward the forced position we want if they aren't there yet + agentData.UseClientAgentPosition = true; + agentData.ClientAgentPosition = forcedPosition.Value; + } + } + } + public void PostInitialise() { @@ -275,9 +319,6 @@ namespace OpenSim.Region.CoreModules.World.Land { avatar.ControllingClient.SendAlertMessage( "You are not allowed on this parcel because you are banned. Please go away."); - - avatar.PhysicsActor.Position = avatar.lastKnownAllowedPosition; - avatar.PhysicsActor.Velocity = Vector3.Zero; } else { @@ -286,6 +327,24 @@ namespace OpenSim.Region.CoreModules.World.Land } } + + + private void ForceAvatarToPosition(ScenePresence avatar, Vector3? position) + { + if (m_scene.Permissions.IsGod(avatar.UUID)) return; + if (position.HasValue) + { + forcedPosition = position; + } + } + + public void SendYouAreRestrictedNotice(ScenePresence avatar) + { + avatar.ControllingClient.SendAlertMessage( + "You are not allowed on this parcel because the land owner has restricted access."); + + } + public void EventManagerOnAvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID) { if (m_scene.RegionInfo.RegionID == regionID) @@ -303,11 +362,12 @@ namespace OpenSim.Region.CoreModules.World.Land if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) { SendYouAreBannedNotice(avatar); + ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar)); } else if (parcelAvatarIsEntering.IsRestrictedFromLand(avatar.UUID)) { - avatar.ControllingClient.SendAlertMessage( - "You are not allowed on this parcel because the land owner has restricted access. For now, you can enter, but please respect the land owner's decisions (or he can ban you!)."); + SendYouAreRestrictedNotice(avatar); + ForceAvatarToPosition(avatar, m_scene.GetNearestAllowedPosition(avatar)); } else { @@ -408,7 +468,26 @@ namespace OpenSim.Region.CoreModules.World.Land else if (clientAvatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT && parcel.IsBannedFromLand(clientAvatar.UUID)) { - SendYouAreBannedNotice(clientAvatar); + //once we've sent the message once, keep going toward the target until we are done + if (forcedPosition == null) + { + SendYouAreBannedNotice(clientAvatar); + ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); + } + } + else if ( parcel.IsRestrictedFromLand(clientAvatar.UUID)) + { + //once we've sent the message once, keep going toward the target until we are done + if (forcedPosition == null) + { + SendYouAreRestrictedNotice(clientAvatar); + ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); + } + } + else + { + //when we are finally in a safe place, lets release the forced position lock + forcedPosition = null; } } } @@ -420,7 +499,7 @@ namespace OpenSim.Region.CoreModules.World.Land ILandObject over = GetLandObject(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); if (over != null) { - if (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT) + if (!over.IsRestrictedFromLand(avatar.UUID) && (!over.IsBannedFromLand(avatar.UUID) || avatar.AbsolutePosition.Z >= LandChannel.BAN_LINE_SAFETY_HIEGHT)) { avatar.lastKnownAllowedPosition = new Vector3(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z); diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 1fa8630..27d9fdb 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -104,7 +104,7 @@ namespace OpenSim.Region.CoreModules.World.Land /// Returns true if the piece of land contains the specified point public bool ContainsPoint(int x, int y) { - if (x >= 0 && y >= 0 && x <= Constants.RegionSize && x <= Constants.RegionSize) + if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) { return (LandBitmap[x / 4, y / 4] == true); } @@ -286,7 +286,8 @@ namespace OpenSim.Region.CoreModules.World.Land entry.AgentID = avatar; entry.Flags = AccessList.Ban; entry.Time = new DateTime(); - if (LandData.ParcelAccessList.Contains(entry)) + //See if they are on the list, but make sure the owner isn't banned + if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar ) { //They are banned, so lets send them a notice about this parcel return true; @@ -303,7 +304,9 @@ namespace OpenSim.Region.CoreModules.World.Land entry.AgentID = avatar; entry.Flags = AccessList.Access; entry.Time = new DateTime(); - if (!LandData.ParcelAccessList.Contains(entry)) + + //If they are not on the access list and are not the owner + if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) { //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel return true; diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 58e3de9..c2753d9 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 388bc99..884f13a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -27,6 +27,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -3251,6 +3252,7 @@ namespace OpenSim.Region.Framework.Scenes /// also return a reason. public bool NewUserConnection(AgentCircuitData agent, uint teleportFlags, out string reason) { + TeleportFlags tp = (TeleportFlags)teleportFlags; //Teleport flags: // // TeleportFlags.ViaGodlikeLure - Border Crossing @@ -3284,6 +3286,17 @@ namespace OpenSim.Region.Framework.Scenes CapsModule.NewUserConnection(agent); + ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); + + //On login or border crossing test land permisions + if (tp != TeleportFlags.Default) + { + if (land != null && !TestLandRestrictions(agent, land, out reason)) + { + return false; + } + } + ScenePresence sp = m_sceneGraph.GetScenePresence(agent.AgentID); if (sp != null) { @@ -3377,6 +3390,40 @@ namespace OpenSim.Region.Framework.Scenes return true; } + private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) + { + + bool banned = land.IsBannedFromLand(agent.AgentID); + bool restricted = land.IsRestrictedFromLand(agent.AgentID); + + if (banned || restricted) + { + ILandObject nearestParcel = GetNearestAllowedParcel(agent.AgentID, agent.startpos.X, agent.startpos.Y); + if (nearestParcel != null) + { + //Move agent to nearest allowed + Vector3 newPosition = GetParcelCenterAtGround(nearestParcel); + agent.startpos.X = newPosition.X; + agent.startpos.Y = newPosition.Y; + } + else + { + if (banned) + { + reason = "Cannot regioncross into banned parcel."; + } + else + { + reason = String.Format("Denied access to private region {0}: You are not on the access list for that region.", + RegionInfo.RegionName); + } + return false; + } + } + reason = ""; + return true; + } + /// /// Verifies that the user has a presence on the Grid /// @@ -3508,6 +3555,18 @@ namespace OpenSim.Region.Framework.Scenes return true; } + private ILandObject GetParcelAtPoint(float x, float y) + { + foreach (var parcel in AllParcels()) + { + if( parcel.ContainsPoint((int)x,(int)y)) + { + return parcel; + } + } + return null; + } + /// /// Update an AgentCircuitData object with new information /// @@ -4780,5 +4839,175 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_allowScriptCrossings; } } + + public Vector3? GetNearestAllowedPosition(ScenePresence avatar) + { + //simulate to make sure we have pretty up to date positions + PhysicsScene.Simulate(0); + + ILandObject nearestParcel = GetNearestAllowedParcel(avatar.UUID, avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); + + if (nearestParcel != null) + { + Vector3 dir = Vector3.Normalize(Vector3.Multiply(avatar.Velocity, -1)); + //Try to get a location that feels like where they came from + Vector3? nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); + if (nearestPoint != null) + { + Debug.WriteLine("Found a sane previous position based on velocity, sending them to: " + nearestPoint.ToString()); + return nearestPoint.Value; + } + + //Sometimes velocity might be zero (local teleport), so try finding point along path from avatar to center of nearest parcel + Vector3 directionToParcelCenter = Vector3.Subtract(GetParcelCenterAtGround(nearestParcel), avatar.AbsolutePosition); + dir = Vector3.Normalize(directionToParcelCenter); + nearestPoint = GetNearestPointInParcelAlongDirectionFromPoint(avatar.AbsolutePosition, dir, nearestParcel); + if (nearestPoint != null) + { + Debug.WriteLine("They had a zero velocity, sending them to: " + nearestPoint.ToString()); + return nearestPoint.Value; + } + + //Ultimate backup if we have no idea where they are + Debug.WriteLine("Have no idea where they are, sending them to: " + avatar.lastKnownAllowedPosition.ToString()); + return avatar.lastKnownAllowedPosition; + + } + + //Go to the edge, this happens in teleporting to a region with no available parcels + Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); + //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); + return nearestRegionEdgePoint; + return null; + } + + private Vector3 GetParcelCenterAtGround(ILandObject parcel) + { + Vector2 center = GetParcelCenter(parcel); + return GetPositionAtGround(center.X, center.Y); + } + + private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel) + { + Vector3 unitDirection = Vector3.Normalize(direction); + //Making distance to search go through some sane limit of distance + for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f) + { + Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance)); + if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y)) + { + return testPos; + } + } + return null; + } + + public ILandObject GetNearestAllowedParcel(UUID avatarId, float x, float y) + { + List all = AllParcels(); + float minParcelDistance = float.MaxValue; + ILandObject nearestParcel = null; + + foreach (var parcel in all) + { + if (!parcel.IsEitherBannedOrRestricted(avatarId)) + { + float parcelDistance = GetParcelDistancefromPoint(parcel, x, y); + if (parcelDistance < minParcelDistance) + { + minParcelDistance = parcelDistance; + nearestParcel = parcel; + } + } + } + + return nearestParcel; + } + + private List AllParcels() + { + return LandChannel.AllParcels(); + } + + private float GetParcelDistancefromPoint(ILandObject parcel, float x, float y) + { + return Vector2.Distance(new Vector2(x, y), GetParcelCenter(parcel)); + } + + //calculate the average center point of a parcel + private Vector2 GetParcelCenter(ILandObject parcel) + { + int count = 0; + int avgx = 0; + int avgy = 0; + for (int x = 0; x < Constants.RegionSize; x++) + { + for (int y = 0; y < Constants.RegionSize; y++) + { + //Just keep a running average as we check if all the points are inside or not + if (parcel.ContainsPoint(x, y)) + { + if (count == 0) + { + avgx = x; + avgy = y; + } + else + { + avgx = (avgx * count + x) / (count + 1); + avgy = (avgy * count + y) / (count + 1); + } + count += 1; + } + } + } + return new Vector2(avgx, avgy); + } + + private Vector3 GetNearestRegionEdgePosition(ScenePresence avatar) + { + float xdistance = avatar.AbsolutePosition.X < Constants.RegionSize / 2 ? avatar.AbsolutePosition.X : Constants.RegionSize - avatar.AbsolutePosition.X; + float ydistance = avatar.AbsolutePosition.Y < Constants.RegionSize / 2 ? avatar.AbsolutePosition.Y : Constants.RegionSize - avatar.AbsolutePosition.Y; + + //find out what vertical edge to go to + if (xdistance < ydistance) + { + if (avatar.AbsolutePosition.X < Constants.RegionSize / 2) + { + return GetPositionAtAvatarHeightOrGroundHeight(avatar, 0.0f, avatar.AbsolutePosition.Y); + } + else + { + return GetPositionAtAvatarHeightOrGroundHeight(avatar, Constants.RegionSize, avatar.AbsolutePosition.Y); + } + } + //find out what horizontal edge to go to + else + { + if (avatar.AbsolutePosition.Y < Constants.RegionSize / 2) + { + return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, 0.0f); + } + else + { + return GetPositionAtAvatarHeightOrGroundHeight(avatar, avatar.AbsolutePosition.X, Constants.RegionSize); + } + } + } + + private Vector3 GetPositionAtAvatarHeightOrGroundHeight(ScenePresence avatar, float x, float y) + { + Vector3 ground = GetPositionAtGround(x, y); + if( avatar.AbsolutePosition.Z > ground.Z) + { + ground.Z = avatar.AbsolutePosition.Z; + } + return ground; + } + + private Vector3 GetPositionAtGround(float x, float y) + { + return new Vector3(x, y, GetGroundHeight(x, y)); + } } } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 99e5b84..711052c 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -680,6 +680,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 15473d8..ebf9333 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -190,6 +190,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 0d9dcc6..715e1a4 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -96,6 +96,7 @@ namespace OpenSim.Tests.Common.Mock public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; public event GenericCall1 OnCompleteMovementToRegion; + public event UpdateAgent OnPreAgentUpdate; public event UpdateAgent OnAgentUpdate; public event AgentRequestSit OnAgentRequestSit; public event AgentSit OnAgentSit; -- cgit v1.1 From 689514a40a52d71f9cfaaedbb295a57b1d7c728a Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Mar 2010 23:10:14 +0000 Subject: Cache UserLevel in ScenePresence on SP creation. Change IsAdministrator to use that stored value. --- .../World/Permissions/PermissionsModule.cs | 8 +++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 28 +++++++++++++++------- 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 2211f3e..845c4c2 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -490,6 +490,14 @@ namespace OpenSim.Region.CoreModules.World.Permissions if (m_allowGridGods) { + ScenePresence sp = m_scene.GetScenePresence(user); + if (sp != null) + { + if (sp.UserLevel >= 200) + return true; + return false; + } + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, user); if (account != null) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 93e66e0..f1be4d8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -150,7 +150,8 @@ namespace OpenSim.Region.Framework.Scenes private float m_sitAvatarHeight = 2.0f; - private float m_godlevel; + private int m_godLevel; + private int m_userLevel; private bool m_invulnerable = true; @@ -304,9 +305,14 @@ namespace OpenSim.Region.Framework.Scenes get { return m_invulnerable; } } - public float GodLevel + public int UserLevel { - get { return m_godlevel; } + get { return m_userLevel; } + } + + public int GodLevel + { + get { return m_godLevel; } } public ulong RegionHandle @@ -678,6 +684,10 @@ namespace OpenSim.Region.Framework.Scenes m_regionInfo = reginfo; m_localId = m_scene.AllocateLocalId(); + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); + + m_userLevel = account.UserLevel; + IGroupsModule gm = m_scene.RequestModuleInterface(); if (gm != null) m_grouptitle = gm.GetGroupTitle(m_uuid); @@ -3164,17 +3174,17 @@ namespace OpenSim.Region.Framework.Scenes if (account != null) { if (account.UserLevel > 0) - m_godlevel = account.UserLevel; + m_godLevel = account.UserLevel; else - m_godlevel = 200; + m_godLevel = 200; } } else { - m_godlevel = 0; + m_godLevel = 0; } - ControllingClient.SendAdminResponse(token, (uint)m_godlevel); + ControllingClient.SendAdminResponse(token, (uint)m_godLevel); } #region Child Agent Updates @@ -3265,7 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes cAgent.ControlFlags = (uint)m_AgentControlFlags; if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - cAgent.GodLevel = (byte)m_godlevel; + cAgent.GodLevel = (byte)m_godLevel; else cAgent.GodLevel = (byte) 0; @@ -3354,7 +3364,7 @@ namespace OpenSim.Region.Framework.Scenes m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - m_godlevel = cAgent.GodLevel; + m_godLevel = cAgent.GodLevel; m_setAlwaysRun = cAgent.AlwaysRun; uint i = 0; -- cgit v1.1 From f6f6ef1532517972b973d8a500818dcd50873352 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 11 Mar 2010 19:12:38 -0500 Subject: Dynamics Integration Part 1 --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 11 +- OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs | 817 ----- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 3816 ++++++++++++-------- 3 files changed, 2266 insertions(+), 2378 deletions(-) delete mode 100644 OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0d19589..1353518 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -747,7 +747,16 @@ namespace OpenSim.Region.Framework.Scenes /// public Vector3 Acceleration { - get { return m_acceleration; } + get + { + PhysicsActor actor = PhysActor; + if (actor != null) + { + m_acceleration = actor.Acceleration; + } + return m_acceleration; + } + set { m_acceleration = value; } } diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs deleted file mode 100644 index b3b09e6..0000000 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEDynamics.cs +++ /dev/null @@ -1,817 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. - * - */ - -/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; -using log4net; -using OpenMetaverse; -using Ode.NET; -using OpenSim.Framework; -using OpenSim.Region.Physics.Manager; - -namespace OpenSim.Region.Physics.OdePlugin -{ - public class ODEDynamics - { - public Vehicle Type - { - get { return m_type; } - } - - public IntPtr Body - { - get { return m_body; } - } - - private int frcount = 0; // Used to limit dynamics debug output to - // every 100th frame - - // private OdeScene m_parentScene = null; - private IntPtr m_body = IntPtr.Zero; -// private IntPtr m_jointGroup = IntPtr.Zero; -// private IntPtr m_aMotor = IntPtr.Zero; - - // Vehicle properties - private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind - // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier - private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings: - // HOVER_TERRAIN_ONLY - // HOVER_GLOBAL_HEIGHT - // NO_DEFLECTION_UP - // HOVER_WATER_ONLY - // HOVER_UP_ONLY - // LIMIT_MOTOR_UP - // LIMIT_ROLL_ONLY - - // Linear properties - private Vector3 m_linearMotorDirection = Vector3.Zero; // (was m_linearMotorDirectionLASTSET) the (local) Velocity - //requested by LSL - private float m_linearMotorTimescale = 0; // Motor Attack rate set by LSL - private float m_linearMotorDecayTimescale = 0; // Motor Decay rate set by LSL - private Vector3 m_linearFrictionTimescale = Vector3.Zero; // General Friction set by LSL - - private Vector3 m_lLinMotorDVel = Vector3.Zero; // decayed motor - private Vector3 m_lLinObjectVel = Vector3.Zero; // local frame object velocity - private Vector3 m_wLinObjectVel = Vector3.Zero; // world frame object velocity - - //Angular properties - private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor - - private float m_angularMotorTimescale = 0; // motor angular Attack rate set by LSL - private float m_angularMotorDecayTimescale = 0; // motor angular Decay rate set by LSL - private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular Friction set by LSL - - private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor -// private Vector3 m_angObjectVel = Vector3.Zero; // current body angular velocity - private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body - - private Vector3 m_angularLock = Vector3.One; - - //Deflection properties - // private float m_angularDeflectionEfficiency = 0; - // private float m_angularDeflectionTimescale = 0; - // private float m_linearDeflectionEfficiency = 0; - // private float m_linearDeflectionTimescale = 0; - - //Banking properties - // private float m_bankingEfficiency = 0; - // private float m_bankingMix = 0; - // private float m_bankingTimescale = 0; - - //Hover and Buoyancy properties - private float m_VhoverHeight = 0f; -// private float m_VhoverEfficiency = 0f; - private float m_VhoverTimescale = 0f; - private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height - private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle. - // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) - // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. - // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. - - //Attractor properties - private float m_verticalAttractionEfficiency = 1.0f; // damped - private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. - - - - - - internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) - { - switch (pParam) - { - case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: - if (pValue < 0.01f) pValue = 0.01f; - // m_angularDeflectionEfficiency = pValue; - break; - case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - // m_angularDeflectionTimescale = pValue; - break; - case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_angularMotorDecayTimescale = pValue; - break; - case Vehicle.ANGULAR_MOTOR_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_angularMotorTimescale = pValue; - break; - case Vehicle.BANKING_EFFICIENCY: - if (pValue < 0.01f) pValue = 0.01f; - // m_bankingEfficiency = pValue; - break; - case Vehicle.BANKING_MIX: - if (pValue < 0.01f) pValue = 0.01f; - // m_bankingMix = pValue; - break; - case Vehicle.BANKING_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - // m_bankingTimescale = pValue; - break; - case Vehicle.BUOYANCY: - if (pValue < -1f) pValue = -1f; - if (pValue > 1f) pValue = 1f; - m_VehicleBuoyancy = pValue; - break; -// case Vehicle.HOVER_EFFICIENCY: -// if (pValue < 0f) pValue = 0f; -// if (pValue > 1f) pValue = 1f; -// m_VhoverEfficiency = pValue; -// break; - case Vehicle.HOVER_HEIGHT: - m_VhoverHeight = pValue; - break; - case Vehicle.HOVER_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_VhoverTimescale = pValue; - break; - case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: - if (pValue < 0.01f) pValue = 0.01f; - // m_linearDeflectionEfficiency = pValue; - break; - case Vehicle.LINEAR_DEFLECTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - // m_linearDeflectionTimescale = pValue; - break; - case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_linearMotorDecayTimescale = pValue; - break; - case Vehicle.LINEAR_MOTOR_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_linearMotorTimescale = pValue; - break; - case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: - if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable - if (pValue > 1.0f) pValue = 1.0f; - m_verticalAttractionEfficiency = pValue; - break; - case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; - m_verticalAttractionTimescale = pValue; - break; - - // These are vector properties but the engine lets you use a single float value to - // set all of the components to the same value - case Vehicle.ANGULAR_FRICTION_TIMESCALE: - if (pValue > 30f) pValue = 30f; - if (pValue < 0.1f) pValue = 0.1f; - m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); - break; - case Vehicle.ANGULAR_MOTOR_DIRECTION: - m_angularMotorDirection = new Vector3(pValue, pValue, pValue); - UpdateAngDecay(); - break; - case Vehicle.LINEAR_FRICTION_TIMESCALE: - m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); - break; - case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue, pValue, pValue); - UpdateLinDecay(); - break; - case Vehicle.LINEAR_MOTOR_OFFSET: - // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); - break; - - } - - }//end ProcessFloatVehicleParam - - internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) - { - switch (pParam) - { - case Vehicle.ANGULAR_FRICTION_TIMESCALE: - if (pValue.X > 30f) pValue.X = 30f; - if (pValue.X < 0.1f) pValue.X = 0.1f; - if (pValue.Y > 30f) pValue.Y = 30f; - if (pValue.Y < 0.1f) pValue.Y = 0.1f; - if (pValue.Z > 30f) pValue.Z = 30f; - if (pValue.Z < 0.1f) pValue.Z = 0.1f; - m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.ANGULAR_MOTOR_DIRECTION: - m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); - // Limit requested angular speed to 2 rps= 4 pi rads/sec - if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; - if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; - if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; - if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; - if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; - if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; - UpdateAngDecay(); - break; - case Vehicle.LINEAR_FRICTION_TIMESCALE: - m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - case Vehicle.LINEAR_MOTOR_DIRECTION: - m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, for max limiting - UpdateLinDecay(); - break; - case Vehicle.LINEAR_MOTOR_OFFSET: - // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); - break; - } - - }//end ProcessVectorVehicleParam - - internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) - { - switch (pParam) - { - case Vehicle.REFERENCE_FRAME: - // m_referenceFrame = pValue; - break; - } - - }//end ProcessRotationVehicleParam - - internal void SetAngularLock(Vector3 pValue) - { - m_angularLock = pValue; - } - - internal void ProcessFlagsVehicleSet(int flags) - { - m_flags |= (VehicleFlag)flags; - } - - internal void ProcessFlagsVehicleRemove(int flags) - { - m_flags &= ~((VehicleFlag)flags); - } - - internal void ProcessTypeChange(Vehicle pType) - { - // Set Defaults For Type - m_type = pType; - switch (pType) - { - case Vehicle.TYPE_SLED: - m_linearFrictionTimescale = new Vector3(30, 1, 1000); - m_angularFrictionTimescale = new Vector3(30, 30, 30); -// m_lLinMotorVel = Vector3.Zero; - m_linearMotorTimescale = 1000; - m_linearMotorDecayTimescale = 120; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; - m_angularMotorTimescale = 1000; - m_angularMotorDecayTimescale = 120; - m_VhoverHeight = 0; -// m_VhoverEfficiency = 1; - m_VhoverTimescale = 10; - m_VehicleBuoyancy = 0; - // m_linearDeflectionEfficiency = 1; - // m_linearDeflectionTimescale = 1; - // m_angularDeflectionEfficiency = 1; - // m_angularDeflectionTimescale = 1000; - // m_bankingEfficiency = 0; - // m_bankingMix = 1; - // m_bankingTimescale = 10; - // m_referenceFrame = Quaternion.Identity; - m_flags &= - ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - break; - case Vehicle.TYPE_CAR: - m_linearFrictionTimescale = new Vector3(100, 2, 1000); - m_angularFrictionTimescale = new Vector3(30, 30, 30); // was 1000, but sl max frict time is 30. -// m_lLinMotorVel = Vector3.Zero; - m_linearMotorTimescale = 1; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; - m_angularMotorTimescale = 1; - m_angularMotorDecayTimescale = 0.8f; - m_VhoverHeight = 0; -// m_VhoverEfficiency = 0; - m_VhoverTimescale = 1000; - m_VehicleBuoyancy = 0; - // // m_linearDeflectionEfficiency = 1; - // // m_linearDeflectionTimescale = 2; - // // m_angularDeflectionEfficiency = 0; - // m_angularDeflectionTimescale = 10; - m_verticalAttractionEfficiency = 1f; - m_verticalAttractionTimescale = 10f; - // m_bankingEfficiency = -0.2f; - // m_bankingMix = 1; - // m_bankingTimescale = 1; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | - VehicleFlag.LIMIT_MOTOR_UP); - break; - case Vehicle.TYPE_BOAT: - m_linearFrictionTimescale = new Vector3(10, 3, 2); - m_angularFrictionTimescale = new Vector3(10,10,10); -// m_lLinMotorVel = Vector3.Zero; - m_linearMotorTimescale = 5; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; - m_angularMotorTimescale = 4; - m_angularMotorDecayTimescale = 4; - m_VhoverHeight = 0; -// m_VhoverEfficiency = 0.5f; - m_VhoverTimescale = 2; - m_VehicleBuoyancy = 1; - // m_linearDeflectionEfficiency = 0.5f; - // m_linearDeflectionTimescale = 3; - // m_angularDeflectionEfficiency = 0.5f; - // m_angularDeflectionTimescale = 5; - m_verticalAttractionEfficiency = 0.5f; - m_verticalAttractionTimescale = 5f; - // m_bankingEfficiency = -0.3f; - // m_bankingMix = 0.8f; - // m_bankingTimescale = 1; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); - m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | - VehicleFlag.LIMIT_MOTOR_UP); - break; - case Vehicle.TYPE_AIRPLANE: - m_linearFrictionTimescale = new Vector3(200, 10, 5); - m_angularFrictionTimescale = new Vector3(20, 20, 20); -// m_lLinMotorVel = Vector3.Zero; - m_linearMotorTimescale = 2; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; - m_angularMotorTimescale = 4; - m_angularMotorDecayTimescale = 4; - m_VhoverHeight = 0; -// m_VhoverEfficiency = 0.5f; - m_VhoverTimescale = 1000; - m_VehicleBuoyancy = 0; - // m_linearDeflectionEfficiency = 0.5f; - // m_linearDeflectionTimescale = 3; - // m_angularDeflectionEfficiency = 1; - // m_angularDeflectionTimescale = 2; - m_verticalAttractionEfficiency = 0.9f; - m_verticalAttractionTimescale = 2f; - // m_bankingEfficiency = 1; - // m_bankingMix = 0.7f; - // m_bankingTimescale = 2; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); - break; - case Vehicle.TYPE_BALLOON: - m_linearFrictionTimescale = new Vector3(5, 5, 5); - m_angularFrictionTimescale = new Vector3(10, 10, 10); - m_linearMotorTimescale = 5; - m_linearMotorDecayTimescale = 60; - m_angularMotorDirection = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; - m_angularMotorTimescale = 6; - m_angularMotorDecayTimescale = 10; - m_VhoverHeight = 5; -// m_VhoverEfficiency = 0.8f; - m_VhoverTimescale = 10; - m_VehicleBuoyancy = 1; - // m_linearDeflectionEfficiency = 0; - // m_linearDeflectionTimescale = 5; - // m_angularDeflectionEfficiency = 0; - // m_angularDeflectionTimescale = 5; - m_verticalAttractionEfficiency = 1f; - m_verticalAttractionTimescale = 100f; - // m_bankingEfficiency = 0; - // m_bankingMix = 0.7f; - // m_bankingTimescale = 5; - // m_referenceFrame = Quaternion.Identity; - m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | - VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); - m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); - break; - - } - }//end SetDefaultsForType - - internal void Enable(IntPtr pBody, OdeScene pParentScene) - { - if (m_type == Vehicle.TYPE_NONE) - return; - - m_body = pBody; - } - - internal void Step(float pTimestep, OdeScene pParentScene) - { - if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) - return; - frcount++; // used to limit debug comment output - if (frcount > 24) - frcount = 0; - - MoveLinear(pTimestep, pParentScene); - MoveAngular(pTimestep); - }// end Step - - internal void Halt() - { // Kill all motions, when non-physical - m_linearMotorDirection = Vector3.Zero; - m_lLinMotorDVel = Vector3.Zero; - m_lLinObjectVel = Vector3.Zero; - m_wLinObjectVel = Vector3.Zero; - m_angularMotorDirection = Vector3.Zero; - m_lastAngularVelocity = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; - } - - private void UpdateLinDecay() - { - if (Math.Abs(m_linearMotorDirection.X) > Math.Abs(m_lLinMotorDVel.X)) m_lLinMotorDVel.X = m_linearMotorDirection.X; - if (Math.Abs(m_linearMotorDirection.Y) > Math.Abs(m_lLinMotorDVel.Y)) m_lLinMotorDVel.Y = m_linearMotorDirection.Y; - if (Math.Abs(m_linearMotorDirection.Z) > Math.Abs(m_lLinMotorDVel.Z)) m_lLinMotorDVel.Z = m_linearMotorDirection.Z; - } // else let the motor decay on its own - - private void MoveLinear(float pTimestep, OdeScene _pParentScene) - { - Vector3 acceleration = new Vector3(0f, 0f, 0f); - - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object - Quaternion irotq = Quaternion.Inverse(rotq); - d.Vector3 velnow = d.BodyGetLinearVel(Body); // this is in world frame - Vector3 vel_now = new Vector3(velnow.X, velnow.Y, velnow.Z); - acceleration = vel_now - m_wLinObjectVel; - m_lLinObjectVel = vel_now * irotq; - - if (m_linearMotorDecayTimescale < 300.0f) //setting of 300 or more disables decay rate - { - if ( Vector3.Mag(m_lLinMotorDVel) < 1.0f) - { - float decayfactor = m_linearMotorDecayTimescale/pTimestep; - Vector3 decayAmount = (m_lLinMotorDVel/decayfactor); - m_lLinMotorDVel -= decayAmount; - } - else - { - float decayfactor = 3.0f - (0.57f * (float)Math.Log((double)(m_linearMotorDecayTimescale))); - Vector3 decel = Vector3.Normalize(m_lLinMotorDVel) * decayfactor * pTimestep; - m_lLinMotorDVel -= decel; - } - if (m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) - { - m_lLinMotorDVel = Vector3.Zero; - } - else - { - if (Math.Abs(m_lLinMotorDVel.X) < Math.Abs(m_lLinObjectVel.X)) m_lLinObjectVel.X = m_lLinMotorDVel.X; - if (Math.Abs(m_lLinMotorDVel.Y) < Math.Abs(m_lLinObjectVel.Y)) m_lLinObjectVel.Y = m_lLinMotorDVel.Y; - if (Math.Abs(m_lLinMotorDVel.Z) < Math.Abs(m_lLinObjectVel.Z)) m_lLinObjectVel.Z = m_lLinMotorDVel.Z; - } - } - - if ( (! m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! m_lLinObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) - { - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); - if (m_linearMotorTimescale < 300.0f) - { - Vector3 attack_error = m_lLinMotorDVel - m_lLinObjectVel; - float linfactor = m_linearMotorTimescale/pTimestep; - Vector3 attackAmount = (attack_error/linfactor) * 1.3f; - m_lLinObjectVel += attackAmount; - } - if (m_linearFrictionTimescale.X < 300.0f) - { - float fricfactor = m_linearFrictionTimescale.X / pTimestep; - float fricX = m_lLinObjectVel.X / fricfactor; - m_lLinObjectVel.X -= fricX; - } - if (m_linearFrictionTimescale.Y < 300.0f) - { - float fricfactor = m_linearFrictionTimescale.Y / pTimestep; - float fricY = m_lLinObjectVel.Y / fricfactor; - m_lLinObjectVel.Y -= fricY; - } - if (m_linearFrictionTimescale.Z < 300.0f) - { - float fricfactor = m_linearFrictionTimescale.Z / pTimestep; -//if(frcount == 0) Console.WriteLine("Zfric={0}", fricfactor); - float fricZ = m_lLinObjectVel.Z / fricfactor; - m_lLinObjectVel.Z -= fricZ; - } - } - m_wLinObjectVel = m_lLinObjectVel * rotq; - // Add Gravity and Buoyancy - Vector3 grav = Vector3.Zero; - if(m_VehicleBuoyancy < 1.0f) - { - // There is some gravity, make a gravity force vector - // that is applied after object velocity. - d.Mass objMass; - d.BodyGetMass(Body, out objMass); - // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; - grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); // Applied later as a force - } // else its 1.0, no gravity. - - // Check if hovering - if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) - { - // We should hover, get the target height - d.Vector3 pos = d.BodyGetPosition(Body); - if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) - { - m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight; - } - else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) - { - m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; - } - else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) - { - m_VhoverTargetHeight = m_VhoverHeight; - } - - if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) - { - // If body is aready heigher, use its height as target height - if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; - } - -// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped -// m_VhoverTimescale = 0f; // time to acheive height -// pTimestep is time since last frame,in secs - float herr0 = pos.Z - m_VhoverTargetHeight; - // Replace Vertical speed with correction figure if significant - if(Math.Abs(herr0) > 0.01f ) - { - d.Mass objMass; - d.BodyGetMass(Body, out objMass); - m_wLinObjectVel.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale); - //KF: m_VhoverEfficiency is not yet implemented - } - else - { - m_wLinObjectVel.Z = 0f; - } - } - else - { // not hovering, Gravity rules - m_wLinObjectVel.Z = vel_now.Z; -//if(frcount == 0) Console.WriteLine(" Z {0} a.Z {1}", m_wLinObjectVel.Z, acceleration.Z); - } - // Apply velocity - d.BodySetLinearVel(Body, m_wLinObjectVel.X, m_wLinObjectVel.Y, m_wLinObjectVel.Z); - // apply gravity force - d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); -//if(frcount == 0) Console.WriteLine("Grav {0}", grav); - } // end MoveLinear() - - private void UpdateAngDecay() - { - if (Math.Abs(m_angularMotorDirection.X) > Math.Abs(m_angularMotorDVel.X)) m_angularMotorDVel.X = m_angularMotorDirection.X; - if (Math.Abs(m_angularMotorDirection.Y) > Math.Abs(m_angularMotorDVel.Y)) m_angularMotorDVel.Y = m_angularMotorDirection.Y; - if (Math.Abs(m_angularMotorDirection.Z) > Math.Abs(m_angularMotorDVel.Z)) m_angularMotorDVel.Z = m_angularMotorDirection.Z; - } // else let the motor decay on its own - - private void MoveAngular(float pTimestep) - { - /* - private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor - - private float m_angularMotorTimescale = 0; // motor angular Attack rate set by LSL - private float m_angularMotorDecayTimescale = 0; // motor angular Decay rate set by LSL - private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular Friction set by LSL - - private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor - private Vector3 m_angObjectVel = Vector3.Zero; // what was last applied to body - */ -//if(frcount == 0) Console.WriteLine("MoveAngular "); - - // Get what the body is doing, this includes 'external' influences - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object - Quaternion irotq = Quaternion.Inverse(rotq); - d.Vector3 angularObjectVel = d.BodyGetAngularVel(Body); - Vector3 angObjectVel = new Vector3(angularObjectVel.X, angularObjectVel.Y, angularObjectVel.Z); - angObjectVel = angObjectVel * irotq; // ============ Converts to LOCAL rotation - -//if(frcount == 0) Console.WriteLine("V0 = {0}", angObjectVel); -// Vector3 FrAaccel = m_lastAngularVelocity - angObjectVel; -// Vector3 initavel = angObjectVel; - // Decay Angular Motor 1. In SL this also depends on attack rate! decay ~= 23/Attack. - float atk_decayfactor = 23.0f / (m_angularMotorTimescale * pTimestep); - m_angularMotorDVel -= m_angularMotorDVel / atk_decayfactor; - // Decay Angular Motor 2. - if (m_angularMotorDecayTimescale < 300.0f) - { -//#### - if ( Vector3.Mag(m_angularMotorDVel) < 1.0f) - { - float decayfactor = (m_angularMotorDecayTimescale)/pTimestep; - Vector3 decayAmount = (m_angularMotorDVel/decayfactor); - m_angularMotorDVel -= decayAmount; - } - else - { - Vector3 decel = Vector3.Normalize(m_angularMotorDVel) * pTimestep / m_angularMotorDecayTimescale; - m_angularMotorDVel -= decel; - } - - if (m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) - { - m_angularMotorDVel = Vector3.Zero; - } - else - { - if (Math.Abs(m_angularMotorDVel.X) < Math.Abs(angObjectVel.X)) angObjectVel.X = m_angularMotorDVel.X; - if (Math.Abs(m_angularMotorDVel.Y) < Math.Abs(angObjectVel.Y)) angObjectVel.Y = m_angularMotorDVel.Y; - if (Math.Abs(m_angularMotorDVel.Z) < Math.Abs(angObjectVel.Z)) angObjectVel.Z = m_angularMotorDVel.Z; - } - } // end decay angular motor -//if(frcount == 0) Console.WriteLine("MotorDvel {0} Obj {1}", m_angularMotorDVel, angObjectVel); - -//if(frcount == 0) Console.WriteLine("VA = {0}", angObjectVel); - // Vertical attractor section - Vector3 vertattr = Vector3.Zero; - - if(m_verticalAttractionTimescale < 300) - { - float VAservo = 1.0f / (m_verticalAttractionTimescale * pTimestep); - // get present body rotation -// d.Quaternion rot = d.BodyGetQuaternion(Body); -// Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); - // make a vector pointing up - Vector3 verterr = Vector3.Zero; - verterr.Z = 1.0f; - // rotate it to Body Angle - verterr = verterr * rotq; - // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. - // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go - // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. - - if (verterr.Z < 0.0f) - { // Deflection from vertical exceeds 90-degrees. This method will ensure stable return to - // vertical, BUT for some reason a z-rotation is imparted to the object. TBI. -//Console.WriteLine("InvertFlip"); - verterr.X = 2.0f - verterr.X; - verterr.Y = 2.0f - verterr.Y; - } - verterr *= 0.5f; - // verterror is 0 (no error) to +/- 1 (max error at 180-deg tilt) - - if ((!angObjectVel.ApproxEquals(Vector3.Zero, 0.001f)) || (verterr.Z < 0.49f)) - { -//if(frcount == 0) - // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so - // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. - vertattr.X = verterr.Y; - vertattr.Y = - verterr.X; - vertattr.Z = 0f; -//if(frcount == 0) Console.WriteLine("VAerr=" + verterr); - - // scaling appears better usingsquare-law - float damped = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; - float bounce = 1.0f - damped; - // 0 = crit damp, 1 = bouncy - float oavz = angObjectVel.Z; // retain z velocity - angObjectVel = (angObjectVel + (vertattr * VAservo * 0.0333f)) * bounce; // The time-scaled correction, which sums, therefore is bouncy - angObjectVel = angObjectVel + (vertattr * VAservo * 0.0667f * damped); // damped, good @ < 90. - angObjectVel.Z = oavz; -//if(frcount == 0) Console.WriteLine("VA+"); -//Console.WriteLine("VAttr {0} OAvel {1}", vertattr, angObjectVel); - } - else - { - // else error is very small - angObjectVel.X = 0f; - angObjectVel.Y = 0f; -//if(frcount == 0) Console.WriteLine("VA0"); - } - } // else vertical attractor is off -//if(frcount == 0) Console.WriteLine("V1 = {0}", angObjectVel); - - if ( (! m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! angObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) - { // if motor or object have motion - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); - - if (m_angularMotorTimescale < 300.0f) - { - Vector3 attack_error = m_angularMotorDVel - angObjectVel; - float angfactor = m_angularMotorTimescale/pTimestep; - Vector3 attackAmount = (attack_error/angfactor); - angObjectVel += attackAmount; -//if(frcount == 0) Console.WriteLine("Accel {0} Attk {1}",FrAaccel, attackAmount); -//if(frcount == 0) Console.WriteLine("V2+= {0}", angObjectVel); - } - - angObjectVel.X -= angObjectVel.X / (m_angularFrictionTimescale.X * 0.7f / pTimestep); - angObjectVel.Y -= angObjectVel.Y / (m_angularFrictionTimescale.Y * 0.7f / pTimestep); - angObjectVel.Z -= angObjectVel.Z / (m_angularFrictionTimescale.Z * 0.7f / pTimestep); - } // else no signif. motion - -//if(frcount == 0) Console.WriteLine("Dmotor {0} Obj {1}", m_angularMotorDVel, angObjectVel); - // Bank section tba - // Deflection section tba -//if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); - - m_lastAngularVelocity = angObjectVel; -/* - if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.0001f)) - { - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); - } - else - { - m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero. - } - */ -//if(frcount == 0) Console.WriteLine("angularLock {0}", m_angularLock); - - if (!m_angularLock.ApproxEquals(Vector3.One, 0.003f)) - { - if (m_angularLock.X == 0) - m_lastAngularVelocity.X = 0f; - if (m_angularLock.Y == 0) - m_lastAngularVelocity.Y = 0f; - if (m_angularLock.Z == 0) - m_lastAngularVelocity.Z = 0f; - } - // Apply to the body -// Vector3 aInc = m_lastAngularVelocity - initavel; -//if(frcount == 0) Console.WriteLine("Inc {0}", aInc); - m_lastAngularVelocity = m_lastAngularVelocity * rotq; // ================ Converts to WORLD rotation - - d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); -//if(frcount == 0) Console.WriteLine("V4 = {0}", m_lastAngularVelocity); - - } //end MoveAngular - } -} diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index fb6cb55..5d24388 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -22,32 +22,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. + * Revised March 5th 2010 by Kitto Flora. ODEDynamics.cs + * rolled into ODEPrim.cs */ -/* - * Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces - * ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised: - * ODEPrim.cs contains methods dealing with Prim editing, Prim - * characteristics and Kinetic motion. - * ODEDynamics.cs contains methods dealing with Prim Physical motion - * (dynamics) and the associated settings. Old Linear and angular - * motors for dynamic motion have been replace with MoveLinear() - * and MoveAngular(); 'Physical' is used only to switch ODE dynamic - * simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_ is to - * switch between 'VEHICLE' parameter use and general dynamics - * settings use. - */ using System; using System.Collections.Generic; using System.Reflection; @@ -59,6 +37,7 @@ using Ode.NET; using OpenSim.Framework; using OpenSim.Region.Physics.Manager; + namespace OpenSim.Region.Physics.OdePlugin { /// @@ -102,8 +81,8 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_APIDDamping = 0.5f; private bool m_useAPID = false; - // KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), - // and are for non-VEHICLES only. + // These next 7 params apply to llSetHoverHeight(float height, integer water, float tau), + // do not confuse with VEHICLE HOVER private float m_PIDHoverHeight; private float m_PIDHoverTau; @@ -112,7 +91,7 @@ namespace OpenSim.Region.Physics.OdePlugin private float m_targetHoverHeight; private float m_groundHeight; private float m_waterHeight; - private float m_buoyancy; //KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle. + private float m_buoyancy; //m_buoyancy set by llSetBuoyancy() // private float m_tensor = 5f; private int body_autodisable_frames = 20; @@ -183,7 +162,7 @@ namespace OpenSim.Region.Physics.OdePlugin public bool outofBounds; private float m_density = 10.000006836f; // Aluminum g/cm3; - public bool _zeroFlag; + public bool _zeroFlag; // if body has been stopped private bool m_lastUpdateSent; public IntPtr Body = IntPtr.Zero; @@ -198,18 +177,81 @@ namespace OpenSim.Region.Physics.OdePlugin public volatile bool childPrim; - private ODEDynamics m_vehicle; - internal int m_material = (int)Material.Wood; private int frcount = 0; // Used to limit dynamics debug output to + private IntPtr m_body = IntPtr.Zero; + + // Vehicle properties ============================================================================================ + private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind + // private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier + private VehicleFlag m_flags = (VehicleFlag) 0; // Bit settings: + // HOVER_TERRAIN_ONLY + // HOVER_GLOBAL_HEIGHT + // NO_DEFLECTION_UP + // HOVER_WATER_ONLY + // HOVER_UP_ONLY + // LIMIT_MOTOR_UP + // LIMIT_ROLL_ONLY + + // Linear properties + private Vector3 m_linearMotorDirection = Vector3.Zero; // (was m_linearMotorDirectionLASTSET) the (local) Velocity + //requested by LSL + private float m_linearMotorTimescale = 0; // Motor Attack rate set by LSL + private float m_linearMotorDecayTimescale = 0; // Motor Decay rate set by LSL + private Vector3 m_linearFrictionTimescale = Vector3.Zero; // General Friction set by LSL + + private Vector3 m_lLinMotorDVel = Vector3.Zero; // decayed motor + private Vector3 m_lLinObjectVel = Vector3.Zero; // local frame object velocity + private Vector3 m_wLinObjectVel = Vector3.Zero; // world frame object velocity + + //Angular properties + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + + private float m_angularMotorTimescale = 0; // motor angular Attack rate set by LSL + private float m_angularMotorDecayTimescale = 0; // motor angular Decay rate set by LSL + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular Friction set by LSL + + private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor +// private Vector3 m_angObjectVel = Vector3.Zero; // current body angular velocity + private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body + + private Vector3 m_angularLock = Vector3.One; + + //Deflection properties + // private float m_angularDeflectionEfficiency = 0; + // private float m_angularDeflectionTimescale = 0; + // private float m_linearDeflectionEfficiency = 0; + // private float m_linearDeflectionTimescale = 0; + + //Banking properties + // private float m_bankingEfficiency = 0; + // private float m_bankingMix = 0; + // private float m_bankingTimescale = 0; + + //Hover and Buoyancy properties + private float m_VhoverHeight = 0f; +// private float m_VhoverEfficiency = 0f; + private float m_VhoverTimescale = 0f; + private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height + private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle. + // Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity) + // KF: So far I have found no good method to combine a script-requested .Z velocity and gravity. + // Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity. + + //Attractor properties + private float m_verticalAttractionEfficiency = 1.0f; // damped + private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor. + + + + + public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size, Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode) { - m_vehicle = new ODEDynamics(); - //gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned); ode = dode; if (!pos.IsFinite()) { @@ -302,7 +344,7 @@ namespace OpenSim.Region.Physics.OdePlugin { set { - +Console.WriteLine("Sel {0} {1} {2}", m_primName, value, m_isphysical); // This only makes the object not collidable if the object // is physical or the object is modified somehow *IN THE FUTURE* // without this, if an avatar selects prim, they can walk right @@ -322,326 +364,563 @@ namespace OpenSim.Region.Physics.OdePlugin } } - public void SetGeom(IntPtr geom) + public override bool IsPhysical { - prev_geom = prim_geom; - prim_geom = geom; -//Console.WriteLine("SetGeom to " + prim_geom + " for " + m_primName); - if (prim_geom != IntPtr.Zero) - { - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + get { return m_isphysical; } + set + { + m_isphysical = value; + if (!m_isphysical) + { // Zero the remembered last velocity + m_lastVelocity = Vector3.Zero; + if (m_type != Vehicle.TYPE_NONE) Halt(); + } } + } - if (childPrim) + public void setPrimForRemoval() + { + m_taintremove = true; + } + + public override bool Flying + { + // no flying prims for you + get { return false; } + set { } + } + + public override bool IsColliding + { + get { return iscolliding; } + set { iscolliding = value; } + } + + public override bool CollidingGround + { + get { return false; } + set { return; } + } + + public override bool CollidingObj + { + get { return false; } + set { return; } + } + + public override bool ThrottleUpdates + { + get { return m_throttleUpdates; } + set { m_throttleUpdates = value; } + } + + public override bool Stopped + { + get { return _zeroFlag; } + } + + public override Vector3 Position + { + get { return _position; } + + set { _position = value; + //m_log.Info("[PHYSICS]: " + _position.ToString()); + } + } + + public override Vector3 Size + { + get { return _size; } + set { - if (_parent != null && _parent is OdePrim) + if (value.IsFinite()) { - OdePrim parent = (OdePrim)_parent; -//Console.WriteLine("SetGeom calls ChildSetGeom"); - parent.ChildSetGeom(this); + _size = value; + } + else + { + m_log.Warn("[PHYSICS]: Got NaN Size on object"); } } - //m_log.Warn("Setting Geom to: " + prim_geom); } - + public override float Mass + { + get { return CalculateMass(); } + } - public void enableBodySoft() + public override Vector3 Force { - if (!childPrim) + //get { return Vector3.Zero; } + get { return m_force; } + set { - if (m_isphysical && Body != IntPtr.Zero) + if (value.IsFinite()) { - d.BodyEnable(Body); - if (m_vehicle.Type != Vehicle.TYPE_NONE) - m_vehicle.Enable(Body, _parent_scene); + m_force = value; + } + else + { + m_log.Warn("[PHYSICS]: NaN in Force Applied to an Object"); } - - m_disabled = false; } } - public void disableBodySoft() + public override int VehicleType { - m_disabled = true; + get { return (int)m_type; } + set { ProcessTypeChange((Vehicle)value); } + } - if (m_isphysical && Body != IntPtr.Zero) - { - d.BodyDisable(Body); - } + public override void VehicleFloatParam(int param, float value) + { + ProcessFloatVehicleParam((Vehicle) param, value); } - public void enableBody() + public override void VehicleVectorParam(int param, Vector3 value) { - // Don't enable this body if we're a child prim - // this should be taken care of in the parent function not here - if (!childPrim) + ProcessVectorVehicleParam((Vehicle) param, value); + } + + public override void VehicleRotationParam(int param, Quaternion rotation) + { + ProcessRotationVehicleParam((Vehicle) param, rotation); + } + + public override void VehicleFlagsSet(int flags) + { + ProcessFlagsVehicleSet(flags); + } + + public override void VehicleFlagsRemove(int flags) + { + ProcessFlagsVehicleRemove(flags); + } + + public override void SetVolumeDetect(int param) + { + lock (_parent_scene.OdeLock) { - // Sets the geom to a body - Body = d.BodyCreate(_parent_scene.world); + m_isVolumeDetect = (param!=0); + } + } - setMass(); - d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); - myrot.X = _orientation.X; - myrot.Y = _orientation.Y; - myrot.Z = _orientation.Z; - myrot.W = _orientation.W; - d.BodySetQuaternion(Body, ref myrot); - d.GeomSetBody(prim_geom, Body); - m_collisionCategories |= CollisionCategories.Body; - m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + public override Vector3 CenterOfMass + { + get { return Vector3.Zero; } + } - d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + public override Vector3 GeometricCenter + { + get { return Vector3.Zero; } + } - d.BodySetAutoDisableFlag(Body, true); - d.BodySetAutoDisableSteps(Body, body_autodisable_frames); - - // disconnect from world gravity so we can apply buoyancy - d.BodySetGravityMode (Body, false); + public override PrimitiveBaseShape Shape + { + set + { + _pbs = value; + m_taintshape = true; + } + } - m_interpenetrationcount = 0; - m_collisionscore = 0; - m_disabled = false; + public override Vector3 Velocity + { + get + { + // Averate previous velocity with the new one so + // client object interpolation works a 'little' better + if (_zeroFlag) + return Vector3.Zero; - // The body doesn't already have a finite rotation mode set here - /* ### if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0.0f)) && _parent == null) + Vector3 returnVelocity = Vector3.Zero; + returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2; + returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2; + returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2; + return returnVelocity; + } + set + { + if (value.IsFinite()) { - createAMotor(m_angularlock); - } */ - if (m_vehicle.Type != Vehicle.TYPE_NONE) + _velocity = value; + + m_taintVelocity = value; + _parent_scene.AddPhysicsActorTaint(this); + } + else { - m_vehicle.Enable(Body, _parent_scene); + m_log.Warn("[PHYSICS]: Got NaN Velocity in Object"); } - _parent_scene.addActivePrim(this); } } - #region Mass Calculation - - private float CalculateMass() + public override Vector3 Torque { - float volume = 0; - - // No material is passed to the physics engines yet.. soo.. - // we're using the m_density constant in the class definition + get + { + if (!m_isphysical || Body == IntPtr.Zero) + return Vector3.Zero; - float returnMass = 0; + return _torque; + } - switch (_pbs.ProfileShape) + set { - case ProfileShape.Square: - // Profile Volume - - volume = _size.X*_size.Y*_size.Z; + if (value.IsFinite()) + { + m_taintTorque = value; + _parent_scene.AddPhysicsActorTaint(this); + } + else + { + m_log.Warn("[PHYSICS]: Got NaN Torque in Object"); + } + } + } - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage + public override float CollisionScore + { + get { return m_collisionscore; } + set { m_collisionscore = value; } + } - if (((float) _pbs.ProfileHollow/50000f) > 0.0) - { - float hollowAmount = (float) _pbs.ProfileHollow/50000f; + public override bool Kinematic + { + get { return false; } + set { } + } - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) - { - case HollowShape.Square: - case HollowShape.Same: - // Cube Hollow volume calculation - float hollowsizex = _size.X*hollowAmount; - float hollowsizey = _size.Y*hollowAmount; - float hollowsizez = _size.Z*hollowAmount; - hollowVolume = hollowsizex*hollowsizey*hollowsizez; - break; + public override Quaternion Orientation + { + get { return _orientation; } + set + { + if (QuaternionIsFinite(value)) + { + _orientation = value; + } + else + m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object"); - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X/2; - float hLength = _size.Z; + } + } + + + public override bool FloatOnWater + { + set { + m_taintCollidesWater = value; + _parent_scene.AddPhysicsActorTaint(this); + } + } - // pi * r2 * h - hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount); - break; + public override void SetMomentum(Vector3 momentum) + { + } - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + public override Vector3 PIDTarget + { + set + { + if (value.IsFinite()) + { + m_PIDTarget = value; + } + else + m_log.Warn("[PHYSICS]: Got NaN PIDTarget from Scene on Object"); + } + } + public override bool PIDActive { set { m_usePID = value; } } + public override float PIDTau { set { m_PIDTau = value; } } + + // For RotLookAt + public override Quaternion APIDTarget { set { m_APIDTarget = value; } } + public override bool APIDActive { set { m_useAPID = value; } } + public override float APIDStrength { set { m_APIDStrength = value; } } + public override float APIDDamping { set { m_APIDDamping = value; } } - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); - break; + public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } + public override bool PIDHoverActive { set { m_useHoverPID = value; } } + public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } + public override float PIDHoverTau { set { m_PIDHoverTau = value; } } - default: - hollowVolume = 0; - break; - } - volume = volume - hollowVolume; - } + internal static bool QuaternionIsFinite(Quaternion q) + { + if (Single.IsNaN(q.X) || Single.IsInfinity(q.X)) + return false; + if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y)) + return false; + if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z)) + return false; + if (Single.IsNaN(q.W) || Single.IsInfinity(q.W)) + return false; + return true; + } - break; - case ProfileShape.Circle: - if (_pbs.PathCurve == (byte)Extrusion.Straight) - { - // Cylinder - float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z); - float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z); + public override Vector3 Acceleration + { + get { return _acceleration; } + } - // Approximating the cylinder's irregularity. - if (volume1 > volume2) - { - volume = (float)volume1 - (volume1 - volume2); - } - else if (volume2 > volume1) - { - volume = (float)volume2 - (volume2 - volume1); - } - else - { - // Regular cylinder - volume = volume1; - } - } - else - { - // We don't know what the shape is yet, so use default - volume = _size.X * _size.Y * _size.Z; - } - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage - if (((float)_pbs.ProfileHollow / 50000f) > 0.0) - { - float hollowAmount = (float)_pbs.ProfileHollow / 50000f; + public void SetAcceleration(Vector3 accel) // No one calls this, and it would not do anything. + { + _acceleration = accel; + } - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) - { - case HollowShape.Same: - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X / 2; - float hLength = _size.Z; + public override void AddForce(Vector3 force, bool pushforce) + { + if (force.IsFinite()) + { + lock (m_forcelist) + m_forcelist.Add(force); - // pi * r2 * h - hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); - break; + m_taintforce = true; + } + else + { + m_log.Warn("[PHYSICS]: Got Invalid linear force vector from Scene in Object"); + } + //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString()); + } - case HollowShape.Square: - // Cube Hollow volume calculation - float hollowsizex = _size.X * hollowAmount; - float hollowsizey = _size.Y * hollowAmount; - float hollowsizez = _size.Z * hollowAmount; - hollowVolume = hollowsizex * hollowsizey * hollowsizez; - break; + public override void AddAngularForce(Vector3 force, bool pushforce) + { + if (force.IsFinite()) + { + m_angularforcelist.Add(force); + m_taintaddangularforce = true; + } + else + { + m_log.Warn("[PHYSICS]: Got Invalid Angular force vector from Scene in Object"); + } + } - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + public override Vector3 RotationalVelocity + { + get + { +/* Vector3 pv = Vector3.Zero; + if (_zeroFlag) + return pv; + m_lastUpdateSent = false; - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); - break; + if (m_rotationalVelocity.ApproxEquals(pv, 0.2f)) + return pv; +*/ + return m_rotationalVelocity; + } + set + { + if (value.IsFinite()) + { + m_rotationalVelocity = value; + } + else + { + m_log.Warn("[PHYSICS]: Got NaN RotationalVelocity in Object"); + } + } + } - default: - hollowVolume = 0; - break; - } - volume = volume - hollowVolume; - } - break; + public override void CrossingFailure() + { + m_crossingfailures++; + if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { + base.RaiseOutOfBounds(_position); + return; + } + else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { + m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName); + } + } - case ProfileShape.HalfCircle: - if (_pbs.PathCurve == (byte)Extrusion.Curve1) - { - if (_size.X == _size.Y && _size.Y == _size.Z) - { - // regular sphere - // v = 4/3 * pi * r^3 - float sradius3 = (float)Math.Pow((_size.X / 2), 3); - volume = (float)((4f / 3f) * Math.PI * sradius3); - } - else - { - // we treat this as a box currently - volume = _size.X * _size.Y * _size.Z; - } - } - else - { - // We don't know what the shape is yet, so use default - volume = _size.X * _size.Y * _size.Z; - } - break; + public override float Buoyancy + { + get { return m_buoyancy; } + set { m_buoyancy = value; } + } - case ProfileShape.EquilateralTriangle: - /* - v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h + public override void link(PhysicsActor obj) + { + m_taintparent = obj; + } - // seed mesh - Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); - Vertex PM = new Vertex(+0.5f, 0f, 0.0f); - Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f); - */ - float xA = -0.25f * _size.X; - float yA = -0.45f * _size.Y; + public override void delink() + { + m_taintparent = null; + } - float xB = 0.5f * _size.X; - float yB = 0; + public override void LockAngularMotion(Vector3 axis) + { + // reverse the zero/non zero values for ODE. + if (axis.IsFinite()) + { + axis.X = (axis.X > 0) ? 1f : 0f; + axis.Y = (axis.Y > 0) ? 1f : 0f; + axis.Z = (axis.Z > 0) ? 1f : 0f; + m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); + m_taintAngularLock = axis; + } + else + { + m_log.Warn("[PHYSICS]: Got NaN locking axis from Scene on Object"); + } + } - float xC = -0.25f * _size.X; - float yC = 0.45f * _size.Y; - volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); + public void SetGeom(IntPtr geom) + { + prev_geom = prim_geom; + prim_geom = geom; +//Console.WriteLine("SetGeom to " + prim_geom + " for " + m_primName); + if (prim_geom != IntPtr.Zero) + { + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + + if (childPrim) + { + if (_parent != null && _parent is OdePrim) + { + OdePrim parent = (OdePrim)_parent; +//Console.WriteLine("SetGeom calls ChildSetGeom"); + parent.ChildSetGeom(this); + } + } + //m_log.Warn("Setting Geom to: " + prim_geom); + } + + public void enableBodySoft() + { + if (!childPrim) + { + if (m_isphysical && Body != IntPtr.Zero) + { + d.BodyEnable(Body); + if (m_type != Vehicle.TYPE_NONE) + Enable(Body, _parent_scene); + } + + m_disabled = false; + } + } + + public void disableBodySoft() + { + m_disabled = true; + + if (m_isphysical && Body != IntPtr.Zero) + { + d.BodyDisable(Body); + } + } + + public void enableBody() + { + // Don't enable this body if we're a child prim + // this should be taken care of in the parent function not here + if (!childPrim) + { + // Sets the geom to a body + Body = d.BodyCreate(_parent_scene.world); + + setMass(); + d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + d.BodySetQuaternion(Body, ref myrot); + d.GeomSetBody(prim_geom, Body); + m_collisionCategories |= CollisionCategories.Body; + m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); + + d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + + d.BodySetAutoDisableFlag(Body, true); + d.BodySetAutoDisableSteps(Body, body_autodisable_frames); + + // disconnect from world gravity so we can apply buoyancy + d.BodySetGravityMode (Body, false); + + m_interpenetrationcount = 0; + m_collisionscore = 0; + m_disabled = false; + + if (m_type != Vehicle.TYPE_NONE) + { + Enable(Body, _parent_scene); + } + + _parent_scene.addActivePrim(this); + } + } + + #region Mass Calculation + + private float CalculateMass() + { + float volume = 0; + + // No material is passed to the physics engines yet.. soo.. + // we're using the m_density constant in the class definition + + float returnMass = 0; + + switch (_pbs.ProfileShape) + { + case ProfileShape.Square: + // Profile Volume + + volume = _size.X*_size.Y*_size.Z; // If the user has 'hollowed out' // ProfileHollow is one of those 0 to 50000 values :P // we like percentages better.. so turning into a percentage - float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f); - if (((float)fhollowFactor / 50000f) > 0.0) + + if (((float) _pbs.ProfileHollow/50000f) > 0.0) { - float hollowAmount = (float)fhollowFactor / 50000f; + float hollowAmount = (float) _pbs.ProfileHollow/50000f; // calculate the hollow volume by it's shape compared to the prim shape float hollowVolume = 0; switch (_pbs.HollowShape) { - case HollowShape.Same: - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y - - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); - break; - case HollowShape.Square: + case HollowShape.Same: // Cube Hollow volume calculation - float hollowsizex = _size.X * hollowAmount; - float hollowsizey = _size.Y * hollowAmount; - float hollowsizez = _size.Z * hollowAmount; - hollowVolume = hollowsizex * hollowsizey * hollowsizez; + float hollowsizex = _size.X*hollowAmount; + float hollowsizey = _size.Y*hollowAmount; + float hollowsizez = _size.Z*hollowAmount; + hollowVolume = hollowsizex*hollowsizey*hollowsizez; break; case HollowShape.Circle: // Hollow shape is a perfect cyllinder in respect to the cube's scale // Cyllinder hollow volume calculation - float hRadius = _size.X / 2; + float hRadius = _size.X/2; float hLength = _size.Z; // pi * r2 * h - hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); + hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount); + break; + + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); break; default: @@ -650,28 +929,194 @@ namespace OpenSim.Region.Physics.OdePlugin } volume = volume - hollowVolume; } - break; - default: - // we don't have all of the volume formulas yet so - // use the common volume formula for all - volume = _size.X*_size.Y*_size.Z; break; - } + case ProfileShape.Circle: + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + // Cylinder + float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z); + float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z); - // Calculate Path cut effect on volume - // Not exact, in the triangle hollow example - // They should never be zero or less then zero.. - // we'll ignore it if it's less then zero + // Approximating the cylinder's irregularity. + if (volume1 > volume2) + { + volume = (float)volume1 - (volume1 - volume2); + } + else if (volume2 > volume1) + { + volume = (float)volume2 - (volume2 - volume1); + } + else + { + // Regular cylinder + volume = volume1; + } + } + else + { + // We don't know what the shape is yet, so use default + volume = _size.X * _size.Y * _size.Z; + } + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage - // ProfileEnd and ProfileBegin are values - // from 0 to 50000 + if (((float)_pbs.ProfileHollow / 50000f) > 0.0) + { + float hollowAmount = (float)_pbs.ProfileHollow / 50000f; - // Turning them back into percentages so that I can cut that percentage off the volume + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X / 2; + float hLength = _size.Z; - float PathCutEndAmount = _pbs.ProfileEnd; - float PathCutStartAmount = _pbs.ProfileBegin; - if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f) + // pi * r2 * h + hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); + break; + + case HollowShape.Square: + // Cube Hollow volume calculation + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + break; + + case ProfileShape.HalfCircle: + if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + if (_size.X == _size.Y && _size.Y == _size.Z) + { + // regular sphere + // v = 4/3 * pi * r^3 + float sradius3 = (float)Math.Pow((_size.X / 2), 3); + volume = (float)((4f / 3f) * Math.PI * sradius3); + } + else + { + // we treat this as a box currently + volume = _size.X * _size.Y * _size.Z; + } + } + else + { + // We don't know what the shape is yet, so use default + volume = _size.X * _size.Y * _size.Z; + } + break; + + case ProfileShape.EquilateralTriangle: + /* + v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h + + // seed mesh + Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); + Vertex PM = new Vertex(+0.5f, 0f, 0.0f); + Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f); + */ + float xA = -0.25f * _size.X; + float yA = -0.45f * _size.Y; + + float xB = 0.5f * _size.X; + float yB = 0; + + float xC = -0.25f * _size.X; + float yC = 0.45f * _size.Y; + + volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); + + // If the user has 'hollowed out' + // ProfileHollow is one of those 0 to 50000 values :P + // we like percentages better.. so turning into a percentage + float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f); + if (((float)fhollowFactor / 50000f) > 0.0) + { + float hollowAmount = (float)fhollowFactor / 50000f; + + // calculate the hollow volume by it's shape compared to the prim shape + float hollowVolume = 0; + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + // Equilateral Triangular Prism volume hollow calculation + // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + + float aLength = _size.Y; + // 1/2 abh + hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); + break; + + case HollowShape.Square: + // Cube Hollow volume calculation + float hollowsizex = _size.X * hollowAmount; + float hollowsizey = _size.Y * hollowAmount; + float hollowsizez = _size.Z * hollowAmount; + hollowVolume = hollowsizex * hollowsizey * hollowsizez; + break; + + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation + float hRadius = _size.X / 2; + float hLength = _size.Z; + + // pi * r2 * h + hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); + break; + + default: + hollowVolume = 0; + break; + } + volume = volume - hollowVolume; + } + break; + + default: + // we don't have all of the volume formulas yet so + // use the common volume formula for all + volume = _size.X*_size.Y*_size.Z; + break; + } + + // Calculate Path cut effect on volume + // Not exact, in the triangle hollow example + // They should never be zero or less then zero.. + // we'll ignore it if it's less then zero + + // ProfileEnd and ProfileBegin are values + // from 0 to 50000 + + // Turning them back into percentages so that I can cut that percentage off the volume + + float PathCutEndAmount = _pbs.ProfileEnd; + float PathCutStartAmount = _pbs.ProfileBegin; + if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f) { float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f); @@ -894,9 +1339,8 @@ namespace OpenSim.Region.Physics.OdePlugin // } } - public void ProcessTaints(float timestep) + public void ProcessTaints(float timestep) //============================================================================= { -//Console.WriteLine("ProcessTaints for " + m_primName ); if (m_taintadd) { changeadd(timestep); @@ -985,30 +1429,6 @@ namespace OpenSim.Region.Physics.OdePlugin { //Console.WriteLine("Alock changed to {0}", m_taintAngularLock); m_angularlock = m_taintAngularLock; - m_vehicle.SetAngularLock(m_angularlock); - - -/* - if (!m_taintAngularLock.ApproxEquals(Vector3.One, 0f)) - { - //d.BodySetFiniteRotationMode(Body, 0); - //d.BodySetFiniteRotationAxis(Body,m_taintAngularLock.X,m_taintAngularLock.Y,m_taintAngularLock.Z); - createAMotor(m_taintAngularLock); - } - else - { - if (Amotor != IntPtr.Zero) - { - d.JointDestroy(Amotor); - Amotor = IntPtr.Zero; - } - } - } - } - // Store this for later in case we get turned into a separate body - m_angularlock = m_taintAngularLock; - m_vehicle.SetAngularLock(m_angularlock); - } */ } } @@ -1151,11 +1571,6 @@ namespace OpenSim.Region.Physics.OdePlugin prm.m_collisionscore = 0; prm.m_disabled = false; - // The body doesn't already have a finite rotation mode set here - /* ### if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) - { - prm.createAMotor(m_angularlock); - } */ prm.Body = Body; _parent_scene.addActivePrim(prm); } @@ -1194,13 +1609,8 @@ namespace OpenSim.Region.Physics.OdePlugin m_collisionscore = 0; m_disabled = false; - // The body doesn't already have a finite rotation mode set here - /* ### if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) - { - createAMotor(m_angularlock); - } */ d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); - if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); + if (m_type != Vehicle.TYPE_NONE) Enable(Body, _parent_scene); _parent_scene.addActivePrim(this); } } @@ -1267,17 +1677,12 @@ namespace OpenSim.Region.Physics.OdePlugin //Console.WriteLine("childrenPrim.Remove " + odePrim); childrenPrim.Remove(odePrim); } - - - if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); } - - lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) @@ -1286,8 +1691,6 @@ namespace OpenSim.Region.Physics.OdePlugin ParentPrim(prm); } } - - } private void changeSelectedStatus(float timestep) @@ -1515,17 +1918,22 @@ namespace OpenSim.Region.Physics.OdePlugin public void changemove(float timestep) { +//Console.WriteLine("changemove for {0}", m_primName ); + if (m_isphysical) { - - if (!m_disabled && !m_taintremove && !childPrim) +//Console.WriteLine("phys {0} {1} {2}", m_disabled, m_taintremove, childPrim); +// if (!m_disabled && !m_taintremove && !childPrim) After one edit m_disabled is sometimes set, disabling further edits! + if (!m_taintremove && !childPrim) { +//Console.WriteLine("physOK"); if (Body == IntPtr.Zero) enableBody(); //Prim auto disable after 20 frames, //if you move it, re-enable the prim manually. if (_parent != null) { +//Console.WriteLine("physChild"); if (m_linkJoint != IntPtr.Zero) { d.JointDestroy(m_linkJoint); @@ -1534,6 +1942,7 @@ namespace OpenSim.Region.Physics.OdePlugin } if (Body != IntPtr.Zero) { +//Console.WriteLine("physNotIPZ"); d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); if (_parent != null) @@ -1549,9 +1958,9 @@ Console.WriteLine(" JointCreateFixed"); } } d.BodyEnable(Body); - if (m_vehicle.Type != Vehicle.TYPE_NONE) + if (m_type != Vehicle.TYPE_NONE) { - m_vehicle.Enable(Body, _parent_scene); + Enable(Body, _parent_scene); } } else @@ -1566,6 +1975,7 @@ Console.WriteLine(" JointCreateFixed"); } else { +//Console.WriteLine("NONphys"); // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); _parent_scene.waitForSpaceUnlock(m_targetSpace); @@ -1589,433 +1999,234 @@ Console.WriteLine(" JointCreateFixed"); m_taintposition = _position; } - public void Move(float timestep) - { - float fx = 0; - float fy = 0; - float fz = 0; - - frcount++; // used to limit debug comment output - if (frcount > 100) - frcount = 0; - - if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. - { -//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type + - // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); - if (m_vehicle.Type != Vehicle.TYPE_NONE) - { - // 'VEHICLES' are dealt with in ODEDynamics.cs - m_vehicle.Step(timestep, _parent_scene); - } - else - { - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 - // NON-'VEHICLES' are dealt with here - // m_angularlock = <1,1,1> means no lock. a 0 on axis means locked. - -// NB this may be wrong - may lock global axis! Should be LOCAL axis! - if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.One, 0.003f)) - { - d.Vector3 avel2 = d.BodyGetAngularVel(Body); - if (m_angularlock.X == 0) - avel2.X = 0; - if (m_angularlock.Y == 0) - avel2.Y = 0; - if (m_angularlock.Z == 0) - avel2.Z = 0; - d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); - } - //float PID_P = 900.0f; - float m_mass = CalculateMass(); -// fz = 0f; - //m_log.Info(m_collisionFlags.ToString()); + public void rotate(float timestep) + { + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + if (Body != IntPtr.Zero) + { + // KF: If this is a root prim do BodySet + d.BodySetQuaternion(Body, ref myrot); + } + else + { + // daughter prim, do Geom set + d.GeomSetQuaternion(prim_geom, ref myrot); + } + + resetCollisionAccounting(); + m_taintrot = _orientation; + } - - //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle. - // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up - // NB Prims in ODE are no subject to global gravity - fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass + private void resetCollisionAccounting() + { + m_collisionscore = 0; + m_interpenetrationcount = 0; + m_disabled = false; + } - if (m_usePID) - { -//if(frcount == 0) Console.WriteLine("PID " + m_primName); - // KF - this is for object MoveToTarget. - - //if (!d.BodyIsEnabled(Body)) - //d.BodySetForce(Body, 0f, 0f, 0f); + public void changedisable(float timestep) + { + m_disabled = true; + if (Body != IntPtr.Zero) + { + d.BodyDisable(Body); + Body = IntPtr.Zero; + } - // no lock; for now it's only called from within Simulate() - - // If the PID Controller isn't active then we set our force - // calculating base velocity to the current position + m_taintdisable = false; + } - if ((m_PIDTau < 1) && (m_PIDTau != 0)) - { - //PID_G = PID_G / m_PIDTau; - m_PIDTau = 1; - } - - if ((PID_G - m_PIDTau) <= 0) - { - PID_G = m_PIDTau + 1; - } - //PidStatus = true; + public void changePhysicsStatus(float timestep) + { + if (m_isphysical == true) + { + if (Body == IntPtr.Zero) + { + if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) + { + changeshape(2f); + } + else + { + enableBody(); + } + } + } + else + { + if (Body != IntPtr.Zero) + { + if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) + { + - // PhysicsVector vec = new PhysicsVector(); - d.Vector3 vel = d.BodyGetLinearVel(Body); + if (prim_geom != IntPtr.Zero) + { + try + { + d.GeomDestroy(prim_geom); + prim_geom = IntPtr.Zero; + _mesh = null; + } + catch (System.AccessViolationException) + { + prim_geom = IntPtr.Zero; + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + } +//Console.WriteLine("changePhysicsStatus for " + m_primName ); + changeadd(2f); + } + if (childPrim) + { + if (_parent != null) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildDelink(this); + } + } + else + { + disableBody(); + } + } + } - d.Vector3 pos = d.BodyGetPosition(Body); - _target_velocity = - new Vector3( - (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), - (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), - (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) - ); + changeSelectedStatus(timestep); - // if velocity is zero, use position control; otherwise, velocity control + resetCollisionAccounting(); + m_taintPhysics = m_isphysical; + } - if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f)) - { - // keep track of where we stopped. No more slippin' & slidin' - - // We only want to deactivate the PID Controller if we think we want to have our surrogate - // react to the physics scene by moving it's position. - // Avatar to Avatar collisions - // Prim to avatar collisions + public void changesize(float timestamp) + { + + string oldname = _parent_scene.geom_name_map[prim_geom]; - //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); - //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); - //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; - d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); - d.BodySetLinearVel(Body, 0, 0, 0); - d.BodyAddForce(Body, 0, 0, fz); - return; - } - else - { - _zeroFlag = false; + if (_size.X <= 0) _size.X = 0.01f; + if (_size.Y <= 0) _size.Y = 0.01f; + if (_size.Z <= 0) _size.Z = 0.01f; - // We're flying and colliding with something - fx = ((_target_velocity.X) - vel.X) * (PID_D); - fy = ((_target_velocity.Y) - vel.Y) * (PID_D); - - // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; + // Cleanup of old prim geometry + if (_mesh != null) + { + // Cleanup meshing here + } + //kill body to rebuild + if (IsPhysical && Body != IntPtr.Zero) + { + if (childPrim) + { + if (_parent != null) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildDelink(this); + } + } + else + { + disableBody(); + } + } + if (d.SpaceQuery(m_targetSpace, prim_geom)) + { + _parent_scene.waitForSpaceUnlock(m_targetSpace); + d.SpaceRemove(m_targetSpace, prim_geom); + } + d.GeomDestroy(prim_geom); + prim_geom = IntPtr.Zero; + // we don't need to do space calculation because the client sends a position update also. - fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); - } - } // end if (m_usePID) + // Construction of new prim + if (_parent_scene.needsMeshing(_pbs)) + { + float meshlod = _parent_scene.meshSculptLOD; - // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller - if (m_useHoverPID && !m_usePID) - { -//Console.WriteLine("Hover " + m_primName); - - // If we're using the PID controller, then we have no gravity - fz = (-1 * _parent_scene.gravityz) * m_mass; + if (IsPhysical) + meshlod = _parent_scene.MeshSculptphysicalLOD; + // Don't need to re-enable body.. it's done in SetMesh - // no lock; for now it's only called from within Simulate() + IMesh mesh = null; - // If the PID Controller isn't active then we set our force - // calculating base velocity to the current position + if (_parent_scene.needsMeshing(_pbs)) + mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); - if ((m_PIDTau < 1)) - { - PID_G = PID_G / m_PIDTau; - } + //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); +//Console.WriteLine("changesize 1"); + CreateGeom(m_targetSpace, mesh); - if ((PID_G - m_PIDTau) <= 0) - { - PID_G = m_PIDTau + 1; - } - + + } + else + { + _mesh = null; +//Console.WriteLine("changesize 2"); + CreateGeom(m_targetSpace, _mesh); + } - // Where are we, and where are we headed? - d.Vector3 pos = d.BodyGetPosition(Body); - d.Vector3 vel = d.BodyGetLinearVel(Body); + d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); + d.Quaternion myrot = new d.Quaternion(); + myrot.X = _orientation.X; + myrot.Y = _orientation.Y; + myrot.Z = _orientation.Z; + myrot.W = _orientation.W; + d.GeomSetQuaternion(prim_geom, ref myrot); + //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); + if (IsPhysical && Body == IntPtr.Zero && !childPrim) + { + // Re creates body on size. + // EnableBody also does setMass() + enableBody(); + d.BodyEnable(Body); + } - // Non-Vehicles have a limited set of Hover options. - // determine what our target height really is based on HoverType - switch (m_PIDHoverType) - { - case PIDHoverType.Ground: - m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); - m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; - break; - case PIDHoverType.GroundAndWater: - m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); - m_waterHeight = _parent_scene.GetWaterLevel(); - if (m_groundHeight > m_waterHeight) - { - m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; - } - else - { - m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; - } - break; + _parent_scene.geom_name_map[prim_geom] = oldname; - } // end switch (m_PIDHoverType) + changeSelectedStatus(timestamp); + if (childPrim) + { + if (_parent is OdePrim) + { + OdePrim parent = (OdePrim)_parent; + parent.ChildSetGeom(this); + } + } + resetCollisionAccounting(); + m_taintsize = _size; + } + - _target_velocity = - new Vector3(0.0f, 0.0f, - (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) - ); + public void changefloatonwater(float timestep) + { + m_collidesWater = m_taintCollidesWater; - // if velocity is zero, use position control; otherwise, velocity control + if (prim_geom != IntPtr.Zero) + { + if (m_collidesWater) + { + m_collisionFlags |= CollisionCategories.Water; + } + else + { + m_collisionFlags &= ~CollisionCategories.Water; + } + d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); + } + } - if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) - { - // keep track of where we stopped. No more slippin' & slidin' - - // We only want to deactivate the PID Controller if we think we want to have our surrogate - // react to the physics scene by moving it's position. - // Avatar to Avatar collisions - // Prim to avatar collisions + public void changeshape(float timestamp) + { + string oldname = _parent_scene.geom_name_map[prim_geom]; - d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); - d.BodySetLinearVel(Body, vel.X, vel.Y, 0); - d.BodyAddForce(Body, 0, 0, fz); - //KF this prevents furthur motions return; - } - else - { - _zeroFlag = false; - - // We're flying and colliding with something - fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); - } - } // end m_useHoverPID && !m_usePID - - if (m_useAPID) - { - // RotLookAt, apparently overrides all other rotation sources. Inputs: - // Quaternion m_APIDTarget - // float m_APIDStrength // From SL experiments, this is the time to get there - // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly - // Also in SL the mass of the object has no effect on time to get there. - // Factors: -//if(frcount == 0) Console.WriteLine("APID "); - // get present body rotation - float limit = 1.0f; - float scaler = 50f; // adjusts damping time - float RLAservo = 0f; - - d.Quaternion rot = d.BodyGetQuaternion(Body); - Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); - Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget; - float diff_angle; - Vector3 diff_axis; - rot_diff.GetAxisAngle(out diff_axis, out diff_angle); - diff_axis.Normalize(); - if(diff_angle > 0.01f) // diff_angle is always +ve - { -// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); - Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z); - rotforce = rotforce * rotq; - if(diff_angle > limit) diff_angle = limit; // cap the rotate rate -// RLAservo = timestep / m_APIDStrength * m_mass * scaler; - // rotforce = rotforce * RLAservo * diff_angle ; - // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); - RLAservo = timestep / m_APIDStrength * scaler; - rotforce = rotforce * RLAservo * diff_angle ; - - if (m_angularlock.X == 0) - rotforce.X = 0; - if (m_angularlock.Y == 0) - rotforce.Y = 0; - if (m_angularlock.Z == 0) - rotforce.Z = 0; - - - - - d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); -//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); - } -//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); - } // end m_useAPID - - fx *= m_mass; - fy *= m_mass; - //fz *= m_mass; - - fx += m_force.X; - fy += m_force.Y; - fz += m_force.Z; - - //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); - if (fx != 0 || fy != 0 || fz != 0) - { - //m_taintdisable = true; - //base.RaiseOutOfBounds(Position); - //d.BodySetLinearVel(Body, fx, fy, 0f); - if (!d.BodyIsEnabled(Body)) - { - // A physical body at rest on a surface will auto-disable after a while, - // this appears to re-enable it incase the surface it is upon vanishes, - // and the body should fall again. - d.BodySetLinearVel(Body, 0f, 0f, 0f); - d.BodySetForce(Body, 0, 0, 0); - enableBodySoft(); - } - - // 35x10 = 350n times the mass per second applied maximum. - float nmax = 35f * m_mass; - float nmin = -35f * m_mass; - - - if (fx > nmax) - fx = nmax; - if (fx < nmin) - fx = nmin; - if (fy > nmax) - fy = nmax; - if (fy < nmin) - fy = nmin; - d.BodyAddForce(Body, fx, fy, fz); -//Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); - } - } - } - else - { // is not physical, or is not a body or is selected - // _zeroPosition = d.BodyGetPosition(Body); - return; -//Console.WriteLine("Nothing " + m_primName); - - } - } - - - - public void rotate(float timestep) - { - d.Quaternion myrot = new d.Quaternion(); - myrot.X = _orientation.X; - myrot.Y = _orientation.Y; - myrot.Z = _orientation.Z; - myrot.W = _orientation.W; - if (Body != IntPtr.Zero) - { - // KF: If this is a root prim do BodySet - d.BodySetQuaternion(Body, ref myrot); - /* ### if (m_isphysical) - { - if (!m_angularlock.ApproxEquals(Vector3.One, 0f)) - createAMotor(m_angularlock); - } */ - } - else - { - // daughter prim, do Geom set - d.GeomSetQuaternion(prim_geom, ref myrot); - } - - resetCollisionAccounting(); - m_taintrot = _orientation; - } - - private void resetCollisionAccounting() - { - m_collisionscore = 0; - m_interpenetrationcount = 0; - m_disabled = false; - } - - public void changedisable(float timestep) - { - m_disabled = true; - if (Body != IntPtr.Zero) - { - d.BodyDisable(Body); - Body = IntPtr.Zero; - } - - m_taintdisable = false; - } - - public void changePhysicsStatus(float timestep) - { - if (m_isphysical == true) - { - if (Body == IntPtr.Zero) - { - if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) - { - changeshape(2f); - } - else - { - enableBody(); - } - } - } - else - { - if (Body != IntPtr.Zero) - { - if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) - { - - - if (prim_geom != IntPtr.Zero) - { - try - { - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; - _mesh = null; - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.Error("[PHYSICS]: PrimGeom dead"); - } - } -//Console.WriteLine("changePhysicsStatus for " + m_primName ); - changeadd(2f); - } - if (childPrim) - { - if (_parent != null) - { - OdePrim parent = (OdePrim)_parent; - parent.ChildDelink(this); - } - } - else - { - disableBody(); - } - } - } - - changeSelectedStatus(timestep); - - resetCollisionAccounting(); - m_taintPhysics = m_isphysical; - } - - public void changesize(float timestamp) - { - - string oldname = _parent_scene.geom_name_map[prim_geom]; - - if (_size.X <= 0) _size.X = 0.01f; - if (_size.Y <= 0) _size.Y = 0.01f; - if (_size.Z <= 0) _size.Z = 0.01f; - - // Cleanup of old prim geometry - if (_mesh != null) - { - // Cleanup meshing here - } - //kill body to rebuild + // Cleanup of old prim geometry and Bodies if (IsPhysical && Body != IntPtr.Zero) { if (childPrim) @@ -2031,133 +2242,25 @@ Console.WriteLine(" JointCreateFixed"); disableBody(); } } - if (d.SpaceQuery(m_targetSpace, prim_geom)) + try { - _parent_scene.waitForSpaceUnlock(m_targetSpace); - d.SpaceRemove(m_targetSpace, prim_geom); + d.GeomDestroy(prim_geom); + } + catch (System.AccessViolationException) + { + prim_geom = IntPtr.Zero; + m_log.Error("[PHYSICS]: PrimGeom dead"); } - d.GeomDestroy(prim_geom); prim_geom = IntPtr.Zero; // we don't need to do space calculation because the client sends a position update also. - + if (_size.X <= 0) _size.X = 0.01f; + if (_size.Y <= 0) _size.Y = 0.01f; + if (_size.Z <= 0) _size.Z = 0.01f; // Construction of new prim + if (_parent_scene.needsMeshing(_pbs)) { - float meshlod = _parent_scene.meshSculptLOD; - - if (IsPhysical) - meshlod = _parent_scene.MeshSculptphysicalLOD; - // Don't need to re-enable body.. it's done in SetMesh - - IMesh mesh = null; - - if (_parent_scene.needsMeshing(_pbs)) - mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); - - //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); -//Console.WriteLine("changesize 1"); - CreateGeom(m_targetSpace, mesh); - - - } - else - { - _mesh = null; -//Console.WriteLine("changesize 2"); - CreateGeom(m_targetSpace, _mesh); - } - - d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z); - d.Quaternion myrot = new d.Quaternion(); - myrot.X = _orientation.X; - myrot.Y = _orientation.Y; - myrot.Z = _orientation.Z; - myrot.W = _orientation.W; - d.GeomSetQuaternion(prim_geom, ref myrot); - - //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z); - if (IsPhysical && Body == IntPtr.Zero && !childPrim) - { - // Re creates body on size. - // EnableBody also does setMass() - enableBody(); - d.BodyEnable(Body); - } - - _parent_scene.geom_name_map[prim_geom] = oldname; - - changeSelectedStatus(timestamp); - if (childPrim) - { - if (_parent is OdePrim) - { - OdePrim parent = (OdePrim)_parent; - parent.ChildSetGeom(this); - } - } - resetCollisionAccounting(); - m_taintsize = _size; - } - - - - public void changefloatonwater(float timestep) - { - m_collidesWater = m_taintCollidesWater; - - if (prim_geom != IntPtr.Zero) - { - if (m_collidesWater) - { - m_collisionFlags |= CollisionCategories.Water; - } - else - { - m_collisionFlags &= ~CollisionCategories.Water; - } - d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); - } - } - - public void changeshape(float timestamp) - { - string oldname = _parent_scene.geom_name_map[prim_geom]; - - // Cleanup of old prim geometry and Bodies - if (IsPhysical && Body != IntPtr.Zero) - { - if (childPrim) - { - if (_parent != null) - { - OdePrim parent = (OdePrim)_parent; - parent.ChildDelink(this); - } - } - else - { - disableBody(); - } - } - try - { - d.GeomDestroy(prim_geom); - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.Error("[PHYSICS]: PrimGeom dead"); - } - prim_geom = IntPtr.Zero; - // we don't need to do space calculation because the client sends a position update also. - if (_size.X <= 0) _size.X = 0.01f; - if (_size.Y <= 0) _size.Y = 0.01f; - if (_size.Z <= 0) _size.Z = 0.01f; - // Construction of new prim - - if (_parent_scene.needsMeshing(_pbs)) - { - // Don't need to re-enable body.. it's done in SetMesh + // Don't need to re-enable body.. it's done in SetMesh float meshlod = _parent_scene.meshSculptLOD; if (IsPhysical) @@ -2319,392 +2422,834 @@ Console.WriteLine(" JointCreateFixed"); m_taintVelocity = Vector3.Zero; } - public override bool IsPhysical + public void UpdatePositionAndVelocity() { - get { return m_isphysical; } - set - { - m_isphysical = value; - if (!m_isphysical) - { // Zero the remembered last velocity - m_lastVelocity = Vector3.Zero; - if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Halt(); - } - } - } + return; // moved to the MOVE() method + // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! + if (_parent == null) + { + Vector3 pv = Vector3.Zero; + bool lastZeroFlag = _zeroFlag; + if (Body != (IntPtr)0) // FIXME -> or if it is a joint + { + d.Vector3 vec = d.BodyGetPosition(Body); + d.Quaternion ori = d.BodyGetQuaternion(Body); + d.Vector3 vel = d.BodyGetLinearVel(Body); + d.Vector3 rotvel = d.BodyGetAngularVel(Body); + d.Vector3 torque = d.BodyGetTorque(Body); + _torque = new Vector3(torque.X, torque.Y, torque.Z); + Vector3 l_position = Vector3.Zero; + Quaternion l_orientation = Quaternion.Identity; - public void setPrimForRemoval() - { - m_taintremove = true; - } + // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) + //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } + //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - public override bool Flying - { - // no flying prims for you - get { return false; } - set { } - } + m_lastposition = _position; + m_lastorientation = _orientation; + + l_position.X = vec.X; + l_position.Y = vec.Y; + l_position.Z = vec.Z; + l_orientation.X = ori.X; + l_orientation.Y = ori.Y; + l_orientation.Z = ori.Z; + l_orientation.W = ori.W; + +// if(l_position.Y != m_lastposition.Y){ +// Console.WriteLine("UP&V {0} {1}", m_primName, l_position); +// } - public override bool IsColliding - { - get { return iscolliding; } - set { iscolliding = value; } - } + if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) + { + //base.RaiseOutOfBounds(l_position); - public override bool CollidingGround - { - get { return false; } - set { return; } - } + if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { + _position = l_position; + //_parent_scene.remActivePrim(this); + if (_parent == null) + base.RequestPhysicsterseUpdate(); + return; + } + else + { + if (_parent == null) + base.RaiseOutOfBounds(l_position); + return; + } + } - public override bool CollidingObj - { - get { return false; } - set { return; } - } + if (l_position.Z < 0) + { + // This is so prim that get lost underground don't fall forever and suck up + // + // Sim resources and memory. + // Disables the prim's movement physics.... + // It's a hack and will generate a console message if it fails. - public override bool ThrottleUpdates - { - get { return m_throttleUpdates; } - set { m_throttleUpdates = value; } - } + //IsPhysical = false; + if (_parent == null) + base.RaiseOutOfBounds(_position); - public override bool Stopped - { - get { return _zeroFlag; } - } + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; - public override Vector3 Position - { - get { return _position; } + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; - set { _position = value; - //m_log.Info("[PHYSICS]: " + _position.ToString()); - } - } + if (_parent == null) + base.RequestPhysicsterseUpdate(); - public override Vector3 Size - { - get { return _size; } - set - { - if (value.IsFinite()) - { - _size = value; - } - else - { - m_log.Warn("[PHYSICS]: Got NaN Size on object"); - } - } - } + m_throttleUpdates = false; + throttleCounter = 0; + _zeroFlag = true; + //outofBounds = true; + } - public override float Mass - { - get { return CalculateMass(); } - } + //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); +//Console.WriteLine("Adiff " + m_primName + " = " + Adiff); + if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) + && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) + && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) +// && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01)) + && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large + { + _zeroFlag = true; +//Console.WriteLine("ZFT 2"); + m_throttleUpdates = false; + } + else + { + //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); + _zeroFlag = false; + m_lastUpdateSent = false; + //m_throttleUpdates = false; + } - public override Vector3 Force - { - //get { return Vector3.Zero; } - get { return m_force; } - set - { - if (value.IsFinite()) - { - m_force = value; + if (_zeroFlag) + { + _velocity.X = 0.0f; + _velocity.Y = 0.0f; + _velocity.Z = 0.0f; + + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + + //_orientation.w = 0f; + //_orientation.X = 0f; + //_orientation.Y = 0f; + //_orientation.Z = 0f; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + if (!m_lastUpdateSent) + { + m_throttleUpdates = false; + throttleCounter = 0; + m_rotationalVelocity = pv; + + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } + + m_lastUpdateSent = true; + } + } + else + { + if (lastZeroFlag != _zeroFlag) + { + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } + } + + m_lastVelocity = _velocity; + + _position = l_position; + + _velocity.X = vel.X; + _velocity.Y = vel.Y; + _velocity.Z = vel.Z; + + _acceleration = ((_velocity - m_lastVelocity) / 0.1f); + _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); + //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); + +// if (_velocity.ApproxEquals(pv, 0.5f)) ???? Disregard rotational vel if lin vel is < 0.5 ????? +// { +// m_rotationalVelocity = pv;/ + +// } +// else +// { + m_rotationalVelocity = new Vector3(rotvel.X, rotvel.Y, rotvel.Z); +// } + + //m_log.Debug("ODE: " + m_rotationalVelocity.ToString()); + _orientation.X = ori.X; + _orientation.Y = ori.Y; + _orientation.Z = ori.Z; + _orientation.W = ori.W; + m_lastUpdateSent = false; + if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) + { + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } + } + else + { + throttleCounter++; + } + } + m_lastposition = l_position; } else { - m_log.Warn("[PHYSICS]: NaN in Force Applied to an Object"); + // Not a body.. so Make sure the client isn't interpolating + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + _zeroFlag = true; } } } - public override int VehicleType + public Matrix4 FromDMass(d.Mass pMass) { - get { return (int)m_vehicle.Type; } - set { m_vehicle.ProcessTypeChange((Vehicle)value); } + Matrix4 obj; + obj.M11 = pMass.I.M00; + obj.M12 = pMass.I.M01; + obj.M13 = pMass.I.M02; + obj.M14 = 0; + obj.M21 = pMass.I.M10; + obj.M22 = pMass.I.M11; + obj.M23 = pMass.I.M12; + obj.M24 = 0; + obj.M31 = pMass.I.M20; + obj.M32 = pMass.I.M21; + obj.M33 = pMass.I.M22; + obj.M34 = 0; + obj.M41 = 0; + obj.M42 = 0; + obj.M43 = 0; + obj.M44 = 1; + return obj; } - public override void VehicleFloatParam(int param, float value) + public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) { - m_vehicle.ProcessFloatVehicleParam((Vehicle) param, value); + obj.I.M00 = pMat[0, 0]; + obj.I.M01 = pMat[0, 1]; + obj.I.M02 = pMat[0, 2]; + obj.I.M10 = pMat[1, 0]; + obj.I.M11 = pMat[1, 1]; + obj.I.M12 = pMat[1, 2]; + obj.I.M20 = pMat[2, 0]; + obj.I.M21 = pMat[2, 1]; + obj.I.M22 = pMat[2, 2]; + return obj; } - public override void VehicleVectorParam(int param, Vector3 value) + public override void SubscribeEvents(int ms) { - m_vehicle.ProcessVectorVehicleParam((Vehicle) param, value); + m_eventsubscription = ms; + _parent_scene.addCollisionEventReporting(this); } - public override void VehicleRotationParam(int param, Quaternion rotation) - { - m_vehicle.ProcessRotationVehicleParam((Vehicle) param, rotation); - } - - public override void VehicleFlagsSet(int flags) - { - m_vehicle.ProcessFlagsVehicleSet(flags); - } - - public override void VehicleFlagsRemove(int flags) + public override void UnSubscribeEvents() { - m_vehicle.ProcessFlagsVehicleRemove(flags); + _parent_scene.remCollisionEventReporting(this); + m_eventsubscription = 0; } - - public override void SetVolumeDetect(int param) + + public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) { - lock (_parent_scene.OdeLock) - { - m_isVolumeDetect = (param!=0); - } + if (CollisionEventsThisFrame == null) + CollisionEventsThisFrame = new CollisionEventUpdate(); + CollisionEventsThisFrame.addCollider(CollidedWith, contact); } - public override Vector3 CenterOfMass + public void SendCollisions() { - get { return Vector3.Zero; } + if (CollisionEventsThisFrame == null) + return; + + base.SendCollisionUpdate(CollisionEventsThisFrame); + + if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) + CollisionEventsThisFrame = null; + else + CollisionEventsThisFrame = new CollisionEventUpdate(); } - public override Vector3 GeometricCenter + public override bool SubscribedEvents() { - get { return Vector3.Zero; } + if (m_eventsubscription > 0) + return true; + return false; } - public override PrimitiveBaseShape Shape + public static Matrix4 Inverse(Matrix4 pMat) { - set + if (determinant3x3(pMat) == 0) { - _pbs = value; - m_taintshape = true; + return Matrix4.Identity; // should probably throw an error. singluar matrix inverse not possible } + + + + return (Adjoint(pMat) / determinant3x3(pMat)); } - public override Vector3 Velocity + public static Matrix4 Adjoint(Matrix4 pMat) { - get - { - // Averate previous velocity with the new one so - // client object interpolation works a 'little' better - if (_zeroFlag) - return Vector3.Zero; - - Vector3 returnVelocity = Vector3.Zero; - returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2; - returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2; - returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2; - return returnVelocity; - } - set + Matrix4 adjointMatrix = new Matrix4(); + for (int i=0; i<4; i++) { - if (value.IsFinite()) - { - _velocity = value; - - m_taintVelocity = value; - _parent_scene.AddPhysicsActorTaint(this); - } - else + for (int j=0; j<4; j++) { - m_log.Warn("[PHYSICS]: Got NaN Velocity in Object"); + Matrix4SetValue(ref adjointMatrix, i, j, (float)(Math.Pow(-1, i + j) * (determinant3x3(Minor(pMat, i, j))))); } - } + + adjointMatrix = Transpose(adjointMatrix); + return adjointMatrix; } - public override Vector3 Torque + public static Matrix4 Minor(Matrix4 matrix, int iRow, int iCol) { - get + Matrix4 minor = new Matrix4(); + int m = 0, n = 0; + for (int i = 0; i < 4; i++) { - if (!m_isphysical || Body == IntPtr.Zero) - return Vector3.Zero; - - return _torque; - } - - set - { - if (value.IsFinite()) - { - m_taintTorque = value; - _parent_scene.AddPhysicsActorTaint(this); - } - else + if (i == iRow) + continue; + n = 0; + for (int j = 0; j < 4; j++) { - m_log.Warn("[PHYSICS]: Got NaN Torque in Object"); + if (j == iCol) + continue; + Matrix4SetValue(ref minor, m,n, matrix[i, j]); + n++; } + m++; } - } -/* - public Vector3 AngularLock - { - get { return m_angularlock; } - set { } - } - -*/ - public override float CollisionScore - { - get { return m_collisionscore; } - set { m_collisionscore = value; } + return minor; } - public override bool Kinematic + public static Matrix4 Transpose(Matrix4 pMat) { - get { return false; } - set { } + Matrix4 transposeMatrix = new Matrix4(); + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + Matrix4SetValue(ref transposeMatrix, i, j, pMat[j, i]); + return transposeMatrix; } - public override Quaternion Orientation + public static void Matrix4SetValue(ref Matrix4 pMat, int r, int c, float val) { - get { return _orientation; } - set + switch (r) { - if (QuaternionIsFinite(value)) - { - _orientation = value; - } - else - m_log.Warn("[PHYSICS]: Got NaN quaternion Orientation from Scene in Object"); + case 0: + switch (c) + { + case 0: + pMat.M11 = val; + break; + case 1: + pMat.M12 = val; + break; + case 2: + pMat.M13 = val; + break; + case 3: + pMat.M14 = val; + break; + } + + break; + case 1: + switch (c) + { + case 0: + pMat.M21 = val; + break; + case 1: + pMat.M22 = val; + break; + case 2: + pMat.M23 = val; + break; + case 3: + pMat.M24 = val; + break; + } + + break; + case 2: + switch (c) + { + case 0: + pMat.M31 = val; + break; + case 1: + pMat.M32 = val; + break; + case 2: + pMat.M33 = val; + break; + case 3: + pMat.M34 = val; + break; + } + + break; + case 3: + switch (c) + { + case 0: + pMat.M41 = val; + break; + case 1: + pMat.M42 = val; + break; + case 2: + pMat.M43 = val; + break; + case 3: + pMat.M44 = val; + break; + } + break; } } + private static float determinant3x3(Matrix4 pMat) + { + float det = 0; + float diag1 = pMat[0, 0]*pMat[1, 1]*pMat[2, 2]; + float diag2 = pMat[0, 1]*pMat[2, 1]*pMat[2, 0]; + float diag3 = pMat[0, 2]*pMat[1, 0]*pMat[2, 1]; + float diag4 = pMat[2, 0]*pMat[1, 1]*pMat[0, 2]; + float diag5 = pMat[2, 1]*pMat[1, 2]*pMat[0, 0]; + float diag6 = pMat[2, 2]*pMat[1, 0]*pMat[0, 1]; - internal static bool QuaternionIsFinite(Quaternion q) + det = diag1 + diag2 + diag3 - (diag4 + diag5 + diag6); + return det; + + } + + private static void DMassCopy(ref d.Mass src, ref d.Mass dst) { - if (Single.IsNaN(q.X) || Single.IsInfinity(q.X)) - return false; - if (Single.IsNaN(q.Y) || Single.IsInfinity(q.Y)) - return false; - if (Single.IsNaN(q.Z) || Single.IsInfinity(q.Z)) - return false; - if (Single.IsNaN(q.W) || Single.IsInfinity(q.W)) - return false; - return true; + dst.c.W = src.c.W; + dst.c.X = src.c.X; + dst.c.Y = src.c.Y; + dst.c.Z = src.c.Z; + dst.mass = src.mass; + dst.I.M00 = src.I.M00; + dst.I.M01 = src.I.M01; + dst.I.M02 = src.I.M02; + dst.I.M10 = src.I.M10; + dst.I.M11 = src.I.M11; + dst.I.M12 = src.I.M12; + dst.I.M20 = src.I.M20; + dst.I.M21 = src.I.M21; + dst.I.M22 = src.I.M22; } - public override Vector3 Acceleration + public override void SetMaterial(int pMaterial) { - get { return _acceleration; } + m_material = pMaterial; } + + - public void SetAcceleration(Vector3 accel) - { - _acceleration = accel; - } - public override void AddForce(Vector3 force, bool pushforce) + + internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { - if (force.IsFinite()) + switch (pParam) { - lock (m_forcelist) - m_forcelist.Add(force); + case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionEfficiency = pValue; + break; + case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_angularDeflectionTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorDecayTimescale = pValue; + break; + case Vehicle.ANGULAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_angularMotorTimescale = pValue; + break; + case Vehicle.BANKING_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingEfficiency = pValue; + break; + case Vehicle.BANKING_MIX: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingMix = pValue; + break; + case Vehicle.BANKING_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_bankingTimescale = pValue; + break; + case Vehicle.BUOYANCY: + if (pValue < -1f) pValue = -1f; + if (pValue > 1f) pValue = 1f; + m_VehicleBuoyancy = pValue; + break; +// case Vehicle.HOVER_EFFICIENCY: +// if (pValue < 0f) pValue = 0f; +// if (pValue > 1f) pValue = 1f; +// m_VhoverEfficiency = pValue; +// break; + case Vehicle.HOVER_HEIGHT: + m_VhoverHeight = pValue; + break; + case Vehicle.HOVER_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_VhoverTimescale = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionEfficiency = pValue; + break; + case Vehicle.LINEAR_DEFLECTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + // m_linearDeflectionTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorDecayTimescale = pValue; + break; + case Vehicle.LINEAR_MOTOR_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_linearMotorTimescale = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: + if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable + if (pValue > 1.0f) pValue = 1.0f; + m_verticalAttractionEfficiency = pValue; + break; + case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: + if (pValue < 0.01f) pValue = 0.01f; + m_verticalAttractionTimescale = pValue; + break; + + // These are vector properties but the engine lets you use a single float value to + // set all of the components to the same value + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + if (pValue > 30f) pValue = 30f; + if (pValue < 0.1f) pValue = 0.1f; + m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue, pValue, pValue); + UpdateAngDecay(); + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue, pValue, pValue); + UpdateLinDecay(); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue, pValue, pValue); + break; - m_taintforce = true; - } - else - { - m_log.Warn("[PHYSICS]: Got Invalid linear force vector from Scene in Object"); } - //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString()); - } + + }//end ProcessFloatVehicleParam - public override void AddAngularForce(Vector3 force, bool pushforce) + internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue) { - if (force.IsFinite()) - { - m_angularforcelist.Add(force); - m_taintaddangularforce = true; - } - else + switch (pParam) { - m_log.Warn("[PHYSICS]: Got Invalid Angular force vector from Scene in Object"); + case Vehicle.ANGULAR_FRICTION_TIMESCALE: + if (pValue.X > 30f) pValue.X = 30f; + if (pValue.X < 0.1f) pValue.X = 0.1f; + if (pValue.Y > 30f) pValue.Y = 30f; + if (pValue.Y < 0.1f) pValue.Y = 0.1f; + if (pValue.Z > 30f) pValue.Z = 30f; + if (pValue.Z < 0.1f) pValue.Z = 0.1f; + m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.ANGULAR_MOTOR_DIRECTION: + m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); + // Limit requested angular speed to 2 rps= 4 pi rads/sec + if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f; + if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f; + if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f; + if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f; + if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f; + if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f; + UpdateAngDecay(); + break; + case Vehicle.LINEAR_FRICTION_TIMESCALE: + m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; + case Vehicle.LINEAR_MOTOR_DIRECTION: + m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z); // velocity requested by LSL, for max limiting + UpdateLinDecay(); + break; + case Vehicle.LINEAR_MOTOR_OFFSET: + // m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z); + break; } - } + + }//end ProcessVectorVehicleParam - public override Vector3 RotationalVelocity + internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue) { - get - { -/* Vector3 pv = Vector3.Zero; - if (_zeroFlag) - return pv; - m_lastUpdateSent = false; - - if (m_rotationalVelocity.ApproxEquals(pv, 0.2f)) - return pv; -*/ - return m_rotationalVelocity; - } - set + switch (pParam) { - if (value.IsFinite()) - { - m_rotationalVelocity = value; - } - else - { - m_log.Warn("[PHYSICS]: Got NaN RotationalVelocity in Object"); - } + case Vehicle.REFERENCE_FRAME: + // m_referenceFrame = pValue; + break; } - } + + }//end ProcessRotationVehicleParam - public override void CrossingFailure() + internal void ProcessFlagsVehicleSet(int flags) { - m_crossingfailures++; - if (m_crossingfailures > _parent_scene.geomCrossingFailuresBeforeOutofbounds) - { - base.RaiseOutOfBounds(_position); - return; - } - else if (m_crossingfailures == _parent_scene.geomCrossingFailuresBeforeOutofbounds) - { - m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName); - } + m_flags |= (VehicleFlag)flags; } - public override float Buoyancy + internal void ProcessFlagsVehicleRemove(int flags) { - get { return m_buoyancy; } - set { m_buoyancy = value; } + m_flags &= ~((VehicleFlag)flags); } + + internal void ProcessTypeChange(Vehicle pType) + { + // Set Defaults For Type + m_type = pType; + switch (pType) + { + case Vehicle.TYPE_SLED: + m_linearFrictionTimescale = new Vector3(30, 1, 1000); + m_angularFrictionTimescale = new Vector3(30, 30, 30); +// m_lLinMotorVel = Vector3.Zero; + m_linearMotorTimescale = 1000; + m_linearMotorDecayTimescale = 120; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + m_angularMotorTimescale = 1000; + m_angularMotorDecayTimescale = 120; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 1; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 1; + // m_linearDeflectionTimescale = 1; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 1000; + // m_bankingEfficiency = 0; + // m_bankingMix = 1; + // m_bankingTimescale = 10; + // m_referenceFrame = Quaternion.Identity; + m_flags &= + ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_CAR: + m_linearFrictionTimescale = new Vector3(100, 2, 1000); + m_angularFrictionTimescale = new Vector3(30, 30, 30); // was 1000, but sl max frict time is 30. +// m_lLinMotorVel = Vector3.Zero; + m_linearMotorTimescale = 1; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + m_angularMotorTimescale = 1; + m_angularMotorDecayTimescale = 0.8f; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // // m_linearDeflectionEfficiency = 1; + // // m_linearDeflectionTimescale = 2; + // // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 10; + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 10f; + // m_bankingEfficiency = -0.2f; + // m_bankingMix = 1; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_BOAT: + m_linearFrictionTimescale = new Vector3(10, 3, 2); + m_angularFrictionTimescale = new Vector3(10,10,10); +// m_lLinMotorVel = Vector3.Zero; + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 2; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 0.5f; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 0.5f; + m_verticalAttractionTimescale = 5f; + // m_bankingEfficiency = -0.3f; + // m_bankingMix = 0.8f; + // m_bankingTimescale = 1; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY); + m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | + VehicleFlag.LIMIT_MOTOR_UP); + break; + case Vehicle.TYPE_AIRPLANE: + m_linearFrictionTimescale = new Vector3(200, 10, 5); + m_angularFrictionTimescale = new Vector3(20, 20, 20); +// m_lLinMotorVel = Vector3.Zero; + m_linearMotorTimescale = 2; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + m_angularMotorTimescale = 4; + m_angularMotorDecayTimescale = 4; + m_VhoverHeight = 0; +// m_VhoverEfficiency = 0.5f; + m_VhoverTimescale = 1000; + m_VehicleBuoyancy = 0; + // m_linearDeflectionEfficiency = 0.5f; + // m_linearDeflectionTimescale = 3; + // m_angularDeflectionEfficiency = 1; + // m_angularDeflectionTimescale = 2; + m_verticalAttractionEfficiency = 0.9f; + m_verticalAttractionTimescale = 2f; + // m_bankingEfficiency = 1; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 2; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY); + break; + case Vehicle.TYPE_BALLOON: + m_linearFrictionTimescale = new Vector3(5, 5, 5); + m_angularFrictionTimescale = new Vector3(10, 10, 10); + m_linearMotorTimescale = 5; + m_linearMotorDecayTimescale = 60; + m_angularMotorDirection = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + m_angularMotorTimescale = 6; + m_angularMotorDecayTimescale = 10; + m_VhoverHeight = 5; +// m_VhoverEfficiency = 0.8f; + m_VhoverTimescale = 10; + m_VehicleBuoyancy = 1; + // m_linearDeflectionEfficiency = 0; + // m_linearDeflectionTimescale = 5; + // m_angularDeflectionEfficiency = 0; + // m_angularDeflectionTimescale = 5; + m_verticalAttractionEfficiency = 1f; + m_verticalAttractionTimescale = 100f; + // m_bankingEfficiency = 0; + // m_bankingMix = 0.7f; + // m_bankingTimescale = 5; + // m_referenceFrame = Quaternion.Identity; + m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | + VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP); + m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT); + break; - public override void link(PhysicsActor obj) - { - m_taintparent = obj; - } + } + }//end SetDefaultsForType - public override void delink() + internal void Enable(IntPtr pBody, OdeScene pParentScene) { - m_taintparent = null; - } + if (m_type == Vehicle.TYPE_NONE) + return; - public override void LockAngularMotion(Vector3 axis) + m_body = pBody; + } + + + internal void Halt() + { // Kill all motions, when non-physical + m_linearMotorDirection = Vector3.Zero; + m_lLinMotorDVel = Vector3.Zero; + m_lLinObjectVel = Vector3.Zero; + m_wLinObjectVel = Vector3.Zero; + m_angularMotorDirection = Vector3.Zero; + m_lastAngularVelocity = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + } + + private void UpdateLinDecay() + { + if (Math.Abs(m_linearMotorDirection.X) > Math.Abs(m_lLinMotorDVel.X)) m_lLinMotorDVel.X = m_linearMotorDirection.X; + if (Math.Abs(m_linearMotorDirection.Y) > Math.Abs(m_lLinMotorDVel.Y)) m_lLinMotorDVel.Y = m_linearMotorDirection.Y; + if (Math.Abs(m_linearMotorDirection.Z) > Math.Abs(m_lLinMotorDVel.Z)) m_lLinMotorDVel.Z = m_linearMotorDirection.Z; + } // else let the motor decay on its own + + private void UpdateAngDecay() + { + if (Math.Abs(m_angularMotorDirection.X) > Math.Abs(m_angularMotorDVel.X)) m_angularMotorDVel.X = m_angularMotorDirection.X; + if (Math.Abs(m_angularMotorDirection.Y) > Math.Abs(m_angularMotorDVel.Y)) m_angularMotorDVel.Y = m_angularMotorDirection.Y; + if (Math.Abs(m_angularMotorDirection.Z) > Math.Abs(m_angularMotorDVel.Z)) m_angularMotorDVel.Z = m_angularMotorDirection.Z; + } // else let the motor decay on its own + + public void Move(float timestep) { - // reverse the zero/non zero values for ODE. - if (axis.IsFinite()) - { - axis.X = (axis.X > 0) ? 1f : 0f; - axis.Y = (axis.Y > 0) ? 1f : 0f; - axis.Z = (axis.Z > 0) ? 1f : 0f; - m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); - m_taintAngularLock = axis; - } - else - { - m_log.Warn("[PHYSICS]: Got NaN locking axis from Scene on Object"); - } - } + float fx = 0; + float fy = 0; + float fz = 0; - public void UpdatePositionAndVelocity() - { - // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! - if (_parent == null) + frcount++; // used to limit debug comment output + if (frcount > 100) + frcount = 0; + + if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. { - Vector3 pv = Vector3.Zero; - bool lastZeroFlag = _zeroFlag; - if (Body != (IntPtr)0) // FIXME -> or if it is a joint - { + +// Old public void UpdatePositionAndVelocity(), more accuratley calculated here + // Vector3 pv = Vector3.Zero; // what was this for? + bool lastZeroFlag = _zeroFlag; // was it stopped + // if (Body != (IntPtr)0) // FIXME -> or if it is a joint + // { d.Vector3 vec = d.BodyGetPosition(Body); d.Quaternion ori = d.BodyGetQuaternion(Body); d.Vector3 vel = d.BodyGetLinearVel(Body); @@ -2730,12 +3275,13 @@ Console.WriteLine(" JointCreateFixed"); l_orientation.Y = ori.Y; l_orientation.Z = ori.Z; l_orientation.W = ori.W; +//Console.WriteLine("Move {0} at {1}", m_primName, l_position); -// if(l_position.Y != m_lastposition.Y){ -// Console.WriteLine("UP&V {0} {1}", m_primName, l_position); -// } - if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) + if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || + l_position.X < 0f || + l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || + l_position.Y < 0f) { //base.RaiseOutOfBounds(l_position); @@ -2808,7 +3354,7 @@ Console.WriteLine(" JointCreateFixed"); } if (_zeroFlag) - { + { // Its stopped _velocity.X = 0.0f; _velocity.Y = 0.0f; _velocity.Z = 0.0f; @@ -2828,7 +3374,7 @@ Console.WriteLine(" JointCreateFixed"); { m_throttleUpdates = false; throttleCounter = 0; - m_rotationalVelocity = pv; + // m_rotationalVelocity = pv; What was this for? if (_parent == null) { @@ -2839,7 +3385,7 @@ Console.WriteLine(" JointCreateFixed"); } } else - { + { // Its moving if (lastZeroFlag != _zeroFlag) { if (_parent == null) @@ -2855,22 +3401,14 @@ Console.WriteLine(" JointCreateFixed"); _velocity.X = vel.X; _velocity.Y = vel.Y; _velocity.Z = vel.Z; - - _acceleration = ((_velocity - m_lastVelocity) / 0.1f); - _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); - //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); - -// if (_velocity.ApproxEquals(pv, 0.5f)) ???? Disregard rotational vel if lin vel is < 0.5 ????? -// { -// m_rotationalVelocity = pv;/ - -// } -// else -// { - m_rotationalVelocity = new Vector3(rotvel.X, rotvel.Y, rotvel.Z); -// } - - //m_log.Debug("ODE: " + m_rotationalVelocity.ToString()); +// Why 2 calcs??? +// _acceleration = ((_velocity - m_lastVelocity) / 0.1f); +// _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, +// _velocity.Y - m_lastVelocity.Y / 0.1f, +// _velocity.Z - m_lastVelocity.Z / 0.1f); + + _acceleration = ((_velocity - m_lastVelocity) / timestep); + _orientation.X = ori.X; _orientation.Y = ori.Y; _orientation.Z = ori.Z; @@ -2889,434 +3427,592 @@ Console.WriteLine(" JointCreateFixed"); } } m_lastposition = l_position; - } - else - { - // Not a body.. so Make sure the client isn't interpolating - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; + + /// End of old UpdatePositionAndVelocity insert + +//if (!Acceleration.ApproxEquals(Vector3.Zero, 0.01f)) Console.WriteLine("Move " + m_primName + " Accel=" + Acceleration); +//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_type + + // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); + if (m_type != Vehicle.TYPE_NONE) + { + // get body attitude + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object + Quaternion irotq = Quaternion.Inverse(rotq); + + // VEHICLE Linear Motion + d.Vector3 velnow = d.BodyGetLinearVel(Body); // this is in world frame + Vector3 vel_now = new Vector3(velnow.X, velnow.Y, velnow.Z); + m_lLinObjectVel = vel_now * irotq; + + if (m_linearMotorDecayTimescale < 300.0f) //setting of 300 or more disables decay rate + { + if ( Vector3.Mag(m_lLinMotorDVel) < 1.0f) + { + float decayfactor = m_linearMotorDecayTimescale/timestep; + Vector3 decayAmount = (m_lLinMotorDVel/decayfactor); + m_lLinMotorDVel -= decayAmount; + } + else + { + float decayfactor = 3.0f - (0.57f * (float)Math.Log((double)(m_linearMotorDecayTimescale))); + Vector3 decel = Vector3.Normalize(m_lLinMotorDVel) * decayfactor * timestep; + m_lLinMotorDVel -= decel; + } + if (m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_lLinMotorDVel = Vector3.Zero; + } + else + { + if (Math.Abs(m_lLinMotorDVel.X) < Math.Abs(m_lLinObjectVel.X)) m_lLinObjectVel.X = m_lLinMotorDVel.X; + if (Math.Abs(m_lLinMotorDVel.Y) < Math.Abs(m_lLinObjectVel.Y)) m_lLinObjectVel.Y = m_lLinMotorDVel.Y; + if (Math.Abs(m_lLinMotorDVel.Z) < Math.Abs(m_lLinObjectVel.Z)) m_lLinObjectVel.Z = m_lLinMotorDVel.Z; + } + } // end linear motor decay + + if ( (! m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! m_lLinObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + if (m_linearMotorTimescale < 300.0f) + { + Vector3 attack_error = m_lLinMotorDVel - m_lLinObjectVel; + float linfactor = m_linearMotorTimescale/timestep; + Vector3 attackAmount = (attack_error/linfactor) * 1.3f; + m_lLinObjectVel += attackAmount; + } + if (m_linearFrictionTimescale.X < 300.0f) + { + float fricfactor = m_linearFrictionTimescale.X / timestep; + float fricX = m_lLinObjectVel.X / fricfactor; + m_lLinObjectVel.X -= fricX; + } + if (m_linearFrictionTimescale.Y < 300.0f) + { + float fricfactor = m_linearFrictionTimescale.Y / timestep; + float fricY = m_lLinObjectVel.Y / fricfactor; + m_lLinObjectVel.Y -= fricY; + } + if (m_linearFrictionTimescale.Z < 300.0f) + { + float fricfactor = m_linearFrictionTimescale.Z / timestep; +//if(frcount == 0) Console.WriteLine("Zfric={0}", fricfactor); + float fricZ = m_lLinObjectVel.Z / fricfactor; + m_lLinObjectVel.Z -= fricZ; + } + } + m_wLinObjectVel = m_lLinObjectVel * rotq; + + // Gravity and Buoyancy + Vector3 grav = Vector3.Zero; + if(m_VehicleBuoyancy < 1.0f) + { + // There is some gravity, make a gravity force vector + // that is applied after object velocity. + d.Mass objMass; + d.BodyGetMass(Body, out objMass); + // m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g; + grav.Z = _parent_scene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy); // Applied later as a force + } // else its 1.0, no gravity. + + // Hovering + if( (m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0) + { + // We should hover, get the target height + d.Vector3 pos = d.BodyGetPosition(Body); + if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY) + { + m_VhoverTargetHeight = _parent_scene.GetWaterLevel() + m_VhoverHeight; + } + else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY) + { + m_VhoverTargetHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; + } + else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT) + { + m_VhoverTargetHeight = m_VhoverHeight; + } + + if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY) + { + // If body is aready heigher, use its height as target height + if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z; + } + +// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped +// m_VhoverTimescale = 0f; // time to acheive height +// timestep is time since last frame,in secs + float herr0 = pos.Z - m_VhoverTargetHeight; + // Replace Vertical speed with correction figure if significant + if(Math.Abs(herr0) > 0.01f ) + { + //? d.Mass objMass; + //? d.BodyGetMass(Body, out objMass); + m_wLinObjectVel.Z = - ( (herr0 * timestep * 50.0f) / m_VhoverTimescale); + //KF: m_VhoverEfficiency is not yet implemented + } + else + { + m_wLinObjectVel.Z = 0f; + } + } + else + { // not hovering, Gravity rules + m_wLinObjectVel.Z = vel_now.Z; + } + + + // Vehicle Linear Motion done ======================================= + // Apply velocity + d.BodySetLinearVel(Body, m_wLinObjectVel.X, m_wLinObjectVel.Y, m_wLinObjectVel.Z); + // apply gravity force + d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); +//if(frcount == 0) Console.WriteLine("Grav {0}", grav); + // end MoveLinear() + + + // MoveAngular + /* + private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor + + private float m_angularMotorTimescale = 0; // motor angular Attack rate set by LSL + private float m_angularMotorDecayTimescale = 0; // motor angular Decay rate set by LSL + private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular Friction set by LSL + + private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor + private Vector3 m_angObjectVel = Vector3.Zero; // what was last applied to body + */ +//if(frcount == 0) Console.WriteLine("MoveAngular "); + + d.Vector3 angularObjectVel = d.BodyGetAngularVel(Body); + Vector3 angObjectVel = new Vector3(angularObjectVel.X, angularObjectVel.Y, angularObjectVel.Z); + angObjectVel = angObjectVel * irotq; // ============ Converts to LOCAL rotation + +//if(frcount == 0) Console.WriteLine("V0 = {0}", angObjectVel); + + // Decay Angular Motor 1. In SL this also depends on attack rate! decay ~= 23/Attack. + float atk_decayfactor = 23.0f / (m_angularMotorTimescale * timestep); + m_angularMotorDVel -= m_angularMotorDVel / atk_decayfactor; + // Decay Angular Motor 2. + if (m_angularMotorDecayTimescale < 300.0f) + { + if ( Vector3.Mag(m_angularMotorDVel) < 1.0f) + { + float decayfactor = (m_angularMotorDecayTimescale)/timestep; + Vector3 decayAmount = (m_angularMotorDVel/decayfactor); + m_angularMotorDVel -= decayAmount; + } + else + { + Vector3 decel = Vector3.Normalize(m_angularMotorDVel) * timestep / m_angularMotorDecayTimescale; + m_angularMotorDVel -= decel; + } + + if (m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) + { + m_angularMotorDVel = Vector3.Zero; + } + else + { + if (Math.Abs(m_angularMotorDVel.X) < Math.Abs(angObjectVel.X)) angObjectVel.X = m_angularMotorDVel.X; + if (Math.Abs(m_angularMotorDVel.Y) < Math.Abs(angObjectVel.Y)) angObjectVel.Y = m_angularMotorDVel.Y; + if (Math.Abs(m_angularMotorDVel.Z) < Math.Abs(angObjectVel.Z)) angObjectVel.Z = m_angularMotorDVel.Z; + } + } // end decay angular motor +//if(frcount == 0) Console.WriteLine("MotorDvel {0} Obj {1}", m_angularMotorDVel, angObjectVel); + +//if(frcount == 0) Console.WriteLine("VA = {0}", angObjectVel); + + // Vertical attractor section + Vector3 vertattr = Vector3.Zero; + + if(m_verticalAttractionTimescale < 300) + { + float VAservo = 1.0f / (m_verticalAttractionTimescale * timestep); + // make a vector pointing up + Vector3 verterr = Vector3.Zero; + verterr.Z = 1.0f; + // rotate it to Body Angle + verterr = verterr * rotq; + // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1. + // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go + // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body. + + if (verterr.Z < 0.0f) + { // Deflection from vertical exceeds 90-degrees. This method will ensure stable return to + // vertical, BUT for some reason a z-rotation is imparted to the object. TBI. +//Console.WriteLine("InvertFlip"); + verterr.X = 2.0f - verterr.X; + verterr.Y = 2.0f - verterr.Y; + } + verterr *= 0.5f; + // verterror is 0 (no error) to +/- 1 (max error at 180-deg tilt) + + if ((!angObjectVel.ApproxEquals(Vector3.Zero, 0.001f)) || (verterr.Z < 0.49f)) + { + // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so + // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. + vertattr.X = verterr.Y; + vertattr.Y = - verterr.X; + vertattr.Z = 0f; +//if(frcount == 0) Console.WriteLine("VAerr=" + verterr); + + // scaling appears better usingsquare-law + float damped = m_verticalAttractionEfficiency * m_verticalAttractionEfficiency; + float bounce = 1.0f - damped; + // 0 = crit damp, 1 = bouncy + float oavz = angObjectVel.Z; // retain z velocity + // time-scaled correction, which sums, therefore is bouncy: + angObjectVel = (angObjectVel + (vertattr * VAservo * 0.0333f)) * bounce; + // damped, good @ < 90: + angObjectVel = angObjectVel + (vertattr * VAservo * 0.0667f * damped); + angObjectVel.Z = oavz; +//if(frcount == 0) Console.WriteLine("VA+"); +//Console.WriteLine("VAttr {0} OAvel {1}", vertattr, angObjectVel); + } + else + { + // else error is very small + angObjectVel.X = 0f; + angObjectVel.Y = 0f; +//if(frcount == 0) Console.WriteLine("VA0"); + } + } // else vertical attractor is off +//if(frcount == 0) Console.WriteLine("V1 = {0}", angObjectVel); + + if ( (! m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! angObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) + { // if motor or object have motion + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + + if (m_angularMotorTimescale < 300.0f) + { + Vector3 attack_error = m_angularMotorDVel - angObjectVel; + float angfactor = m_angularMotorTimescale/timestep; + Vector3 attackAmount = (attack_error/angfactor); + angObjectVel += attackAmount; +//if(frcount == 0) Console.WriteLine("Accel {0} Attk {1}",FrAaccel, attackAmount); +//if(frcount == 0) Console.WriteLine("V2+= {0}", angObjectVel); + } + + angObjectVel.X -= angObjectVel.X / (m_angularFrictionTimescale.X * 0.7f / timestep); + angObjectVel.Y -= angObjectVel.Y / (m_angularFrictionTimescale.Y * 0.7f / timestep); + angObjectVel.Z -= angObjectVel.Z / (m_angularFrictionTimescale.Z * 0.7f / timestep); + } // else no signif. motion + +//if(frcount == 0) Console.WriteLine("Dmotor {0} Obj {1}", m_angularMotorDVel, angObjectVel); + // Bank section tba + // Deflection section tba +//if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); + + m_lastAngularVelocity = angObjectVel; +//if(frcount == 0) Console.WriteLine("angularLock {0}", m_angularLock); + + if (!m_angularLock.ApproxEquals(Vector3.One, 0.003f)) + { + if (m_angularLock.X == 0) + m_lastAngularVelocity.X = 0f; + if (m_angularLock.Y == 0) + m_lastAngularVelocity.Y = 0f; + if (m_angularLock.Z == 0) + m_lastAngularVelocity.Z = 0f; + } + // Apply to the body +// Vector3 aInc = m_lastAngularVelocity - initavel; +//if(frcount == 0) Console.WriteLine("Inc {0}", aInc); + m_lastAngularVelocity = m_lastAngularVelocity * rotq; // ================ Converts to WORLD rotation + + d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); +//if(frcount == 0) Console.WriteLine("V4 = {0}", m_lastAngularVelocity); + + } // end VEHICLES #### + else + { + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 + // NON-'VEHICLES' are dealt with here + // m_angularlock = <1,1,1> means no lock. a 0 on axis means locked. + +// NB this may be wrong - may lock global axis! Should be LOCAL axis! + /// Dynamics Angular Lock ======================================================================== + if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.One, 0.003f)) + { + d.Vector3 avel2 = d.BodyGetAngularVel(Body); + if (m_angularlock.X == 0) + avel2.X = 0; + if (m_angularlock.Y == 0) + avel2.Y = 0; + if (m_angularlock.Z == 0) + avel2.Z = 0; + d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); + } - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - _zeroFlag = true; - } - } - } + /// Dynamics Buoyancy =============================================================================== + //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle. + // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up + // NB Prims in ODE are no subject to global gravity + float m_mass = CalculateMass(); + fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass - public override bool FloatOnWater - { - set { - m_taintCollidesWater = value; - _parent_scene.AddPhysicsActorTaint(this); - } - } + if (m_usePID) + { +//if(frcount == 0) Console.WriteLine("PID " + m_primName); + // KF - this is for object MoveToTarget. + + //if (!d.BodyIsEnabled(Body)) + //d.BodySetForce(Body, 0f, 0f, 0f); - public override void SetMomentum(Vector3 momentum) - { - } + // no lock; for now it's only called from within Simulate() + + // If the PID Controller isn't active then we set our force + // calculating base velocity to the current position - public override Vector3 PIDTarget - { - set - { - if (value.IsFinite()) - { - m_PIDTarget = value; - } - else - m_log.Warn("[PHYSICS]: Got NaN PIDTarget from Scene on Object"); - } - } - public override bool PIDActive { set { m_usePID = value; } } - public override float PIDTau { set { m_PIDTau = value; } } - - // For RotLookAt - public override Quaternion APIDTarget { set { m_APIDTarget = value; } } - public override bool APIDActive { set { m_useAPID = value; } } - public override float APIDStrength { set { m_APIDStrength = value; } } - public override float APIDDamping { set { m_APIDDamping = value; } } + if ((m_PIDTau < 1) && (m_PIDTau != 0)) + { + //PID_G = PID_G / m_PIDTau; + m_PIDTau = 1; + } + + if ((PID_G - m_PIDTau) <= 0) + { + PID_G = m_PIDTau + 1; + } + //PidStatus = true; - public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } } - public override bool PIDHoverActive { set { m_useHoverPID = value; } } - public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } } - public override float PIDHoverTau { set { m_PIDHoverTau = value; } } + // PhysicsVector vec = new PhysicsVector(); +// d.Vector3 vel = d.BodyGetLinearVel(Body); - private void createAMotor(Vector3 axis) // ##* - { -Console.WriteLine(" createAMotor called! ----------------------------"); - if (Body == IntPtr.Zero) - return; + d.Vector3 pos = d.BodyGetPosition(Body); + _target_velocity = + new Vector3( + (m_PIDTarget.X - pos.X) * ((PID_G - m_PIDTau) * timestep), + (m_PIDTarget.Y - pos.Y) * ((PID_G - m_PIDTau) * timestep), + (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) + ); - if (Amotor != IntPtr.Zero) - { - d.JointDestroy(Amotor); - Amotor = IntPtr.Zero; - } + // if velocity is zero, use position control; otherwise, velocity control - float axisnum = 3; + if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f)) + { + // keep track of where we stopped. No more slippin' & slidin' + + // We only want to deactivate the PID Controller if we think we want to have our surrogate + // react to the physics scene by moving it's position. + // Avatar to Avatar collisions + // Prim to avatar collisions - axisnum = (axisnum - (axis.X + axis.Y + axis.Z)); + //fx = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); + //fy = (_target_velocity.Y - vel.Y) * (PID_D) + (_zeroPosition.Y - pos.Y) * (PID_P * 2); + //fz = fz + (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; + d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); + d.BodySetLinearVel(Body, 0, 0, 0); + d.BodyAddForce(Body, 0, 0, fz); + return; + } + else + { + _zeroFlag = false; - // PhysicsVector totalSize = new PhysicsVector(_size.X, _size.Y, _size.Z); + // We're flying and colliding with something + fx = ((_target_velocity.X) - vel.X) * (PID_D); + fy = ((_target_velocity.Y) - vel.Y) * (PID_D); + + // vec.Z = (_target_velocity.Z - vel.Z) * PID_D + (_zeroPosition.Z - pos.Z) * PID_P; - - // Inverse Inertia Matrix, set the X, Y, and/r Z inertia to 0 then invert it again. - d.Mass objMass; - d.MassSetZero(out objMass); - DMassCopy(ref pMass, ref objMass); + fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); + } + } // end if (m_usePID) + + /// Dynamics Hover =================================================================================== + // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller + if (m_useHoverPID && !m_usePID) + { +//Console.WriteLine("Hover " + m_primName); + + // If we're using the PID controller, then we have no gravity + fz = (-1 * _parent_scene.gravityz) * m_mass; - //m_log.DebugFormat("1-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); + // no lock; for now it's only called from within Simulate() - Matrix4 dMassMat = FromDMass(objMass); + // If the PID Controller isn't active then we set our force + // calculating base velocity to the current position - Matrix4 mathmat = Inverse(dMassMat); + if ((m_PIDTau < 1)) + { + PID_G = PID_G / m_PIDTau; + } - /* - //m_log.DebugFormat("2-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", mathmat[0, 0], mathmat[0, 1], mathmat[0, 2], mathmat[1, 0], mathmat[1, 1], mathmat[1, 2], mathmat[2, 0], mathmat[2, 1], mathmat[2, 2]); + if ((PID_G - m_PIDTau) <= 0) + { + PID_G = m_PIDTau + 1; + } + - mathmat = Inverse(mathmat); - - - objMass = FromMatrix4(mathmat, ref objMass); - //m_log.DebugFormat("3-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); - - mathmat = Inverse(mathmat); - */ - if (axis.X == 0) - { - mathmat.M33 = 50.0000001f; - //objMass.I.M22 = 0; - } - if (axis.Y == 0) - { - mathmat.M22 = 50.0000001f; - //objMass.I.M11 = 0; - } - if (axis.Z == 0) - { - mathmat.M11 = 50.0000001f; - //objMass.I.M00 = 0; - } - - - - mathmat = Inverse(mathmat); - objMass = FromMatrix4(mathmat, ref objMass); - //m_log.DebugFormat("4-{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, ", objMass.I.M00, objMass.I.M01, objMass.I.M02, objMass.I.M10, objMass.I.M11, objMass.I.M12, objMass.I.M20, objMass.I.M21, objMass.I.M22); - - //return; - if (d.MassCheck(ref objMass)) - { - d.BodySetMass(Body, ref objMass); - } - else - { - //m_log.Debug("[PHYSICS]: Mass invalid, ignoring"); - } - - if (axisnum <= 0) - return; - // int dAMotorEuler = 1; - - Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); - d.JointAttach(Amotor, Body, IntPtr.Zero); - d.JointSetAMotorMode(Amotor, 0); - - d.JointSetAMotorNumAxes(Amotor,(int)axisnum); - int i = 0; - - if (axis.X == 0) - { - d.JointSetAMotorAxis(Amotor, i, 0, 1, 0, 0); - i++; - } - - if (axis.Y == 0) - { - d.JointSetAMotorAxis(Amotor, i, 0, 0, 1, 0); - i++; - } - - if (axis.Z == 0) - { - d.JointSetAMotorAxis(Amotor, i, 0, 0, 0, 1); - i++; - } - - for (int j = 0; j < (int)axisnum; j++) - { - //d.JointSetAMotorAngle(Amotor, j, 0); - } - - //d.JointSetAMotorAngle(Amotor, 1, 0); - //d.JointSetAMotorAngle(Amotor, 2, 0); - - // These lowstops and high stops are effectively (no wiggle room) - d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0f); - d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0f); - //d.JointSetAMotorParam(Amotor, (int) dParam.Vel, 9000f); - d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f); - d.JointSetAMotorParam(Amotor, (int)dParam.FMax, Mass * 50f);// - - } - - public Matrix4 FromDMass(d.Mass pMass) - { - Matrix4 obj; - obj.M11 = pMass.I.M00; - obj.M12 = pMass.I.M01; - obj.M13 = pMass.I.M02; - obj.M14 = 0; - obj.M21 = pMass.I.M10; - obj.M22 = pMass.I.M11; - obj.M23 = pMass.I.M12; - obj.M24 = 0; - obj.M31 = pMass.I.M20; - obj.M32 = pMass.I.M21; - obj.M33 = pMass.I.M22; - obj.M34 = 0; - obj.M41 = 0; - obj.M42 = 0; - obj.M43 = 0; - obj.M44 = 1; - return obj; - } - - public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) - { - obj.I.M00 = pMat[0, 0]; - obj.I.M01 = pMat[0, 1]; - obj.I.M02 = pMat[0, 2]; - obj.I.M10 = pMat[1, 0]; - obj.I.M11 = pMat[1, 1]; - obj.I.M12 = pMat[1, 2]; - obj.I.M20 = pMat[2, 0]; - obj.I.M21 = pMat[2, 1]; - obj.I.M22 = pMat[2, 2]; - return obj; - } - - public override void SubscribeEvents(int ms) - { - m_eventsubscription = ms; - _parent_scene.addCollisionEventReporting(this); - } - - public override void UnSubscribeEvents() - { - _parent_scene.remCollisionEventReporting(this); - m_eventsubscription = 0; - } - - public void AddCollisionEvent(uint CollidedWith, ContactPoint contact) - { - if (CollisionEventsThisFrame == null) - CollisionEventsThisFrame = new CollisionEventUpdate(); - CollisionEventsThisFrame.addCollider(CollidedWith, contact); - } - - public void SendCollisions() - { - if (CollisionEventsThisFrame == null) - return; - - base.SendCollisionUpdate(CollisionEventsThisFrame); - - if (CollisionEventsThisFrame.m_objCollisionList.Count == 0) - CollisionEventsThisFrame = null; - else - CollisionEventsThisFrame = new CollisionEventUpdate(); - } - - public override bool SubscribedEvents() - { - if (m_eventsubscription > 0) - return true; - return false; - } + // Where are we, and where are we headed? + d.Vector3 pos = d.BodyGetPosition(Body); +// d.Vector3 vel = d.BodyGetLinearVel(Body); - public static Matrix4 Inverse(Matrix4 pMat) - { - if (determinant3x3(pMat) == 0) - { - return Matrix4.Identity; // should probably throw an error. singluar matrix inverse not possible - } + // Non-Vehicles have a limited set of Hover options. + // determine what our target height really is based on HoverType + switch (m_PIDHoverType) + { + case PIDHoverType.Ground: + m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); + m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; + break; + case PIDHoverType.GroundAndWater: + m_groundHeight = _parent_scene.GetTerrainHeightAtXY(pos.X, pos.Y); + m_waterHeight = _parent_scene.GetWaterLevel(); + if (m_groundHeight > m_waterHeight) + { + m_targetHoverHeight = m_groundHeight + m_PIDHoverHeight; + } + else + { + m_targetHoverHeight = m_waterHeight + m_PIDHoverHeight; + } + break; + } // end switch (m_PIDHoverType) - return (Adjoint(pMat) / determinant3x3(pMat)); - } - public static Matrix4 Adjoint(Matrix4 pMat) - { - Matrix4 adjointMatrix = new Matrix4(); - for (int i=0; i<4; i++) - { - for (int j=0; j<4; j++) - { - Matrix4SetValue(ref adjointMatrix, i, j, (float)(Math.Pow(-1, i + j) * (determinant3x3(Minor(pMat, i, j))))); - } - } + _target_velocity = + new Vector3(0.0f, 0.0f, + (m_targetHoverHeight - pos.Z) * ((PID_G - m_PIDHoverTau) * timestep) + ); - adjointMatrix = Transpose(adjointMatrix); - return adjointMatrix; - } + // if velocity is zero, use position control; otherwise, velocity control - public static Matrix4 Minor(Matrix4 matrix, int iRow, int iCol) - { - Matrix4 minor = new Matrix4(); - int m = 0, n = 0; - for (int i = 0; i < 4; i++) - { - if (i == iRow) - continue; - n = 0; - for (int j = 0; j < 4; j++) - { - if (j == iCol) - continue; - Matrix4SetValue(ref minor, m,n, matrix[i, j]); - n++; - } - m++; - } - return minor; - } + if (_target_velocity.ApproxEquals(Vector3.Zero, 0.1f)) + { + // keep track of where we stopped. No more slippin' & slidin' + + // We only want to deactivate the PID Controller if we think we want to have our surrogate + // react to the physics scene by moving it's position. + // Avatar to Avatar collisions + // Prim to avatar collisions - public static Matrix4 Transpose(Matrix4 pMat) - { - Matrix4 transposeMatrix = new Matrix4(); - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - Matrix4SetValue(ref transposeMatrix, i, j, pMat[j, i]); - return transposeMatrix; - } + d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); + d.BodySetLinearVel(Body, vel.X, vel.Y, 0); + d.BodyAddForce(Body, 0, 0, fz); + //KF this prevents furthur motions return; + } + else + { + _zeroFlag = false; - public static void Matrix4SetValue(ref Matrix4 pMat, int r, int c, float val) - { - switch (r) - { - case 0: - switch (c) - { - case 0: - pMat.M11 = val; - break; - case 1: - pMat.M12 = val; - break; - case 2: - pMat.M13 = val; - break; - case 3: - pMat.M14 = val; - break; - } + // We're flying and colliding with something + fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); + } + } // end m_useHoverPID && !m_usePID + + /// Dynamics RotLookAt ================================================================================= + if (m_useAPID) + { + // RotLookAt, apparently overrides all other rotation sources. Inputs: + // Quaternion m_APIDTarget + // float m_APIDStrength // From SL experiments, this is the time to get there + // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly + // Also in SL the mass of the object has no effect on time to get there. + // Factors: +//if(frcount == 0) Console.WriteLine("APID "); + // get present body rotation + float limit = 1.0f; + float scaler = 50f; // adjusts damping time + float RLAservo = 0f; + + d.Quaternion rot = d.BodyGetQuaternion(Body); + Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); + Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget; + float diff_angle; + Vector3 diff_axis; + rot_diff.GetAxisAngle(out diff_axis, out diff_angle); + diff_axis.Normalize(); + if(diff_angle > 0.01f) // diff_angle is always +ve + { +// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z); + Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z); + rotforce = rotforce * rotq; + if(diff_angle > limit) diff_angle = limit; // cap the rotate rate +// RLAservo = timestep / m_APIDStrength * m_mass * scaler; + // rotforce = rotforce * RLAservo * diff_angle ; + // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); + RLAservo = timestep / m_APIDStrength * scaler; + rotforce = rotforce * RLAservo * diff_angle ; + + if (m_angularlock.X == 0) + rotforce.X = 0; + if (m_angularlock.Y == 0) + rotforce.Y = 0; + if (m_angularlock.Z == 0) + rotforce.Z = 0; + + d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); +//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); + } +//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle); + } // end m_useAPID + + /// Dynamics Apply Forces =================================================================================== + fx *= m_mass; + fy *= m_mass; + //fz *= m_mass; - break; - case 1: - switch (c) - { - case 0: - pMat.M21 = val; - break; - case 1: - pMat.M22 = val; - break; - case 2: - pMat.M23 = val; - break; - case 3: - pMat.M24 = val; - break; - } + fx += m_force.X; + fy += m_force.Y; + fz += m_force.Z; - break; - case 2: - switch (c) - { - case 0: - pMat.M31 = val; - break; - case 1: - pMat.M32 = val; - break; - case 2: - pMat.M33 = val; - break; - case 3: - pMat.M34 = val; - break; - } + //m_log.Info("[OBJPID]: X:" + fx.ToString() + " Y:" + fy.ToString() + " Z:" + fz.ToString()); + if (fx != 0 || fy != 0 || fz != 0) + { + //m_taintdisable = true; + //base.RaiseOutOfBounds(Position); + //d.BodySetLinearVel(Body, fx, fy, 0f); + if (!d.BodyIsEnabled(Body)) + { + // A physical body at rest on a surface will auto-disable after a while, + // this appears to re-enable it incase the surface it is upon vanishes, + // and the body should fall again. + d.BodySetLinearVel(Body, 0f, 0f, 0f); + d.BodySetForce(Body, 0, 0, 0); + enableBodySoft(); + } - break; - case 3: - switch (c) - { - case 0: - pMat.M41 = val; - break; - case 1: - pMat.M42 = val; - break; - case 2: - pMat.M43 = val; - break; - case 3: - pMat.M44 = val; - break; - } + // 35x10 = 350n times the mass per second applied maximum. + float nmax = 35f * m_mass; + float nmin = -35f * m_mass; - break; + + if (fx > nmax) + fx = nmax; + if (fx < nmin) + fx = nmin; + if (fy > nmax) + fy = nmax; + if (fy < nmin) + fy = nmin; + d.BodyAddForce(Body, fx, fy, fz); +//Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); + } + } } - } - private static float determinant3x3(Matrix4 pMat) - { - float det = 0; - float diag1 = pMat[0, 0]*pMat[1, 1]*pMat[2, 2]; - float diag2 = pMat[0, 1]*pMat[2, 1]*pMat[2, 0]; - float diag3 = pMat[0, 2]*pMat[1, 0]*pMat[2, 1]; - float diag4 = pMat[2, 0]*pMat[1, 1]*pMat[0, 2]; - float diag5 = pMat[2, 1]*pMat[1, 2]*pMat[0, 0]; - float diag6 = pMat[2, 2]*pMat[1, 0]*pMat[0, 1]; - - det = diag1 + diag2 + diag3 - (diag4 + diag5 + diag6); - return det; - - } - - private static void DMassCopy(ref d.Mass src, ref d.Mass dst) - { - dst.c.W = src.c.W; - dst.c.X = src.c.X; - dst.c.Y = src.c.Y; - dst.c.Z = src.c.Z; - dst.mass = src.mass; - dst.I.M00 = src.I.M00; - dst.I.M01 = src.I.M01; - dst.I.M02 = src.I.M02; - dst.I.M10 = src.I.M10; - dst.I.M11 = src.I.M11; - dst.I.M12 = src.I.M12; - dst.I.M20 = src.I.M20; - dst.I.M21 = src.I.M21; - dst.I.M22 = src.I.M22; - } + else + { // is not physical, or is not a body or is selected + // from old UpdatePositionAndVelocity, ... Not a body.. so Make sure the client isn't interpolating + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; - public override void SetMaterial(int pMaterial) - { - m_material = pMaterial; - } + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; - } + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + _zeroFlag = true; + return; + } + } // end Move() + } // end class } -- cgit v1.1 From 1379ae4310b94afd1a7a1d9964db26146ca5c7b2 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 12 Mar 2010 16:13:52 -0500 Subject: Fix Rotation Lock. NOTE: This version had poor border crossing control --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 38 ++++++++++++------------- OpenSim/Region/Physics/PhysXPlugin/PhysXPrim.cs | 4 --- 2 files changed, 18 insertions(+), 24 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index e51ef5b..367927d 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -64,7 +64,7 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_taintVelocity; private Vector3 m_taintTorque; private Quaternion m_taintrot; - private Vector3 m_angularlock = Vector3.One; // Current setting + private Vector3 m_angularEnable = Vector3.One; // Current setting private Vector3 m_taintAngularLock = Vector3.One; // Request from LSL @@ -216,8 +216,6 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_angularMotorDVel = Vector3.Zero; // decayed angular motor // private Vector3 m_angObjectVel = Vector3.Zero; // current body angular velocity private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body - - private Vector3 m_angularLock = Vector3.One; //Deflection properties // private float m_angularDeflectionEfficiency = 0; @@ -1401,8 +1399,8 @@ namespace OpenSim.Region.Physics.OdePlugin changefloatonwater(timestep); // ##* - if (!m_angularlock.ApproxEquals(m_taintAngularLock,0f)) -//Console.WriteLine("ALchange req {0} is {1}", m_taintAngularLock, m_angularlock); + if (!m_angularEnable.ApproxEquals(m_taintAngularLock,0f)) +Console.WriteLine("ALchange req {0} is {1}", m_taintAngularLock, m_angularEnable); changeAngularLock(timestep); } @@ -1422,8 +1420,8 @@ namespace OpenSim.Region.Physics.OdePlugin //If we have a parent then we're not authorative here if (_parent == null) { -//Console.WriteLine("Alock changed to {0}", m_taintAngularLock); - m_angularlock = m_taintAngularLock; +Console.WriteLine("Alock changed to {0}", m_taintAngularLock); + m_angularEnable = m_taintAngularLock; } } @@ -3703,15 +3701,15 @@ Console.WriteLine(" JointCreateFixed"); //if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); m_lastAngularVelocity = angObjectVel; -//if(frcount == 0) Console.WriteLine("angularLock {0}", m_angularLock); +if(frcount == 0) Console.WriteLine("angularEnable {0}", m_angularEnable); - if (!m_angularLock.ApproxEquals(Vector3.One, 0.003f)) + if (!m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) { - if (m_angularLock.X == 0) + if (m_angularEnable.X == 0) m_lastAngularVelocity.X = 0f; - if (m_angularLock.Y == 0) + if (m_angularEnable.Y == 0) m_lastAngularVelocity.Y = 0f; - if (m_angularLock.Z == 0) + if (m_angularEnable.Z == 0) m_lastAngularVelocity.Z = 0f; } // Apply to the body @@ -3727,18 +3725,18 @@ Console.WriteLine(" JointCreateFixed"); { if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 // NON-'VEHICLES' are dealt with here - // m_angularlock = <1,1,1> means no lock. a 0 on axis means locked. + // m_angularEnable = <1,1,1> means no lock. a 0 on axis means locked. // NB this may be wrong - may lock global axis! Should be LOCAL axis! /// Dynamics Angular Lock ======================================================================== - if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.One, 0.003f)) + if (d.BodyIsEnabled(Body) && !m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) { d.Vector3 avel2 = d.BodyGetAngularVel(Body); - if (m_angularlock.X == 0) + if (m_angularEnable.X == 0) avel2.X = 0; - if (m_angularlock.Y == 0) + if (m_angularEnable.Y == 0) avel2.Y = 0; - if (m_angularlock.Z == 0) + if (m_angularEnable.Z == 0) avel2.Z = 0; d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); } @@ -3938,11 +3936,11 @@ Console.WriteLine(" JointCreateFixed"); RLAservo = timestep / m_APIDStrength * scaler; rotforce = rotforce * RLAservo * diff_angle ; - if (m_angularlock.X == 0) + if (m_angularEnable.X == 0) rotforce.X = 0; - if (m_angularlock.Y == 0) + if (m_angularEnable.Y == 0) rotforce.Y = 0; - if (m_angularlock.Z == 0) + if (m_angularEnable.Z == 0) rotforce.Z = 0; d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPrim.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPrim.cs index d1b5b7e..c0e24fd 100644 --- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPrim.cs +++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPrim.cs @@ -279,10 +279,6 @@ namespace OpenSim.Region.Physics.PhysXPlugin public override void VehicleFlags(int param, bool remove) { } - public override void VehicleFlagsSet(int param) { } - - public override void VehicleFlagsRemove(int param) { } - public override void SetVolumeDetect(int param) { -- cgit v1.1 From 80e4068b3e85625234270cd7f3735cfd1b4e83dc Mon Sep 17 00:00:00 2001 From: CasperW Date: Sat, 13 Mar 2010 15:13:19 +0100 Subject: Fix the delay in llGiveInventory so that it only takes effect when giving inventory to an avatar (this now replicates SL behaviour) --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 180fba9..0117fa0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4014,14 +4014,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bucket); if (m_TransferModule != null) - m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); + m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); + + //This delay should only occur when giving inventory to avatars. + ScriptSleep(3000); } else { // destination is an object World.MoveTaskInventoryItem(destId, m_host, objId); } - ScriptSleep(3000); + } [DebuggerNonUserCode] -- cgit v1.1 From 819806261026cccd68dee649f11938ae5bf10029 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Sun, 14 Mar 2010 16:22:13 -0400 Subject: RotLookAt repaired; debug msg cleanup. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 4 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 35 +- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 552 ++++++--------------- .../Shared/Api/Implementation/LSL_Api.cs | 4 +- 4 files changed, 151 insertions(+), 444 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f35a7c5..5443c28 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1955,7 +1955,7 @@ namespace OpenSim.Region.Framework.Scenes else { if (rootpart.PhysActor != null) - { + { // APID must be implemented in your physics system for this to function. rootpart.PhysActor.APIDTarget = new Quaternion(target.X, target.Y, target.Z, target.W); rootpart.PhysActor.APIDStrength = strength; rootpart.PhysActor.APIDDamping = damping; @@ -1971,7 +1971,7 @@ namespace OpenSim.Region.Framework.Scenes if (rootpart != null) { if (rootpart.PhysActor != null) - { + { // APID must be implemented in your physics system for this to function. rootpart.PhysActor.APIDActive = false; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 31ea502..548a64f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2705,38 +2705,7 @@ namespace OpenSim.Region.Framework.Scenes public void RotLookAt(Quaternion target, float strength, float damping) { - rotLookAt(target, strength, damping); - } - - public void rotLookAt(Quaternion target, float strength, float damping) - { - if (IsAttachment) - { - /* - ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); - if (avatar != null) - { - Rotate the Av? - } */ - } - else - { - APIDDamp = damping; - APIDStrength = strength; - APIDTarget = target; - } - } - - public void startLookAt(Quaternion rot, float damp, float strength) - { - APIDDamp = damp; - APIDStrength = strength; - APIDTarget = rot; - } - - public void stopLookAt() - { - APIDTarget = Quaternion.Identity; + m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup. } /// @@ -3460,7 +3429,7 @@ namespace OpenSim.Region.Framework.Scenes public void StopLookAt() { - m_parentGroup.stopLookAt(); + m_parentGroup.stopLookAt(); // This calls method in SceneObjectGroup. m_parentGroup.ScheduleGroupForTerseUpdate(); } diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 367927d..5e6696e 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -652,7 +652,7 @@ namespace OpenSim.Region.Physics.OdePlugin return true; } - public override Vector3 Acceleration + public override Vector3 Acceleration // client updates read data via here { get { return _acceleration; } } @@ -696,14 +696,6 @@ namespace OpenSim.Region.Physics.OdePlugin { get { -/* Vector3 pv = Vector3.Zero; - if (_zeroFlag) - return pv; - m_lastUpdateSent = false; - - if (m_rotationalVelocity.ApproxEquals(pv, 0.2f)) - return pv; -*/ return m_rotationalVelocity; } set @@ -1398,9 +1390,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_taintCollidesWater != m_collidesWater) changefloatonwater(timestep); - // ##* if (!m_angularEnable.ApproxEquals(m_taintAngularLock,0f)) -Console.WriteLine("ALchange req {0} is {1}", m_taintAngularLock, m_angularEnable); changeAngularLock(timestep); } @@ -1411,17 +1401,11 @@ Console.WriteLine("ALchange req {0} is {1}", m_taintAngularLock, m_angularEna } - private void changeAngularLock(float timestep) // ##* + private void changeAngularLock(float timestep) { - // do we have a Physical object? -// if (Body != IntPtr.Zero) -// { - //Check that we have a Parent - //If we have a parent then we're not authorative here - if (_parent == null) - { -Console.WriteLine("Alock changed to {0}", m_taintAngularLock); - m_angularEnable = m_taintAngularLock; + if (_parent == null) + { + m_angularEnable = m_taintAngularLock; } } @@ -1435,7 +1419,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); { OdePrim obj = (OdePrim)m_taintparent; //obj.disableBody(); -//Console.WriteLine("changelink calls ParentPrim"); obj.ParentPrim(this); /* @@ -1453,8 +1436,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); // destroy link else if (_parent != null && m_taintparent == null) { -//Console.WriteLine(" changelink B"); - if (_parent is OdePrim) { OdePrim obj = (OdePrim)_parent; @@ -1480,7 +1461,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); // prim is the child public void ParentPrim(OdePrim prim) { -//Console.WriteLine("ParentPrim " + m_primName); if (this.m_localID != prim.m_localID) { if (Body == IntPtr.Zero) @@ -1494,7 +1474,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); { if (!childrenPrim.Contains(prim)) { -//Console.WriteLine("childrenPrim.Add " + prim); childrenPrim.Add(prim); foreach (OdePrim prm in childrenPrim) @@ -1640,7 +1619,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); { foreach (OdePrim prm in childrenPrim) { -//Console.WriteLine("ChildSetGeom calls ParentPrim"); ParentPrim(prm); } } @@ -1667,7 +1645,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); lock (childrenPrim) { - //Console.WriteLine("childrenPrim.Remove " + odePrim); childrenPrim.Remove(odePrim); } @@ -1680,7 +1657,6 @@ Console.WriteLine("Alock changed to {0}", m_taintAngularLock); { foreach (OdePrim prm in childrenPrim) { -//Console.WriteLine("ChildDelink calls ParentPrim"); ParentPrim(prm); } } @@ -2417,219 +2393,9 @@ Console.WriteLine(" JointCreateFixed"); public void UpdatePositionAndVelocity() { - return; // moved to the MOVE() method + return; // moved to the Move() method } - // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! -/* if (_parent == null) - { - Vector3 pv = Vector3.Zero; - bool lastZeroFlag = _zeroFlag; - if (Body != (IntPtr)0) // FIXME -> or if it is a joint - { - d.Vector3 vec = d.BodyGetPosition(Body); - d.Quaternion ori = d.BodyGetQuaternion(Body); - d.Vector3 vel = d.BodyGetLinearVel(Body); - d.Vector3 rotvel = d.BodyGetAngularVel(Body); - d.Vector3 torque = d.BodyGetTorque(Body); - _torque = new Vector3(torque.X, torque.Y, torque.Z); - Vector3 l_position = Vector3.Zero; - Quaternion l_orientation = Quaternion.Identity; - - // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) - //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - - m_lastposition = _position; - m_lastorientation = _orientation; - - l_position.X = vec.X; - l_position.Y = vec.Y; - l_position.Z = vec.Z; - l_orientation.X = ori.X; - l_orientation.Y = ori.Y; - l_orientation.Z = ori.Z; - l_orientation.W = ori.W; - -// if(l_position.Y != m_lastposition.Y){ -// Console.WriteLine("UP&V {0} {1}", m_primName, l_position); -// } - - if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f) - { - //base.RaiseOutOfBounds(l_position); - - if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) - { - _position = l_position; - //_parent_scene.remActivePrim(this); - if (_parent == null) - base.RequestPhysicsterseUpdate(); - return; - } - else - { - if (_parent == null) - base.RaiseOutOfBounds(l_position); - return; - } - } - - if (l_position.Z < 0) - { - // This is so prim that get lost underground don't fall forever and suck up - // - // Sim resources and memory. - // Disables the prim's movement physics.... - // It's a hack and will generate a console message if it fails. - - //IsPhysical = false; - if (_parent == null) - base.RaiseOutOfBounds(_position); - - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - - if (_parent == null) - base.RequestPhysicsterseUpdate(); - - m_throttleUpdates = false; - throttleCounter = 0; - _zeroFlag = true; - //outofBounds = true; - } - - //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); -//Console.WriteLine("Adiff " + m_primName + " = " + Adiff); - if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) - && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) - && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) -// && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01)) - && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large - { - _zeroFlag = true; -//Console.WriteLine("ZFT 2"); - m_throttleUpdates = false; - } - else - { - //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); - _zeroFlag = false; - m_lastUpdateSent = false; - //m_throttleUpdates = false; - } - - if (_zeroFlag) - { - _velocity.X = 0.0f; - _velocity.Y = 0.0f; - _velocity.Z = 0.0f; - - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - - //_orientation.w = 0f; - //_orientation.X = 0f; - //_orientation.Y = 0f; - //_orientation.Z = 0f; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - if (!m_lastUpdateSent) - { - m_throttleUpdates = false; - throttleCounter = 0; - m_rotationalVelocity = pv; - - if (_parent == null) - { - base.RequestPhysicsterseUpdate(); - } - - m_lastUpdateSent = true; - } - } - else - { - if (lastZeroFlag != _zeroFlag) - { - if (_parent == null) - { - base.RequestPhysicsterseUpdate(); - } - } - - m_lastVelocity = _velocity; - - _position = l_position; - - _velocity.X = vel.X; - _velocity.Y = vel.Y; - _velocity.Z = vel.Z; - - _acceleration = ((_velocity - m_lastVelocity) / 0.1f); - _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, _velocity.Y - m_lastVelocity.Y / 0.1f, _velocity.Z - m_lastVelocity.Z / 0.1f); - //m_log.Info("[PHYSICS]: V1: " + _velocity + " V2: " + m_lastVelocity + " Acceleration: " + _acceleration.ToString()); - -// if (_velocity.ApproxEquals(pv, 0.5f)) ???? Disregard rotational vel if lin vel is < 0.5 ????? -// { -// m_rotationalVelocity = pv;/ - -// } -// else -// { - m_rotationalVelocity = new Vector3(rotvel.X, rotvel.Y, rotvel.Z); -// } - - //m_log.Debug("ODE: " + m_rotationalVelocity.ToString()); - _orientation.X = ori.X; - _orientation.Y = ori.Y; - _orientation.Z = ori.Z; - _orientation.W = ori.W; - m_lastUpdateSent = false; - if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) - { - if (_parent == null) - { - base.RequestPhysicsterseUpdate(); - } - } - else - { - throttleCounter++; - } - } - m_lastposition = l_position; - } - else - { - // Not a body.. so Make sure the client isn't interpolating - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; - - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - _zeroFlag = true; - } - } - } -*/ +/* No one uses this? public Matrix4 FromDMass(d.Mass pMass) { Matrix4 obj; @@ -2651,7 +2417,7 @@ Console.WriteLine(" JointCreateFixed"); obj.M44 = 1; return obj; } - +*/ public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) { obj.I.M00 = pMat[0, 0]; @@ -2878,11 +2644,6 @@ Console.WriteLine(" JointCreateFixed"); m_material = pMaterial; } - - - - - internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue) { switch (pParam) @@ -3242,193 +3003,173 @@ Console.WriteLine(" JointCreateFixed"); { // Old public void UpdatePositionAndVelocity(), more accuratley calculated here - // Vector3 pv = Vector3.Zero; // what was this for? - bool lastZeroFlag = _zeroFlag; // was it stopped - // if (Body != (IntPtr)0) // FIXME -> or if it is a joint - // { - d.Vector3 vec = d.BodyGetPosition(Body); - d.Quaternion ori = d.BodyGetQuaternion(Body); - d.Vector3 vel = d.BodyGetLinearVel(Body); + bool lastZeroFlag = _zeroFlag; // was it stopped + d.Vector3 vec = d.BodyGetPosition(Body); + d.Quaternion ori = d.BodyGetQuaternion(Body); + d.Vector3 vel = d.BodyGetLinearVel(Body); // d.Vector3 rotvel = d.BodyGetAngularVel(Body); - d.Vector3 torque = d.BodyGetTorque(Body); - _torque = new Vector3(torque.X, torque.Y, torque.Z); - Vector3 l_position = Vector3.Zero; - Quaternion l_orientation = Quaternion.Identity; - - // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) - //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); } - - m_lastposition = _position; - m_lastorientation = _orientation; + d.Vector3 torque = d.BodyGetTorque(Body); + _torque = new Vector3(torque.X, torque.Y, torque.Z); + Vector3 l_position = Vector3.Zero; + Quaternion l_orientation = Quaternion.Identity; + + m_lastposition = _position; + m_lastorientation = _orientation; - l_position.X = vec.X; - l_position.Y = vec.Y; - l_position.Z = vec.Z; - l_orientation.X = ori.X; - l_orientation.Y = ori.Y; - l_orientation.Z = ori.Z; - l_orientation.W = ori.W; + l_position.X = vec.X; + l_position.Y = vec.Y; + l_position.Z = vec.Z; + l_orientation.X = ori.X; + l_orientation.Y = ori.Y; + l_orientation.Z = ori.Z; + l_orientation.W = ori.W; //Console.WriteLine("Move {0} at {1}", m_primName, l_position); + // Check if outside region horizontally + if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || + l_position.X < 0f || + l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || + l_position.Y < 0f) + { + if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) + { // keep trying to cross? + _position = l_position; + //_parent_scene.remActivePrim(this); + if (_parent == null) base.RequestPhysicsterseUpdate(); + return; // Dont process any other motion? + } + else + { // Too many tries + if (_parent == null) base.RaiseOutOfBounds(l_position); + return; // Dont process any other motion? + } + } // end outside region horizontally - if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || - l_position.X < 0f || - l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || - l_position.Y < 0f) - { - //base.RaiseOutOfBounds(l_position); + if (l_position.Z < 0) + { + // This is so prim that get lost underground don't fall forever and suck up + // + // Sim resources and memory. + // Disables the prim's movement physics.... + // It's a hack and will generate a console message if it fails. - if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) - { - _position = l_position; - //_parent_scene.remActivePrim(this); - if (_parent == null) - base.RequestPhysicsterseUpdate(); - return; - } - else - { - if (_parent == null) - base.RaiseOutOfBounds(l_position); - return; - } - } + //IsPhysical = false; + if (_parent == null) base.RaiseOutOfBounds(_position); + + _acceleration.X = 0; // This stuff may stop client display but it has no + _acceleration.Y = 0; // effect on the object in phys engine! + _acceleration.Z = 0; - if (l_position.Z < 0) - { - // This is so prim that get lost underground don't fall forever and suck up - // - // Sim resources and memory. - // Disables the prim's movement physics.... - // It's a hack and will generate a console message if it fails. + _velocity.X = 0; + _velocity.Y = 0; + _velocity.Z = 0; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; - //IsPhysical = false; - if (_parent == null) - base.RaiseOutOfBounds(_position); + if (_parent == null) base.RequestPhysicsterseUpdate(); - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; + m_throttleUpdates = false; + throttleCounter = 0; + _zeroFlag = true; + //outofBounds = true; + } // end neg Z check - _velocity.X = 0; - _velocity.Y = 0; - _velocity.Z = 0; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; + // Is it moving? + if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) + && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) + && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) + && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large + { + _zeroFlag = true; +//Console.WriteLine("ZFT 2"); + m_throttleUpdates = false; + } + else + { + //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); + _zeroFlag = false; + m_lastUpdateSent = false; + //m_throttleUpdates = false; + } - if (_parent == null) - base.RequestPhysicsterseUpdate(); + if (_zeroFlag) + { // Its stopped + _velocity.X = 0.0f; + _velocity.Y = 0.0f; + _velocity.Z = 0.0f; + _acceleration.X = 0; + _acceleration.Y = 0; + _acceleration.Z = 0; + //_orientation.w = 0f; + //_orientation.X = 0f; + //_orientation.Y = 0f; + //_orientation.Z = 0f; + m_rotationalVelocity.X = 0; + m_rotationalVelocity.Y = 0; + m_rotationalVelocity.Z = 0; + if (!m_lastUpdateSent) + { m_throttleUpdates = false; throttleCounter = 0; - _zeroFlag = true; - //outofBounds = true; - } + if (_parent == null) + { + base.RequestPhysicsterseUpdate(); + } - //float Adiff = 1.0f - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)); -//Console.WriteLine("Adiff " + m_primName + " = " + Adiff); - if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) - && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) - && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) -// && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.01)) - && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large - { - _zeroFlag = true; -//Console.WriteLine("ZFT 2"); - m_throttleUpdates = false; + m_lastUpdateSent = true; } - else + } + else + { // Its moving + if (lastZeroFlag != _zeroFlag) { - //m_log.Debug(Math.Abs(m_lastposition.X - l_position.X).ToString()); - _zeroFlag = false; - m_lastUpdateSent = false; - //m_throttleUpdates = false; - } - - if (_zeroFlag) - { // Its stopped - _velocity.X = 0.0f; - _velocity.Y = 0.0f; - _velocity.Z = 0.0f; - - _acceleration.X = 0; - _acceleration.Y = 0; - _acceleration.Z = 0; - - //_orientation.w = 0f; - //_orientation.X = 0f; - //_orientation.Y = 0f; - //_orientation.Z = 0f; - m_rotationalVelocity.X = 0; - m_rotationalVelocity.Y = 0; - m_rotationalVelocity.Z = 0; - if (!m_lastUpdateSent) + if (_parent == null) { - m_throttleUpdates = false; - throttleCounter = 0; - // m_rotationalVelocity = pv; What was this for? - - if (_parent == null) - { - base.RequestPhysicsterseUpdate(); - } - - m_lastUpdateSent = true; + base.RequestPhysicsterseUpdate(); } } - else - { // Its moving - if (lastZeroFlag != _zeroFlag) - { - if (_parent == null) - { - base.RequestPhysicsterseUpdate(); - } - } - m_lastVelocity = _velocity; + m_lastVelocity = _velocity; - _position = l_position; + _position = l_position; - _velocity.X = vel.X; - _velocity.Y = vel.Y; - _velocity.Z = vel.Z; + _velocity.X = vel.X; + _velocity.Y = vel.Y; + _velocity.Z = vel.Z; // Why 2 calcs??? -// _acceleration = ((_velocity - m_lastVelocity) / 0.1f); -// _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, -// _velocity.Y - m_lastVelocity.Y / 0.1f, +// _acceleration = ((_velocity - m_lastVelocity) / 0.1f); +// _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, +// _velocity.Y - m_lastVelocity.Y / 0.1f, // _velocity.Z - m_lastVelocity.Z / 0.1f); - _acceleration = ((_velocity - m_lastVelocity) / timestep); + _acceleration = ((_velocity - m_lastVelocity) / timestep); - _orientation.X = ori.X; - _orientation.Y = ori.Y; - _orientation.Z = ori.Z; - _orientation.W = ori.W; - m_lastUpdateSent = false; - if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) - { - if (_parent == null) - { - base.RequestPhysicsterseUpdate(); - } - } - else + _orientation.X = ori.X; + _orientation.Y = ori.Y; + _orientation.Z = ori.Z; + _orientation.W = ori.W; + m_lastUpdateSent = false; + if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) + { + if (_parent == null) { - throttleCounter++; + base.RequestPhysicsterseUpdate(); } } - m_lastposition = l_position; - + else + { + throttleCounter++; + } + } + m_lastposition = l_position; + /// End of old UpdatePositionAndVelocity insert //if (!Acceleration.ApproxEquals(Vector3.Zero, 0.01f)) Console.WriteLine("Move " + m_primName + " Accel=" + Acceleration); -//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_type + - // " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); +// if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_type + +// " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); if (m_type != Vehicle.TYPE_NONE) { // get body attitude @@ -3701,7 +3442,6 @@ Console.WriteLine(" JointCreateFixed"); //if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); m_lastAngularVelocity = angObjectVel; -if(frcount == 0) Console.WriteLine("angularEnable {0}", m_angularEnable); if (!m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) { @@ -3720,14 +3460,11 @@ if(frcount == 0) Console.WriteLine("angularEnable {0}", m_angularEnable); d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); //if(frcount == 0) Console.WriteLine("V4 = {0}", m_lastAngularVelocity); - } // end VEHICLES #### + } // end VEHICLES else { if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 // NON-'VEHICLES' are dealt with here - // m_angularEnable = <1,1,1> means no lock. a 0 on axis means locked. - -// NB this may be wrong - may lock global axis! Should be LOCAL axis! /// Dynamics Angular Lock ======================================================================== if (d.BodyIsEnabled(Body) && !m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) { @@ -3802,7 +3539,7 @@ if(frcount == 0) Console.WriteLine("angularEnable {0}", m_angularEnable); d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); d.BodySetLinearVel(Body, 0, 0, 0); d.BodyAddForce(Body, 0, 0, fz); - return; + // return; } else { @@ -3911,7 +3648,6 @@ if(frcount == 0) Console.WriteLine("angularEnable {0}", m_angularEnable); // float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly // Also in SL the mass of the object has no effect on time to get there. // Factors: -//if(frcount == 0) Console.WriteLine("APID "); // get present body rotation float limit = 1.0f; float scaler = 50f; // adjusts damping time diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 180fba9..83f7db0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2899,10 +2899,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // the angles of rotation in radians into rotation value LSL_Types.Quaternion rot = llEuler2Rot(angle); + /* Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); m_host.startLookAt(rotation, (float)damping, (float)strength); + This would only work if your physics system contains an APID controller */ // Orient the object to the angle calculated - //llSetRot(rot); + llSetRot(rot); } public void llRotLookAt(LSL_Rotation target, double strength, double damping) -- cgit v1.1 From a1cd3b5b88cc2cc3fcd552085dc9ab46f9d9b10f Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 15 Mar 2010 17:54:39 +0000 Subject: Change GodLevel to UserLevel so gods can teleport freely without having to enter god mode first --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 24179a9..2661dc3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -879,7 +879,7 @@ namespace OpenSim.Region.Framework.Scenes if (land != null) { //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) { pos = land.LandData.UserLocation; } -- cgit v1.1 From 37815f34029d7fe4404b6733764892a9a2fe9086 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Tue, 16 Mar 2010 18:13:00 +0100 Subject: Debugger tags for VS2010 --- .../Shared/Api/Implementation/LSL_Api.cs | 387 +++++++++++---------- .../ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 2 + 2 files changed, 196 insertions(+), 193 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8e5c203..485a3b5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -221,8 +221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public List GetLinkParts(int linkType) { - List ret = new List(); - if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) + List ret = new List(); + if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) return ret; ret.Add(m_host); @@ -1115,6 +1115,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return detectedParams.TouchUV; } + [DebuggerNonUserCode] public virtual void llDie() { m_host.AddScriptLPS(1); @@ -1190,8 +1191,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void llSetStatus(int status, int value) - { - if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) + { + if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) return; m_host.AddScriptLPS(1); @@ -1367,7 +1368,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetScale(SceneObjectPart part, LSL_Vector scale) - { + { // TODO: this needs to trigger a persistance save as well if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; @@ -1426,8 +1427,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetColor(SceneObjectPart part, LSL_Vector color, int face) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1471,8 +1472,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetTexGen(SceneObjectPart part, int face,int style) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1504,8 +1505,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetGlow(SceneObjectPart part, int face, float glow) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1532,8 +1533,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Shininess sval = new Shininess(); @@ -1584,8 +1585,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void SetFullBright(SceneObjectPart part, int face, bool bright) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1654,8 +1655,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetAlpha(SceneObjectPart part, double alpha, int face) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1702,8 +1703,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, float wind, float tension, LSL_Vector Force) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; if (flexi) @@ -1737,8 +1738,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; if (light) @@ -1823,8 +1824,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetTexture(SceneObjectPart part, string texture, int face) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; UUID textureID=new UUID(); @@ -1871,8 +1872,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1910,8 +1911,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -1949,8 +1950,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void RotateTexture(SceneObjectPart part, double rotation, int face) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; Primitive.TextureEntry tex = part.Shape.Textures; @@ -2022,8 +2023,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) @@ -2119,8 +2120,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetRot(SceneObjectPart part, Quaternion rot) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; part.UpdateRotation(rot); @@ -4016,7 +4017,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bucket); if (m_TransferModule != null) - m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); + m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); //This delay should only occur when giving inventory to avatars. ScriptSleep(3000); @@ -6662,9 +6663,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) - { - ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return shapeBlock; if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && @@ -6735,8 +6736,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; ObjectShapePacket.ObjectDataBlock shapeBlock; @@ -6787,8 +6788,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; ObjectShapePacket.ObjectDataBlock shapeBlock; @@ -6832,8 +6833,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; ObjectShapePacket.ObjectDataBlock shapeBlock; @@ -6956,8 +6957,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); @@ -6993,13 +6994,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } public void llSetPrimitiveParams(LSL_List rules) - { + { m_host.AddScriptLPS(1); SetPrimParams(m_host, rules); } public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) - { + { m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); @@ -7014,8 +7015,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } protected void SetPrimParams(SceneObjectPart part, LSL_List rules) - { - if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) return; int idx = 0; @@ -7848,96 +7849,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case (int)ScriptBaseClass.PRIM_BUMP_SHINY: - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - int shiny; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - Shininess shinyness = tex.GetFace((uint)face).Shiny; - if (shinyness == Shininess.High) - { - shiny = ScriptBaseClass.PRIM_SHINY_HIGH; - } - else if (shinyness == Shininess.Medium) - { - shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; - } - else if (shinyness == Shininess.Low) - { - shiny = ScriptBaseClass.PRIM_SHINY_LOW; - } - else - { - shiny = ScriptBaseClass.PRIM_SHINY_NONE; - } - res.Add(new LSL_Integer(shiny)); - res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); - } - } - else - { - Shininess shinyness = tex.GetFace((uint)face).Shiny; - if (shinyness == Shininess.High) - { - shiny = ScriptBaseClass.PRIM_SHINY_HIGH; - } - else if (shinyness == Shininess.Medium) - { - shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; - } - else if (shinyness == Shininess.Low) - { - shiny = ScriptBaseClass.PRIM_SHINY_LOW; - } - else - { - shiny = ScriptBaseClass.PRIM_SHINY_NONE; - } - res.Add(new LSL_Integer(shiny)); - res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); - } + case (int)ScriptBaseClass.PRIM_BUMP_SHINY: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + int shiny; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + Shininess shinyness = tex.GetFace((uint)face).Shiny; + if (shinyness == Shininess.High) + { + shiny = ScriptBaseClass.PRIM_SHINY_HIGH; + } + else if (shinyness == Shininess.Medium) + { + shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; + } + else if (shinyness == Shininess.Low) + { + shiny = ScriptBaseClass.PRIM_SHINY_LOW; + } + else + { + shiny = ScriptBaseClass.PRIM_SHINY_NONE; + } + res.Add(new LSL_Integer(shiny)); + res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); + } + } + else + { + Shininess shinyness = tex.GetFace((uint)face).Shiny; + if (shinyness == Shininess.High) + { + shiny = ScriptBaseClass.PRIM_SHINY_HIGH; + } + else if (shinyness == Shininess.Medium) + { + shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; + } + else if (shinyness == Shininess.Low) + { + shiny = ScriptBaseClass.PRIM_SHINY_LOW; + } + else + { + shiny = ScriptBaseClass.PRIM_SHINY_NONE; + } + res.Add(new LSL_Integer(shiny)); + res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); + } break; - case (int)ScriptBaseClass.PRIM_FULLBRIGHT: - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - int fullbright; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - if (tex.GetFace((uint)face).Fullbright == true) - { - fullbright = ScriptBaseClass.TRUE; - } - else - { - fullbright = ScriptBaseClass.FALSE; - } - res.Add(new LSL_Integer(fullbright)); - } - } - else - { - if (tex.GetFace((uint)face).Fullbright == true) - { - fullbright = ScriptBaseClass.TRUE; - } - else - { - fullbright = ScriptBaseClass.FALSE; - } - res.Add(new LSL_Integer(fullbright)); - } + case (int)ScriptBaseClass.PRIM_FULLBRIGHT: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + int fullbright; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + if (tex.GetFace((uint)face).Fullbright == true) + { + fullbright = ScriptBaseClass.TRUE; + } + else + { + fullbright = ScriptBaseClass.FALSE; + } + res.Add(new LSL_Integer(fullbright)); + } + } + else + { + if (tex.GetFace((uint)face).Fullbright == true) + { + fullbright = ScriptBaseClass.TRUE; + } + else + { + fullbright = ScriptBaseClass.FALSE; + } + res.Add(new LSL_Integer(fullbright)); + } break; case (int)ScriptBaseClass.PRIM_FLEXIBLE: @@ -7958,37 +7959,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api break; case (int)ScriptBaseClass.PRIM_TEXGEN: - // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); - } - else - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); - } - } - } - else - { - if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); - } - else - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); - } - } + // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } + } + } + else + { + if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } + } break; case (int)ScriptBaseClass.PRIM_POINT_LIGHT: @@ -8006,26 +8007,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api res.Add(new LSL_Float(shape.LightFalloff)); // falloff break; - case (int)ScriptBaseClass.PRIM_GLOW: - if (remain < 1) + case (int)ScriptBaseClass.PRIM_GLOW: + if (remain < 1) return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - float primglow; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - primglow = tex.GetFace((uint)face).Glow; - res.Add(new LSL_Float(primglow)); - } - } - else - { - primglow = tex.GetFace((uint)face).Glow; - res.Add(new LSL_Float(primglow)); - } + face = (int)rules.GetLSLIntegerItem(idx++); + + tex = part.Shape.Textures; + float primglow; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < GetNumberOfSides(part); face++) + { + primglow = tex.GetFace((uint)face).Glow; + res.Add(new LSL_Float(primglow)); + } + } + else + { + primglow = tex.GetFace((uint)face).Glow; + res.Add(new LSL_Float(primglow)); + } break; case (int)ScriptBaseClass.PRIM_TEXT: Color4 textColor = part.GetTextColor(); @@ -9187,7 +9188,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); if (quick_pay_buttons.Data.Length < 4) - { + { int x; for (x=quick_pay_buttons.Data.Length; x<= 4; x++) { @@ -9195,12 +9196,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } int[] nPrice = new int[5]; - nPrice[0]=price; - nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0]; - nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1]; - nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2]; + nPrice[0]=price; + nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0]; + nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1]; + nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2]; nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3]; - m_host.ParentGroup.RootPart.PayPrice = nPrice; + m_host.ParentGroup.RootPart.PayPrice = nPrice; m_host.ParentGroup.HasGroupChanged = true; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 3339995..e86d08c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -26,6 +26,7 @@ */ using System; +using System.Diagnostics; //for [DebuggerNonUserCode] using System.Runtime.Remoting.Lifetime; using System.Threading; using System.Reflection; @@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); } + [DebuggerNonUserCode] public void llDie() { m_LSL_Functions.llDie(); -- cgit v1.1 From e442c2a3f9dc1823c00ddc1c81802fdabd7883dc Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 17 Mar 2010 17:42:33 +0100 Subject: Prevent llTeleportAgentHome from affecting gods --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 485a3b5..10ebf67 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4193,6 +4193,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(agentId); if (presence != null) { + // agent must not be a god + if (presence.GodLevel >= 200) return; + // agent must be over the owners land if (m_host.OwnerID == World.LandChannel.GetLandObject( presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) -- cgit v1.1 From 6df969894c1943dceeefd3765951daaf0a2eb94c Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Wed, 17 Mar 2010 13:30:48 -0400 Subject: Fix AbsolutePosition for autopilot/sit. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 24179a9..608e84c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -463,7 +463,8 @@ namespace OpenSim.Region.Framework.Scenes get { PhysicsActor actor = m_physicsActor; - if (actor != null) +// if (actor != null) + if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! m_pos = actor.Position; return m_parentPosition + m_pos; @@ -484,7 +485,8 @@ namespace OpenSim.Region.Framework.Scenes } } - m_pos = value; + if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! + m_pos = value; m_parentPosition = Vector3.Zero; } } @@ -1267,6 +1269,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); m_pos = m_LastFinitePos; + if (!m_pos.IsFinite()) { m_pos.X = 127f; @@ -1904,6 +1907,7 @@ namespace OpenSim.Region.Framework.Scenes { m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center autopilotTarget = part.AbsolutePosition; +//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); } else return; // occupied small } // end large/small @@ -2280,7 +2284,8 @@ namespace OpenSim.Region.Framework.Scenes m_pos += SIT_TARGET_ADJUSTMENT; m_bodyRot = sitTargetOrient; m_parentPosition = part.AbsolutePosition; - part.IsOccupied = true; + part.IsOccupied = true; +Console.WriteLine("Scripted Sit ofset {0}", m_pos); } else { @@ -3348,6 +3353,7 @@ namespace OpenSim.Region.Framework.Scenes m_callbackURI = cAgent.CallbackURI; m_pos = cAgent.Position; + m_velocity = cAgent.Velocity; m_CameraCenter = cAgent.Center; //m_avHeight = cAgent.Size.Z; -- cgit v1.1 From f35eb8819c6a872e7c4727940ffc560f7d5d68bd Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 18 Mar 2010 18:57:29 +0000 Subject: Unify a previous refactor of object return with the older solution. We really don't need two methods doing the same thing, but differently. --- .../Region/CoreModules/World/Land/LandObject.cs | 2 +- .../World/Permissions/PermissionsModule.cs | 71 ++-------------------- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 7 ++- .../Region/Framework/Scenes/Scene.Permissions.cs | 29 ++------- .../RegionCombinerModule/RegionCombinerModule.cs | 3 +- .../RegionCombinerPermissionModule.cs | 11 +--- 6 files changed, 21 insertions(+), 102 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 1c65965..b8c35f7 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -915,7 +915,7 @@ namespace OpenSim.Region.CoreModules.World.Land foreach (List ol in returns.Values) { - if (m_scene.Permissions.CanUseObjectReturn(this, type, remote_client, ol)) + if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 1533462..7159dc6 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -200,7 +200,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; //FULLY IMPLEMENTED m_scene.Permissions.OnMoveObject += CanMoveObject; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnObjectEntry += CanObjectEntry; - m_scene.Permissions.OnReturnObject += CanReturnObject; //NOT YET IMPLEMENTED + m_scene.Permissions.OnReturnObjects += CanReturnObjects; //NOT YET IMPLEMENTED m_scene.Permissions.OnRezObject += CanRezObject; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; m_scene.Permissions.OnRunScript += CanRunScript; //NOT YET IMPLEMENTED @@ -230,7 +230,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED - m_scene.Permissions.OnUseObjectReturn += CanUseObjectReturn; //NOT YET IMPLEMENTED m_scene.AddCommand(this, "bypass permissions", "bypass permissions ", @@ -1258,12 +1257,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } - private bool CanReturnObject(UUID objectID, UUID returnerID, Scene scene) + private bool CanReturnObjects(ILandObject land, UUID user, List objects, Scene scene) { + if (objects.Count == 0) + return false; + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(returnerID, objectID, false); + return GenericObjectPermission(user, objects[0].UUID, false); } private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) @@ -1730,67 +1732,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericObjectPermission(agentID, prim, false); } - private bool CanUseObjectReturn(ILandObject parcel, uint type, IClientAPI client, List retlist, Scene scene) - { - DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); - if (m_bypassPermissions) return m_bypassPermissionsValue; - - long powers = 0; - if (parcel.LandData.GroupID != UUID.Zero) - client.GetGroupPowers(parcel.LandData.GroupID); - - switch (type) - { - case (uint)ObjectReturnType.Owner: - // Don't let group members return owner's objects, ever - // - if (parcel.LandData.IsGroupOwned) - { - if ((powers & (long)GroupPowers.ReturnGroupOwned) != 0) - return true; - } - else - { - if (parcel.LandData.OwnerID != client.AgentId) - return false; - } - return GenericParcelOwnerPermission(client.AgentId, parcel, (ulong)GroupPowers.ReturnGroupOwned); - case (uint)ObjectReturnType.Group: - if (parcel.LandData.OwnerID != client.AgentId) - { - // If permissionis granted through a group... - // - if ((powers & (long)GroupPowers.ReturnGroupSet) != 0) - { - foreach (SceneObjectGroup g in new List(retlist)) - { - // check for and remove group owned objects unless - // the user also has permissions to return those - // - if (g.OwnerID == g.GroupID && - ((powers & (long)GroupPowers.ReturnGroupOwned) == 0)) - { - retlist.Remove(g); - } - } - // And allow the operation - // - return true; - } - } - return GenericParcelOwnerPermission(client.AgentId, parcel, (ulong)GroupPowers.ReturnGroupSet); - case (uint)ObjectReturnType.Other: - if ((powers & (long)GroupPowers.ReturnNonGroup) != 0) - return true; - return GenericParcelOwnerPermission(client.AgentId, parcel, (ulong)GroupPowers.ReturnNonGroup); - case (uint)ObjectReturnType.List: - break; - } - - return GenericParcelOwnerPermission(client.AgentId, parcel, 0); - // Is it correct to be less restrictive for lists of objects to be returned? - } - private bool CanCompileScript(UUID ownerUUID, int scriptType, Scene scene) { //m_log.DebugFormat("check if {0} is allowed to compile {1}", ownerUUID, scriptType); switch (scriptType) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b2b061e..ffbf745 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1581,9 +1581,10 @@ namespace OpenSim.Region.Framework.Scenes if (remoteClient != null) { permissionToTake = - Permissions.CanReturnObject( - grp.UUID, - remoteClient.AgentId); + Permissions.CanReturnObjects( + null, + remoteClient.AgentId, + new List() {grp}); permissionToDelete = permissionToTake; if (permissionToDelete) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index d1d6b6a..7dab04f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene); public delegate bool MoveObjectHandler(UUID objectID, UUID moverID, Scene scene); public delegate bool ObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene); - public delegate bool ReturnObjectHandler(UUID objectID, UUID returnerID, Scene scene); + public delegate bool ReturnObjectsHandler(ILandObject land, UUID user, List objects, Scene scene); public delegate bool InstantMessageHandler(UUID user, UUID target, Scene startScene); public delegate bool InventoryTransferHandler(UUID user, UUID target, Scene startScene); public delegate bool ViewScriptHandler(UUID script, UUID objectID, UUID user, Scene scene); @@ -81,7 +81,6 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID); public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID); public delegate bool TeleportHandler(UUID userID, Scene scene); - public delegate bool UseObjectReturnHandler(ILandObject landData, uint type, IClientAPI client, List retlist, Scene scene); #endregion public class ScenePermissions @@ -107,7 +106,7 @@ namespace OpenSim.Region.Framework.Scenes public event EditObjectInventoryHandler OnEditObjectInventory; public event MoveObjectHandler OnMoveObject; public event ObjectEntryHandler OnObjectEntry; - public event ReturnObjectHandler OnReturnObject; + public event ReturnObjectsHandler OnReturnObjects; public event InstantMessageHandler OnInstantMessage; public event InventoryTransferHandler OnInventoryTransfer; public event ViewScriptHandler OnViewScript; @@ -140,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes public event CopyUserInventoryHandler OnCopyUserInventory; public event DeleteUserInventoryHandler OnDeleteUserInventory; public event TeleportHandler OnTeleport; - public event UseObjectReturnHandler OnUseObjectReturn; #endregion #region Object Permission Checks @@ -377,15 +375,15 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region RETURN OBJECT - public bool CanReturnObject(UUID objectID, UUID returnerID) + public bool CanReturnObjects(ILandObject land, UUID user, List objects) { - ReturnObjectHandler handler = OnReturnObject; + ReturnObjectsHandler handler = OnReturnObjects; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (ReturnObjectHandler h in list) + foreach (ReturnObjectsHandler h in list) { - if (h(objectID, returnerID, m_scene) == false) + if (h(land, user, objects, m_scene) == false) return false; } } @@ -949,20 +947,5 @@ namespace OpenSim.Region.Framework.Scenes } return true; } - - public bool CanUseObjectReturn(ILandObject landData, uint type , IClientAPI client, List retlist) - { - UseObjectReturnHandler handler = OnUseObjectReturn; - if (handler != null) - { - Delegate[] list = handler.GetInvocationList(); - foreach (UseObjectReturnHandler h in list) - { - if (h(landData, type, client, retlist, m_scene) == false) - return false; - } - } - return true; - } } } diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 92f060b..0b8771c 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -922,7 +922,7 @@ namespace OpenSim.Region.RegionCombinerModule VirtualRegion.Permissions.OnIssueEstateCommand += BigRegion.PermissionModule.CanIssueEstateCommand; //FULLY IMPLEMENTED VirtualRegion.Permissions.OnMoveObject += BigRegion.PermissionModule.CanMoveObject; //MAYBE FULLY IMPLEMENTED VirtualRegion.Permissions.OnObjectEntry += BigRegion.PermissionModule.CanObjectEntry; - VirtualRegion.Permissions.OnReturnObject += BigRegion.PermissionModule.CanReturnObject; //NOT YET IMPLEMENTED + VirtualRegion.Permissions.OnReturnObjects += BigRegion.PermissionModule.CanReturnObjects; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnRezObject += BigRegion.PermissionModule.CanRezObject; //MAYBE FULLY IMPLEMENTED VirtualRegion.Permissions.OnRunConsoleCommand += BigRegion.PermissionModule.CanRunConsoleCommand; VirtualRegion.Permissions.OnRunScript += BigRegion.PermissionModule.CanRunScript; //NOT YET IMPLEMENTED @@ -948,7 +948,6 @@ namespace OpenSim.Region.RegionCombinerModule VirtualRegion.Permissions.OnEditUserInventory += BigRegion.PermissionModule.CanEditUserInventory; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnDeleteUserInventory += BigRegion.PermissionModule.CanDeleteUserInventory; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnTeleport += BigRegion.PermissionModule.CanTeleport; //NOT YET IMPLEMENTED - VirtualRegion.Permissions.OnUseObjectReturn += BigRegion.PermissionModule.CanUseObjectReturn; //NOT YET IMPLEMENTED } #region console commands diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs index 4d1af57..393322d 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs @@ -135,9 +135,9 @@ namespace OpenSim.Region.RegionCombinerModule return m_rootScene.Permissions.CanObjectEntry(objectid, enteringregion, newpoint); } - public bool CanReturnObject(UUID objectid, UUID returnerid, Scene scene) + public bool CanReturnObjects(ILandObject land, UUID user, List objects, Scene scene) { - return m_rootScene.Permissions.CanReturnObject(objectid, returnerid); + return m_rootScene.Permissions.CanReturnObjects(land, user, objects); } public bool CanRezObject(int objectcount, UUID owner, Vector3 objectposition, Scene scene) @@ -265,11 +265,6 @@ namespace OpenSim.Region.RegionCombinerModule return m_rootScene.Permissions.CanTeleport(userid); } - public bool CanUseObjectReturn(ILandObject landdata, uint type, IClientAPI client, List retlist, Scene scene) - { - return m_rootScene.Permissions.CanUseObjectReturn(landdata, type, client, retlist); - } - #endregion } -} \ No newline at end of file +} -- cgit v1.1 From 69b5ddceda1fd418712fb7ada0443555dc82b231 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 18 Mar 2010 18:57:29 +0000 Subject: Unify a previous refactor of object return with the older solution. We really don't need two methods doing the same thing, but differently. --- .../Region/CoreModules/World/Land/LandObject.cs | 2 +- .../World/Permissions/PermissionsModule.cs | 71 ++-------------------- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 7 ++- .../Region/Framework/Scenes/Scene.Permissions.cs | 29 ++------- .../RegionCombinerModule/RegionCombinerModule.cs | 3 +- .../RegionCombinerPermissionModule.cs | 11 +--- 6 files changed, 21 insertions(+), 102 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index e85136a..331f183 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -892,7 +892,7 @@ namespace OpenSim.Region.CoreModules.World.Land foreach (List ol in returns.Values) { - if (m_scene.Permissions.CanUseObjectReturn(this, type, remote_client, ol)) + if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 5c7f3b7..38fc250 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -217,7 +217,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnIssueEstateCommand += CanIssueEstateCommand; //FULLY IMPLEMENTED m_scene.Permissions.OnMoveObject += CanMoveObject; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnObjectEntry += CanObjectEntry; - m_scene.Permissions.OnReturnObject += CanReturnObject; //NOT YET IMPLEMENTED + m_scene.Permissions.OnReturnObjects += CanReturnObjects; //NOT YET IMPLEMENTED m_scene.Permissions.OnRezObject += CanRezObject; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnRunConsoleCommand += CanRunConsoleCommand; m_scene.Permissions.OnRunScript += CanRunScript; //NOT YET IMPLEMENTED @@ -247,7 +247,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnDeleteUserInventory += CanDeleteUserInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnTeleport += CanTeleport; //NOT YET IMPLEMENTED - m_scene.Permissions.OnUseObjectReturn += CanUseObjectReturn; //NOT YET IMPLEMENTED m_scene.AddCommand(this, "bypass permissions", "bypass permissions ", @@ -1275,12 +1274,15 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } - private bool CanReturnObject(UUID objectID, UUID returnerID, Scene scene) + private bool CanReturnObjects(ILandObject land, UUID user, List objects, Scene scene) { + if (objects.Count == 0) + return false; + DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(returnerID, objectID, false); + return GenericObjectPermission(user, objects[0].UUID, false); } private bool CanRezObject(int objectCount, UUID owner, Vector3 objectPosition, Scene scene) @@ -1747,67 +1749,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions return GenericObjectPermission(agentID, prim, false); } - private bool CanUseObjectReturn(ILandObject parcel, uint type, IClientAPI client, List retlist, Scene scene) - { - DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); - if (m_bypassPermissions) return m_bypassPermissionsValue; - - long powers = 0; - if (parcel.LandData.GroupID != UUID.Zero) - client.GetGroupPowers(parcel.LandData.GroupID); - - switch (type) - { - case (uint)ObjectReturnType.Owner: - // Don't let group members return owner's objects, ever - // - if (parcel.LandData.IsGroupOwned) - { - if ((powers & (long)GroupPowers.ReturnGroupOwned) != 0) - return true; - } - else - { - if (parcel.LandData.OwnerID != client.AgentId) - return false; - } - return GenericParcelOwnerPermission(client.AgentId, parcel, (ulong)GroupPowers.ReturnGroupOwned); - case (uint)ObjectReturnType.Group: - if (parcel.LandData.OwnerID != client.AgentId) - { - // If permissionis granted through a group... - // - if ((powers & (long)GroupPowers.ReturnGroupSet) != 0) - { - foreach (SceneObjectGroup g in new List(retlist)) - { - // check for and remove group owned objects unless - // the user also has permissions to return those - // - if (g.OwnerID == g.GroupID && - ((powers & (long)GroupPowers.ReturnGroupOwned) == 0)) - { - retlist.Remove(g); - } - } - // And allow the operation - // - return true; - } - } - return GenericParcelOwnerPermission(client.AgentId, parcel, (ulong)GroupPowers.ReturnGroupSet); - case (uint)ObjectReturnType.Other: - if ((powers & (long)GroupPowers.ReturnNonGroup) != 0) - return true; - return GenericParcelOwnerPermission(client.AgentId, parcel, (ulong)GroupPowers.ReturnNonGroup); - case (uint)ObjectReturnType.List: - break; - } - - return GenericParcelOwnerPermission(client.AgentId, parcel, 0); - // Is it correct to be less restrictive for lists of objects to be returned? - } - private bool CanCompileScript(UUID ownerUUID, int scriptType, Scene scene) { //m_log.DebugFormat("check if {0} is allowed to compile {1}", ownerUUID, scriptType); switch (scriptType) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6ebd048..cadb858 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1522,9 +1522,10 @@ namespace OpenSim.Region.Framework.Scenes if (remoteClient != null) { permissionToTake = - Permissions.CanReturnObject( - grp.UUID, - remoteClient.AgentId); + Permissions.CanReturnObjects( + null, + remoteClient.AgentId, + new List() {grp}); permissionToDelete = permissionToTake; if (permissionToDelete) diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index d1d6b6a..7dab04f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -48,7 +48,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool EditObjectInventoryHandler(UUID objectID, UUID editorID, Scene scene); public delegate bool MoveObjectHandler(UUID objectID, UUID moverID, Scene scene); public delegate bool ObjectEntryHandler(UUID objectID, bool enteringRegion, Vector3 newPoint, Scene scene); - public delegate bool ReturnObjectHandler(UUID objectID, UUID returnerID, Scene scene); + public delegate bool ReturnObjectsHandler(ILandObject land, UUID user, List objects, Scene scene); public delegate bool InstantMessageHandler(UUID user, UUID target, Scene startScene); public delegate bool InventoryTransferHandler(UUID user, UUID target, Scene startScene); public delegate bool ViewScriptHandler(UUID script, UUID objectID, UUID user, Scene scene); @@ -81,7 +81,6 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool CopyUserInventoryHandler(UUID itemID, UUID userID); public delegate bool DeleteUserInventoryHandler(UUID itemID, UUID userID); public delegate bool TeleportHandler(UUID userID, Scene scene); - public delegate bool UseObjectReturnHandler(ILandObject landData, uint type, IClientAPI client, List retlist, Scene scene); #endregion public class ScenePermissions @@ -107,7 +106,7 @@ namespace OpenSim.Region.Framework.Scenes public event EditObjectInventoryHandler OnEditObjectInventory; public event MoveObjectHandler OnMoveObject; public event ObjectEntryHandler OnObjectEntry; - public event ReturnObjectHandler OnReturnObject; + public event ReturnObjectsHandler OnReturnObjects; public event InstantMessageHandler OnInstantMessage; public event InventoryTransferHandler OnInventoryTransfer; public event ViewScriptHandler OnViewScript; @@ -140,7 +139,6 @@ namespace OpenSim.Region.Framework.Scenes public event CopyUserInventoryHandler OnCopyUserInventory; public event DeleteUserInventoryHandler OnDeleteUserInventory; public event TeleportHandler OnTeleport; - public event UseObjectReturnHandler OnUseObjectReturn; #endregion #region Object Permission Checks @@ -377,15 +375,15 @@ namespace OpenSim.Region.Framework.Scenes #endregion #region RETURN OBJECT - public bool CanReturnObject(UUID objectID, UUID returnerID) + public bool CanReturnObjects(ILandObject land, UUID user, List objects) { - ReturnObjectHandler handler = OnReturnObject; + ReturnObjectsHandler handler = OnReturnObjects; if (handler != null) { Delegate[] list = handler.GetInvocationList(); - foreach (ReturnObjectHandler h in list) + foreach (ReturnObjectsHandler h in list) { - if (h(objectID, returnerID, m_scene) == false) + if (h(land, user, objects, m_scene) == false) return false; } } @@ -949,20 +947,5 @@ namespace OpenSim.Region.Framework.Scenes } return true; } - - public bool CanUseObjectReturn(ILandObject landData, uint type , IClientAPI client, List retlist) - { - UseObjectReturnHandler handler = OnUseObjectReturn; - if (handler != null) - { - Delegate[] list = handler.GetInvocationList(); - foreach (UseObjectReturnHandler h in list) - { - if (h(landData, type, client, retlist, m_scene) == false) - return false; - } - } - return true; - } } } diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index 92f060b..0b8771c 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -922,7 +922,7 @@ namespace OpenSim.Region.RegionCombinerModule VirtualRegion.Permissions.OnIssueEstateCommand += BigRegion.PermissionModule.CanIssueEstateCommand; //FULLY IMPLEMENTED VirtualRegion.Permissions.OnMoveObject += BigRegion.PermissionModule.CanMoveObject; //MAYBE FULLY IMPLEMENTED VirtualRegion.Permissions.OnObjectEntry += BigRegion.PermissionModule.CanObjectEntry; - VirtualRegion.Permissions.OnReturnObject += BigRegion.PermissionModule.CanReturnObject; //NOT YET IMPLEMENTED + VirtualRegion.Permissions.OnReturnObjects += BigRegion.PermissionModule.CanReturnObjects; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnRezObject += BigRegion.PermissionModule.CanRezObject; //MAYBE FULLY IMPLEMENTED VirtualRegion.Permissions.OnRunConsoleCommand += BigRegion.PermissionModule.CanRunConsoleCommand; VirtualRegion.Permissions.OnRunScript += BigRegion.PermissionModule.CanRunScript; //NOT YET IMPLEMENTED @@ -948,7 +948,6 @@ namespace OpenSim.Region.RegionCombinerModule VirtualRegion.Permissions.OnEditUserInventory += BigRegion.PermissionModule.CanEditUserInventory; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnDeleteUserInventory += BigRegion.PermissionModule.CanDeleteUserInventory; //NOT YET IMPLEMENTED VirtualRegion.Permissions.OnTeleport += BigRegion.PermissionModule.CanTeleport; //NOT YET IMPLEMENTED - VirtualRegion.Permissions.OnUseObjectReturn += BigRegion.PermissionModule.CanUseObjectReturn; //NOT YET IMPLEMENTED } #region console commands diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs index 4d1af57..393322d 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerPermissionModule.cs @@ -135,9 +135,9 @@ namespace OpenSim.Region.RegionCombinerModule return m_rootScene.Permissions.CanObjectEntry(objectid, enteringregion, newpoint); } - public bool CanReturnObject(UUID objectid, UUID returnerid, Scene scene) + public bool CanReturnObjects(ILandObject land, UUID user, List objects, Scene scene) { - return m_rootScene.Permissions.CanReturnObject(objectid, returnerid); + return m_rootScene.Permissions.CanReturnObjects(land, user, objects); } public bool CanRezObject(int objectcount, UUID owner, Vector3 objectposition, Scene scene) @@ -265,11 +265,6 @@ namespace OpenSim.Region.RegionCombinerModule return m_rootScene.Permissions.CanTeleport(userid); } - public bool CanUseObjectReturn(ILandObject landdata, uint type, IClientAPI client, List retlist, Scene scene) - { - return m_rootScene.Permissions.CanUseObjectReturn(landdata, type, client, retlist); - } - #endregion } -} \ No newline at end of file +} -- cgit v1.1 From 3ea72eeabb12cff4f71523f501450a7df38a17b1 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 19 Mar 2010 13:26:34 -0400 Subject: Fix sit with autopilot. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 123d6f3..2603fe1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -455,8 +455,9 @@ namespace OpenSim.Region.Framework.Scenes get { PhysicsActor actor = m_physicsActor; - if (actor != null) - m_pos = actor.Position; +// if (actor != null) + if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! + m_pos = actor.Position; return m_parentPosition + m_pos; } @@ -476,7 +477,8 @@ namespace OpenSim.Region.Framework.Scenes } } - m_pos = value; + if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! + m_pos = value; m_parentPosition = Vector3.Zero; } } -- cgit v1.1 From add47befacb0397f2a0b5c9455ed1e658616aba4 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 19 Mar 2010 18:53:16 -0400 Subject: Update acceleration to 0 on no tphysical. --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 5e6696e..e8894f7 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -804,6 +804,7 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_isphysical && Body != IntPtr.Zero) { d.BodyDisable(Body); + Halt(); } } @@ -2972,7 +2973,8 @@ Console.WriteLine(" JointCreateFixed"); m_wLinObjectVel = Vector3.Zero; m_angularMotorDirection = Vector3.Zero; m_lastAngularVelocity = Vector3.Zero; - m_angularMotorDVel = Vector3.Zero; + m_angularMotorDVel = Vector3.Zero; + _acceleration = Vector3.Zero; } private void UpdateLinDecay() -- cgit v1.1 From e0b287961f51d776f830728c5e0fdaba5f7e53bc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 23 Mar 2010 17:04:37 +0100 Subject: Change land overlay to send group owned status properly --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 9be94ce..6c9830c 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1014,6 +1014,10 @@ namespace OpenSim.Region.CoreModules.World.Land //Owner Flag tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_REQUESTER); } + else if (currentParcelBlock.LandData.IsGroupOwned && remote_client.IsGroupMember(currentParcelBlock.LandData.GroupID)) + { + tempByte = Convert.ToByte(tempByte | LandChannel.LAND_TYPE_OWNED_BY_GROUP); + } else if (currentParcelBlock.LandData.SalePrice > 0 && (currentParcelBlock.LandData.AuthBuyerID == UUID.Zero || currentParcelBlock.LandData.AuthBuyerID == remote_client.AgentId)) -- cgit v1.1 From dd544f811a8a46b91b6101fb83b3504ef246a83c Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 26 Mar 2010 19:09:09 +0000 Subject: switch flavor to RC1 --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index ec94b2d..f8ed5ae 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -30,7 +30,7 @@ namespace OpenSim public class VersionInfo { private const string VERSION_NUMBER = "0.6.9"; - private const Flavour VERSION_FLAVOUR = Flavour.Dev; + private const Flavour VERSION_FLAVOUR = Flavour.RC1; public enum Flavour { -- cgit v1.1 From 7d917e7c5c599549d2a87451fe3d6ca2bf6e62a4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 30 Mar 2010 23:29:03 +0100 Subject: Rename Meta7Windlight to LightShare --- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 6 +- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 6 +- OpenSim/Data/Null/NullDataStore.cs | 6 +- OpenSim/Data/SQLite/SQLiteRegionData.cs | 6 +- OpenSim/Framework/RegionInfo.cs | 10 +- .../CoreModules/World/Land/LandManagementModule.cs | 10 +- .../World/Meta7Windlight/Meta7WindlightModule.cs | 274 --------------------- .../Framework/Interfaces/IRegionDataStore.cs | 4 +- OpenSim/Region/Framework/Scenes/EventManager.cs | 4 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 11 +- .../Region/Framework/Scenes/Tests/SceneTests.cs | 6 +- .../Shared/Api/Implementation/CM_Api.cs | 116 ++++----- 13 files changed, 93 insertions(+), 368 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index b1339b6..d6cb91f 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -691,13 +691,13 @@ VALUES cmd.ExecuteNonQuery(); } } - public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { //This connector doesn't support the windlight module yet //Return default LL windlight settings - return new RegionMeta7WindlightData(); + return new RegionLightShareData(); } - public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + public void StoreRegionWindlightSettings(RegionLightShareData wl) { //This connector doesn't support the windlight module yet } diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index f84beb6..a395ddc 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -711,9 +711,9 @@ namespace OpenSim.Data.MySQL } } - public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { - RegionMeta7WindlightData nWP = new RegionMeta7WindlightData(); + RegionLightShareData nWP = new RegionLightShareData(); nWP.OnSave += StoreRegionWindlightSettings; using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) @@ -845,7 +845,7 @@ namespace OpenSim.Data.MySQL return rs; } - public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + public void StoreRegionWindlightSettings(RegionLightShareData wl) { using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) { diff --git a/OpenSim/Data/Null/NullDataStore.cs b/OpenSim/Data/Null/NullDataStore.cs index 4b6d0f3..3ba44bb 100644 --- a/OpenSim/Data/Null/NullDataStore.cs +++ b/OpenSim/Data/Null/NullDataStore.cs @@ -50,13 +50,13 @@ namespace OpenSim.Data.Null public void StoreRegionSettings(RegionSettings rs) { } - public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { //This connector doesn't support the windlight module yet //Return default LL windlight settings - return new RegionMeta7WindlightData(); + return new RegionLightShareData(); } - public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + public void StoreRegionWindlightSettings(RegionLightShareData wl) { //This connector doesn't support the windlight module yet } diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 81c0703..d2ba9ae 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -272,13 +272,13 @@ namespace OpenSim.Data.SQLite Commit(); } } - public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { //This connector doesn't support the windlight module yet //Return default LL windlight settings - return new RegionMeta7WindlightData(); + return new RegionLightShareData(); } - public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + public void StoreRegionWindlightSettings(RegionLightShareData wl) { //This connector doesn't support the windlight module yet } diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index 05f9cf9..5eacd73 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -39,7 +39,7 @@ using OpenSim.Framework.Console; namespace OpenSim.Framework { - public class RegionMeta7WindlightData : ICloneable + public class RegionLightShareData : ICloneable { public UUID regionID = UUID.Zero; public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f); @@ -80,7 +80,7 @@ namespace OpenSim.Framework public bool cloudScrollYLock = false; public bool drawClassicClouds = true; - public delegate void SaveDelegate(RegionMeta7WindlightData wl); + public delegate void SaveDelegate(RegionLightShareData wl); public event SaveDelegate OnSave; public void Save() { @@ -356,7 +356,7 @@ namespace OpenSim.Framework private bool m_clampPrimSize = false; private int m_objectCapacity = 0; private string m_regionType = String.Empty; - private RegionMeta7WindlightData m_windlight = new RegionMeta7WindlightData(); + private RegionLightShareData m_windlight = new RegionLightShareData(); protected uint m_httpPort; protected string m_serverURI; protected string m_regionName = String.Empty; @@ -495,13 +495,13 @@ namespace OpenSim.Framework set { m_regionSettings = value; } } - public RegionMeta7WindlightData WindlightSettings + public RegionLightShareData WindlightSettings { get { if (m_windlight == null) { - m_windlight = new RegionMeta7WindlightData(); + m_windlight = new RegionLightShareData(); } return m_windlight; diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index b6afac6..7f6a0ad 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1532,7 +1532,7 @@ namespace OpenSim.Region.CoreModules.World.Land private void ClientOnSimWideDeletes(IClientAPI client, UUID agentID, int flags, UUID targetID) { ScenePresence SP; - ((Scene)client.Scene).TryGetAvatar(client.AgentId, out SP); + ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out SP); List returns = new List(); if (SP.GodLevel != 0) { @@ -1597,9 +1597,9 @@ namespace OpenSim.Region.CoreModules.World.Land public void ClientOnParcelFreezeUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) { ScenePresence targetAvatar = null; - ((Scene)client.Scene).TryGetAvatar(target, out targetAvatar); + ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar); ScenePresence parcelManager = null; - ((Scene)client.Scene).TryGetAvatar(client.AgentId, out parcelManager); + ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); System.Threading.Timer Timer; if (targetAvatar.GodLevel == 0) @@ -1641,9 +1641,9 @@ namespace OpenSim.Region.CoreModules.World.Land public void ClientOnParcelEjectUser(IClientAPI client, UUID parcelowner, uint flags, UUID target) { ScenePresence targetAvatar = null; - ((Scene)client.Scene).TryGetAvatar(target, out targetAvatar); + ((Scene)client.Scene).TryGetScenePresence(target, out targetAvatar); ScenePresence parcelManager = null; - ((Scene)client.Scene).TryGetAvatar(client.AgentId, out parcelManager); + ((Scene)client.Scene).TryGetScenePresence(client.AgentId, out parcelManager); //Just eject if (flags == 0) { diff --git a/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs b/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs deleted file mode 100644 index 72b0b38..0000000 --- a/OpenSim/Region/CoreModules/World/Meta7Windlight/Meta7WindlightModule.cs +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) Thomas Grimshaw and Magne Metaverse Research - * - * This module is not open source. All rights reserved. - * Unauthorised copying, distribution or public display is prohibited. - * - */ - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using OpenMetaverse; -using log4net; -using Nini.Config; -using OpenSim.Data; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.Framework.InterfaceCommander; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - - -namespace OpenSim.Region.CoreModules.World.Meta7Windlight -{ - public class Meta7WindlightModule : IRegionModule, ICommandableModule - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private readonly Commander m_commander = new Commander("windlight"); - private Scene m_scene; - private static bool m_enableWindlight; - - #region ICommandableModule Members - - public ICommander CommandInterface - { - get { return m_commander; } - } - - #endregion - - #region IRegionModule Members - - public static bool EnableWindlight - { - get - { - return m_enableWindlight; - } - set - { - } - } - - public void Initialise(Scene scene, IConfigSource config) - { - m_scene = scene; - m_scene.RegisterModuleInterface(this); - m_scene.EventManager.OnPluginConsole += EventManager_OnPluginConsole; - - // ini file settings - try - { - m_enableWindlight = config.Configs["Meta7Windlight"].GetBoolean("enable_windlight", false); - } - catch (Exception) - { - m_log.Debug("[WINDLIGHT]: ini failure for enable_windlight - using default"); - } - - if (m_enableWindlight) - { - m_scene.EventManager.OnMakeRootAgent += EventManager_OnMakeRootAgent; - m_scene.EventManager.OnSaveNewWindlightProfile += EventManager_OnSaveNewWindlightProfile; - m_scene.EventManager.OnSendNewWindlightProfileTargeted += EventManager_OnSendNewWindlightProfileTargeted; - } - - InstallCommands(); - - m_log.Debug("[WINDLIGHT]: Initialised windlight module"); - } - - private List compileWindlightSettings(RegionMeta7WindlightData wl) - { - byte[] mBlock = new Byte[249]; - int pos = 0; - - wl.waterColor.ToBytes(mBlock, 0); pos += 12; - Utils.FloatToBytes(wl.waterFogDensityExponent).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.underwaterFogModifier).CopyTo(mBlock, pos); pos += 4; - wl.reflectionWaveletScale.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.fresnelScale).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.fresnelOffset).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.refractScaleAbove).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.refractScaleBelow).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.blurMultiplier).CopyTo(mBlock, pos); pos += 4; - wl.bigWaveDirection.ToBytes(mBlock, pos); pos += 8; - wl.littleWaveDirection.ToBytes(mBlock, pos); pos += 8; - wl.normalMapTexture.ToBytes(mBlock, pos); pos += 16; - wl.horizon.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.hazeHorizon).CopyTo(mBlock, pos); pos += 4; - wl.blueDensity.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.hazeDensity).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.densityMultiplier).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.distanceMultiplier).CopyTo(mBlock, pos); pos += 4; - wl.sunMoonColor.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.sunMoonPosition).CopyTo(mBlock, pos); pos += 4; - wl.ambient.ToBytes(mBlock, pos); pos += 16; - Utils.FloatToBytes(wl.eastAngle).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sunGlowFocus).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sunGlowSize).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.sceneGamma).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.starBrightness).CopyTo(mBlock, pos); pos += 4; - wl.cloudColor.ToBytes(mBlock, pos); pos += 16; - wl.cloudXYDensity.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.cloudCoverage).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.cloudScale).CopyTo(mBlock, pos); pos += 4; - wl.cloudDetailXYDensity.ToBytes(mBlock, pos); pos += 12; - Utils.FloatToBytes(wl.cloudScrollX).CopyTo(mBlock, pos); pos += 4; - Utils.FloatToBytes(wl.cloudScrollY).CopyTo(mBlock, pos); pos += 4; - Utils.UInt16ToBytes(wl.maxAltitude).CopyTo(mBlock, pos); pos += 2; - mBlock[pos] = Convert.ToByte(wl.cloudScrollXLock); pos++; - mBlock[pos] = Convert.ToByte(wl.cloudScrollYLock); pos++; - mBlock[pos] = Convert.ToByte(wl.drawClassicClouds); pos++; - List param = new List(); - param.Add(mBlock); - return param; - } - public void SendProfileToClient(ScenePresence presence) - { - IClientAPI client = presence.ControllingClient; - if (m_enableWindlight) - { - if (presence.IsChildAgent == false) - { - List param = compileWindlightSettings(m_scene.RegionInfo.WindlightSettings); - client.SendGenericMessage("Windlight", param); - } - } - else - { - //We probably don't want to spam chat with this.. probably - //m_log.Debug("[WINDLIGHT]: Module disabled"); - } - } - public void SendProfileToClient(ScenePresence presence, RegionMeta7WindlightData wl) - { - IClientAPI client = presence.ControllingClient; - if (m_enableWindlight) - { - if (presence.IsChildAgent == false) - { - List param = compileWindlightSettings(wl); - client.SendGenericMessage("Windlight", param); - } - } - else - { - //We probably don't want to spam chat with this.. probably - //m_log.Debug("[WINDLIGHT]: Module disabled"); - } - } - private void EventManager_OnMakeRootAgent(ScenePresence presence) - { - m_log.Debug("[WINDLIGHT]: Sending windlight scene to new client"); - SendProfileToClient(presence); - } - private void EventManager_OnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID pUUID) - { - ScenePresence Sc; - if (m_scene.TryGetAvatar(pUUID,out Sc)) - { - SendProfileToClient(Sc,wl); - } - } - private void EventManager_OnSaveNewWindlightProfile() - { - m_scene.ForEachScenePresence(SendProfileToClient); - } - - public void PostInitialise() - { - - } - - public void Close() - { - } - - public string Name - { - get { return "Meta7WindlightModule"; } - } - - public bool IsSharedModule - { - get { return false; } - } - - #endregion - - #region events - - #endregion - - #region ICommandableModule Members - - private void InstallCommands() - { - Command wlload = new Command("load", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleLoad, "Load windlight profile from the database and broadcast"); - Command wlenable = new Command("enable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleEnable, "Enable the windlight plugin"); - Command wldisable = new Command("disable", CommandIntentions.COMMAND_NON_HAZARDOUS, HandleDisable, "Enable the windlight plugin"); - - m_commander.RegisterCommand("load", wlload); - m_commander.RegisterCommand("enable", wlenable); - m_commander.RegisterCommand("disable", wldisable); - - m_scene.RegisterModuleCommander(m_commander); - } - - private void HandleLoad(Object[] args) - { - if (!m_enableWindlight) - { - m_log.InfoFormat("[WINDLIGHT]: Cannot load windlight profile, module disabled. Use 'windlight enable' first."); - } - else - { - m_log.InfoFormat("[WINDLIGHT]: Loading Windlight profile from database"); - m_scene.LoadWindlightProfile(); - m_log.InfoFormat("[WINDLIGHT]: Load complete"); - } - } - - private void HandleDisable(Object[] args) - { - m_log.InfoFormat("[WINDLIGHT]: Plugin now disabled"); - m_enableWindlight=false; - } - - private void HandleEnable(Object[] args) - { - m_log.InfoFormat("[WINDLIGHT]: Plugin now enabled"); - m_enableWindlight = true; - } - - /// - /// Processes commandline input. Do not call directly. - /// - /// Commandline arguments - private void EventManager_OnPluginConsole(string[] args) - { - if (args[0] == "windlight") - { - if (args.Length == 1) - { - m_commander.ProcessConsoleCommand("add", new string[0]); - return; - } - - string[] tmpArgs = new string[args.Length - 2]; - int i; - for (i = 2; i < args.Length; i++) - { - tmpArgs[i - 2] = args[i]; - } - - m_commander.ProcessConsoleCommand(args[1], tmpArgs); - } - } - #endregion - - } -} - diff --git a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs index 7312799..3e8e196 100644 --- a/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/IRegionDataStore.cs @@ -103,8 +103,8 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionSettings(RegionSettings rs); RegionSettings LoadRegionSettings(UUID regionUUID); - RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID); - void StoreRegionWindlightSettings(RegionMeta7WindlightData wl); + RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID); + void StoreRegionWindlightSettings(RegionLightShareData wl); void Shutdown(); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 37a51d9..ef125cd 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -207,7 +207,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate void OnMakeRootAgentDelegate(ScenePresence presence); public delegate void OnSaveNewWindlightProfileDelegate(); - public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionMeta7WindlightData wl, UUID user); + public delegate void OnSendNewWindlightProfileTargetedDelegate(RegionLightShareData wl, UUID user); public event OnMakeRootAgentDelegate OnMakeRootAgent; public event OnSendNewWindlightProfileTargetedDelegate OnSendNewWindlightProfileTargeted; public event OnSaveNewWindlightProfileDelegate OnSaveNewWindlightProfile; @@ -1220,7 +1220,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public void TriggerOnSendNewWindlightProfileTargeted(RegionMeta7WindlightData wl, UUID user) + public void TriggerOnSendNewWindlightProfileTargeted(RegionLightShareData wl, UUID user) { OnSendNewWindlightProfileTargetedDelegate handlerSendNewWindlightProfileTargeted = OnSendNewWindlightProfileTargeted; if (handlerSendNewWindlightProfileTargeted != null) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2b6f80b..1f604c5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1729,7 +1729,7 @@ namespace OpenSim.Region.Framework.Scenes m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); } - public void StoreWindlightProfile(RegionMeta7WindlightData wl) + public void StoreWindlightProfile(RegionLightShareData wl) { m_regInfo.WindlightSettings = wl; m_storageManager.DataStore.StoreRegionWindlightSettings(wl); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3895d93..7ed29a5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1370,21 +1370,20 @@ namespace OpenSim.Region.Framework.Scenes { // part.Inventory.RemoveScriptInstances(); - List avatars = Scene.GetScenePresences(); - for (int i = 0; i < avatars.Count; i++) + Scene.ForEachScenePresence(delegate (ScenePresence sp) { - if (avatars[i].ParentID == LocalId) + if (sp.ParentID == LocalId) { - avatars[i].StandUp(); + sp.StandUp(); } if (!silent) { part.UpdateFlag = 0; if (part == m_rootPart) - avatars[i].ControllingClient.SendKillObject(m_regionHandle, part.LocalId); + sp.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); } - } + }); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs index 68035ca..8b2d387 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneTests.cs @@ -101,13 +101,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests { throw new NotImplementedException(); } - public RegionMeta7WindlightData LoadRegionWindlightSettings(UUID regionUUID) + public RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID) { //This connector doesn't support the windlight module yet //Return default LL windlight settings - return new RegionMeta7WindlightData(); + return new RegionLightShareData(); } - public void StoreRegionWindlightSettings(RegionMeta7WindlightData wl) + public void StoreRegionWindlightSettings(RegionLightShareData wl) { //This connector doesn't support the windlight module yet } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 99973b4..4e8a3c4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -7,7 +7,7 @@ using OpenMetaverse; using Nini.Config; using OpenSim; using OpenSim.Framework; -using OpenSim.Region.CoreModules.World.Meta7Windlight; +using OpenSim.Region.CoreModules.World.LightShare; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Region.ScriptEngine.Shared; @@ -97,7 +97,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return new LSL_List(); } m_host.AddScriptLPS(1); - RegionMeta7WindlightData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; LSL_List values = new LSL_List(); int idx = 0; @@ -229,11 +229,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return values; - } - - private RegionMeta7WindlightData getWindlightProfileFromRules(LSL_List rules) - { - RegionMeta7WindlightData wl = (RegionMeta7WindlightData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); + } + + private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) + { + RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); LSL_List values = new LSL_List(); int idx = 0; @@ -244,9 +244,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Types.Vector3 iV; switch (rule) { - case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: - idx++; - wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); + case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: + idx++; + wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); break; case (int)ScriptBaseClass.WL_AMBIENT: idx++; @@ -419,58 +419,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CMShoutError("Careminster functions are not enabled."); return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - CMShoutError("cmSetWindlightScene can only be used by estate managers or owners."); - return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + CMShoutError("cmSetWindlightScene can only be used by estate managers or owners."); + return 0; } int success = 0; - m_host.AddScriptLPS(1); - if (Meta7WindlightModule.EnableWindlight) - { - RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; - } - else - { - CMShoutError("Windlight module is disabled"); - return 0; + m_host.AddScriptLPS(1); + if (LightShareModule.EnableWindlight) + { + RegionLightShareData wl = getWindlightProfileFromRules(rules); + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + success = 1; + } + else + { + CMShoutError("Windlight module is disabled"); + return 0; + } + return success; + } + /// + /// Set the current Windlight scene to a target avatar + /// + /// + /// success: true or false + public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) + { + if (!m_CMFunctionsEnabled) + { + CMShoutError("Careminster functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (LightShareModule.EnableWindlight) + { + RegionLightShareData wl = getWindlightProfileFromRules(rules); + World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); + success = 1; + } + else + { + CMShoutError("Windlight module is disabled"); + return 0; } return success; - } - /// - /// Set the current Windlight scene to a target avatar - /// - /// - /// success: true or false - public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) - { - if (!m_CMFunctionsEnabled) - { - CMShoutError("Careminster functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (Meta7WindlightModule.EnableWindlight) - { - RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); - World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); - success = 1; - } - else - { - CMShoutError("Windlight module is disabled"); - return 0; - } - return success; } } -- cgit v1.1 From 956225f0e1a3441e47a74b8882cc975f626e8b36 Mon Sep 17 00:00:00 2001 From: lcc Date: Sun, 4 Apr 2010 18:29:18 +0200 Subject: Fixed Ban and parcel exclusion. Need to fix the parcel chat too --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 6c9830c..8039558 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -390,7 +390,7 @@ namespace OpenSim.Region.CoreModules.World.Land { if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) { - if (parcelAvatarIsEntering.IsBannedFromLand(avatar.UUID)) + if (parcelAvatarIsEntering.IsEitherBannedOrRestricted(avatar.UUID)) { MoveUserOutOfParcel(avatar); } -- cgit v1.1 From e2a521742a737aa54e43dd934c0a0d5f2e380e8f Mon Sep 17 00:00:00 2001 From: kitto Date: Sun, 4 Apr 2010 22:57:32 -0400 Subject: ChODE Only: Corrected Heightmap load to iliminate crack at 255M. Added 'fence' option to prevent physical objects crossing region border. --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 202 +++++++++++++----------- OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 111 ++++++------- 2 files changed, 157 insertions(+), 156 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index e8894f7..67f8af5 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -180,6 +180,7 @@ namespace OpenSim.Region.Physics.OdePlugin internal int m_material = (int)Material.Wood; private int frcount = 0; // Used to limit dynamics debug output to + private int revcount = 0; // Reverse motion while > 0 private IntPtr m_body = IntPtr.Zero; @@ -1888,22 +1889,19 @@ namespace OpenSim.Region.Physics.OdePlugin public void changemove(float timestep) { -//Console.WriteLine("changemove for {0}", m_primName ); - +//Console.WriteLine("changemove sing/root {0} to {1}", m_primName, _position ); if (m_isphysical) { //Console.WriteLine("phys {0} {1} {2}", m_disabled, m_taintremove, childPrim); // if (!m_disabled && !m_taintremove && !childPrim) After one edit m_disabled is sometimes set, disabling further edits! if (!m_taintremove && !childPrim) { -//Console.WriteLine("physOK"); if (Body == IntPtr.Zero) enableBody(); //Prim auto disable after 20 frames, //if you move it, re-enable the prim manually. if (_parent != null) { -//Console.WriteLine("physChild"); if (m_linkJoint != IntPtr.Zero) { d.JointDestroy(m_linkJoint); @@ -1912,7 +1910,6 @@ namespace OpenSim.Region.Physics.OdePlugin } if (Body != IntPtr.Zero) { -//Console.WriteLine("physNotIPZ"); d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); if (_parent != null) @@ -1945,7 +1942,6 @@ Console.WriteLine(" JointCreateFixed"); } else { -//Console.WriteLine("NONphys"); // string primScenAvatarIn = _parent_scene.whichspaceamIin(_position); // int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position); _parent_scene.waitForSpaceUnlock(m_targetSpace); @@ -2382,9 +2378,7 @@ Console.WriteLine(" JointCreateFixed"); if (IsPhysical) { if (Body != IntPtr.Zero) - { d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z); - } } //resetCollisionAccounting(); @@ -2394,31 +2388,9 @@ Console.WriteLine(" JointCreateFixed"); public void UpdatePositionAndVelocity() { - return; // moved to the Move() method - } -/* No one uses this? - public Matrix4 FromDMass(d.Mass pMass) - { - Matrix4 obj; - obj.M11 = pMass.I.M00; - obj.M12 = pMass.I.M01; - obj.M13 = pMass.I.M02; - obj.M14 = 0; - obj.M21 = pMass.I.M10; - obj.M22 = pMass.I.M11; - obj.M23 = pMass.I.M12; - obj.M24 = 0; - obj.M31 = pMass.I.M20; - obj.M32 = pMass.I.M21; - obj.M33 = pMass.I.M22; - obj.M34 = 0; - obj.M41 = 0; - obj.M42 = 0; - obj.M43 = 0; - obj.M44 = 1; - return obj; + return; // moved to the Move () method } -*/ + public d.Mass FromMatrix4(Matrix4 pMat, ref d.Mass obj) { obj.I.M00 = pMat[0, 0]; @@ -2996,44 +2968,114 @@ Console.WriteLine(" JointCreateFixed"); float fx = 0; float fy = 0; float fz = 0; + Vector3 linvel; // velocity applied, including any reversal + int outside = 0; + + // If geomCrossingFailuresBeforeOutofbounds is set to 0 in OpenSim.ini then phys objects bounce off region borders. + // This is a temp patch until proper region crossing is developed. + + int failureLimit = _parent_scene.geomCrossingFailuresBeforeOutofbounds; + int fence = _parent_scene.geomRegionFence; + + float border_limit = 0.05f; // original limit + if (fence == 1) border_limit = 0.5f; // bounce point frcount++; // used to limit debug comment output if (frcount > 100) frcount = 0; - if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims. + if(revcount > 0) revcount--; + + if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // Only move root prims. { - -// Old public void UpdatePositionAndVelocity(), more accuratley calculated here + // Old public void UpdatePositionAndVelocity(), more accuratley calculated here bool lastZeroFlag = _zeroFlag; // was it stopped + d.Vector3 vec = d.BodyGetPosition(Body); - d.Quaternion ori = d.BodyGetQuaternion(Body); - d.Vector3 vel = d.BodyGetLinearVel(Body); - // d.Vector3 rotvel = d.BodyGetAngularVel(Body); - d.Vector3 torque = d.BodyGetTorque(Body); - _torque = new Vector3(torque.X, torque.Y, torque.Z); Vector3 l_position = Vector3.Zero; - Quaternion l_orientation = Quaternion.Identity; - - m_lastposition = _position; - m_lastorientation = _orientation; - l_position.X = vec.X; l_position.Y = vec.Y; l_position.Z = vec.Z; - l_orientation.X = ori.X; - l_orientation.Y = ori.Y; - l_orientation.Z = ori.Z; - l_orientation.W = ori.W; + m_lastposition = _position; + _position = l_position; + + d.Quaternion ori = d.BodyGetQuaternion(Body); + // Quaternion l_orientation = Quaternion.Identity; + _orientation.X = ori.X; + _orientation.Y = ori.Y; + _orientation.Z = ori.Z; + _orientation.W = ori.W; + m_lastorientation = _orientation; + + d.Vector3 vel = d.BodyGetLinearVel(Body); + m_lastVelocity = _velocity; + _velocity.X = vel.X; + _velocity.Y = vel.Y; + _velocity.Z = vel.Z; + _acceleration = ((_velocity - m_lastVelocity) / timestep); + + d.Vector3 torque = d.BodyGetTorque(Body); + _torque = new Vector3(torque.X, torque.Y, torque.Z); + + base.RequestPhysicsterseUpdate(); + //Console.WriteLine("Move {0} at {1}", m_primName, l_position); - // Check if outside region horizontally - if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || - l_position.X < 0f || - l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || - l_position.Y < 0f) + // Check if outside region + // In Scene.cs/CrossPrimGroupIntoNewRegion the object is checked for 0.1M from border! + if (l_position.X > ((float)_parent_scene.WorldExtents.X - border_limit)) + { + l_position.X = ((float)_parent_scene.WorldExtents.X - border_limit); + outside = 1; + } + + if (l_position.X < border_limit) + { + l_position.X = border_limit; + outside = 2; + } + if (l_position.Y > ((float)_parent_scene.WorldExtents.Y - border_limit)) + { + l_position.Y = ((float)_parent_scene.WorldExtents.Y - border_limit); + outside = 3; + } + + if (l_position.Y < border_limit) + { + l_position.Y = border_limit; + outside = 4; + } + + if (outside > 0) { - if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) +//Console.WriteLine(" fence = {0}",fence); + +//Console.WriteLine("Border {0}", l_position); + if (fence == 1) // bounce object off boundary + { + if (revcount == 0) + { + if (outside < 3) + { + _velocity.X = -_velocity.X; + } + else + { + _velocity.Y = -_velocity.Y; + } + if (m_type != Vehicle.TYPE_NONE) Halt(); + _position = l_position; + m_taintposition = _position; + m_lastVelocity = _velocity; + _acceleration = Vector3.Zero; + d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); + d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z); + base.RequestPhysicsterseUpdate(); + + revcount = 25; // wait for object to move away from border + } + } // else old crossing mode + else if (m_crossingfailures < failureLimit) { // keep trying to cross? _position = l_position; //_parent_scene.remActivePrim(this); @@ -3043,9 +3085,12 @@ Console.WriteLine(" JointCreateFixed"); else { // Too many tries if (_parent == null) base.RaiseOutOfBounds(l_position); +//Console.WriteLine("ROOB 2"); + return; // Dont process any other motion? - } + } // end various methods } // end outside region horizontally + if (l_position.Z < 0) { @@ -3057,6 +3102,8 @@ Console.WriteLine(" JointCreateFixed"); //IsPhysical = false; if (_parent == null) base.RaiseOutOfBounds(_position); +//Console.WriteLine("ROOB 3"); + _acceleration.X = 0; // This stuff may stop client display but it has no _acceleration.Y = 0; // effect on the object in phys engine! @@ -3081,10 +3128,9 @@ Console.WriteLine(" JointCreateFixed"); if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02) && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02) && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02) - && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, l_orientation)) < 0.0001)) // KF 0.01 is far to large + && (1.0 - Math.Abs(Quaternion.Dot(m_lastorientation, _orientation)) < 0.0001)) // KF 0.01 is far to large { _zeroFlag = true; -//Console.WriteLine("ZFT 2"); m_throttleUpdates = false; } else @@ -3104,10 +3150,7 @@ Console.WriteLine(" JointCreateFixed"); _acceleration.X = 0; _acceleration.Y = 0; _acceleration.Z = 0; - //_orientation.w = 0f; - //_orientation.X = 0f; - //_orientation.Y = 0f; - //_orientation.Z = 0f; + m_rotationalVelocity.X = 0; m_rotationalVelocity.Y = 0; m_rotationalVelocity.Z = 0; @@ -3132,26 +3175,6 @@ Console.WriteLine(" JointCreateFixed"); base.RequestPhysicsterseUpdate(); } } - - m_lastVelocity = _velocity; - - _position = l_position; - - _velocity.X = vel.X; - _velocity.Y = vel.Y; - _velocity.Z = vel.Z; -// Why 2 calcs??? -// _acceleration = ((_velocity - m_lastVelocity) / 0.1f); -// _acceleration = new Vector3(_velocity.X - m_lastVelocity.X / 0.1f, -// _velocity.Y - m_lastVelocity.Y / 0.1f, -// _velocity.Z - m_lastVelocity.Z / 0.1f); - - _acceleration = ((_velocity - m_lastVelocity) / timestep); - - _orientation.X = ori.X; - _orientation.Y = ori.Y; - _orientation.Z = ori.Z; - _orientation.W = ori.W; m_lastUpdateSent = false; if (!m_throttleUpdates || throttleCounter > _parent_scene.geomUpdatesPerThrottledUpdate) { @@ -3167,11 +3190,8 @@ Console.WriteLine(" JointCreateFixed"); } m_lastposition = l_position; - /// End of old UpdatePositionAndVelocity insert + /// End UpdatePositionAndVelocity insert -//if (!Acceleration.ApproxEquals(Vector3.Zero, 0.01f)) Console.WriteLine("Move " + m_primName + " Accel=" + Acceleration); -// if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_type + -// " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID); if (m_type != Vehicle.TYPE_NONE) { // get body attitude @@ -3299,11 +3319,12 @@ Console.WriteLine(" JointCreateFixed"); { // not hovering, Gravity rules m_wLinObjectVel.Z = vel_now.Z; } - - + linvel = m_wLinObjectVel; + // Vehicle Linear Motion done ======================================= // Apply velocity - d.BodySetLinearVel(Body, m_wLinObjectVel.X, m_wLinObjectVel.Y, m_wLinObjectVel.Z); +//if(frcount == 0) Console.WriteLine("LV {0}", linvel); + d.BodySetLinearVel(Body, linvel.X, linvel.Y, linvel.Z); // apply gravity force d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); //if(frcount == 0) Console.WriteLine("Grav {0}", grav); @@ -3626,9 +3647,10 @@ Console.WriteLine(" JointCreateFixed"); // react to the physics scene by moving it's position. // Avatar to Avatar collisions // Prim to avatar collisions + d.Vector3 dlinvel = vel; d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight); - d.BodySetLinearVel(Body, vel.X, vel.Y, 0); + d.BodySetLinearVel(Body, dlinvel.X, dlinvel.Y, dlinvel.Z); d.BodyAddForce(Body, 0, 0, fz); //KF this prevents furthur motions return; } diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index deb6164..79e2986 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -224,6 +224,7 @@ namespace OpenSim.Region.Physics.OdePlugin public float bodyPIDG = 25; public int geomCrossingFailuresBeforeOutofbounds = 5; + public int geomRegionFence = 0; public float bodyMotorJointMaxforceTensor = 2; @@ -447,6 +448,7 @@ namespace OpenSim.Region.Physics.OdePlugin geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3); geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15); geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5); + geomRegionFence = physicsconfig.GetInt("region_border_fence", 0); geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", 10.000006836f); bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", 20); @@ -3419,76 +3421,56 @@ namespace OpenSim.Region.Physics.OdePlugin public void SetTerrain(float[] heightMap, Vector3 pOffset) { - // this._heightmap[i] = (double)heightMap[i]; - // dbm (danx0r) -- creating a buffer zone of one extra sample all around - //_origheightmap = heightMap; + uint regionsize = (uint) Constants.RegionSize; // visible region size eg. 256(M) + + uint heightmapWidth = regionsize + 1; // ODE map size 257 x 257 (Meters) (1 extra + uint heightmapHeight = regionsize + 1; + + uint heightmapWidthSamples = (uint)regionsize + 2; // Sample file size, 258 x 258 samples + uint heightmapHeightSamples = (uint)regionsize + 2; + + // Array of height samples for ODE float[] _heightmap; + _heightmap = new float[(heightmapWidthSamples * heightmapHeightSamples)]; // loaded samples 258 x 258 - // zero out a heightmap array float array (single dimension [flattened])) - //if ((int)Constants.RegionSize == 256) - // _heightmap = new float[514 * 514]; - //else - - _heightmap = new float[(((int)Constants.RegionSize + 2) * ((int)Constants.RegionSize + 2))]; - - uint heightmapWidth = Constants.RegionSize + 1; - uint heightmapHeight = Constants.RegionSize + 1; - - uint heightmapWidthSamples; - - uint heightmapHeightSamples; - - //if (((int)Constants.RegionSize) == 256) - //{ - // heightmapWidthSamples = 2 * (uint)Constants.RegionSize + 2; - // heightmapHeightSamples = 2 * (uint)Constants.RegionSize + 2; - // heightmapWidth++; - // heightmapHeight++; - //} - //else - //{ - - heightmapWidthSamples = (uint)Constants.RegionSize + 1; - heightmapHeightSamples = (uint)Constants.RegionSize + 1; - //} - + // Other ODE parameters const float scale = 1.0f; const float offset = 0.0f; - const float thickness = 0.2f; + const float thickness = 2.0f; // Was 0.2f, Larger appears to prevent Av fall-through const int wrap = 0; - int regionsize = (int) Constants.RegionSize + 2; - //Double resolution - //if (((int)Constants.RegionSize) == 256) - // heightMap = ResizeTerrain512Interpolation(heightMap); - - - // if (((int)Constants.RegionSize) == 256 && (int)Constants.RegionSize == 256) - // regionsize = 512; - - float hfmin = 2000; - float hfmax = -2000; + float hfmin = 2000f; + float hfmax = -2000f; + float minele = 0.0f; // Dont allow -ve heights - for (int x = 0; x < heightmapWidthSamples; x++) + uint x = 0; + uint y = 0; + uint xx = 0; + uint yy = 0; + + // load the height samples array from the heightMap + for ( x = 0; x < heightmapWidthSamples; x++) // 0 to 257 + { + for ( y = 0; y < heightmapHeightSamples; y++) // 0 to 257 { - for (int y = 0; y < heightmapHeightSamples; y++) - { - int xx = Util.Clip(x - 1, 0, regionsize - 1); - int yy = Util.Clip(y - 1, 0, regionsize - 1); - - - float val= heightMap[yy * (int)Constants.RegionSize + xx]; - _heightmap[x * ((int)Constants.RegionSize + 2) + y] = val; - - hfmin = (val < hfmin) ? val : hfmin; - hfmax = (val > hfmax) ? val : hfmax; - } + xx = x - 1; + if (xx < 0) xx = 0; + if (xx > (regionsize - 1)) xx = regionsize - 1; + + yy = y - 1; + if (yy < 0) yy = 0; + if (yy > (regionsize - 1)) yy = regionsize - 1; + // Input xx = 0 0 1 2 ..... 254 255 255 256 total in + // Output x = 0 1 2 3 ..... 255 256 257 258 total out + float val= heightMap[(yy * regionsize) + xx]; // input from heightMap, <0-255 * 256> <0-255> + if (val < minele) val = minele; + _heightmap[x * (regionsize + 2) + y] = val; // samples output to _heightmap, <0-257 * 258> <0-257> + hfmin = (val < hfmin) ? val : hfmin; + hfmax = (val > hfmax) ? val : hfmax; } + } - - - lock (OdeLock) { IntPtr GroundGeom = IntPtr.Zero; @@ -3504,19 +3486,17 @@ namespace OpenSim.Region.Physics.OdePlugin d.SpaceRemove(space, GroundGeom); d.GeomDestroy(GroundGeom); } - } IntPtr HeightmapData = d.GeomHeightfieldDataCreate(); - d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth + 1, heightmapHeight + 1, - (int)heightmapWidthSamples + 1, (int)heightmapHeightSamples + 1, scale, - offset, thickness, wrap); + d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, + heightmapWidth, heightmapHeight, (int)heightmapWidthSamples, + (int)heightmapHeightSamples, scale, offset, thickness, wrap); d.GeomHeightfieldDataSetBounds(HeightmapData, hfmin - 1, hfmax + 1); GroundGeom = d.CreateHeightfield(space, HeightmapData, 1); if (GroundGeom != IntPtr.Zero) { d.GeomSetCategoryBits(GroundGeom, (int)(CollisionCategories.Land)); d.GeomSetCollideBits(GroundGeom, (int)(CollisionCategories.Space)); - } geom_name_map[GroundGeom] = "Terrain"; @@ -3534,7 +3514,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle); d.GeomSetRotation(GroundGeom, ref R); - d.GeomSetPosition(GroundGeom, (pOffset.X + ((int)Constants.RegionSize * 0.5f)) - 1, (pOffset.Y + ((int)Constants.RegionSize * 0.5f)) - 1, 0); + d.GeomSetPosition(GroundGeom, (pOffset.X + (regionsize * 0.5f)) - 0.5f, (pOffset.Y + (regionsize * 0.5f)) - 0.5f, 0); IntPtr testGround = IntPtr.Zero; if (RegionTerrain.TryGetValue(pOffset, out testGround)) { @@ -3542,7 +3522,6 @@ namespace OpenSim.Region.Physics.OdePlugin } RegionTerrain.Add(pOffset, GroundGeom, GroundGeom); TerrainHeightFieldHeights.Add(GroundGeom,_heightmap); - } } -- cgit v1.1 From 2fbbc13c71052e66269035031e894b736e2ead5d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 5 Apr 2010 19:42:15 +0100 Subject: Fix some overlooked merge conflicts that got committed --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5951a92..0785f7f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2203,13 +2203,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForTerseUpdate() { -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs lockPartsForRead(true); -======= -// m_log.DebugFormat("[SOG]: Scheduling terse update for {0} {1}", Name, UUID); - - lock (m_parts) ->>>>>>> 0.6.9-post-fixes:OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs { foreach (SceneObjectPart part in m_parts.Values) { @@ -3765,15 +3759,11 @@ namespace OpenSim.Region.Framework.Scenes HasGroupChanged = true; } -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs lockPartsForRead(false); - ScheduleGroupForFullUpdate(); -======= // Don't trigger the update here - otherwise some client issues occur when multiple updates are scheduled // for the same object with very different properties. The caller must schedule the update. //ScheduleGroupForFullUpdate(); ->>>>>>> 0.6.9-post-fixes:OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs } public void TriggerScriptChangedEvent(Changed val) -- cgit v1.1 From f34cc6b46949033803c79235b9d82da9bf9634dd Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Mon, 5 Apr 2010 22:08:34 +0200 Subject: Add a much cheaper agent count retrieval method. This is obsoleted by 0.7 so it can be reverted then. --- OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs | 2 +- .../ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 10 +++++++++- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs index ed18207..dea166d 100644 --- a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs @@ -192,7 +192,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions protected string RegionStats(OSHttpResponse httpResponse, Scene scene) { - int users = scene.GetAvatars().Count; + int users = scene.GetRootAgentCount(); int objects = scene.Entities.Count - users; RestXmlWriter rxw = new RestXmlWriter(new StringWriter()); diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs index 5798286..82e9d9b 100644 --- a/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs +++ b/OpenSim/ApplicationPlugins/Rest/Regions/GETRegionInfoHandler.cs @@ -125,7 +125,7 @@ namespace OpenSim.ApplicationPlugins.Rest.Regions rxw.WriteString(s.RegionInfo.InternalEndPoint.ToString()); rxw.WriteEndAttribute(); - int users = s.GetAvatars().Count; + int users = s.GetRootAgentCount(); rxw.WriteStartAttribute(String.Empty, "avatars", String.Empty); rxw.WriteValue(users); rxw.WriteEndAttribute(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ab0d397..e5e6fc9 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1523,7 +1523,7 @@ namespace OpenSim.Region.Framework.Scenes public void SaveTerrain() { m_storageManager.DataStore.StoreTerrain(Heightmap.GetDoubles(), RegionInfo.RegionID); - } + } public void StoreWindlightProfile(RegionMeta7WindlightData wl) { @@ -4339,6 +4339,14 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Cheaply return the number of avatars in a region (without fetching a list object) + /// + public int GetRootAgentCount() + { + return m_sceneGraph.GetRootAgentCount(); + } + + /// /// Return a list of all ScenePresences in this region. This returns child agents as well as root agents. /// This list is a new object, so it can be iterated over without locking. /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 10ebf67..a76f386 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5266,7 +5266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetRegionAgentCount() { m_host.AddScriptLPS(1); - return new LSL_Integer(World.GetAvatars().Count); + return new LSL_Integer(World.GetRootAgentCount()); } public LSL_Vector llGetRegionCorner() -- cgit v1.1 From 7a3bb266ebc057a1af589fc642bfeca08de72c98 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Mon, 5 Apr 2010 22:11:05 +0200 Subject: This commit adds some randomness to object persistence. It's a Work In Progress, I am working on improving this to a tiered approach. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 46 ++++++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5443c28..9a205e0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -104,8 +104,12 @@ namespace OpenSim.Region.Framework.Scenes /// since the group's last persistent backup /// private bool m_hasGroupChanged = false; - private long timeFirstChanged; - private long timeLastChanged; + private long timeFirstChanged = 0; + private long timeLastChanged = 0; + long m_maxPersistTime = 0; + long m_minPersistTime = 0; + Random m_rand; + private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); public void lockPartsForRead(bool locked) @@ -182,6 +186,28 @@ namespace OpenSim.Region.Framework.Scenes timeLastChanged = DateTime.Now.Ticks; if (!m_hasGroupChanged) timeFirstChanged = DateTime.Now.Ticks; + if (m_rand == null) + { + byte[] val = new byte[16]; + m_rootPart.UUID.ToBytes(val, 0); + m_rand = new Random(BitConverter.ToInt32(val, 0)); + } + if (Scene.GetRootAgentCount() == 0) + { + //If the region is empty, this change has been made by an automated process + //and thus we delay the persist time by a random amount between 1.5 and 2.5. + + float factor = 1.5f + (float)(m_rand.NextDouble()); + m_maxPersistTime = (long)((float)Scene.m_persistAfter * factor); + m_minPersistTime = (long)((float)Scene.m_dontPersistBefore * factor); + } + else + { + //If the region is not empty, we want to obey the minimum and maximum persist times + //but add a random factor so we stagger the object persistance a little + m_maxPersistTime = (long)((float)Scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5 + m_minPersistTime = (long)((float)Scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0 + } } m_hasGroupChanged = value; } @@ -197,8 +223,19 @@ namespace OpenSim.Region.Framework.Scenes return false; if (m_scene.ShuttingDown) return true; + + if (m_minPersistTime == 0 || m_maxPersistTime == 0) + { + m_maxPersistTime = m_scene.m_persistAfter; + m_minPersistTime = m_scene.m_dontPersistBefore; + } + long currentTime = DateTime.Now.Ticks; - if (currentTime - timeLastChanged > m_scene.m_dontPersistBefore || currentTime - timeFirstChanged > m_scene.m_persistAfter) + + if (timeLastChanged == 0) timeLastChanged = currentTime; + if (timeFirstChanged == 0) timeFirstChanged = currentTime; + + if (currentTime - timeLastChanged > m_minPersistTime || currentTime - timeFirstChanged > m_maxPersistTime) return true; return false; } @@ -529,6 +566,7 @@ namespace OpenSim.Region.Framework.Scenes /// public SceneObjectGroup() { + } /// @@ -545,7 +583,7 @@ namespace OpenSim.Region.Framework.Scenes /// Constructor. This object is added to the scene later via AttachToScene() /// public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape) - { + { SetRootPart(new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero)); } -- cgit v1.1 From 5c04d768a69814324521181f37c7da87ba2b4819 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 5 Apr 2010 22:26:18 +0200 Subject: Bump version number --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 58d65d1..d7c2ed0 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.6.8CM"; + private const string VERSION_NUMBER = "0.6.9CM"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour -- cgit v1.1 From a573b5767b42766a6782d549b22cc53f079ecc14 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 5 Apr 2010 22:31:30 +0200 Subject: Test commit --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index d7c2ed0..cf417d7 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -33,7 +33,7 @@ namespace OpenSim private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour - { + { Unknown, Dev, RC1, -- cgit v1.1 From 2f454843d82ce0253af393817cf6f0ebb9046112 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Mon, 5 Apr 2010 23:17:06 +0200 Subject: Fix up my own shoddy code! Fixes prim rez break. Whups! --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 48 ++++++++++++---------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0277ed8..13d1d4e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -106,9 +106,9 @@ namespace OpenSim.Region.Framework.Scenes private bool m_hasGroupChanged = false; private long timeFirstChanged = 0; private long timeLastChanged = 0; - long m_maxPersistTime = 0; - long m_minPersistTime = 0; - Random m_rand; + private long m_maxPersistTime = 0; + private long m_minPersistTime = 0; + private Random m_rand; private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); @@ -186,27 +186,31 @@ namespace OpenSim.Region.Framework.Scenes timeLastChanged = DateTime.Now.Ticks; if (!m_hasGroupChanged) timeFirstChanged = DateTime.Now.Ticks; - if (m_rand == null) + if (m_rootPart != null && m_rootPart.UUID != null && m_scene != null) { - byte[] val = new byte[16]; - m_rootPart.UUID.ToBytes(val, 0); - m_rand = new Random(BitConverter.ToInt32(val, 0)); - } - if (Scene.GetRootAgentCount() == 0) - { - //If the region is empty, this change has been made by an automated process - //and thus we delay the persist time by a random amount between 1.5 and 2.5. + if (m_rand == null) + { + byte[] val = new byte[16]; + m_rootPart.UUID.ToBytes(val, 0); + m_rand = new Random(BitConverter.ToInt32(val, 0)); + } + + if (m_scene.GetRootAgentCount() == 0) + { + //If the region is empty, this change has been made by an automated process + //and thus we delay the persist time by a random amount between 1.5 and 2.5. - float factor = 1.5f + (float)(m_rand.NextDouble()); - m_maxPersistTime = (long)((float)Scene.m_persistAfter * factor); - m_minPersistTime = (long)((float)Scene.m_dontPersistBefore * factor); - } - else - { - //If the region is not empty, we want to obey the minimum and maximum persist times - //but add a random factor so we stagger the object persistance a little - m_maxPersistTime = (long)((float)Scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5 - m_minPersistTime = (long)((float)Scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0 + float factor = 1.5f + (float)(m_rand.NextDouble()); + m_maxPersistTime = (long)((float)m_scene.m_persistAfter * factor); + m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * factor); + } + else + { + //If the region is not empty, we want to obey the minimum and maximum persist times + //but add a random factor so we stagger the object persistance a little + m_maxPersistTime = (long)((float)m_scene.m_persistAfter * (1.0d - (m_rand.NextDouble() / 5.0d))); //Multiply by 1.0-1.5 + m_minPersistTime = (long)((float)m_scene.m_dontPersistBefore * (1.0d + (m_rand.NextDouble() / 2.0d))); //Multiply by 0.8-1.0 + } } } m_hasGroupChanged = value; -- cgit v1.1 From e7be131b8990e5397e13c5049caaafde4c0c447c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 5 Apr 2010 23:20:56 +0200 Subject: Add the ISnmpModule interface definition to Careminster release --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/ISnmpModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs new file mode 100644 index 0000000..9790fc7 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -0,0 +1,11 @@ +/////////////////////////////////////////////////////////////////// +// +// (c) Careminster LImited, Melanie Thielker and the Meta7 Team +// +// This file is not open source. All rights reserved +// +public interface ISnmpModule +{ + void Alert(string message); + void Trap(string message); +} -- cgit v1.1 From 335c1b44206531bc6c0996157884d6873a580527 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 07:48:26 +0200 Subject: Implement PSYS_SRC_INNERANGLE and PSYS_SRC_OUTERANGLE --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a76f386..5be8929 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6195,6 +6195,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api tempf = (float)rules.GetLSLFloatItem(i + 1); prules.OuterAngle = (float)tempf; break; + + case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE: + tempf = (float)rules.GetLSLFloatItem(i + 1); + prules.InnerAngle = (float)tempf; + break; + + case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE: + tempf = (float)rules.GetLSLFloatItem(i + 1); + prules.OuterAngle = (float)tempf; + break; } } -- cgit v1.1 From 20e3de1f0a1434d51cf833b6418e983101438568 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 08:28:57 +0200 Subject: Add CHANGED_REGION_START (alias for CHANGED_REGION_RESTART as per LL Jira SVC-3773) --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index ee35fa4..b3e4740 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -274,6 +274,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int CHANGED_ALLOWED_DROP = 64; public const int CHANGED_OWNER = 128; public const int CHANGED_REGION_RESTART = 256; + public const int CHANGED_REGION_START = 256; //LL Changed the constant from CHANGED_REGION_RESTART public const int CHANGED_REGION = 512; public const int CHANGED_TELEPORT = 1024; public const int CHANGED_ANIMATION = 16384; -- cgit v1.1 From db5ea850f66308038b16c4adcabd9e0d529ec947 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 09:49:11 +0200 Subject: Fix llLookAt so that it doesn't "roll" the object and more closely imitates the behaviour in SL. ( http://bugs.meta7.com/view.php?id=28 ) --- .../Shared/Api/Implementation/LSL_Api.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5be8929..75dd615 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2881,6 +2881,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llLookAt(LSL_Vector target, double strength, double damping) { + /* m_host.AddScriptLPS(1); // Determine where we are looking from LSL_Vector from = llGetPos(); @@ -2900,12 +2901,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // the angles of rotation in radians into rotation value LSL_Types.Quaternion rot = llEuler2Rot(angle); - /* - Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); - m_host.startLookAt(rotation, (float)damping, (float)strength); - This would only work if your physics system contains an APID controller */ + + // This would only work if your physics system contains an APID controller: + // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); + // m_host.startLookAt(rotation, (float)damping, (float)strength); + // Orient the object to the angle calculated llSetRot(rot); + */ + + //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object. + //There's probably a smarter way of doing this, my rotation math-fu is weak. + // http://bugs.meta7.com/view.php?id=28 + // - Tom + + LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d)); + llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos())); + } public void llRotLookAt(LSL_Rotation target, double strength, double damping) -- cgit v1.1 From 309f440fc04cc965e31232947bed698864308356 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 10:13:47 +0200 Subject: Fix llDialog responses so that they can be heard throughout the region. This now conforms to the behaviour in SL. ( http://bugs.meta7.com/view.php?id=13 ) --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index ebcdd62..b0e3655 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -5200,7 +5200,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP args.Channel = ch; args.From = String.Empty; args.Message = Utils.BytesToString(msg); - args.Type = ChatTypeEnum.Shout; + args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance args.Position = new Vector3(); args.Scene = Scene; args.Sender = this; -- cgit v1.1 From e80e04c5fd3892cf3c988baaa00aa8ccfa330256 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 22:59:13 +0200 Subject: Increase the amount of time we wait for a teleport to complete. This allows teleportation to a remote region without a local connection to the asset server without timing out. --- OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 5f84252..04626d3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -1032,7 +1032,7 @@ namespace OpenSim.Region.Framework.Scenes public bool WaitForCallback(UUID id) { - int count = 200; + int count = 400; while (m_agentsInTransit.Contains(id) && count-- > 0) { //m_log.Debug(" >>> Waiting... " + count); -- cgit v1.1 From d834a2c3da1aa97887e087e5a265e73a914c5f7b Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 23:53:08 +0200 Subject: Implement cmGetAvatarList(). This returns a strided list of all avatars in the region, including their UUID, position and name. The radar is often the most taxing scripts on a sim, this function can help radars reduce their impact by 66% by eliminating the need for sensors. --- .../Shared/Api/Implementation/CM_Api.cs | 130 ++++++++++++--------- .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 3 +- .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 14 ++- 3 files changed, 87 insertions(+), 60 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 99973b4..9f829da 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -86,6 +86,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } /// + /// Like osGetAgents but returns enough info for a radar + /// + /// Strided list of the UUID, position and name of each avatar in the region + public LSL_List cmGetAvatarList() + { + LSL_List result = new LSL_List(); + foreach (ScenePresence avatar in World.GetAvatars()) + { + if (avatar.UUID != m_host.OwnerID) + { + if (avatar.IsChildAgent == false) + { + result.Add(avatar.UUID); + result.Add(avatar.PhysicsActor.Position); + result.Add(avatar.Name); + } + } + } + return result; + } + + /// /// Get the current Windlight scene /// /// List of windlight parameters @@ -229,10 +251,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return values; - } - + } + private RegionMeta7WindlightData getWindlightProfileFromRules(LSL_List rules) - { + { RegionMeta7WindlightData wl = (RegionMeta7WindlightData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); LSL_List values = new LSL_List(); @@ -244,9 +266,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Types.Vector3 iV; switch (rule) { - case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: - idx++; - wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); + case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: + idx++; + wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); break; case (int)ScriptBaseClass.WL_AMBIENT: idx++; @@ -419,58 +441,58 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { CMShoutError("Careminster functions are not enabled."); return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - CMShoutError("cmSetWindlightScene can only be used by estate managers or owners."); - return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + CMShoutError("cmSetWindlightScene can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (Meta7WindlightModule.EnableWindlight) + { + RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + success = 1; + } + else + { + CMShoutError("Windlight module is disabled"); + return 0; + } + return success; + } + /// + /// Set the current Windlight scene to a target avatar + /// + /// + /// success: true or false + public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) + { + if (!m_CMFunctionsEnabled) + { + CMShoutError("Careminster functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners."); + return 0; } int success = 0; - m_host.AddScriptLPS(1); - if (Meta7WindlightModule.EnableWindlight) - { - RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; - } - else - { - CMShoutError("Windlight module is disabled"); - return 0; + m_host.AddScriptLPS(1); + if (Meta7WindlightModule.EnableWindlight) + { + RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); + World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); + success = 1; + } + else + { + CMShoutError("Windlight module is disabled"); + return 0; } return success; - } - /// - /// Set the current Windlight scene to a target avatar - /// - /// - /// success: true or false - public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) - { - if (!m_CMFunctionsEnabled) - { - CMShoutError("Careminster functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (Meta7WindlightModule.EnableWindlight) - { - RegionMeta7WindlightData wl = getWindlightProfileFromRules(rules); - World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); - success = 1; - } - else - { - CMShoutError("Windlight module is disabled"); - return 0; - } - return success; } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs index ef990a1..6239726 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs @@ -15,7 +15,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { // Windlight Functions LSL_List cmGetWindlightScene(LSL_List rules); - int cmSetWindlightScene(LSL_List rules); + int cmSetWindlightScene(LSL_List rules); int cmSetWindlightSceneTargeted(LSL_List rules, key target); + LSL_List cmGetAvatarList(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs index 5bc3a88..aaffbe4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs @@ -66,11 +66,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public int cmSetWindlightScene(LSL_List rules) { return m_CM_Functions.cmSetWindlightScene(rules); - } - - public int cmSetWindlightSceneTargeted(LSL_List rules, key target) - { - return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target); + } + + public int cmSetWindlightSceneTargeted(LSL_List rules, key target) + { + return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target); + } + public LSL_List cmGetAvatarList() + { + return m_CM_Functions.cmGetAvatarList(); } } } -- cgit v1.1 From 0f3314c04ccd07e0ff9b5be69903b0a72dd73115 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:00:01 -0700 Subject: Backported GetTextureModule and IAssetService.GetCached() --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 7 +- .../Region/CoreModules/Asset/FlotsamAssetCache.cs | 5 + .../CoreModules/Avatar/Assets/GetTextureModule.cs | 220 +++++++++++++++++++++ .../ServiceConnectorsOut/Asset/HGAssetBroker.cs | 8 + .../Asset/LocalAssetServiceConnector.cs | 8 + OpenSim/Services/AssetService/AssetService.cs | 5 + .../Connectors/Asset/AssetServiceConnector.cs | 8 + .../Connectors/Asset/HGAssetServiceConnector.cs | 14 ++ OpenSim/Services/Interfaces/IAssetService.cs | 10 +- OpenSim/Tests/Common/Mock/MockAssetService.cs | 5 + 10 files changed, 287 insertions(+), 3 deletions(-) create mode 100644 OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 2ca2657..8b81377 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -11228,9 +11228,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_groupPowers.Clear(); - for (int i = 0; i < GroupMembership.Length; i++) + if (GroupMembership != null) { - m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; + for (int i = 0; i < GroupMembership.Length; i++) + { + m_groupPowers[GroupMembership[i].GroupID] = GroupMembership[i].GroupPowers; + } } } } diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 967c0a1..dd796da 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -406,6 +406,11 @@ namespace Flotsam.RegionModules.AssetCache return asset; } + public AssetBase GetCached(string id) + { + return Get(id); + } + public void Expire(string id) { if (m_LogLevel >= 2) diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs new file mode 100644 index 0000000..53d2cef --- /dev/null +++ b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs @@ -0,0 +1,220 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Reflection; +using System.IO; +using System.Web; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using Caps = OpenSim.Framework.Capabilities.Caps; + +namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps +{ + #region Stream Handler + + public delegate byte[] StreamHandlerCallback(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse); + + public class StreamHandler : BaseStreamHandler + { + StreamHandlerCallback m_callback; + + public StreamHandler(string httpMethod, string path, StreamHandlerCallback callback) + : base(httpMethod, path) + { + m_callback = callback; + } + + public override byte[] Handle(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + return m_callback(path, request, httpRequest, httpResponse); + } + } + + #endregion Stream Handler + + public class GetTextureModule : IRegionModule + { + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private Scene m_scene; + private IAssetService m_assetService; + + #region IRegionModule Members + + public void Initialise(Scene pScene, IConfigSource pSource) + { + m_scene = pScene; + } + + public void PostInitialise() + { + m_assetService = m_scene.RequestModuleInterface(); + m_scene.EventManager.OnRegisterCaps += RegisterCaps; + } + + public void Close() { } + + public string Name { get { return "GetTextureModule"; } } + public bool IsSharedModule { get { return false; } } + + public void RegisterCaps(UUID agentID, Caps caps) + { + UUID capID = UUID.Random(); + + m_log.Info("[GETTEXTURE]: /CAPS/" + capID); + caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture)); + } + + #endregion + + private byte[] ProcessGetTexture(string path, Stream request, OSHttpRequest httpRequest, OSHttpResponse httpResponse) + { + // TODO: Change this to a config option + const string REDIRECT_URL = null; + + // Try to parse the texture ID from the request URL + NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); + string textureStr = query.GetOne("texture_id"); + + if (m_assetService == null) + { + m_log.Error("[GETTEXTURE]: Cannot fetch texture " + textureStr + " without an asset service"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + return null; + } + + UUID textureID; + if (!String.IsNullOrEmpty(textureStr) && UUID.TryParse(textureStr, out textureID)) + { + AssetBase texture; + + if (!String.IsNullOrEmpty(REDIRECT_URL)) + { + // Only try to fetch locally cached textures. Misses are redirected + texture = m_assetService.GetCached(textureID.ToString()); + + if (texture != null) + { + SendTexture(httpRequest, httpResponse, texture); + } + else + { + string textureUrl = REDIRECT_URL + textureID.ToString(); + m_log.Debug("[GETTEXTURE]: Redirecting texture request to " + textureUrl); + httpResponse.RedirectLocation = textureUrl; + } + } + else + { + // Fetch locally or remotely. Misses return a 404 + texture = m_assetService.Get(textureID.ToString()); + + if (texture != null) + { + SendTexture(httpRequest, httpResponse, texture); + } + else + { + m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + } + } + } + else + { + m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); + } + + httpResponse.Send(); + return null; + } + + private void SendTexture(OSHttpRequest request, OSHttpResponse response, AssetBase texture) + { + string range = request.Headers.GetOne("Range"); + if (!String.IsNullOrEmpty(range)) + { + // Range request + int start, end; + if (TryParseRange(range, out start, out end)) + { + end = Utils.Clamp(end, 1, texture.Data.Length); + start = Utils.Clamp(start, 0, end - 1); + + m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); + + if (end - start < texture.Data.Length) + response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; + + response.ContentLength = end - start; + response.ContentType = texture.Metadata.ContentType; + + response.Body.Write(texture.Data, start, end - start); + } + else + { + m_log.Warn("Malformed Range header: " + range); + response.StatusCode = (int)System.Net.HttpStatusCode.BadRequest; + } + } + else + { + // Full content request + response.ContentLength = texture.Data.Length; + response.ContentType = texture.Metadata.ContentType; + response.Body.Write(texture.Data, 0, texture.Data.Length); + } + } + + private bool TryParseRange(string header, out int start, out int end) + { + if (header.StartsWith("bytes=")) + { + string[] rangeValues = header.Substring(6).Split('-'); + if (rangeValues.Length == 2) + { + if (Int32.TryParse(rangeValues[0], out start) && Int32.TryParse(rangeValues[1], out end)) + return true; + } + } + + start = end = 0; + return false; + } + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 0aa753d..0522256 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs @@ -229,6 +229,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset return asset; } + public AssetBase GetCached(string id) + { + if (m_Cache != null) + return m_Cache.Get(id); + + return null; + } + public AssetMetadata GetMetadata(string id) { AssetBase asset = null; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs index 50348da..1b3419d 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/LocalAssetServiceConnector.cs @@ -165,6 +165,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset return asset; } + public AssetBase GetCached(string id) + { + if (m_Cache != null) + return m_Cache.Get(id); + + return null; + } + public AssetMetadata GetMetadata(string id) { AssetBase asset = null; diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index b9723a8..ed87f3f 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -93,6 +93,11 @@ namespace OpenSim.Services.AssetService return m_Database.GetAsset(assetID); } + public AssetBase GetCached(string id) + { + return Get(id); + } + public AssetMetadata GetMetadata(string id) { UUID assetID; diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index 8e311d7..84fbcd3 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -111,6 +111,14 @@ namespace OpenSim.Services.Connectors return asset; } + public AssetBase GetCached(string id) + { + if (m_Cache != null) + return m_Cache.Get(id); + + return null; + } + public AssetMetadata GetMetadata(string id) { if (m_Cache != null) diff --git a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs index 677169d..34df54a 100644 --- a/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/HGAssetServiceConnector.cs @@ -116,6 +116,20 @@ namespace OpenSim.Services.Connectors return null; } + public AssetBase GetCached(string id) + { + string url = string.Empty; + string assetID = string.Empty; + + if (StringToUrlAndAssetID(id, out url, out assetID)) + { + IAssetService connector = GetConnector(url); + return connector.GetCached(assetID); + } + + return null; + } + public AssetMetadata GetMetadata(string id) { string url = string.Empty; diff --git a/OpenSim/Services/Interfaces/IAssetService.cs b/OpenSim/Services/Interfaces/IAssetService.cs index 6dfe78d..3be6815 100644 --- a/OpenSim/Services/Interfaces/IAssetService.cs +++ b/OpenSim/Services/Interfaces/IAssetService.cs @@ -51,7 +51,15 @@ namespace OpenSim.Services.Interfaces byte[] GetData(string id); /// - /// Get an asset asynchronously + /// Synchronously fetches an asset from the local cache only + /// + /// Asset ID + /// The fetched asset, or null if it did not exist in the local cache + AssetBase GetCached(string id); + + /// + /// Get an asset synchronously or asynchronously (depending on whether + /// it is locally cached) and fire a callback with the fetched asset /// /// The asset id /// Represents the requester. Passed back via the handler diff --git a/OpenSim/Tests/Common/Mock/MockAssetService.cs b/OpenSim/Tests/Common/Mock/MockAssetService.cs index cb38043..4118308 100644 --- a/OpenSim/Tests/Common/Mock/MockAssetService.cs +++ b/OpenSim/Tests/Common/Mock/MockAssetService.cs @@ -65,6 +65,11 @@ namespace OpenSim.Tests.Common.Mock return asset; } + public AssetBase GetCached(string id) + { + return Get(id); + } + public AssetMetadata GetMetadata(string id) { throw new System.NotImplementedException(); -- cgit v1.1 From c4c4c3696edbe99496ad7e6db9b3eb0b339f09c5 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:26:51 -0700 Subject: Backported WebUtil.cs from master to 0.6.9-postfixes to fix the build break --- OpenSim/Framework/WebUtil.cs | 361 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 OpenSim/Framework/WebUtil.cs (limited to 'OpenSim') diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs new file mode 100644 index 0000000..2843e20 --- /dev/null +++ b/OpenSim/Framework/WebUtil.cs @@ -0,0 +1,361 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Reflection; +using System.Text; +using System.Web; +using log4net; +using OpenSim.Framework.Servers.HttpServer; +using OpenMetaverse.StructuredData; + +namespace OpenSim.Framework +{ + /// + /// Miscellaneous static methods and extension methods related to the web + /// + public static class WebUtil + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + /// + /// Send LLSD to an HTTP client in application/llsd+json form + /// + /// HTTP response to send the data in + /// LLSD to send to the client + public static void SendJSONResponse(OSHttpResponse response, OSDMap body) + { + byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body)); + + response.ContentEncoding = Encoding.UTF8; + response.ContentLength = responseData.Length; + response.ContentType = "application/llsd+json"; + response.Body.Write(responseData, 0, responseData.Length); + } + + /// + /// Send LLSD to an HTTP client in application/llsd+xml form + /// + /// HTTP response to send the data in + /// LLSD to send to the client + public static void SendXMLResponse(OSHttpResponse response, OSDMap body) + { + byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body); + + response.ContentEncoding = Encoding.UTF8; + response.ContentLength = responseData.Length; + response.ContentType = "application/llsd+xml"; + response.Body.Write(responseData, 0, responseData.Length); + } + + /// + /// Make a GET or GET-like request to a web service that returns LLSD + /// or JSON data + /// + public static OSDMap ServiceRequest(string url, string httpVerb) + { + string errorMessage; + + try + { + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); + request.Method = httpVerb; + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + { + try + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + return (OSDMap)responseOSD; + else + errorMessage = "Response format was invalid."; + } + catch + { + errorMessage = "Failed to parse the response."; + } + } + } + } + catch (Exception ex) + { + m_log.Warn("GET from URL " + url + " failed: " + ex.Message); + errorMessage = ex.Message; + } + + return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; + } + + /// + /// POST URL-encoded form data to a web service that returns LLSD or + /// JSON data + /// + public static OSDMap PostToService(string url, NameValueCollection data) + { + string errorMessage; + + try + { + string queryString = BuildQueryString(data); + byte[] requestData = System.Text.Encoding.UTF8.GetBytes(queryString); + + HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); + request.Method = "POST"; + request.ContentLength = requestData.Length; + request.ContentType = "application/x-www-form-urlencoded"; + + using (Stream requestStream = request.GetRequestStream()) + requestStream.Write(requestData, 0, requestData.Length); + + using (WebResponse response = request.GetResponse()) + { + using (Stream responseStream = response.GetResponseStream()) + { + try + { + string responseStr = responseStream.GetStreamString(); + OSD responseOSD = OSDParser.Deserialize(responseStr); + if (responseOSD.Type == OSDType.Map) + return (OSDMap)responseOSD; + else + errorMessage = "Response format was invalid."; + } + catch + { + errorMessage = "Failed to parse the response."; + } + } + } + } + catch (Exception ex) + { + m_log.Warn("POST to URL " + url + " failed: " + ex.Message); + errorMessage = ex.Message; + } + + return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; + } + + #region Uri + + /// + /// Combines a Uri that can contain both a base Uri and relative path + /// with a second relative path fragment + /// + /// Starting (base) Uri + /// Relative path fragment to append to the end + /// of the Uri + /// The combined Uri + /// This is similar to the Uri constructor that takes a base + /// Uri and the relative path, except this method can append a relative + /// path fragment on to an existing relative path + public static Uri Combine(this Uri uri, string fragment) + { + string fragment1 = uri.Fragment; + string fragment2 = fragment; + + if (!fragment1.EndsWith("/")) + fragment1 = fragment1 + '/'; + if (fragment2.StartsWith("/")) + fragment2 = fragment2.Substring(1); + + return new Uri(uri, fragment1 + fragment2); + } + + /// + /// Combines a Uri that can contain both a base Uri and relative path + /// with a second relative path fragment. If the fragment is absolute, + /// it will be returned without modification + /// + /// Starting (base) Uri + /// Relative path fragment to append to the end + /// of the Uri, or an absolute Uri to return unmodified + /// The combined Uri + public static Uri Combine(this Uri uri, Uri fragment) + { + if (fragment.IsAbsoluteUri) + return fragment; + + string fragment1 = uri.Fragment; + string fragment2 = fragment.ToString(); + + if (!fragment1.EndsWith("/")) + fragment1 = fragment1 + '/'; + if (fragment2.StartsWith("/")) + fragment2 = fragment2.Substring(1); + + return new Uri(uri, fragment1 + fragment2); + } + + /// + /// Appends a query string to a Uri that may or may not have existing + /// query parameters + /// + /// Uri to append the query to + /// Query string to append. Can either start with ? + /// or just containg key/value pairs + /// String representation of the Uri with the query string + /// appended + public static string AppendQuery(this Uri uri, string query) + { + if (String.IsNullOrEmpty(query)) + return uri.ToString(); + + if (query[0] == '?' || query[0] == '&') + query = query.Substring(1); + + string uriStr = uri.ToString(); + + if (uriStr.Contains("?")) + return uriStr + '&' + query; + else + return uriStr + '?' + query; + } + + #endregion Uri + + #region NameValueCollection + + /// + /// Convert a NameValueCollection into a query string. This is the + /// inverse of HttpUtility.ParseQueryString() + /// + /// Collection of key/value pairs to convert + /// A query string with URL-escaped values + public static string BuildQueryString(NameValueCollection parameters) + { + List items = new List(parameters.Count); + + foreach (string key in parameters.Keys) + { + string[] values = parameters.GetValues(key); + if (values != null) + { + foreach (string value in values) + items.Add(String.Concat(key, "=", HttpUtility.UrlEncode(value ?? String.Empty))); + } + } + + return String.Join("&", items.ToArray()); + } + + /// + /// + /// + /// + /// + /// + public static string GetOne(this NameValueCollection collection, string key) + { + string[] values = collection.GetValues(key); + if (values != null && values.Length > 0) + return values[0]; + + return null; + } + + #endregion NameValueCollection + + #region Stream + + /// + /// Copies the contents of one stream to another, starting at the + /// current position of each stream + /// + /// The stream to copy from, at the position + /// where copying should begin + /// The stream to copy to, at the position where + /// bytes should be written + /// The maximum bytes to copy + /// The total number of bytes copied + /// + /// Copying begins at the streams' current positions. The positions are + /// NOT reset after copying is complete. + /// + public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) + { + byte[] buffer = new byte[4096]; + int readBytes; + int totalCopiedBytes = 0; + + while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(4096, maximumBytesToCopy))) > 0) + { + int writeBytes = Math.Min(maximumBytesToCopy, readBytes); + copyTo.Write(buffer, 0, writeBytes); + totalCopiedBytes += writeBytes; + maximumBytesToCopy -= writeBytes; + } + + return totalCopiedBytes; + } + + /// + /// Converts an entire stream to a string, regardless of current stream + /// position + /// + /// The stream to convert to a string + /// + /// When this method is done, the stream position will be + /// reset to its previous position before this method was called + public static string GetStreamString(this Stream stream) + { + string value = null; + + if (stream != null && stream.CanRead) + { + long rewindPos = -1; + + if (stream.CanSeek) + { + rewindPos = stream.Position; + stream.Seek(0, SeekOrigin.Begin); + } + + StreamReader reader = new StreamReader(stream); + value = reader.ReadToEnd(); + + if (rewindPos >= 0) + stream.Seek(rewindPos, SeekOrigin.Begin); + } + + return value; + } + + #endregion Stream + } +} -- cgit v1.1 From 54cedfe4320573ac302b11716e293086110a4f9b Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:57:00 -0700 Subject: Changed the GetTextureModule backport to work with the 0.6.9 codebase --- OpenSim/Framework/WebUtil.cs | 361 --------------------- .../CoreModules/Avatar/Assets/GetTextureModule.cs | 13 +- 2 files changed, 11 insertions(+), 363 deletions(-) delete mode 100644 OpenSim/Framework/WebUtil.cs (limited to 'OpenSim') diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs deleted file mode 100644 index 2843e20..0000000 --- a/OpenSim/Framework/WebUtil.cs +++ /dev/null @@ -1,361 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; -using System.Net; -using System.Net.Security; -using System.Reflection; -using System.Text; -using System.Web; -using log4net; -using OpenSim.Framework.Servers.HttpServer; -using OpenMetaverse.StructuredData; - -namespace OpenSim.Framework -{ - /// - /// Miscellaneous static methods and extension methods related to the web - /// - public static class WebUtil - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - /// - /// Send LLSD to an HTTP client in application/llsd+json form - /// - /// HTTP response to send the data in - /// LLSD to send to the client - public static void SendJSONResponse(OSHttpResponse response, OSDMap body) - { - byte[] responseData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(body)); - - response.ContentEncoding = Encoding.UTF8; - response.ContentLength = responseData.Length; - response.ContentType = "application/llsd+json"; - response.Body.Write(responseData, 0, responseData.Length); - } - - /// - /// Send LLSD to an HTTP client in application/llsd+xml form - /// - /// HTTP response to send the data in - /// LLSD to send to the client - public static void SendXMLResponse(OSHttpResponse response, OSDMap body) - { - byte[] responseData = OSDParser.SerializeLLSDXmlBytes(body); - - response.ContentEncoding = Encoding.UTF8; - response.ContentLength = responseData.Length; - response.ContentType = "application/llsd+xml"; - response.Body.Write(responseData, 0, responseData.Length); - } - - /// - /// Make a GET or GET-like request to a web service that returns LLSD - /// or JSON data - /// - public static OSDMap ServiceRequest(string url, string httpVerb) - { - string errorMessage; - - try - { - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); - request.Method = httpVerb; - - using (WebResponse response = request.GetResponse()) - { - using (Stream responseStream = response.GetResponseStream()) - { - try - { - string responseStr = responseStream.GetStreamString(); - OSD responseOSD = OSDParser.Deserialize(responseStr); - if (responseOSD.Type == OSDType.Map) - return (OSDMap)responseOSD; - else - errorMessage = "Response format was invalid."; - } - catch - { - errorMessage = "Failed to parse the response."; - } - } - } - } - catch (Exception ex) - { - m_log.Warn("GET from URL " + url + " failed: " + ex.Message); - errorMessage = ex.Message; - } - - return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; - } - - /// - /// POST URL-encoded form data to a web service that returns LLSD or - /// JSON data - /// - public static OSDMap PostToService(string url, NameValueCollection data) - { - string errorMessage; - - try - { - string queryString = BuildQueryString(data); - byte[] requestData = System.Text.Encoding.UTF8.GetBytes(queryString); - - HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); - request.Method = "POST"; - request.ContentLength = requestData.Length; - request.ContentType = "application/x-www-form-urlencoded"; - - using (Stream requestStream = request.GetRequestStream()) - requestStream.Write(requestData, 0, requestData.Length); - - using (WebResponse response = request.GetResponse()) - { - using (Stream responseStream = response.GetResponseStream()) - { - try - { - string responseStr = responseStream.GetStreamString(); - OSD responseOSD = OSDParser.Deserialize(responseStr); - if (responseOSD.Type == OSDType.Map) - return (OSDMap)responseOSD; - else - errorMessage = "Response format was invalid."; - } - catch - { - errorMessage = "Failed to parse the response."; - } - } - } - } - catch (Exception ex) - { - m_log.Warn("POST to URL " + url + " failed: " + ex.Message); - errorMessage = ex.Message; - } - - return new OSDMap { { "Message", OSD.FromString("Service request failed. " + errorMessage) } }; - } - - #region Uri - - /// - /// Combines a Uri that can contain both a base Uri and relative path - /// with a second relative path fragment - /// - /// Starting (base) Uri - /// Relative path fragment to append to the end - /// of the Uri - /// The combined Uri - /// This is similar to the Uri constructor that takes a base - /// Uri and the relative path, except this method can append a relative - /// path fragment on to an existing relative path - public static Uri Combine(this Uri uri, string fragment) - { - string fragment1 = uri.Fragment; - string fragment2 = fragment; - - if (!fragment1.EndsWith("/")) - fragment1 = fragment1 + '/'; - if (fragment2.StartsWith("/")) - fragment2 = fragment2.Substring(1); - - return new Uri(uri, fragment1 + fragment2); - } - - /// - /// Combines a Uri that can contain both a base Uri and relative path - /// with a second relative path fragment. If the fragment is absolute, - /// it will be returned without modification - /// - /// Starting (base) Uri - /// Relative path fragment to append to the end - /// of the Uri, or an absolute Uri to return unmodified - /// The combined Uri - public static Uri Combine(this Uri uri, Uri fragment) - { - if (fragment.IsAbsoluteUri) - return fragment; - - string fragment1 = uri.Fragment; - string fragment2 = fragment.ToString(); - - if (!fragment1.EndsWith("/")) - fragment1 = fragment1 + '/'; - if (fragment2.StartsWith("/")) - fragment2 = fragment2.Substring(1); - - return new Uri(uri, fragment1 + fragment2); - } - - /// - /// Appends a query string to a Uri that may or may not have existing - /// query parameters - /// - /// Uri to append the query to - /// Query string to append. Can either start with ? - /// or just containg key/value pairs - /// String representation of the Uri with the query string - /// appended - public static string AppendQuery(this Uri uri, string query) - { - if (String.IsNullOrEmpty(query)) - return uri.ToString(); - - if (query[0] == '?' || query[0] == '&') - query = query.Substring(1); - - string uriStr = uri.ToString(); - - if (uriStr.Contains("?")) - return uriStr + '&' + query; - else - return uriStr + '?' + query; - } - - #endregion Uri - - #region NameValueCollection - - /// - /// Convert a NameValueCollection into a query string. This is the - /// inverse of HttpUtility.ParseQueryString() - /// - /// Collection of key/value pairs to convert - /// A query string with URL-escaped values - public static string BuildQueryString(NameValueCollection parameters) - { - List items = new List(parameters.Count); - - foreach (string key in parameters.Keys) - { - string[] values = parameters.GetValues(key); - if (values != null) - { - foreach (string value in values) - items.Add(String.Concat(key, "=", HttpUtility.UrlEncode(value ?? String.Empty))); - } - } - - return String.Join("&", items.ToArray()); - } - - /// - /// - /// - /// - /// - /// - public static string GetOne(this NameValueCollection collection, string key) - { - string[] values = collection.GetValues(key); - if (values != null && values.Length > 0) - return values[0]; - - return null; - } - - #endregion NameValueCollection - - #region Stream - - /// - /// Copies the contents of one stream to another, starting at the - /// current position of each stream - /// - /// The stream to copy from, at the position - /// where copying should begin - /// The stream to copy to, at the position where - /// bytes should be written - /// The maximum bytes to copy - /// The total number of bytes copied - /// - /// Copying begins at the streams' current positions. The positions are - /// NOT reset after copying is complete. - /// - public static int CopyTo(this Stream copyFrom, Stream copyTo, int maximumBytesToCopy) - { - byte[] buffer = new byte[4096]; - int readBytes; - int totalCopiedBytes = 0; - - while ((readBytes = copyFrom.Read(buffer, 0, Math.Min(4096, maximumBytesToCopy))) > 0) - { - int writeBytes = Math.Min(maximumBytesToCopy, readBytes); - copyTo.Write(buffer, 0, writeBytes); - totalCopiedBytes += writeBytes; - maximumBytesToCopy -= writeBytes; - } - - return totalCopiedBytes; - } - - /// - /// Converts an entire stream to a string, regardless of current stream - /// position - /// - /// The stream to convert to a string - /// - /// When this method is done, the stream position will be - /// reset to its previous position before this method was called - public static string GetStreamString(this Stream stream) - { - string value = null; - - if (stream != null && stream.CanRead) - { - long rewindPos = -1; - - if (stream.CanSeek) - { - rewindPos = stream.Position; - stream.Seek(0, SeekOrigin.Begin); - } - - StreamReader reader = new StreamReader(stream); - value = reader.ReadToEnd(); - - if (rewindPos >= 0) - stream.Seek(rewindPos, SeekOrigin.Begin); - } - - return value; - } - - #endregion Stream - } -} diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs index 53d2cef..3b66859 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps // Try to parse the texture ID from the request URL NameValueCollection query = HttpUtility.ParseQueryString(httpRequest.Url.Query); - string textureStr = query.GetOne("texture_id"); + string textureStr = GetOne(query, "texture_id"); if (m_assetService == null) { @@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps private void SendTexture(OSHttpRequest request, OSHttpResponse response, AssetBase texture) { - string range = request.Headers.GetOne("Range"); + string range = GetOne(request.Headers, "Range"); if (!String.IsNullOrEmpty(range)) { // Range request @@ -216,5 +216,14 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps start = end = 0; return false; } + + private static string GetOne(NameValueCollection collection, string key) + { + string[] values = collection.GetValues(key); + if (values != null && values.Length > 0) + return values[0]; + + return null; + } } } -- cgit v1.1 From 7701ea27983be851a3c9d3954346018e07680ae6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 9 Apr 2010 06:49:14 +0100 Subject: Add Scene.SnmpService, which is of type ISnmpModule and, if nun-null, can be used to send snmp alerts --- OpenSim/Region/Framework/Scenes/Scene.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 55f4550..db073e8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -158,6 +158,20 @@ namespace OpenSim.Region.Framework.Scenes public IXfer XferManager; + protected ISnmpModule m_snmpService = null; + public ISnmpModule SnmpService + { + get + { + if (m_snmpService == null) + { + m_snmpService = RequestModuleInterface(); + } + + return m_snmpService; + } + } + protected IAssetService m_AssetService; protected IAuthorizationService m_AuthorizationService; -- cgit v1.1 From d975bd8e5c937314bbcd5c3b66a48f87057358d0 Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 17:51:51 +0200 Subject: Fixing Trap --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 OpenSim/Region/Framework/Interfaces/ISnmpModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs deleted file mode 100644 index 9790fc7..0000000 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ /dev/null @@ -1,11 +0,0 @@ -/////////////////////////////////////////////////////////////////// -// -// (c) Careminster LImited, Melanie Thielker and the Meta7 Team -// -// This file is not open source. All rights reserved -// -public interface ISnmpModule -{ - void Alert(string message); - void Trap(string message); -} -- cgit v1.1 From c4eaf195b53be3f19fe25bd7ac4a41bd002bbc8d Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 17:59:08 +0200 Subject: dding this deleted file... --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index 9790fc7..cdd1bd8 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -3,9 +3,9 @@ // (c) Careminster LImited, Melanie Thielker and the Meta7 Team // // This file is not open source. All rights reserved -// +// Mod 2 public interface ISnmpModule { void Alert(string message); - void Trap(string message); + void Trap(int code,string simname,string Message); } -- cgit v1.1 From 58dac970afb09bc003c7089f35fe592516fb209e Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 18:05:08 +0200 Subject: re-fixing this darn file --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/ISnmpModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs new file mode 100644 index 0000000..4e03df5 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -0,0 +1,11 @@ +/////////////////////////////////////////////////////////////////// +// +// (c) Careminster LImited, Melanie Thielker and the Meta7 Team +// +// This file is not open source. All rights reserved +// +public interface ISnmpModule +{ + void Alert(string message); + void Trap(int code,string simname,string Message); +} -- cgit v1.1 From 0b2b2daf23dbf7a51f3d568903548cd964334ce2 Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Sat, 10 Apr 2010 14:43:26 -0400 Subject: guarantee that a script engine's GetScriptErrors() will not be called until after its OnRezScript() returns so that script compile error messages can be retrieved --- .../Framework/Interfaces/IEntityInventory.cs | 4 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 3 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 76 +++++++++++++++++++--- 3 files changed, 71 insertions(+), 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index f58904f..16ca3f9 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -73,8 +73,6 @@ namespace OpenSim.Region.Framework.Interfaces /// void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); - ArrayList GetScriptErrors(UUID itemID); - /// /// Stop all the scripts in this entity. /// @@ -104,6 +102,8 @@ namespace OpenSim.Region.Framework.Interfaces /// void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); + ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource); + /// /// Stop a script which is in this prim's inventory. /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b04871e..6c57d18 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -271,8 +271,7 @@ namespace OpenSim.Region.Framework.Scenes { // Needs to determine which engine was running it and use that // - part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); - errors = part.Inventory.GetScriptErrors(item.ItemID); + errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 0); } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 5d00917..d03b464 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -46,6 +46,8 @@ namespace OpenSim.Region.Framework.Scenes private string m_inventoryFileName = String.Empty; private int m_inventoryFileNameSerial = 0; + + private Dictionary m_scriptErrors = new Dictionary(); /// /// The part to which the inventory belongs. @@ -211,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes } } - public ArrayList GetScriptErrors(UUID itemID) + private ArrayList GetScriptErrors(UUID itemID) { ArrayList ret = new ArrayList(); @@ -270,7 +272,10 @@ namespace OpenSim.Region.Framework.Scenes // item.Name, item.ItemID, Name, UUID); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) + { + StoreScriptError(item.ItemID, "no permission"); return; + } m_part.AddFlag(PrimFlags.Scripted); @@ -285,6 +290,7 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForWrite(false); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); + StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); return; @@ -294,11 +300,13 @@ namespace OpenSim.Region.Framework.Scenes { if (null == asset) { + string msg = String.Format("asset ID {0} could not be found", item.AssetID); + StoreScriptError(item.ItemID, msg); m_log.ErrorFormat( "[PRIM INVENTORY]: " + - "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", + "Couldn't start script {0}, {1} at {2} in {3} since {4}", item.Name, item.ItemID, m_part.AbsolutePosition, - m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); + m_part.ParentGroup.Scene.RegionInfo.RegionName, msg); } else { @@ -311,11 +319,16 @@ namespace OpenSim.Region.Framework.Scenes string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); + StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); } }); } + else + { + StoreScriptError(item.ItemID, "scripts disabled"); + } } private void RestoreSavedScriptState(UUID oldID, UUID newID) @@ -392,24 +405,71 @@ namespace OpenSim.Region.Framework.Scenes else { m_items.LockItemsForRead(false); + string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, + m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + StoreScriptError(itemId, msg); m_log.ErrorFormat( "[PRIM INVENTORY]: " + - "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", - itemId, m_part.Name, m_part.UUID, - m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); + "Couldn't start script with ID {0} since it {1}", itemId, msg); } } else { m_items.LockItemsForRead(false); + string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); + StoreScriptError(itemId, msg); m_log.ErrorFormat( "[PRIM INVENTORY]: " + - "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}", - itemId, m_part.Name, m_part.UUID); + "Couldn't start script with ID {0} since it {1}", itemId, msg); } } + public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) + { + ArrayList errors; + + lock (m_scriptErrors) + { + m_scriptErrors.Remove(itemId); + } + CreateScriptInstance(itemId, startParam, postOnRez, engine, stateSource); + lock (m_scriptErrors) + { + while (!m_scriptErrors.TryGetValue(itemId, out errors)) + { + if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) + { + m_log.ErrorFormat( + "[PRIM INVENTORY]: " + + "timedout waiting for script {0} errors", itemId); + if (!m_scriptErrors.TryGetValue(itemId, out errors)) + { + errors = new ArrayList(1); + errors.Add("timedout waiting for errors"); + } + break; + } + } + m_scriptErrors.Remove(itemId); + } + return errors; + } + private void StoreScriptErrors(UUID itemId, ArrayList errors) + { + lock (m_scriptErrors) + { + m_scriptErrors[itemId] = errors; + System.Threading.Monitor.PulseAll(m_scriptErrors); + } + } + private void StoreScriptError(UUID itemId, string message) + { + ArrayList errors = new ArrayList(1); + errors.Add(message); + StoreScriptErrors(itemId, errors); + } + /// /// Stop a script which is in this prim's inventory. /// -- cgit v1.1 From c6ba50b7e29789937170c6efdee5386bce54ff3d Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 23:39:06 +0200 Subject: Adding ColdStart event --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index cdd1bd8..6fd6ba7 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -8,4 +8,5 @@ public interface ISnmpModule { void Alert(string message); void Trap(int code,string simname,string Message); + void ColdStart(int step , string simname); } -- cgit v1.1 From 9b6e89457c692fd65a0a221ef7809cc0e4836fe7 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Sun, 11 Apr 2010 14:12:01 -0400 Subject: Fixed LINEAR_MOTOR Z drive, Mantis #30 --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 58 ++++++++++++++++----------- 1 file changed, 35 insertions(+), 23 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 67f8af5..01c3f81 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -2626,15 +2626,15 @@ Console.WriteLine(" JointCreateFixed"); // m_angularDeflectionEfficiency = pValue; break; case Vehicle.ANGULAR_DEFLECTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.1f) pValue = 0.1f; // m_angularDeflectionTimescale = pValue; break; case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.3f) pValue = 0.3f; m_angularMotorDecayTimescale = pValue; break; case Vehicle.ANGULAR_MOTOR_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.3f) pValue = 0.3f; m_angularMotorTimescale = pValue; break; case Vehicle.BANKING_EFFICIENCY: @@ -2663,7 +2663,7 @@ Console.WriteLine(" JointCreateFixed"); m_VhoverHeight = pValue; break; case Vehicle.HOVER_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.1f) pValue = 0.1f; m_VhoverTimescale = pValue; break; case Vehicle.LINEAR_DEFLECTION_EFFICIENCY: @@ -2675,11 +2675,11 @@ Console.WriteLine(" JointCreateFixed"); // m_linearDeflectionTimescale = pValue; break; case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.3f) pValue = 0.3f; m_linearMotorDecayTimescale = pValue; break; case Vehicle.LINEAR_MOTOR_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.1f) pValue = 0.1f; m_linearMotorTimescale = pValue; break; case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY: @@ -2688,7 +2688,7 @@ Console.WriteLine(" JointCreateFixed"); m_verticalAttractionEfficiency = pValue; break; case Vehicle.VERTICAL_ATTRACTION_TIMESCALE: - if (pValue < 0.01f) pValue = 0.01f; + if (pValue < 0.1f) pValue = 0.1f; m_verticalAttractionTimescale = pValue; break; @@ -2704,6 +2704,7 @@ Console.WriteLine(" JointCreateFixed"); UpdateAngDecay(); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: + if (pValue < 0.1f) pValue = 0.1f; m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue); break; case Vehicle.LINEAR_MOTOR_DIRECTION: @@ -2743,6 +2744,9 @@ Console.WriteLine(" JointCreateFixed"); UpdateAngDecay(); break; case Vehicle.LINEAR_FRICTION_TIMESCALE: + if (pValue.X < 0.1f) pValue.X = 0.1f; + if (pValue.Y < 0.1f) pValue.Y = 0.1f; + if (pValue.Z < 0.1f) pValue.Z = 0.1f; m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z); break; case Vehicle.LINEAR_MOTOR_DIRECTION: @@ -2939,7 +2943,7 @@ Console.WriteLine(" JointCreateFixed"); internal void Halt() { // Kill all motions, when non-physical - m_linearMotorDirection = Vector3.Zero; + // m_linearMotorDirection = Vector3.Zero; m_lLinMotorDVel = Vector3.Zero; m_lLinObjectVel = Vector3.Zero; m_wLinObjectVel = Vector3.Zero; @@ -2951,16 +2955,22 @@ Console.WriteLine(" JointCreateFixed"); private void UpdateLinDecay() { - if (Math.Abs(m_linearMotorDirection.X) > Math.Abs(m_lLinMotorDVel.X)) m_lLinMotorDVel.X = m_linearMotorDirection.X; - if (Math.Abs(m_linearMotorDirection.Y) > Math.Abs(m_lLinMotorDVel.Y)) m_lLinMotorDVel.Y = m_linearMotorDirection.Y; - if (Math.Abs(m_linearMotorDirection.Z) > Math.Abs(m_lLinMotorDVel.Z)) m_lLinMotorDVel.Z = m_linearMotorDirection.Z; +// if (Math.Abs(m_linearMotorDirection.X) > Math.Abs(m_lLinMotorDVel.X)) m_lLinMotorDVel.X = m_linearMotorDirection.X; +// if (Math.Abs(m_linearMotorDirection.Y) > Math.Abs(m_lLinMotorDVel.Y)) m_lLinMotorDVel.Y = m_linearMotorDirection.Y; +// if (Math.Abs(m_linearMotorDirection.Z) > Math.Abs(m_lLinMotorDVel.Z)) m_lLinMotorDVel.Z = m_linearMotorDirection.Z; + m_lLinMotorDVel.X = m_linearMotorDirection.X; + m_lLinMotorDVel.Y = m_linearMotorDirection.Y; + m_lLinMotorDVel.Z = m_linearMotorDirection.Z; } // else let the motor decay on its own private void UpdateAngDecay() { - if (Math.Abs(m_angularMotorDirection.X) > Math.Abs(m_angularMotorDVel.X)) m_angularMotorDVel.X = m_angularMotorDirection.X; - if (Math.Abs(m_angularMotorDirection.Y) > Math.Abs(m_angularMotorDVel.Y)) m_angularMotorDVel.Y = m_angularMotorDirection.Y; - if (Math.Abs(m_angularMotorDirection.Z) > Math.Abs(m_angularMotorDVel.Z)) m_angularMotorDVel.Z = m_angularMotorDirection.Z; +// if (Math.Abs(m_angularMotorDirection.X) > Math.Abs(m_angularMotorDVel.X)) m_angularMotorDVel.X = m_angularMotorDirection.X; +// if (Math.Abs(m_angularMotorDirection.Y) > Math.Abs(m_angularMotorDVel.Y)) m_angularMotorDVel.Y = m_angularMotorDirection.Y; +// if (Math.Abs(m_angularMotorDirection.Z) > Math.Abs(m_angularMotorDVel.Z)) m_angularMotorDVel.Z = m_angularMotorDirection.Z; + m_angularMotorDVel.X = m_angularMotorDirection.X; + m_angularMotorDVel.Y = m_angularMotorDirection.Y; + m_angularMotorDVel.Z = m_angularMotorDirection.Z; } // else let the motor decay on its own public void Move(float timestep) @@ -2981,7 +2991,7 @@ Console.WriteLine(" JointCreateFixed"); if (fence == 1) border_limit = 0.5f; // bounce point frcount++; // used to limit debug comment output - if (frcount > 100) + if (frcount > 10) frcount = 0; if(revcount > 0) revcount--; @@ -3222,12 +3232,13 @@ Console.WriteLine(" JointCreateFixed"); { m_lLinMotorDVel = Vector3.Zero; } - else + + /* else { if (Math.Abs(m_lLinMotorDVel.X) < Math.Abs(m_lLinObjectVel.X)) m_lLinObjectVel.X = m_lLinMotorDVel.X; if (Math.Abs(m_lLinMotorDVel.Y) < Math.Abs(m_lLinObjectVel.Y)) m_lLinObjectVel.Y = m_lLinMotorDVel.Y; - if (Math.Abs(m_lLinMotorDVel.Z) < Math.Abs(m_lLinObjectVel.Z)) m_lLinObjectVel.Z = m_lLinMotorDVel.Z; - } + if (Math.Abs(m_lLinMotorDVel.Z) < Math.Abs(m_lLinObjectVel.Z)) m_lLinObjectVel.Z = m_lLinMotorDVel.Z; + } */ } // end linear motor decay if ( (! m_lLinMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! m_lLinObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) @@ -3255,7 +3266,6 @@ Console.WriteLine(" JointCreateFixed"); if (m_linearFrictionTimescale.Z < 300.0f) { float fricfactor = m_linearFrictionTimescale.Z / timestep; -//if(frcount == 0) Console.WriteLine("Zfric={0}", fricfactor); float fricZ = m_lLinObjectVel.Z / fricfactor; m_lLinObjectVel.Z -= fricZ; } @@ -3316,15 +3326,17 @@ Console.WriteLine(" JointCreateFixed"); } } else - { // not hovering, Gravity rules - m_wLinObjectVel.Z = vel_now.Z; + { // not hovering + if (m_wLinObjectVel.Z == 0f) + { // Gravity rules + m_wLinObjectVel.Z = vel_now.Z; + } // else the motor has it } linvel = m_wLinObjectVel; // Vehicle Linear Motion done ======================================= // Apply velocity -//if(frcount == 0) Console.WriteLine("LV {0}", linvel); - d.BodySetLinearVel(Body, linvel.X, linvel.Y, linvel.Z); + d.BodySetLinearVel(Body, linvel.X, linvel.Y, linvel.Z); // apply gravity force d.BodyAddForce(Body, grav.X, grav.Y, grav.Z); //if(frcount == 0) Console.WriteLine("Grav {0}", grav); -- cgit v1.1 From 4433f53f72c6be11ee0a3453ceec403b5de567fa Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 13 Apr 2010 20:14:56 +0100 Subject: Drop unused Alert() method from ISnmpModule --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index 6fd6ba7..d37a01b 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -6,7 +6,6 @@ // Mod 2 public interface ISnmpModule { - void Alert(string message); - void Trap(int code,string simname,string Message); + void Trap(int code,string simname,string Message); void ColdStart(int step , string simname); } -- cgit v1.1 From fac55bc78b70a1f8a3a53b222d9df515e32e82ae Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 14 Apr 2010 01:17:27 +0100 Subject: Change ISnmpModule to use scene references --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index d37a01b..5143b21 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -4,8 +4,15 @@ // // This file is not open source. All rights reserved // Mod 2 + +using OpenSim.Region.Framework.Scenes; + public interface ISnmpModule { - void Trap(int code,string simname,string Message); - void ColdStart(int step , string simname); + void Trap(int code, string Message, Scene scene); + void Critcal(string Message, Scene scene); + void Warning(string Message, Scene scene); + void Major(string Message, Scene scene); + void ColdStart(int step , Scene scene); + void Shutdown(int step , Scene scene); } -- cgit v1.1 From 1636f535ba1915732927054be36b909b67a6de6c Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 14 Apr 2010 10:42:14 +0100 Subject: Committing sacha's partial work (from orpheus). The GridBrat needs to learn a bit of git --- OpenSim/Region/Application/OpenSimBase.cs | 45 ++++++++++++++++++++++ OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index cf2ab65..f3aaa76 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -346,10 +346,28 @@ namespace OpenSim else m_log.Error("[MODULES]: The new RegionModulesController is missing..."); scene.SetModuleInterfaces(); +// First Step of bootreport sequence + if (scene.SnmpService != null) + { + scene.SnmpService.ColdStart(1,scene); + } + +// it should be a LinkDown event +// Maped inside opennms +// bad... + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("Loading prins", scene); + } // Prims have to be loaded after module configuration since some modules may be invoked during the load scene.LoadPrimsFromStorage(regionInfo.originRegionID); + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("Creating region texture", scene); + } + // moved these here as the terrain texture has to be created after the modules are initialized // and has to happen before the region is registered with the grid. scene.CreateTerrainTexture(false); @@ -357,6 +375,10 @@ namespace OpenSim // TODO : Try setting resource for region xstats here on scene MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo)); + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("Grid Registration in progress", scene); + } try { scene.RegisterRegionWithGrid(); @@ -365,11 +387,20 @@ namespace OpenSim { m_log.ErrorFormat("[STARTUP]: Registration of region with grid failed, aborting startup - {0}", e.StackTrace); + if (scene.SnmpService != null) + { + scene.SnmpService.Critical("Grid registration failed. Startup aborted.", scene); + } // Carrying on now causes a lot of confusion down the // line - we need to get the user's attention Environment.Exit(1); } + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("Grid Registration done", scene); + } + // We need to do this after we've initialized the // scripting engines. scene.CreateScriptInstances(); @@ -377,6 +408,11 @@ namespace OpenSim scene.loadAllLandObjectsFromStorage(regionInfo.originRegionID); scene.EventManager.TriggerParcelPrimCountUpdate(); + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("ScriptEngine started", scene); + } + m_sceneManager.Add(scene); if (m_autoCreateClientStack) @@ -385,6 +421,10 @@ namespace OpenSim clientServer.Start(); } + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("Initializing region modules", scene); + } if (do_post_init) { foreach (IRegionModule module in modules) @@ -396,6 +436,11 @@ namespace OpenSim mscene = scene; + if (scene.SnmpService != null) + { + scene.SnmpService.Warning("The region is operational", scene); + } + scene.StartTimer(); return clientServer; diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index 5143b21..8a83fe9 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -10,7 +10,7 @@ using OpenSim.Region.Framework.Scenes; public interface ISnmpModule { void Trap(int code, string Message, Scene scene); - void Critcal(string Message, Scene scene); + void Critical(string Message, Scene scene); void Warning(string Message, Scene scene); void Major(string Message, Scene scene); void ColdStart(int step , Scene scene); -- cgit v1.1 From c77444a8215748633812e67adea8c7ff66a5480d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Apr 2010 20:40:01 +0100 Subject: Fix http://opensimulator.org/mantis/view.php?id=4657 where OpenSim.Grid.UserServer.exe fails on startup if no previous config probably appears to occur because mono 2.4.2.3 (and possibly later) erroneously returns a value of 0 for BufferWidth and BufferHeight in some circumstances --- OpenSim/Framework/Console/LocalConsole.cs | 63 +++++++++++++++++++++++-------- OpenSim/Framework/Util.cs | 2 +- 2 files changed, 48 insertions(+), 17 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs index be936b6..a3036d0 100644 --- a/OpenSim/Framework/Console/LocalConsole.cs +++ b/OpenSim/Framework/Console/LocalConsole.cs @@ -38,7 +38,7 @@ namespace OpenSim.Framework.Console { /// /// A console that uses cursor control and color - /// + /// public class LocalConsole : CommandConsole { // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -100,24 +100,40 @@ namespace OpenSim.Framework.Console private int SetCursorTop(int top) { // From at least mono 2.4.2.3, window resizing can give mono an invalid row and column values. If we try - // to set a cursor row position with a currently invalid column, mono will throw an exception. - // Therefore, we need to make sure that the column position is valid first. + // to set a cursor row position with a currently invalid column, mono will throw an exception. + // Therefore, we need to make sure that the column position is valid first. int left = System.Console.CursorLeft; if (left < 0) + { System.Console.CursorLeft = 0; - else if (left >= System.Console.BufferWidth) - System.Console.CursorLeft = System.Console.BufferWidth - 1; + } + else + { + int bw = System.Console.BufferWidth; + + // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) + if (bw > 0 && left >= bw) + System.Console.CursorLeft = bw - 1; + } if (top < 0) + { top = 0; - if (top >= System.Console.BufferHeight) - top = System.Console.BufferHeight - 1; + } + else + { + int bh = System.Console.BufferHeight; + + // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) + if (bh > 0 && top >= bh) + top = bh - 1; + } System.Console.CursorTop = top; return top; - } + } /// /// Set the cursor column. @@ -129,23 +145,38 @@ namespace OpenSim.Framework.Console /// /// /// The new cursor column. - /// + /// private int SetCursorLeft(int left) { // From at least mono 2.4.2.3, window resizing can give mono an invalid row and column values. If we try - // to set a cursor column position with a currently invalid row, mono will throw an exception. - // Therefore, we need to make sure that the row position is valid first. + // to set a cursor column position with a currently invalid row, mono will throw an exception. + // Therefore, we need to make sure that the row position is valid first. int top = System.Console.CursorTop; if (top < 0) + { System.Console.CursorTop = 0; - else if (top >= System.Console.BufferHeight) - System.Console.CursorTop = System.Console.BufferHeight - 1; + } + else + { + int bh = System.Console.BufferHeight; + // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) + if (bh > 0 && top >= bh) + System.Console.CursorTop = bh - 1; + } if (left < 0) + { left = 0; - if (left >= System.Console.BufferWidth) - left = System.Console.BufferWidth - 1; + } + else + { + int bw = System.Console.BufferWidth; + + // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) + if (bw > 0 && left >= bw) + left = bw - 1; + } System.Console.CursorLeft = left; @@ -183,7 +214,7 @@ namespace OpenSim.Framework.Console System.Console.Write("{0}", prompt); SetCursorTop(new_y); - SetCursorLeft(new_x); + SetCursorLeft(new_x); } } diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 48435cb..ec33b5e 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1441,4 +1441,4 @@ namespace OpenSim.Framework return (diff >= 0) ? diff : (diff + EnvironmentTickCountMask + 1); } } -} +} \ No newline at end of file -- cgit v1.1 From 68a4f897b4f39e46c291d180db5062725130392d Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Sun, 18 Apr 2010 19:19:16 -0400 Subject: This GetScriptErrors() change allows initial XEngine to run in background thread. It should block only for the case of being called by CapsUpdateTaskInventoryScriptAsset(). --- .../Framework/Scenes/SceneObjectPartInventory.cs | 71 ++++++++++++++++++++-- 1 file changed, 65 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index d03b464..a2fceb7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -290,7 +290,7 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForWrite(false); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); - StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); + StoreScriptErrors(item.ItemID, null); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); return; @@ -319,7 +319,7 @@ namespace OpenSim.Region.Framework.Scenes string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); - StoreScriptErrors(item.ItemID, GetScriptErrors(item.ItemID)); + StoreScriptErrors(item.ItemID, null); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); } @@ -388,12 +388,23 @@ namespace OpenSim.Region.Framework.Scenes /// /// Start a script which is in this prim's inventory. + /// Some processing may occur in the background, but this routine returns asap. /// /// /// A /// public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) { + lock (m_scriptErrors) + { + // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion + m_scriptErrors.Remove(itemId); + } + CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); + } + + private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) + { m_items.LockItemsForRead(true); if (m_items.ContainsKey(itemId)) { @@ -425,25 +436,38 @@ namespace OpenSim.Region.Framework.Scenes } + /// + /// Start a script which is in this prim's inventory and return any compilation error messages. + /// + /// + /// A + /// public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) { ArrayList errors; + // Indicate to CreateScriptInstanceInternal() we want it to + // post any compilation/loading error messages lock (m_scriptErrors) { - m_scriptErrors.Remove(itemId); + m_scriptErrors[itemId] = null; } - CreateScriptInstance(itemId, startParam, postOnRez, engine, stateSource); + + // Perform compilation/loading + CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); + + // Wait for and retrieve any errors lock (m_scriptErrors) { - while (!m_scriptErrors.TryGetValue(itemId, out errors)) + while ((errors = m_scriptErrors[itemId]) == null) { if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) { m_log.ErrorFormat( "[PRIM INVENTORY]: " + "timedout waiting for script {0} errors", itemId); - if (!m_scriptErrors.TryGetValue(itemId, out errors)) + errors = m_scriptErrors[itemId]; + if (errors == null) { errors = new ArrayList(1); errors.Add("timedout waiting for errors"); @@ -455,14 +479,49 @@ namespace OpenSim.Region.Framework.Scenes } return errors; } + + // Signal to CreateScriptInstanceEr() that compilation/loading is complete private void StoreScriptErrors(UUID itemId, ArrayList errors) { lock (m_scriptErrors) { + // If compilation/loading initiated via CreateScriptInstance(), + // it does not want the errors, so just get out + if (!m_scriptErrors.ContainsKey(itemId)) + { + return; + } + + // Initiated via CreateScriptInstanceEr(), if we know what the + // errors are, save them and wake CreateScriptInstanceEr(). + if (errors != null) + { + m_scriptErrors[itemId] = errors; + System.Threading.Monitor.PulseAll(m_scriptErrors); + return; + } + } + + // Initiated via CreateScriptInstanceEr() but we don't know what + // the errors are yet, so retrieve them from the script engine. + // This may involve some waiting internal to GetScriptErrors(). + errors = GetScriptErrors(itemId); + + // Get a default non-null value to indicate success. + if (errors == null) + { + errors = new ArrayList(); + } + + // Post to CreateScriptInstanceEr() and wake it up + lock (m_scriptErrors) + { m_scriptErrors[itemId] = errors; System.Threading.Monitor.PulseAll(m_scriptErrors); } } + + // Like StoreScriptErrors(), but just posts a single string message private void StoreScriptError(UUID itemId, string message) { ArrayList errors = new ArrayList(1); -- cgit v1.1 From 1667a29c88905e6734c1402a51a9365209114e1d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 19 Apr 2010 12:54:33 +0200 Subject: And some more rez modes that weren't covered before --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 66ed64b..2f1a189 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1281,6 +1281,7 @@ namespace OpenSim.Region.Framework.Scenes // "Rezzed script {0} into prim local ID {1} for user {2}", // item.inventoryName, localID, remoteClient.Name); part.GetProperties(remoteClient); + part.ParentGroup.ResumeScripts(); } else { @@ -1350,6 +1351,7 @@ namespace OpenSim.Region.Framework.Scenes part.GetProperties(remoteClient); part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); + part.ParentGroup.ResumeScripts(); } } -- cgit v1.1 From 80024c023ad134416038b68a29d5e583f5d5e8a0 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 19 Apr 2010 18:44:21 +0200 Subject: Remove the event trigger for the attach event from the attachment module. The script engine already triggers this internally. --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 77e73fb..9178a0e 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -241,7 +241,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); + //m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); } else { -- cgit v1.1 From de63b60748e33fb5089a463b7a114bb2de33bb5f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 19 Apr 2010 19:27:45 +0200 Subject: Avoid duplicate script resumes. Move resume calls to more logical places --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 9178a0e..354994b 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -239,6 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Fire after attach, so we don't get messy perms dialogs // 3 == AttachedRez objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); + objatt.ResumeScripts(); // Do this last so that event listeners have access to all the effects of the attachment //m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); @@ -250,7 +251,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments itemID, remoteClient.Name, AttachmentPt); } - objatt.ResumeScripts(); return objatt; } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 32a0df9..2352ced 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -601,6 +601,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // Fire on_rez group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); + rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); } @@ -621,7 +622,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - rootPart.ParentGroup.ResumeScripts(); return rootPart.ParentGroup; } } -- cgit v1.1 From 780630d7c05f7306ffceb52db0eda1401112f426 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 23 Apr 2010 14:41:20 +0200 Subject: Fix a nullref in attachment handling. Add some debug to find the attachment state issue --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 3 ++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 6 ++++++ 4 files changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 354994b..a667b80 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -271,7 +271,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); - item = m_scene.InventoryService.GetItem(item); + if (m_scene.InventoryService != null) + item = m_scene.InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e6e414f..44fd2e1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1628,6 +1628,7 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.AgentId); AssetService.Store(asset); + m_log.DebugFormat("[ScriptState]: Saved attachment as asset {0}", asset.FullID); item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 84c3719..1f8c732 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -612,6 +612,7 @@ namespace OpenSim.Region.Framework.Scenes { UUID itemid = new UUID(node.Attributes["UUID"].Value); m_savedScriptState.Add(itemid, node.InnerXml); + m_log.DebugFormat("[ScriptState]: Retrieved state for script item ID {0}", itemid.ToString()); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 04df35a..ce4802d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -333,8 +333,10 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) // No engine at all return; + m_log.DebugFormat("[ScriptState]: Item ID changed: {0} to {1}", oldID, newID); if (m_part.ParentGroup.m_savedScriptState.ContainsKey(oldID)) { + m_log.DebugFormat("[ScriptState]: Found script state for {0}, applying to new script item {1}", oldID, newID); XmlDocument doc = new XmlDocument(); doc.LoadXml(m_part.ParentGroup.m_savedScriptState[oldID]); @@ -380,6 +382,10 @@ namespace OpenSim.Region.Framework.Scenes } m_part.ParentGroup.m_savedScriptState.Remove(oldID); } + else + { + m_log.DebugFormat("[ScriptState]: No state for old ID {0}", oldID); + } } /// -- cgit v1.1 From 7eda9364fd93906d6657e720681e8c079cb2ce1e Mon Sep 17 00:00:00 2001 From: sacha Date: Fri, 23 Apr 2010 10:51:27 -0400 Subject: Adding LinkUp/LinkDown when a region is started or stoped. Those two events could be used to compute the region availibility --- OpenSim/Region/Application/OpenSimBase.cs | 5 ++--- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index f3aaa76..06bb886 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -350,11 +350,9 @@ namespace OpenSim if (scene.SnmpService != null) { scene.SnmpService.ColdStart(1,scene); + scene.SnmpService.LinkDown(scene); } -// it should be a LinkDown event -// Maped inside opennms -// bad... if (scene.SnmpService != null) { scene.SnmpService.Warning("Loading prins", scene); @@ -439,6 +437,7 @@ namespace OpenSim if (scene.SnmpService != null) { scene.SnmpService.Warning("The region is operational", scene); + scene.SnmpService.LinkUp(scene); } scene.StartTimer(); diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index 8a83fe9..cc31322 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -15,4 +15,9 @@ public interface ISnmpModule void Major(string Message, Scene scene); void ColdStart(int step , Scene scene); void Shutdown(int step , Scene scene); + // + // Node Start/stop events + // + void LinkUp(Scene scene); + void LinkDown(Scene scene); } -- cgit v1.1 From 31e0704c8d7f6100153ddedd64be7f2ab1ad9311 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 23 Apr 2010 17:48:50 +0200 Subject: Remove debug output, the culprit has been identified --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 1 - OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 - OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 6 ------ 3 files changed, 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 44fd2e1..e6e414f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1628,7 +1628,6 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.AgentId); AssetService.Store(asset); - m_log.DebugFormat("[ScriptState]: Saved attachment as asset {0}", asset.FullID); item.AssetID = asset.FullID; item.Description = asset.Description; item.Name = asset.Name; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1f8c732..84c3719 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -612,7 +612,6 @@ namespace OpenSim.Region.Framework.Scenes { UUID itemid = new UUID(node.Attributes["UUID"].Value); m_savedScriptState.Add(itemid, node.InnerXml); - m_log.DebugFormat("[ScriptState]: Retrieved state for script item ID {0}", itemid.ToString()); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index ce4802d..04df35a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -333,10 +333,8 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) // No engine at all return; - m_log.DebugFormat("[ScriptState]: Item ID changed: {0} to {1}", oldID, newID); if (m_part.ParentGroup.m_savedScriptState.ContainsKey(oldID)) { - m_log.DebugFormat("[ScriptState]: Found script state for {0}, applying to new script item {1}", oldID, newID); XmlDocument doc = new XmlDocument(); doc.LoadXml(m_part.ParentGroup.m_savedScriptState[oldID]); @@ -382,10 +380,6 @@ namespace OpenSim.Region.Framework.Scenes } m_part.ParentGroup.m_savedScriptState.Remove(oldID); } - else - { - m_log.DebugFormat("[ScriptState]: No state for old ID {0}", oldID); - } } /// -- cgit v1.1 From 85646b157ce0e07ef37e41de72b553bb377243e1 Mon Sep 17 00:00:00 2001 From: sacha Date: Fri, 23 Apr 2010 12:40:27 -0400 Subject: Adding some more SNMP events and some refactoring Signed : The Masqued Foxi --- OpenSim/Region/Application/OpenSimBase.cs | 21 +++++++++++++-------- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 1 + 2 files changed, 14 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 06bb886..1ec96a0 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -355,7 +355,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("Loading prins", scene); + scene.SnmpService.BootInfo("Loading prins", scene); } // Prims have to be loaded after module configuration since some modules may be invoked during the load @@ -363,7 +363,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("Creating region texture", scene); + scene.SnmpService.BootInfo("Creating region texture", scene); } // moved these here as the terrain texture has to be created after the modules are initialized @@ -375,8 +375,8 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("Grid Registration in progress", scene); - } + scene.SnmpService.BootInfo("Grid Registration in progress", scene); + } try { scene.RegisterRegionWithGrid(); @@ -396,7 +396,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("Grid Registration done", scene); + scene.SnmpService.BootInfo("Grid Registration done", scene); } // We need to do this after we've initialized the @@ -408,7 +408,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("ScriptEngine started", scene); + scene.SnmpService.BootInfo("ScriptEngine started", scene); } m_sceneManager.Add(scene); @@ -421,7 +421,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("Initializing region modules", scene); + scene.SnmpService.BootInfo("Initializing region modules", scene); } if (do_post_init) { @@ -436,7 +436,7 @@ namespace OpenSim if (scene.SnmpService != null) { - scene.SnmpService.Warning("The region is operational", scene); + scene.SnmpService.BootInfo("The region is operational", scene); scene.SnmpService.LinkUp(scene); } @@ -448,6 +448,11 @@ namespace OpenSim private void ShutdownRegion(Scene scene) { m_log.DebugFormat("[SHUTDOWN]: Shutting down region {0}", scene.RegionInfo.RegionName); + if (scene.SnmpService != null) + { + scene.SnmpService.BootInfo("The region is shutting down", scene); + scene.SnmpService.LinkDown(scene); + } IRegionModulesController controller; if (ApplicationRegistry.TryGet(out controller)) { diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index cc31322..16a243c 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -20,4 +20,5 @@ public interface ISnmpModule // void LinkUp(Scene scene); void LinkDown(Scene scene); + void BootInfo(string data, Scene scene); } -- cgit v1.1 From 56f60a04d943c3270819ac66a3ae80773b6352e1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 23 Apr 2010 20:18:34 +0200 Subject: Add an additional serialization call do the detach procedure. This call is executed only for it's side effects, which are to block until attach(NULL_KEY) completes, before commencing detachment. --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index a667b80..8307467 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -35,6 +35,7 @@ using OpenSim.Framework; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; namespace OpenSim.Region.CoreModules.Avatar.Attachments { @@ -405,6 +406,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (group.GetFromItemID() == itemID) { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); + // CM / XMREngine!!!! Needed to conclude attach event + SceneObjectSerializer.ToOriginalXmlFormat(group); group.DetachToInventoryPrep(); m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); m_scene.UpdateKnownItem(remoteClient, group,group.GetFromItemID(), group.OwnerID); -- cgit v1.1 From 71f42f185a48ef96391b39fa0197c1a8b793e969 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 24 Apr 2010 16:45:25 +0200 Subject: Plumb a data path to initialize an attachment from an alternate source --- .../Avatar/Attachments/AttachmentsModule.cs | 20 ++++++++++++-- .../InventoryAccess/InventoryAccessModule.cs | 1 + .../Framework/Interfaces/IAttachmentsModule.cs | 7 ++++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- OpenSim/Services/Interfaces/IAttachmentsService.cs | 31 ++++++++++++++++++++++ 5 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 OpenSim/Services/Interfaces/IAttachmentsService.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8307467..1992bd4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using System.Reflection; +using System.Xml; using log4net; using Nini.Config; using OpenMetaverse; @@ -191,8 +192,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public UUID RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus) + { + return RezSingleAttachmentFromInventory(remoteClient, itemID, AttachmentPt, true, null); + } + + public UUID RezSingleAttachmentFromInventory( + IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc) { - SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt); + SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(remoteClient, itemID, AttachmentPt, doc); if (updateInventoryStatus) { @@ -211,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + IClientAPI remoteClient, UUID itemID, uint AttachmentPt, XmlDocument doc) { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) @@ -237,6 +244,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (tainted) objatt.HasGroupChanged = true; + if (doc != null) + objatt.LoadScriptState(doc); + // Fire after attach, so we don't get messy perms dialogs // 3 == AttachedRez objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); @@ -318,6 +328,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { // XXYY!! InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); + if (item == null) + m_log.Error("[ATTACHMENT]: item == null"); + if (m_scene == null) + m_log.Error("[ATTACHMENT]: m_scene == null"); + if (m_scene.InventoryService == null) + m_log.Error("[ATTACHMENT]: m_scene.InventoryService == null"); item = m_scene.InventoryService.GetItem(item); presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /* att.UUID */); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 2352ced..c50abb8 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -524,6 +524,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } else { + throw new Exception("AttachTracer"); group.SetFromItemID(itemID); } diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index f8af367..958847b 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -26,6 +26,7 @@ */ using System; +using System.Xml; using OpenMetaverse; using OpenMetaverse.Packets; using OpenSim.Framework; @@ -82,6 +83,10 @@ namespace OpenSim.Region.Framework.Interfaces UUID RezSingleAttachmentFromInventory( IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus); + // Same as above, but also load script states from a separate doc + UUID RezSingleAttachmentFromInventory( + IClientAPI remoteClient, UUID itemID, uint AttachmentPt, bool updateInventoryStatus, XmlDocument doc); + /// /// Rez multiple attachments from a user's inventory /// @@ -132,4 +137,4 @@ namespace OpenSim.Region.Framework.Interfaces /// void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c220bf0..a5c0b0d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3984,7 +3984,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); { // Rez from inventory UUID asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p); + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); m_log.InfoFormat( "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", diff --git a/OpenSim/Services/Interfaces/IAttachmentsService.cs b/OpenSim/Services/Interfaces/IAttachmentsService.cs new file mode 100644 index 0000000..3b9f2f2 --- /dev/null +++ b/OpenSim/Services/Interfaces/IAttachmentsService.cs @@ -0,0 +1,31 @@ +//////////////////////////////////////////////////////////////// +// +// (c) 2009, 2010 Careminster Limited and Melanie Thielker +// +// All rights reserved +// +using System; +using System.Diagnostics; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading; +using System.Reflection; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Server.Base; +using OpenSim.Services.Base; +using OpenSim.Services.Interfaces; +using Nini.Config; +using log4net; +using Careminster; +using OpenMetaverse; + +namespace Careminster +{ + public interface IAttachmentsService + { + string Get(string id); + void Store(string id, string data); + } +} -- cgit v1.1 From 27b3f23ff3c7b040885784b46a90e9523e633e93 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 24 Apr 2010 16:53:47 +0200 Subject: Remove some usings that stopped compilation --- OpenSim/Services/Interfaces/IAttachmentsService.cs | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Interfaces/IAttachmentsService.cs b/OpenSim/Services/Interfaces/IAttachmentsService.cs index 3b9f2f2..bdde369 100644 --- a/OpenSim/Services/Interfaces/IAttachmentsService.cs +++ b/OpenSim/Services/Interfaces/IAttachmentsService.cs @@ -5,23 +5,9 @@ // All rights reserved // using System; -using System.Diagnostics; -using System.Collections.Generic; -using System.IO; -using System.Text; -using System.Threading; -using System.Reflection; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Server.Base; -using OpenSim.Services.Base; -using OpenSim.Services.Interfaces; using Nini.Config; -using log4net; -using Careminster; -using OpenMetaverse; -namespace Careminster +namespace OpenSim.Services.Interfaces { public interface IAttachmentsService { -- cgit v1.1 From 899d521ab41910e09e66849a5c086d7ae32d01a4 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 24 Apr 2010 18:59:34 +0200 Subject: Use the saved script states --- .../InventoryAccess/InventoryAccessModule.cs | 1 - OpenSim/Region/Framework/Scenes/ScenePresence.cs | 37 +++++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index c50abb8..2352ced 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -524,7 +524,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } else { - throw new Exception("AttachTracer"); group.SetFromItemID(itemID); } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a5c0b0d..ceb4395 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -26,6 +26,7 @@ */ using System; +using System.Xml; using System.Collections.Generic; using System.Reflection; using System.Timers; @@ -3963,6 +3964,32 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); return; } + XmlDocument doc = new XmlDocument(); + string stateData = String.Empty; + + IAttachmentsService attServ = m_scene.RequestModuleInterface(); + if (attServ != null) + { + m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); + stateData = attServ.Get(ControllingClient.AgentId.ToString()); + doc.LoadXml(stateData); + } + + Dictionary itemData = new Dictionary(); + + XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); + if (nodes.Count > 0) + { + foreach (XmlNode n in nodes) + { + XmlElement elem = (XmlElement)n; + string itemID = elem.GetAttribute("ItemID"); + string xml = elem.InnerXml; + + itemData[new UUID(itemID)] = xml; + } + } + List attPoints = m_appearance.GetAttachedPoints(); foreach (int p in attPoints) { @@ -3982,9 +4009,17 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); try { + string xmlData; + XmlDocument d = new XmlDocument(); + if (itemData.TryGetValue(itemID, out xmlData)) + { + d.LoadXml(xmlData); + m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); + } + // Rez from inventory UUID asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); m_log.InfoFormat( "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", -- cgit v1.1 From 81ff5eaba09e7569ef5359874ffcfc7f8855f0b4 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 25 Apr 2010 22:03:35 +0200 Subject: Make scripted attachment states work. Finally. Also replace two monitor locks with RWLocks, hunting the 10^3 bug. Not successful, but needed to be done anyway --- .../Framework/Interfaces/IEntityInventory.cs | 1 + .../Region/Framework/Scenes/SceneObjectGroup.cs | 7 +++- .../Framework/Scenes/SceneObjectPartInventory.cs | 41 +++++++++++++++------- 3 files changed, 35 insertions(+), 14 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 4dd50d6..d893890 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -215,5 +215,6 @@ namespace OpenSim.Region.Framework.Interfaces /// A /// Dictionary GetScriptStates(); + Dictionary GetScriptStates(bool oldIDs); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 84c3719..1c6f2d1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1041,6 +1041,11 @@ namespace OpenSim.Region.Framework.Scenes public void SaveScriptedState(XmlTextWriter writer) { + SaveScriptedState(writer, false); + } + + public void SaveScriptedState(XmlTextWriter writer, bool oldIDs) + { XmlDocument doc = new XmlDocument(); Dictionary states = new Dictionary(); @@ -1050,7 +1055,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in m_parts.Values) { - Dictionary pstates = part.Inventory.GetScriptStates(); + Dictionary pstates = part.Inventory.GetScriptStates(oldIDs); foreach (UUID itemid in pstates.Keys) { states.Add(itemid, pstates[itemid]); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 04df35a..f875224 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -311,11 +311,12 @@ namespace OpenSim.Region.Framework.Scenes if (m_part.ParentGroup.m_savedScriptState != null) RestoreSavedScriptState(item.OldItemID, item.ItemID); - lock (m_items) - { - m_items[item.ItemID].PermsMask = 0; - m_items[item.ItemID].PermsGranter = UUID.Zero; - } + m_items.LockItemsForWrite(true); + + m_items[item.ItemID].PermsMask = 0; + m_items[item.ItemID].PermsGranter = UUID.Zero; + + m_items.LockItemsForWrite(false); string script = Utils.BytesToString(asset.Data); m_part.ParentGroup.Scene.EventManager.TriggerRezScript( @@ -713,15 +714,16 @@ namespace OpenSim.Region.Framework.Scenes { IList items = new List(); - lock (m_items) + m_items.LockItemsForRead(true); + + foreach (TaskInventoryItem item in m_items.Values) { - foreach (TaskInventoryItem item in m_items.Values) - { - if (item.Name == name) - items.Add(item); - } + if (item.Name == name) + items.Add(item); } + m_items.LockItemsForRead(false); + return items; } @@ -1115,6 +1117,11 @@ namespace OpenSim.Region.Framework.Scenes public Dictionary GetScriptStates() { + return GetScriptStates(false); + } + + public Dictionary GetScriptStates(bool oldIDs) + { IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); Dictionary ret = new Dictionary(); @@ -1132,8 +1139,16 @@ namespace OpenSim.Region.Framework.Scenes string n = e.GetXMLState(item.ItemID); if (n != String.Empty) { - if (!ret.ContainsKey(item.ItemID)) - ret[item.ItemID] = n; + if (oldIDs) + { + if (!ret.ContainsKey(item.OldItemID)) + ret[item.OldItemID] = n; + } + else + { + if (!ret.ContainsKey(item.ItemID)) + ret[item.ItemID] = n; + } break; } } -- cgit v1.1 From 06661708b4b2ed33116839ced93d43ca0f0909a0 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 27 Apr 2010 02:40:30 +0200 Subject: Add a parameter to prim inventory update to prevent event firing --- OpenSim/Region/Framework/Interfaces/IEntityInventory.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index d893890..1e2f60b 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -163,6 +163,7 @@ namespace OpenSim.Region.Framework.Interfaces /// in this prim's inventory. /// false if the item did not exist, true if the update occurred successfully bool UpdateInventoryItem(TaskInventoryItem item); + bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents); /// /// Remove an item from this entity's inventory diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index f875224..bc3225a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -735,6 +735,11 @@ namespace OpenSim.Region.Framework.Scenes /// false if the item did not exist, true if the update occurred successfully public bool UpdateInventoryItem(TaskInventoryItem item) { + return UpdateInventoryItem(item, true); + } + + public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) + { m_items.LockItemsForWrite(true); if (m_items.ContainsKey(item.ItemID)) @@ -765,7 +770,8 @@ namespace OpenSim.Region.Framework.Scenes m_items[item.ItemID] = item; m_inventorySerial++; - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); + if (fireScriptEvents) + m_part.TriggerScriptChangedEvent(Changed.INVENTORY); HasInventoryChanged = true; m_part.ParentGroup.HasGroupChanged = true; m_items.LockItemsForWrite(false); -- cgit v1.1 From 5c23b4aa56a9de1baceb833ecba67f66274dca49 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 29 Apr 2010 13:50:11 -0400 Subject: Fix vertical attractor --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 84 ++++++++++++++------------- 1 file changed, 43 insertions(+), 41 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 01c3f81..fbe52c8 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -3395,6 +3395,44 @@ Console.WriteLine(" JointCreateFixed"); //if(frcount == 0) Console.WriteLine("VA = {0}", angObjectVel); + if ( (! m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! angObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) + { // if motor or object have motion + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); + + if (m_angularMotorTimescale < 300.0f) + { + Vector3 attack_error = m_angularMotorDVel - angObjectVel; + float angfactor = m_angularMotorTimescale/timestep; + Vector3 attackAmount = (attack_error/angfactor); + angObjectVel += attackAmount; +//if(frcount == 0) Console.WriteLine("Accel {0} Attk {1}",FrAaccel, attackAmount); +//if(frcount == 0) Console.WriteLine("V2+= {0}", angObjectVel); + } + + angObjectVel.X -= angObjectVel.X / (m_angularFrictionTimescale.X * 0.7f / timestep); + angObjectVel.Y -= angObjectVel.Y / (m_angularFrictionTimescale.Y * 0.7f / timestep); + angObjectVel.Z -= angObjectVel.Z / (m_angularFrictionTimescale.Z * 0.7f / timestep); + } // else no signif. motion + +//if(frcount == 0) Console.WriteLine("Dmotor {0} Obj {1}", m_angularMotorDVel, angObjectVel); + // Bank section tba + // Deflection section tba +//if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); + + + // Rotation Axis Disables: + if (!m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) + { + if (m_angularEnable.X == 0) + angObjectVel.X = 0f; + if (m_angularEnable.Y == 0) + angObjectVel.Y = 0f; + if (m_angularEnable.Z == 0) + angObjectVel.Z = 0f; + } + + angObjectVel = angObjectVel * rotq; // ================ Converts to WORLD rotation + // Vertical attractor section Vector3 vertattr = Vector3.Zero; @@ -3419,8 +3457,9 @@ Console.WriteLine(" JointCreateFixed"); } verterr *= 0.5f; // verterror is 0 (no error) to +/- 1 (max error at 180-deg tilt) - - if ((!angObjectVel.ApproxEquals(Vector3.Zero, 0.001f)) || (verterr.Z < 0.49f)) + Vector3 xyav = angObjectVel; + xyav.Z = 0.0f; + if ((!xyav.ApproxEquals(Vector3.Zero, 0.001f)) || (verterr.Z < 0.49f)) { // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so // Change Body angular velocity X based on Y, and Y based on X. Z is not changed. @@ -3452,46 +3491,9 @@ Console.WriteLine(" JointCreateFixed"); } // else vertical attractor is off //if(frcount == 0) Console.WriteLine("V1 = {0}", angObjectVel); - if ( (! m_angularMotorDVel.ApproxEquals(Vector3.Zero, 0.01f)) || (! angObjectVel.ApproxEquals(Vector3.Zero, 0.01f)) ) - { // if motor or object have motion - if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); - - if (m_angularMotorTimescale < 300.0f) - { - Vector3 attack_error = m_angularMotorDVel - angObjectVel; - float angfactor = m_angularMotorTimescale/timestep; - Vector3 attackAmount = (attack_error/angfactor); - angObjectVel += attackAmount; -//if(frcount == 0) Console.WriteLine("Accel {0} Attk {1}",FrAaccel, attackAmount); -//if(frcount == 0) Console.WriteLine("V2+= {0}", angObjectVel); - } - - angObjectVel.X -= angObjectVel.X / (m_angularFrictionTimescale.X * 0.7f / timestep); - angObjectVel.Y -= angObjectVel.Y / (m_angularFrictionTimescale.Y * 0.7f / timestep); - angObjectVel.Z -= angObjectVel.Z / (m_angularFrictionTimescale.Z * 0.7f / timestep); - } // else no signif. motion - -//if(frcount == 0) Console.WriteLine("Dmotor {0} Obj {1}", m_angularMotorDVel, angObjectVel); - // Bank section tba - // Deflection section tba -//if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); - + m_lastAngularVelocity = angObjectVel; - - if (!m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) - { - if (m_angularEnable.X == 0) - m_lastAngularVelocity.X = 0f; - if (m_angularEnable.Y == 0) - m_lastAngularVelocity.Y = 0f; - if (m_angularEnable.Z == 0) - m_lastAngularVelocity.Z = 0f; - } - // Apply to the body -// Vector3 aInc = m_lastAngularVelocity - initavel; -//if(frcount == 0) Console.WriteLine("Inc {0}", aInc); - m_lastAngularVelocity = m_lastAngularVelocity * rotq; // ================ Converts to WORLD rotation - + // apply Angular Velocity to body d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z); //if(frcount == 0) Console.WriteLine("V4 = {0}", m_lastAngularVelocity); -- cgit v1.1 From f3c21524be94dac139e15b0cd80b1e79570f7916 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 29 Apr 2010 19:41:08 -0400 Subject: Fix Av jump motion S/W --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 8e87ad9..7a5093b 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -1025,11 +1025,11 @@ namespace OpenSim.Region.Physics.OdePlugin // m_iscolliding includes collisions with the ground. // d.Vector3 pos = d.BodyGetPosition(Body); - if (_target_velocity.X > 0) + if (Math.Abs(_target_velocity.X) > 0) { vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D; } - if (_target_velocity.Y > 0) + if (Math.Abs(_target_velocity.Y) > 0) { vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D; } -- cgit v1.1 From 9c79fd630819412f4db94c86caea73200933db5d Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 05:33:45 +0100 Subject: Treat a UserLevel of -1 as an unverified account and refer them to their activation email. --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 5 +++++ OpenSim/Services/LLLoginService/LLLoginService.cs | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index ee30fa3..0cd8f5b 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -57,6 +57,7 @@ namespace OpenSim.Services.LLLoginService public static LLFailedLoginResponse InventoryProblem; public static LLFailedLoginResponse DeadRegionProblem; public static LLFailedLoginResponse LoginBlockedProblem; + public static LLFailedLoginResponse UnverifiedAccountProblem; public static LLFailedLoginResponse AlreadyLoggedInProblem; public static LLFailedLoginResponse InternalError; @@ -80,6 +81,10 @@ namespace OpenSim.Services.LLLoginService LoginBlockedProblem = new LLFailedLoginResponse("presence", "Logins are currently restricted. Please try again later.", "false"); + UnverifiedAccountProblem = new LLFailedLoginResponse("presence", + "Your account has not yet been verified. Please check " + + "your email and click the provided link.", + "false"); AlreadyLoggedInProblem = new LLFailedLoginResponse("presence", "You appear to be already logged in. " + "If this is not the case please wait for your session to timeout. " + diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 4d7dfd1..5301140 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -164,6 +164,12 @@ namespace OpenSim.Services.LLLoginService return LLFailedLoginResponse.UserProblem; } + if (account.UserLevel < 0) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: Unverified account"); + return LLFailedLoginResponse.UnverifiedAccountProblem; + } + if (account.UserLevel < m_MinLoginLevel) { m_log.InfoFormat("[LLOGIN SERVICE]: Login failed, reason: login is blocked for user level {0}", account.UserLevel); -- cgit v1.1 From 04845c1898fee6a8b8563a8103b73cbe38525416 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 11:46:50 +0100 Subject: Fix link security issue --- OpenSim/Framework/IClientAPI.cs | 2 +- .../Region/ClientStack/LindenUDP/LLClientView.cs | 2 +- .../World/Permissions/PermissionsModule.cs | 4 +- OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 50 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 41 ++++-------------- 7 files changed, 68 insertions(+), 41 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 222bae0..a6a081d 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -73,7 +73,7 @@ namespace OpenSim.Framework public delegate void LinkObjects(IClientAPI remoteClient, uint parent, List children); - public delegate void DelinkObjects(List primIds); + public delegate void DelinkObjects(List primIds, IClientAPI client); public delegate void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 8b81377..2ab713d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -6084,7 +6084,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP DelinkObjects handlerDelinkObjects = OnDelinkObjects; if (handlerDelinkObjects != null) { - handlerDelinkObjects(prims); + handlerDelinkObjects(prims, this); } return true; diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 1533462..33e0884 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1592,7 +1592,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return true; + return GenericObjectPermission(editorID, objectID, false); } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1600,7 +1600,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return true; + return GenericObjectPermission(editorID, objectID, false); } private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs index 76dac61..62666a4 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs @@ -69,7 +69,7 @@ namespace OpenSim.Region.DataSnapshot.Providers byte RayEndIsIntersection) { this.Stale = true; }; client.OnLinkObjects += delegate (IClientAPI remoteClient, uint parent, List children) { this.Stale = true; }; - client.OnDelinkObjects += delegate(List primIds) { this.Stale = true; }; + client.OnDelinkObjects += delegate(List primIds, IClientAPI clientApi) { this.Stale = true; }; client.OnGrabUpdate += delegate(UUID objectID, Vector3 offset, Vector3 grapPos, IClientAPI remoteClient, List surfaceArgs) { this.Stale = true; }; client.OnObjectAttach += delegate(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 5b21332..8716e0a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2568,5 +2568,55 @@ namespace OpenSim.Region.Framework.Scenes part.GetProperties(remoteClient); } } + + public void DelinkObjects(List primIds, IClientAPI client) + { + List parts = new List(); + + foreach (uint localID in primIds) + { + SceneObjectPart part = GetSceneObjectPart(localID); + + if (part == null) + continue; + + if (Permissions.CanDelinkObject(client.AgentId, part.ParentGroup.RootPart.UUID)) + parts.Add(part); + } + + m_sceneGraph.DelinkObjects(parts); + } + + public void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) + { + List owners = new List(); + + List children = new List(); + SceneObjectPart root = GetSceneObjectPart(parentPrimId); + + if (Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + return; + + foreach (uint localID in childPrimIds) + { + SceneObjectPart part = GetSceneObjectPart(localID); + + if (part == null) + continue; + + if (!owners.Contains(part.OwnerID)) + owners.Add(part.OwnerID); + + if (Permissions.CanLinkObject(client.AgentId, part.ParentGroup.RootPart.UUID)) + children.Add(part); + } + + // Must be all one owner + // + if (owners.Count > 1) + return; + + m_sceneGraph.LinkObjects(root, children); + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7796b8d..637ebff 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2721,8 +2721,8 @@ namespace OpenSim.Region.Framework.Scenes client.OnObjectName += m_sceneGraph.PrimName; client.OnObjectClickAction += m_sceneGraph.PrimClickAction; client.OnObjectMaterial += m_sceneGraph.PrimMaterial; - client.OnLinkObjects += m_sceneGraph.LinkObjects; - client.OnDelinkObjects += m_sceneGraph.DelinkObjects; + client.OnLinkObjects += LinkObjects; + client.OnDelinkObjects += DelinkObjects; client.OnObjectDuplicate += m_sceneGraph.DuplicateObject; client.OnObjectDuplicateOnRay += doObjectDuplicateOnRay; client.OnUpdatePrimFlags += m_sceneGraph.UpdatePrimFlags; @@ -2877,8 +2877,8 @@ namespace OpenSim.Region.Framework.Scenes client.OnObjectName -= m_sceneGraph.PrimName; client.OnObjectClickAction -= m_sceneGraph.PrimClickAction; client.OnObjectMaterial -= m_sceneGraph.PrimMaterial; - client.OnLinkObjects -= m_sceneGraph.LinkObjects; - client.OnDelinkObjects -= m_sceneGraph.DelinkObjects; + client.OnLinkObjects -= LinkObjects; + client.OnDelinkObjects -= DelinkObjects; client.OnObjectDuplicate -= m_sceneGraph.DuplicateObject; client.OnObjectDuplicateOnRay -= doObjectDuplicateOnRay; client.OnUpdatePrimFlags -= m_sceneGraph.UpdatePrimFlags; diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d31b45e..ad24160 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1619,20 +1619,21 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - protected internal void LinkObjects(IClientAPI client, uint parentPrimId, List childPrimIds) + protected internal void LinkObjects(SceneObjectPart root, List children) { Monitor.Enter(m_updateLock); try { - SceneObjectGroup parentGroup = GetGroupByPrim(parentPrimId); + SceneObjectGroup parentGroup = root.ParentGroup; List childGroups = new List(); if (parentGroup != null) { // We do this in reverse to get the link order of the prims correct - for (int i = childPrimIds.Count - 1; i >= 0; i--) + for (int i = children.Count - 1; i >= 0; i--) { - SceneObjectGroup child = GetGroupByPrim(childPrimIds[i]); + SceneObjectGroup child = children[i].ParentGroup; + if (child != null) { // Make sure no child prim is set for sale @@ -1665,17 +1666,6 @@ namespace OpenSim.Region.Framework.Scenes parentGroup.HasGroupChanged = true; parentGroup.ScheduleGroupForFullUpdate(); -// if (client != null) -// { -// parentGroup.GetProperties(client); -// } -// else -// { -// foreach (ScenePresence p in GetScenePresences()) -// { -// parentGroup.GetProperties(p.ControllingClient); -// } -// } } finally { @@ -1687,12 +1677,7 @@ namespace OpenSim.Region.Framework.Scenes /// Delink a linkset /// /// - protected internal void DelinkObjects(List primIds) - { - DelinkObjects(primIds, true); - } - - protected internal void DelinkObjects(List primIds, bool sendEvents) + protected internal void DelinkObjects(List prims) { Monitor.Enter(m_updateLock); try @@ -1702,9 +1687,8 @@ namespace OpenSim.Region.Framework.Scenes List affectedGroups = new List(); // Look them all up in one go, since that is comparatively expensive // - foreach (uint primID in primIds) + foreach (SceneObjectPart part in prims) { - SceneObjectPart part = m_parentScene.GetSceneObjectPart(primID); if (part != null) { if (part.ParentGroup.Children.Count != 1) // Skip single @@ -1719,17 +1703,13 @@ namespace OpenSim.Region.Framework.Scenes affectedGroups.Add(group); } } - else - { - m_log.ErrorFormat("Viewer requested unlink of nonexistent part {0}", primID); - } } foreach (SceneObjectPart child in childParts) { // Unlink all child parts from their groups // - child.ParentGroup.DelinkFromGroup(child, sendEvents); + child.ParentGroup.DelinkFromGroup(child, true); } foreach (SceneObjectPart root in rootParts) @@ -1784,12 +1764,9 @@ namespace OpenSim.Region.Framework.Scenes List linkIDs = new List(); foreach (SceneObjectPart newChild in newSet) - { newChild.UpdateFlag = 0; - linkIDs.Add(newChild.LocalId); - } - LinkObjects(null, newRoot.LocalId, linkIDs); + LinkObjects(newRoot, newSet); if (!affectedGroups.Contains(newRoot.ParentGroup)) affectedGroups.Add(newRoot.ParentGroup); } -- cgit v1.1 From 9500ba2ff59fc2a47136337a2b06c000b420fd78 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 12:06:58 +0100 Subject: Fix some symbol errors --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 86c91ac..212cfee 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1594,7 +1594,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1602,7 +1602,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) -- cgit v1.1 From 10750421a3c7f9748f9263f587ff2b2350b48249 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 12:06:58 +0100 Subject: Fix some symbol errors --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 33e0884..b557186 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1592,7 +1592,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1600,7 +1600,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) -- cgit v1.1 From 486ab82c027639c62e98ceb8850aaf385f9cef5f Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 30 Apr 2010 12:06:58 +0100 Subject: Fix some symbol errors --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index f6bb3fe..69b247c 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1721,7 +1721,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanDelinkObject(UUID userID, UUID objectID) @@ -1729,7 +1729,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - return GenericObjectPermission(editorID, objectID, false); + return GenericObjectPermission(userID, objectID, false); } private bool CanBuyLand(UUID userID, ILandObject parcel, Scene scene) -- cgit v1.1 From 3e30de7430bff6f2eede395140e45207a15c23a5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Apr 2010 22:35:07 +0200 Subject: Fix linking issue introduced in my earlier commit --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 90bce39..cfcd544 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1970,8 +1970,17 @@ namespace OpenSim.Region.Framework.Scenes List children = new List(); SceneObjectPart root = GetSceneObjectPart(parentPrimId); - if (Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + if (root == null) + { + m_log.DebugFormat("[LINK]: Can't find linkset root prim {0{", parentPrimId); + return; + } + + if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim"); return; + } foreach (uint localID in childPrimIds) { @@ -1990,7 +1999,16 @@ namespace OpenSim.Region.Framework.Scenes // Must be all one owner // if (owners.Count > 1) + { + m_log.DebugFormat("[LINK]: Refusing link. Too many owners"); + return; + } + + if (children.Count == 0) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children"); return; + } m_sceneGraph.LinkObjects(root, children); } -- cgit v1.1 From 0a9c98e7c472f93986f2eedcfaff0d05c8686cee Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Apr 2010 22:35:07 +0200 Subject: Fix linking issue introduced in my earlier commit --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8716e0a..4f2b446 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2594,8 +2594,17 @@ namespace OpenSim.Region.Framework.Scenes List children = new List(); SceneObjectPart root = GetSceneObjectPart(parentPrimId); - if (Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + if (root == null) + { + m_log.DebugFormat("[LINK]: Can't find linkset root prim {0{", parentPrimId); + return; + } + + if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim"); return; + } foreach (uint localID in childPrimIds) { @@ -2614,7 +2623,16 @@ namespace OpenSim.Region.Framework.Scenes // Must be all one owner // if (owners.Count > 1) + { + m_log.DebugFormat("[LINK]: Refusing link. Too many owners"); + return; + } + + if (children.Count == 0) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children"); return; + } m_sceneGraph.LinkObjects(root, children); } -- cgit v1.1 From 7ae55f624883b711e5a9d4d5f040ba884fc8bd5e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Apr 2010 22:35:07 +0200 Subject: Fix linking issue introduced in my earlier commit --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a430bc4..e031ebc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -2603,8 +2603,17 @@ namespace OpenSim.Region.Framework.Scenes List children = new List(); SceneObjectPart root = GetSceneObjectPart(parentPrimId); - if (Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + if (root == null) + { + m_log.DebugFormat("[LINK]: Can't find linkset root prim {0{", parentPrimId); + return; + } + + if (!Permissions.CanLinkObject(client.AgentId, root.ParentGroup.RootPart.UUID)) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions on root prim"); return; + } foreach (uint localID in childPrimIds) { @@ -2623,7 +2632,16 @@ namespace OpenSim.Region.Framework.Scenes // Must be all one owner // if (owners.Count > 1) + { + m_log.DebugFormat("[LINK]: Refusing link. Too many owners"); + return; + } + + if (children.Count == 0) + { + m_log.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children"); return; + } m_sceneGraph.LinkObjects(root, children); } -- cgit v1.1 From 881fcb7def0ef1ff81c6de10137abcdca8bc7679 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Apr 2010 23:32:58 +0200 Subject: Allow retrieval if admin users in scope mode --- .../Services/UserAccountService/UserAccountService.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/UserAccountService/UserAccountService.cs b/OpenSim/Services/UserAccountService/UserAccountService.cs index 7b38aa6..35e2826 100644 --- a/OpenSim/Services/UserAccountService/UserAccountService.cs +++ b/OpenSim/Services/UserAccountService/UserAccountService.cs @@ -104,6 +104,12 @@ namespace OpenSim.Services.UserAccountService d = m_Database.Get( new string[] { "ScopeID", "FirstName", "LastName" }, new string[] { scopeID.ToString(), firstName, lastName }); + if (d.Length < 1) + { + d = m_Database.Get( + new string[] { "ScopeID", "FirstName", "LastName" }, + new string[] { UUID.Zero.ToString(), firstName, lastName }); + } } else { @@ -172,6 +178,12 @@ namespace OpenSim.Services.UserAccountService d = m_Database.Get( new string[] { "ScopeID", "Email" }, new string[] { scopeID.ToString(), email }); + if (d.Length < 1) + { + d = m_Database.Get( + new string[] { "ScopeID", "Email" }, + new string[] { UUID.Zero.ToString(), email }); + } } else { @@ -195,6 +207,12 @@ namespace OpenSim.Services.UserAccountService d = m_Database.Get( new string[] { "ScopeID", "PrincipalID" }, new string[] { scopeID.ToString(), principalID.ToString() }); + if (d.Length < 1) + { + d = m_Database.Get( + new string[] { "ScopeID", "PrincipalID" }, + new string[] { UUID.Zero.ToString(), principalID.ToString() }); + } } else { -- cgit v1.1 From 7ad36d3d75bf50a02b4947a63fa03bedf9f196e6 Mon Sep 17 00:00:00 2001 From: sacha Date: Sun, 2 May 2010 08:15:12 -0400 Subject: Adding DebugEvent Trap Adding XMREEvent Trap trapDebug("Modulename" ,"My data here ", scene); trapXMRE(int data, string Message, Scene scene); --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index 16a243c..e01f649 100644 --- a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs @@ -21,4 +21,7 @@ public interface ISnmpModule void LinkUp(Scene scene); void LinkDown(Scene scene); void BootInfo(string data, Scene scene); + void trapDebug(string Module,string data, Scene scene); + void trapXMRE(int data, string Message, Scene scene); + } -- cgit v1.1 From 0fa57cac3fc05988bf182920c82fbeee0be075cf Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 00:54:24 +0200 Subject: Fix sensor cone for sensing avatars --- .../Shared/Api/Implementation/Plugins/SensorRepeat.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 4d7ead6..5e2e205 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // Is the sensor type is AGENT and not SCRIPTED then include agents if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) { - sensedEntities.AddRange(doAgentSensor(ts)); + sensedEntities.AddRange(doAgentSensor(ts)); } // If SCRIPTED or PASSIVE or ACTIVE check objects @@ -309,6 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins // in mouselook. ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); + fromRegionPos = avatar.AbsolutePosition; q = avatar.Rotation; } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); @@ -422,6 +423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins SceneObjectPart SensePoint = ts.host; Vector3 fromRegionPos = SensePoint.AbsolutePosition; Quaternion q = SensePoint.RotationOffset; + if (SensePoint.ParentGroup.RootPart.IsAttachment) + { + // In attachments, the sensor cone always orients with the + // avatar rotation. This may include a nonzero elevation if + // in mouselook. + + ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); + fromRegionPos = avatar.AbsolutePosition; + q = avatar.Rotation; + } LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); -- cgit v1.1 From 175f3f992ab487add20253329bef481a4d20f8aa Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 01:50:32 +0200 Subject: Make the IUserAccountData properly unpack the god mode data, so grid gods work again --- .../Services/Connectors/UserAccounts/UserAccountServiceConnector.cs | 2 +- OpenSim/Services/Interfaces/IUserAccountService.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs index 1527db2..38c191a 100644 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs @@ -113,7 +113,7 @@ namespace OpenSim.Services.Connectors public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) { - m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUSerAccount {0}", userID); + m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccount {0}", userID); Dictionary sendData = new Dictionary(); //sendData["SCOPEID"] = scopeID.ToString(); sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs index befd14e..e316731 100644 --- a/OpenSim/Services/Interfaces/IUserAccountService.cs +++ b/OpenSim/Services/Interfaces/IUserAccountService.cs @@ -84,11 +84,11 @@ namespace OpenSim.Services.Interfaces if (kvp.ContainsKey("ScopeID")) UUID.TryParse(kvp["ScopeID"].ToString(), out ScopeID); if (kvp.ContainsKey("UserLevel")) - Convert.ToInt32(kvp["UserLevel"].ToString()); + UserLevel = Convert.ToInt32(kvp["UserLevel"].ToString()); if (kvp.ContainsKey("UserFlags")) - Convert.ToInt32(kvp["UserFlags"].ToString()); + UserFlags = Convert.ToInt32(kvp["UserFlags"].ToString()); if (kvp.ContainsKey("UserTitle")) - Email = kvp["UserTitle"].ToString(); + UserTitle = kvp["UserTitle"].ToString(); if (kvp.ContainsKey("Created")) Convert.ToInt32(kvp["Created"].ToString()); -- cgit v1.1 From 87664017773227d07b39382efa2aa94f22bbe6c6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 04:28:30 +0200 Subject: Adapt CM to the new CHANGED_OWNER handling --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 3 +++ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 ++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 17 +++++++++++++---- 4 files changed, 36 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 1992bd4..4fac01f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -245,7 +245,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments objatt.HasGroupChanged = true; if (doc != null) + { objatt.LoadScriptState(doc); + objatt.ResetOwnerChangeFlag(); + } // Fire after attach, so we don't get messy perms dialogs // 3 == AttachedRez diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 1c6f2d1..ff471e0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3931,5 +3931,13 @@ namespace OpenSim.Region.Framework.Scenes return priority; } + + public void ResetOwnerChangeFlag() + { + ForEachPart(delegate(SceneObjectPart part) + { + part.ResetOwnerChangeFlag(); + }); + } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 4b2641c..48e65a5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4683,5 +4683,17 @@ namespace OpenSim.Region.Framework.Scenes { return new Color4((byte)Color.R, (byte)Color.G, (byte)Color.B, (byte)(0xFF - Color.A)); } + + public void ResetOwnerChangeFlag() + { + List inv = Inventory.GetInventoryList(); + + foreach (UUID itemID in inv) + { + TaskInventoryItem item = Inventory.GetInventoryItem(itemID); + item.OwnerChanged = false; + Inventory.UpdateInventoryItem(item); + } + } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ceb4395..562232c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4011,15 +4011,24 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); { string xmlData; XmlDocument d = new XmlDocument(); + UUID asset; if (itemData.TryGetValue(itemID, out xmlData)) { d.LoadXml(xmlData); m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); - } - // Rez from inventory - UUID asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); + // Rez from inventory + asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); + + } + else + { + // Rez from inventory (with a null doc to let + // CHANGED_OWNER happen) + asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); + } m_log.InfoFormat( "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", -- cgit v1.1 From 9c8d7d34b39c6351459989f02473b6f5200d14ee Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 04:55:41 +0200 Subject: Fix a bug in owner change notification --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 64282d1..62b44bd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1180,7 +1180,9 @@ namespace OpenSim.Region.Framework.Scenes { if (engine != null) { - engine.PostScriptEvent(item.ItemID, "changed", new Object[] { Changed.OWNER }); + if (item.OwnerChanged) + engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); + item.OwnerChanged = false; engine.ResumeScript(item.ItemID); } } -- cgit v1.1 From 4df87631ede57316fe41ea6c5edcd4996deac625 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 23:44:23 +0200 Subject: Store given items in correct parent folder. Fixes items given to offline avatars not getting lost. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index cfcd544..9b838ab 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -414,6 +414,25 @@ namespace OpenSim.Region.Framework.Scenes itemCopy.BasePermissions = item.BasePermissions; } + if (itemCopy.Folder == UUID.Zero) + { + InventoryFolderBase folder = InventoryService.GetFolderForType(recipient, (AssetType)itemCopy.AssetType); + + if (folder != null) + { + itemCopy.Folder = folder.ID; + } + else + { + InventoryFolderBase root = InventoryService.GetRootFolder(recipient); + + if (root != null) + itemCopy.Folder = root.ID; + else + return null; // No destination + } + } + itemCopy.GroupID = UUID.Zero; itemCopy.GroupOwned = false; itemCopy.Flags = item.Flags; -- cgit v1.1 From 80bf3934af8a5cbeb4ab29f93c7b2a83c80f1de7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 23:45:05 +0200 Subject: Add folder version incrementing to XInventoryService. Fixes offline give for avatar->avatar --- OpenSim/Data/MySQL/MySQLXInventoryData.cs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index 307a4c7..a3b728b 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -160,5 +160,36 @@ namespace OpenSim.Data.MySQL } } } + + public override bool Store(XInventoryItem item) + { + if (base.Store(item)) + return false; + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + using (MySqlCommand cmd = new MySqlCommand()) + { + cmd.Connection = dbcon; + + cmd.CommandText = String.Format("update inventoryfolders set version=version+1 where folderID = ?folderID"); + cmd.Parameters.AddWithValue("?folderID", item.parentFolderID.ToString()); + + try + { + cmd.ExecuteNonQuery(); + } + catch (Exception e) + { + return false; + } + cmd.Dispose(); + } + dbcon.Close(); + } + return true; + } } } -- cgit v1.1 From deaa79ca9e91e3c4d027561647669287a39ceacd Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 3 May 2010 23:53:49 +0200 Subject: Refix the fix --- OpenSim/Data/MySQL/MySQLXInventoryData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLXInventoryData.cs b/OpenSim/Data/MySQL/MySQLXInventoryData.cs index a3b728b..0fe801d 100644 --- a/OpenSim/Data/MySQL/MySQLXInventoryData.cs +++ b/OpenSim/Data/MySQL/MySQLXInventoryData.cs @@ -163,7 +163,7 @@ namespace OpenSim.Data.MySQL public override bool Store(XInventoryItem item) { - if (base.Store(item)) + if (!base.Store(item)) return false; using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) -- cgit v1.1 From c86259c6710c8ce5c97a7a64bbb96dac35440aec Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 00:44:05 +0200 Subject: Fix scripted give and interactive give to offline avatars. Both folder and single items are now supported. Magic Boxes, yeah! --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 16 +++++++++++ .../Shared/Api/Implementation/LSL_Api.cs | 31 ++++++++++++++++------ 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9b838ab..c105560 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -94,6 +94,22 @@ namespace OpenSim.Region.Framework.Scenes public void AddInventoryItem(UUID AgentID, InventoryItemBase item) { + InventoryFolderBase folder; + + if (item.Folder == UUID.Zero) + { + folder = InventoryService.GetFolderForType(AgentID, (AssetType)item.AssetType); + if (folder == null) + { + folder = InventoryService.GetRootFolder(AgentID); + + if (folder == null) + return; + } + + item.Folder = folder.ID; + } + if (InventoryService.AddItem(item)) { int userlevel = 0; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 228e9b8..d216eff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4005,9 +4005,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); } - // check if destination is an avatar - if (World.GetScenePresence(destId) != null) + // check if destination is an object + if (World.GetSceneObjectPart(destId) != null) { + // destination is an object + World.MoveTaskInventoryItem(destId, m_host, objId); + } + else + { + ScenePresence presence = World.GetScenePresence(destId); + + if (presence == null) + { + UserAccount account = + World.UserAccountService.GetUserAccount( + World.RegionInfo.ScopeID, + destId); + + if (account == null) + { + llSay(0, "Can't find destination "+destId.ToString()); + return; + } + } + // destination is an avatar InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); @@ -4037,12 +4058,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api //This delay should only occur when giving inventory to avatars. ScriptSleep(3000); } - else - { - // destination is an object - World.MoveTaskInventoryItem(destId, m_host, objId); - } - } [DebuggerNonUserCode] -- cgit v1.1 From dbce360566dd20d2b0f2ad649ba7a1dca9a27d36 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 02:43:22 +0200 Subject: Fix full circle sensors --- .../ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs index 5e2e205..d354fde 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs @@ -483,6 +483,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins sensedEntities.Add(new SensedEntity(dis, presence.UUID)); } } + else + { + // If full circle is asked for, just add it + sensedEntities.Add(new SensedEntity(dis, presence.UUID)); + } } }); -- cgit v1.1 From da849aea780b83e3b954ef26772c11ca8c4c2371 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 17:56:30 +0200 Subject: Allow regions to get the list of the other regions in the estate --- OpenSim/Data/MySQL/MySQLEstateData.cs | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLEstateData.cs b/OpenSim/Data/MySQL/MySQLEstateData.cs index d0c02f0..08e2144 100644 --- a/OpenSim/Data/MySQL/MySQLEstateData.cs +++ b/OpenSim/Data/MySQL/MySQLEstateData.cs @@ -474,7 +474,36 @@ namespace OpenSim.Data.MySQL public List GetRegions(int estateID) { - return new List(); + List result = new List(); + + using (MySqlConnection dbcon = new MySqlConnection(m_connectionString)) + { + dbcon.Open(); + + try + { + using (MySqlCommand cmd = dbcon.CreateCommand()) + { + cmd.CommandText = "select RegionID from estate_map where EstateID = ?EstateID"; + cmd.Parameters.AddWithValue("?EstateID", estateID.ToString()); + + using (IDataReader reader = cmd.ExecuteReader()) + { + while(reader.Read()) + result.Add(new UUID(reader["RegionID"].ToString())); + reader.Close(); + } + } + } + catch (Exception e) + { + m_log.Error("[REGION DB]: Error reading estate map. " + e.ToString()); + return result; + } + dbcon.Close(); + } + + return result; } public bool DeleteEstate(int estateID) -- cgit v1.1 From 4f93d30790c8392c6f91cb1818d1c16f89169ab7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 18:10:13 +0200 Subject: Allow reloading of estate settings into a running region. Move sun update helper into Scene, since that is less evil than exposing m_storageManager to the public. --- .../World/Estate/EstateManagementModule.cs | 40 ++----------------- OpenSim/Region/Framework/Scenes/Scene.cs | 46 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 37 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 91d40ab..77068b0 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -212,7 +212,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.RegionSettings.FixedSun = UseFixedSun; m_scene.RegionInfo.RegionSettings.SunPosition = SunHour; - TriggerEstateToolsSunUpdate(); + m_scene.TriggerEstateSunUpdate(); //m_log.Debug("[ESTATE]: UFS: " + UseFixedSun.ToString()); //m_log.Debug("[ESTATE]: SunHour: " + SunHour.ToString()); @@ -861,7 +861,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.EstateSettings.Save(); - TriggerEstateToolsSunUpdate(); + m_scene.TriggerEstateSunUpdate(); sendDetailedEstateData(remoteClient, invoice); } @@ -983,7 +983,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { // Sets up the sun module based no the saved Estate and Region Settings // DO NOT REMOVE or the sun will stop working - TriggerEstateToolsSunUpdate(); + m_scene.TriggerEstateSunUpdate(); } public void Close() @@ -1004,40 +1004,6 @@ namespace OpenSim.Region.CoreModules.World.Estate #region Other Functions - private void TriggerEstateToolsSunUpdate() - { - float sun; - if (m_scene.RegionInfo.RegionSettings.UseEstateSun) - { - sun = (float)m_scene.RegionInfo.EstateSettings.SunPosition; - if (m_scene.RegionInfo.EstateSettings.UseGlobalTime) - { - sun = m_scene.EventManager.GetCurrentTimeAsSunLindenHour() - 6.0f; - } - - // - m_scene.EventManager.TriggerEstateToolsSunUpdate( - m_scene.RegionInfo.RegionHandle, - m_scene.RegionInfo.EstateSettings.FixedSun, - m_scene.RegionInfo.RegionSettings.UseEstateSun, - sun); - } - else - { - // Use the Sun Position from the Region Settings - sun = (float)m_scene.RegionInfo.RegionSettings.SunPosition - 6.0f; - - m_scene.EventManager.TriggerEstateToolsSunUpdate( - m_scene.RegionInfo.RegionHandle, - m_scene.RegionInfo.RegionSettings.FixedSun, - m_scene.RegionInfo.RegionSettings.UseEstateSun, - sun); - } - - - } - - public void changeWaterHeight(float height) { setRegionTerrainSettings(height, diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3e78a08..f17e464 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5109,5 +5109,51 @@ namespace OpenSim.Region.Framework.Scenes { return new Vector3(x, y, GetGroundHeight(x, y)); } + + public List GetEstateRegions(int estateID) + { + if (m_storageManager.EstateDataStore == null) + return new List(); + + return m_storageManager.EstateDataStore.GetRegions(estateID); + } + + public void ReloadEstateData() + { + m_regInfo.EstateSettings = m_storageManager.EstateDataStore.LoadEstateSettings(m_regInfo.RegionID, false); + + TriggerEstateSunUpdate(); + } + + public void TriggerEstateSunUpdate() + { + float sun; + if (RegionInfo.RegionSettings.UseEstateSun) + { + sun = (float)RegionInfo.EstateSettings.SunPosition; + if (RegionInfo.EstateSettings.UseGlobalTime) + { + sun = EventManager.GetCurrentTimeAsSunLindenHour() - 6.0f; + } + + // + EventManager.TriggerEstateToolsSunUpdate( + RegionInfo.RegionHandle, + RegionInfo.EstateSettings.FixedSun, + RegionInfo.RegionSettings.UseEstateSun, + sun); + } + else + { + // Use the Sun Position from the Region Settings + sun = (float)RegionInfo.RegionSettings.SunPosition - 6.0f; + + EventManager.TriggerEstateToolsSunUpdate( + RegionInfo.RegionHandle, + RegionInfo.RegionSettings.FixedSun, + RegionInfo.RegionSettings.UseEstateSun, + sun); + } + } } } -- cgit v1.1 From ce86d39c70882a4beb04a23565121b05a4325a46 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 18:31:52 +0200 Subject: Add "reload estate" command to sims --- OpenSim/Region/Framework/Scenes/Scene.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f17e464..0ca5948 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -662,6 +662,10 @@ namespace OpenSim.Region.Framework.Scenes } } + MainConsole.Instance.Commands.AddCommand("region", false, "reload estate", + "reload estate", + "Reload the estate data", HandleReloadEstate); + //Bind Storage Manager functions to some land manager functions for this scene EventManager.OnLandObjectAdded += new EventManager.LandObjectAdded(m_storageManager.DataStore.StoreLandObject); @@ -5155,5 +5159,15 @@ namespace OpenSim.Region.Framework.Scenes sun); } } + + private void HandleReloadEstate(string module, string[] cmd) + { + if (MainConsole.Instance.ConsoleScene == null || + (MainConsole.Instance.ConsoleScene is Scene && + (Scene)MainConsole.Instance.ConsoleScene == this)) + { + ReloadEstateData(); + } + } } } -- cgit v1.1 From 97bbce92a865279de3b240eb07b6b54490d02942 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 20:57:31 +0200 Subject: Add events to the estate interface to let interested modules know of changes to estate settings --- .../World/Estate/EstateManagementModule.cs | 36 ++++++++++++++++++++++ .../Region/Framework/Interfaces/IEstateModule.cs | 5 +++ 2 files changed, 41 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 77068b0..92e9eed 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -48,6 +48,9 @@ namespace OpenSim.Region.CoreModules.World.Estate private EstateTerrainXferHandler TerrainUploader; + public event ChangeDelegate OnRegionInfoChange; + public event ChangeDelegate OnEstateInfoChange; + #region Packet Data Responders private void sendDetailedEstateData(IClientAPI remote_client, UUID invoice) @@ -137,6 +140,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.RegionSettings.AllowLandJoinDivide = false; m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); sendRegionInfoPacketToAll(); } @@ -162,6 +166,7 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); sendRegionInfoPacketToAll(); } @@ -187,6 +192,7 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); sendRegionInfoPacketToAll(); } @@ -219,6 +225,7 @@ namespace OpenSim.Region.CoreModules.World.Estate sendRegionInfoPacketToAll(); m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); } private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) @@ -230,6 +237,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.RegionSettings.Covenant = estateCovenantID; m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); } private void handleEstateAccessDeltaRequest(IClientAPI remote_client, UUID invoice, int estateAccessType, UUID user) @@ -245,6 +253,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.AddEstateUser(user); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AccessOptions, m_scene.RegionInfo.EstateSettings.EstateAccess, m_scene.RegionInfo.EstateSettings.EstateID); } else @@ -259,6 +268,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.RemoveEstateUser(user); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AccessOptions, m_scene.RegionInfo.EstateSettings.EstateAccess, m_scene.RegionInfo.EstateSettings.EstateID); } @@ -273,6 +283,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.AddEstateGroup(user); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AllowedGroups, m_scene.RegionInfo.EstateSettings.EstateGroups, m_scene.RegionInfo.EstateSettings.EstateID); } else @@ -286,6 +297,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.RemoveEstateGroup(user); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AllowedGroups, m_scene.RegionInfo.EstateSettings.EstateGroups, m_scene.RegionInfo.EstateSettings.EstateID); } @@ -323,6 +335,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.EstateSettings.AddBan(item); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); ScenePresence s = m_scene.GetScenePresence(user); if (s != null) @@ -370,6 +383,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.RemoveBan(listitem.BannedUserID); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); } else { @@ -389,6 +403,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.AddEstateManager(user); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } else @@ -402,6 +417,7 @@ namespace OpenSim.Region.CoreModules.World.Estate { m_scene.RegionInfo.EstateSettings.RemoveEstateManager(user); m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } @@ -449,6 +465,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); m_scene.SetSceneCoreDebug(scripted, collisionEvents, physics); } @@ -860,6 +877,7 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.EstateSettings.DenyMinors = false; m_scene.RegionInfo.EstateSettings.Save(); + TriggerEstateInfoChange(); m_scene.TriggerEstateSunUpdate(); @@ -927,6 +945,7 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); sendRegionInfoPacketToAll(); } @@ -972,6 +991,7 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); + TriggerRegionInfoChange(); sendRegionHandshakeToAll(); } } @@ -1141,5 +1161,21 @@ namespace OpenSim.Region.CoreModules.World.Estate return false; } + + protected void TriggerRegionInfoChange() + { + ChangeDelegate change = OnRegionInfoChange; + + if (change != null) + change(); + } + + protected void TriggerEstateInfoChange() + { + ChangeDelegate change = OnEstateInfoChange; + + if (change != null) + change(); + } } } diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index 890fa31..b2135d2 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -29,8 +29,13 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { + public delegate void ChangeDelegate(); + public interface IEstateModule : IRegionModule { + event ChangeDelegate OnRegionInfoChange; + event ChangeDelegate OnEstateInfoChange; + uint GetRegionFlags(); bool IsManager(UUID avatarID); -- cgit v1.1 From 07e0732a10928e317f3245a8a1b4e2c12f294556 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 21:16:20 +0200 Subject: make the events more useful by providing the source region --- OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | 4 ++-- OpenSim/Region/Framework/Interfaces/IEstateModule.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 92e9eed..dcc66ca 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -1167,7 +1167,7 @@ namespace OpenSim.Region.CoreModules.World.Estate ChangeDelegate change = OnRegionInfoChange; if (change != null) - change(); + change(m_scene.RegionInfo.RegionID); } protected void TriggerEstateInfoChange() @@ -1175,7 +1175,7 @@ namespace OpenSim.Region.CoreModules.World.Estate ChangeDelegate change = OnEstateInfoChange; if (change != null) - change(); + change(m_scene.RegionInfo.RegionID); } } } diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index b2135d2..329c3f5 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -29,7 +29,7 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { - public delegate void ChangeDelegate(); + public delegate void ChangeDelegate(UUID regionID); public interface IEstateModule : IRegionModule { -- cgit v1.1 From 49efec2ef17ece206f73acf1665bf973a6204b87 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 4 May 2010 23:45:59 +0200 Subject: Strip estate message sending out from the estate management module and the dialog module. Convert it to an event on the estate module interface. The old implementation did the same as message to region, a button that is right next to it on the UI. This implementation prevented people from adding a more sane one in a module. --- OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs | 8 -------- .../CoreModules/World/Estate/EstateManagementModule.cs | 14 ++++++++++---- OpenSim/Region/Framework/Interfaces/IDialogModule.cs | 13 ------------- OpenSim/Region/Framework/Interfaces/IEstateModule.cs | 2 ++ 4 files changed, 12 insertions(+), 25 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index c31266c..da38ede 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -132,14 +132,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); } - public void SendNotificationToUsersInEstate( - UUID fromAvatarID, string fromAvatarName, string message) - { - // TODO: This does not yet do what it says on the tin - it only sends the message to users in the same - // region as the sending avatar. - SendNotificationToUsersInRegion(fromAvatarID, fromAvatarName, message); - } - public void SendTextBoxToUser(UUID avatarid, string message, int chatChannel, string name, UUID objectid, UUID ownerid) { UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index dcc66ca..abd0fcb 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -50,6 +50,7 @@ namespace OpenSim.Region.CoreModules.World.Estate public event ChangeDelegate OnRegionInfoChange; public event ChangeDelegate OnEstateInfoChange; + public event MessageDelegate OnEstateMessage; #region Packet Data Responders @@ -440,10 +441,7 @@ namespace OpenSim.Region.CoreModules.World.Estate private void SendEstateBlueBoxMessage( IClientAPI remote_client, UUID invoice, UUID senderID, UUID sessionID, string senderName, string message) { - IDialogModule dm = m_scene.RequestModuleInterface(); - - if (dm != null) - dm.SendNotificationToUsersInEstate(senderID, senderName, message); + TriggerEstateMessage(senderID, senderName, message); } private void handleEstateDebugRegionRequest(IClientAPI remote_client, UUID invoice, UUID senderID, bool scripted, bool collisionEvents, bool physics) @@ -1177,5 +1175,13 @@ namespace OpenSim.Region.CoreModules.World.Estate if (change != null) change(m_scene.RegionInfo.RegionID); } + + protected void TriggerEstateMessage(UUID fromID, string fromName, string message) + { + MessageDelegate onmessage = OnEstateMessage; + + if (onmessage != null) + onmessage(m_scene.RegionInfo.RegionID, fromID, fromName, message); + } } } diff --git a/OpenSim/Region/Framework/Interfaces/IDialogModule.cs b/OpenSim/Region/Framework/Interfaces/IDialogModule.cs index 35b4b63..be9764a 100644 --- a/OpenSim/Region/Framework/Interfaces/IDialogModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IDialogModule.cs @@ -120,19 +120,6 @@ namespace OpenSim.Region.Framework.Interfaces void SendNotificationToUsersInRegion(UUID fromAvatarID, string fromAvatarName, string message); /// - /// Send a notification to all users in the estate. This notification should remain around until the - /// user explicitly dismisses it. - /// - /// - /// On the Linden Labs Second Client (as of 1.21), this is a big blue box message on the upper right of the - /// screen. - /// - /// The user sending the message - /// The name of the user doing the sending - /// The message being sent to the user - void SendNotificationToUsersInEstate(UUID fromAvatarID, string fromAvatarName, string message); - - /// /// Send a textbox entry for the client to respond to /// void SendTextBoxToUser(UUID avatarid, string message, int chatChannel, string name, UUID objectid, UUID ownerid); diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index 329c3f5..c850f7f 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs @@ -30,11 +30,13 @@ using OpenMetaverse; namespace OpenSim.Region.Framework.Interfaces { public delegate void ChangeDelegate(UUID regionID); + public delegate void MessageDelegate(UUID regionID, UUID fromID, string fromName, string message); public interface IEstateModule : IRegionModule { event ChangeDelegate OnRegionInfoChange; event ChangeDelegate OnEstateInfoChange; + event MessageDelegate OnEstateMessage; uint GetRegionFlags(); bool IsManager(UUID avatarID); -- cgit v1.1 From efc32415414753adc7f3f170e2d7a339095212db Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 5 May 2010 01:32:55 +0200 Subject: Add perms check to the teleport home client command handlers. --- OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index abd0fcb..940b535 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -470,6 +470,9 @@ namespace OpenSim.Region.CoreModules.World.Estate private void handleEstateTeleportOneUserHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID, UUID prey) { + if (!m_scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false)) + return; + if (prey != UUID.Zero) { ScenePresence s = m_scene.GetScenePresence(prey); @@ -483,6 +486,9 @@ namespace OpenSim.Region.CoreModules.World.Estate private void handleEstateTeleportAllUsersHomeRequest(IClientAPI remover_client, UUID invoice, UUID senderID) { + if (!m_scene.Permissions.CanIssueEstateCommand(remover_client.AgentId, false)) + return; + m_scene.ForEachScenePresence(delegate(ScenePresence sp) { if (sp.UUID != senderID) -- cgit v1.1 From 608bb0dfefbbc97aded6d1357dd9d350053411fb Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 5 May 2010 14:36:24 +0100 Subject: Patch from mcortez: Update groups, add ALPHA Siman grid connector for groups Mantis #4646 Signed-off-by: Melanie --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 341 +++--- .../XmlRpcGroups/IGroupsServicesConnector.cs | 62 +- .../SimianGroupsServicesConnectorModule.cs | 1278 ++++++++++++++++++++ .../XmlRpcGroupsServicesConnectorModule.cs | 209 ++-- 4 files changed, 1570 insertions(+), 320 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8d32e66..6b942cb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -43,6 +43,8 @@ using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; @@ -87,16 +89,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsServicesConnector m_groupData = null; - class GroupRequestIDInfo - { - public GroupRequestID RequestID = new GroupRequestID(); - public DateTime LastUsedTMStamp = DateTime.MinValue; - } - private Dictionary m_clientRequestIDInfo = new Dictionary(); - private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes - private Timer m_clientRequestIDFlushTimer; - - // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; @@ -133,30 +125,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - m_clientRequestIDFlushTimer = new Timer(); - m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; - m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; - m_clientRequestIDFlushTimer.AutoReset = true; - m_clientRequestIDFlushTimer.Start(); - } - } - - void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) - { - lock (m_clientRequestIDInfo) - { - TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); - UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; - foreach (UUID key in CurrentKeys) - { - if (m_clientRequestIDInfo.ContainsKey(key)) - { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) - { - m_clientRequestIDInfo.Remove(key); - } - } - } } } @@ -234,8 +202,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); - - m_clientRequestIDFlushTimer.Stop(); } public Type ReplaceableInterface @@ -272,14 +238,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - lock (m_clientRequestIDInfo) - { - if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - // flush any old RequestID information - m_clientRequestIDInfo.Remove(client.AgentId); - } - } + // Send client thier groups information. SendAgentGroupDataUpdate(client, client.AgentId); } @@ -287,7 +246,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray(); GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -326,15 +285,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } */ - void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", + System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); } } @@ -348,7 +309,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -361,13 +322,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) + private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string GroupName; - GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); + GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); if (group != null) { GroupName = group.GroupName; @@ -388,7 +349,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); if (inviteInfo == null) { @@ -407,7 +368,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -431,14 +392,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } } } @@ -452,7 +413,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -496,21 +457,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { if (m_debugEnabled) { - UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); - if (targetUserProfile != null) + UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); + if (targetUser != null) { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); } else { @@ -588,20 +549,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(null, GroupID, null); + return m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); } + public GroupRecord GetGroupRecord(string name) + { + return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); + } + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); // Changing active group changes title, active powers, all kinds of things // anyone who is in any region that can see this client, should probably be // updated with new group info. At a minimum, they should get ScenePresence // updated with new title. - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } /// @@ -611,10 +577,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + List agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); List titles = new List(); foreach (GroupRolesData role in agentRoles) @@ -636,8 +601,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } + } return data; @@ -647,21 +619,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID); return data; - } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); - + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } + } return data; - - } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) @@ -670,17 +646,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupProfileData profile = new GroupProfileData(); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); if (groupInfo != null) { profile.AllowPublish = groupInfo.AllowPublish; profile.Charter = groupInfo.Charter; profile.FounderID = groupInfo.FounderID; profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID).Count; profile.InsigniaID = groupInfo.GroupPicture; profile.MaturePublish = groupInfo.MaturePublish; profile.MembershipFee = groupInfo.MembershipFee; @@ -691,7 +666,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups profile.ShowInList = groupInfo.ShowInList; } - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); if (memberInfo != null) { profile.MemberTitle = memberInfo.GroupTitle; @@ -705,46 +680,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); + return m_groupData.GetAgentGroupMemberships(UUID.Zero, agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with groupID={1}, agentID={2}", + System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); - return m_groupData.GetAgentGroupMembership(null, agentID, groupID); + return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Check? - - m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + // Note: Permissions checking for modification rights is handled by the Groups Server/Service + m_groupData.UpdateGroup(GetRequestingAgentID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { - // TODO: Security Check? + // Note: Permissions checking for modification rights is handled by the Groups Server/Service if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); + m_groupData.SetAgentGroupInfo(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } // is there is a money module present ? - IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); + IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); if (money != null) { // do the transaction, that is if the agent has got sufficient funds @@ -752,14 +727,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); return UUID.Zero; } - money.ApplyGroupCreationCharge(remoteClient.AgentId); + money.ApplyGroupCreationCharge(GetRequestingAgentID(remoteClient)); } - UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); return groupID; } @@ -770,7 +745,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // ToDo: check if agent is a member of group and is allowed to see notices? - return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); + return m_groupData.GetGroupNotices(GetRequestingAgentID(remoteClient), groupID).ToArray(); } /// @@ -780,7 +755,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(UUID.Zero, avatarID); if (membership != null) { return membership.GroupTitle; @@ -795,13 +770,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); + m_groupData.SetAgentActiveGroupRole(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, titleRoleID); // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too - // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) + // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } @@ -811,16 +786,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Security Checks are handled in the Groups Service. - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); + m_groupData.AddGroupRole(GetRequestingAgentID(remoteClient), groupID, UUID.Random(), name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(grID, groupID, roleID); + m_groupData.RemoveGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: @@ -831,7 +804,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupPowers gp = (GroupPowers)powers; m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); } - m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); + m_groupData.UpdateGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: @@ -842,7 +815,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) @@ -850,18 +823,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch (changes) { case 0: // Add - m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); + m_groupData.AddAgentToGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; case 1: // Remove - m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); + m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; default: @@ -870,25 +841,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); + GroupNoticeInfo data = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), groupNoticeID); if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; msg.message = data.noticeData.Subject + "|" + data.Message; @@ -900,7 +869,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = data.BinaryBucket; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } } @@ -920,7 +889,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; - GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); + GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID); if (info != null) { msg.fromAgentID = info.GroupID.Guid; @@ -947,7 +916,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) @@ -955,19 +924,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); remoteClient.SendLeaveGroupReply(groupID, true); @@ -975,34 +944,32 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // SL sends out notifcations to the group messaging session that the person has left // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); + remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); - if ((groupInfo == null) || (userProfile == null)) + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, ejecteeID); + if ((groupInfo == null) || (account == null)) { return; - } - + } // Send Message to Ejectee GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1028,13 +995,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; - if (userProfile != null) + if (account != null) { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, account.FirstName + " " + account.LastName); } else { @@ -1047,7 +1014,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); // SL sends out messages to everyone in the group @@ -1061,13 +1028,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - GroupRequestID grid = GetClientGroupRequestID(remoteClient); - m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID); if (inviteInfo != null) { @@ -1079,7 +1045,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1132,57 +1098,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return child; } - private GroupRequestID GetClientGroupRequestID(IClientAPI client) - { - if (client == null) - { - return new GroupRequestID(); - } - - lock (m_clientRequestIDInfo) - { - if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - GroupRequestIDInfo info = new GroupRequestIDInfo(); - info.RequestID.AgentID = client.AgentId; - info.RequestID.SessionID = client.SessionId; - - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - if (userProfile == null) - { - // This should be impossible. If I've been passed a reference to a client - // that client should be registered with the UserService. So something - // is horribly wrong somewhere. - - m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); - - // Default to local user service and hope for the best? - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - - } - else if (userProfile is ForeignUserProfileData) - { - // They aren't from around here - ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; - info.RequestID.UserServiceURL = fupd.UserServerURI; - } - else - { - // They're a local user, use this: - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - } - - m_clientRequestIDInfo.Add(client.AgentId, info); - } - - m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; - - return m_clientRequestIDInfo[client.AgentId].RequestID; - } -// Unreachable code! -// return new GroupRequestID(); - } - /// /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. /// @@ -1201,7 +1116,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { - if (remoteClient.AgentId != dataForAgentID) + if (GetRequestingAgentID(remoteClient) != dataForAgentID) { if (!membership.ListInProfile) { @@ -1229,13 +1144,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap llDataStruct = new OSDMap(3); llDataStruct.Add("AgentData", AgentData); llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); + llDataStruct.Add("NewGroupData", NewGroupData); + + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + } IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); } } @@ -1308,7 +1228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) { - List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); + List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; if (requestingClient.AgentId != dataForAgentID) @@ -1330,7 +1250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); foreach (GroupMembershipData membership in membershipArray) { - m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2} - {3}", dataForAgentID, membership.GroupName, membership.GroupTitle, membership.GroupPowers); } } @@ -1342,12 +1262,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); + UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); string firstname, lastname; - if (userProfile != null) + if (account != null) { - firstname = userProfile.FirstName; - lastname = userProfile.SurName; + firstname = account.FirstName; + lastname = account.LastName; } else { @@ -1388,7 +1308,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // } - #endregion + #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; + } } + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 9e0fa2d..6487967 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,42 +36,41 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { interface IGroupsServicesConnector { - UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); - List FindGroups(GroupRequestID requestID, string search); - List GetGroupMembers(GroupRequestID requestID, UUID GroupID); + UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); + List FindGroups(UUID RequestingAgentID, string search); + List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); - void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); - List GetGroupRoles(GroupRequestID requestID, UUID GroupID); - List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); + void AddGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID); + List GetGroupRoles(UUID RequestingAgentID, UUID GroupID); + List GetGroupRoleMembers(UUID RequestingAgentID, UUID GroupID); - void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void AddAgentToGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void AddAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void RemoveAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void AddAgentToGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void SetAgentActiveGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(UUID RequestingAgentID, UUID AgentID); - void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); + void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); - GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); - - void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); - List GetGroupNotices(GroupRequestID requestID, UUID GroupID); + void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); + List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); } public class GroupInviteInfo @@ -81,11 +80,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public UUID AgentID = UUID.Zero; public UUID InviteID = UUID.Zero; } - - public class GroupRequestID - { - public UUID AgentID = UUID.Zero; - public string UserServiceURL = string.Empty; - public UUID SessionID = UUID.Zero; - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs new file mode 100644 index 0000000..590753e --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -0,0 +1,1278 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; + +using Nwc.XmlRpc; + +using log4net; +using Mono.Addins; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; + +/*************************************************************************** + * Simian Data Map + * =============== + * + * OwnerID -> Type -> Key + * ----------------------- + * + * UserID -> Group -> ActiveGroup + * + GroupID + * + * UserID -> GroupMember -> GroupID + * + SelectedRoleID [UUID] + * + AcceptNotices [bool] + * + ListInProfile [bool] + * + Contribution [int] + * + * UserID -> GroupRole[GroupID] -> RoleID + * + * GroupID -> Group -> GroupName + * + Charter + * + ShowInList + * + InsigniaID + * + MembershipFee + * + OpenEnrollment + * + AllowPublish + * + MaturePublish + * + FounderID + * + EveryonePowers + * + OwnerRoleID + * + OwnersPowers + * + * GroupID -> GroupRole -> RoleID + * + Name + * + Description + * + Title + * + Powers + * + * GroupID -> GroupMemberInvite -> InviteID + * + AgentID + * + RoleID + * + * GroupID -> GroupNotice -> NoticeID + * + TimeStamp [uint] + * + FromName [string] + * + Subject [string] + * + Message [string] + * + BinaryBucket [byte[]] + * + * */ + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + + private bool m_connectorEnabled = false; + + private string m_serviceURL = string.Empty; + + private bool m_debugEnabled = false; + + // private IUserAccountService m_accountService = null; + + + #region IRegionModuleBase Members + + public string Name + { + get { return "SimianGroupsServicesConnector"; } + } + + // this module is not intended to be replaced, but there should only be 1 of them. + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + // if groups aren't enabled, we're not needed. + // if we're not specified as the connector to use, then we're not wanted + if ((groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + { + m_connectorEnabled = false; + return; + } + + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); + if ((m_serviceURL == null) || + (m_serviceURL == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_connectorEnabled = false; + return; + } + + // If we got all the config options we need, lets start'er'up + m_connectorEnabled = true; + + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + + } + } + + public void Close() + { + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + } + + public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (m_connectorEnabled) + { + scene.RegisterModuleInterface(this); + } + } + + public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (scene.RequestModuleInterface() == this) + { + scene.UnregisterModuleInterface(this); + } + } + + public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) + { + // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info + // scene.EventManager.OnNewClient += OnNewClient; + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + + + + #region IGroupsServicesConnector Members + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, + bool maturePublish, UUID founderID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + OSDMap GroupInfoMap = new OSDMap(); + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + GroupInfoMap["FounderID"] = OSD.FromUUID(founderID); + GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers); + GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); + GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); + + if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) + { + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + + AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); + + return GroupID; + } + else + { + return UUID.Zero; + } + } + + + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, + bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // TODO: Check to make sure requestingAgentID has permission to update group + + string GroupName; + OSDMap GroupInfoMap; + if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) + { + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + + SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap); + } + + } + + + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupRoleInfo = new OSDMap(); + GroupRoleInfo["Name"] = OSD.FromString(name); + GroupRoleInfo["Description"] = OSD.FromString(description); + GroupRoleInfo["Title"] = OSD.FromString(title); + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + // TODO: Add security, make sure that requestingAgentID has permision to add roles + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Add security + + // Can't delete the Everyone Role + if (roleID != UUID.Zero) + { + // Remove all GroupRole Members from Role + Dictionary GroupRoleMembers; + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) + { + foreach(UUID UserID in GroupRoleMembers.Keys) + { + EnsureRoleNotSelectedByMember(groupID, roleID, UserID); + + SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString()); + } + } + + // Remove role + SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString()); + } + } + + + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security, check that requestingAgentID is allowed to update group roles + + OSDMap GroupRoleInfo; + if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo)) + { + if (name != null) + { + GroupRoleInfo["Name"] = OSD.FromString(name); + } + if (description != null) + { + GroupRoleInfo["Description"] = OSD.FromString(description); + } + if (title != null) + { + GroupRoleInfo["Title"] = OSD.FromString(title); + } + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + } + + + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupInfoMap = null; + if (groupID != UUID.Zero) + { + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap)) + { + return null; + } + } + else if ((groupName != null) && (groupName != string.Empty)) + { + if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) + { + return null; + } + } + + GroupRecord GroupInfo = new GroupRecord(); + + GroupInfo.GroupID = groupID; + GroupInfo.GroupName = groupName; + GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); + GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); + GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID(); + GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger(); + GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean(); + GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean(); + GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean(); + GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID(); + GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID(); + + return GroupInfo; + + } + + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap groupProfile; + string groupName; + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile)) + { + // GroupProfileData is not nullable + return new GroupProfileData(); + } + + GroupProfileData MemberGroupProfile = new GroupProfileData(); + MemberGroupProfile.GroupID = groupID; + MemberGroupProfile.Name = groupName; + + if (groupProfile["Charter"] != null) + { + MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); + } + + MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; + MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); + MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); + MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean(); + MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); + MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); + MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; + MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); + + Dictionary Members; + if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) + { + MemberGroupProfile.GroupMembershipCount = Members.Count; + } + + Dictionary Roles; + if (SimianGetGenericEntries(groupID, "GroupRole", out Roles)) + { + MemberGroupProfile.GroupRolesCount = Roles.Count; + } + + // TODO: Get Group Money balance from somewhere + // group.Money = 0; + + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + } + + public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap ActiveGroup = new OSDMap(); + ActiveGroup.Add("GroupID", OSD.FromUUID(groupID)); + SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup); + } + + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); + GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); + GroupMemberInfo["Contribution"] = OSD.FromInteger(0); + GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Invite = new OSDMap(); + Invite["AgentID"] = OSD.FromUUID(agentID); + Invite["RoleID"] = OSD.FromUUID(roleID); + + SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite); + } + + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInvite; + UUID GroupID; + if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite)) + { + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = GroupID; + inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID(); + inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID(); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID); + SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString()); + } + + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Setup Agent/Group information + SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true); + + // Add agent to Everyone Group + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero); + + // Add agent to Specified Role + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + + // Set selected role in this group to specified role + SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + } + + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If current active group is the group the agent is being removed from, change their group to UUID.Zero + GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID); + if (memberActiveMembership.GroupID == groupID) + { + SetAgentActiveGroup(agentID, agentID, UUID.Zero); + } + + // Remove Group Member information for this group + SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); + + // By using a Simian Generics Type consisting of a prefix and a groupID, + // combined with RoleID as key allows us to get a list of roles a particular member + // of a group is assigned to. + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + + // Take Agent out of all other group roles + Dictionary GroupRoles; + if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles)) + { + foreach (string roleID in GroupRoles.Keys) + { + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID); + } + } + } + + public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap()); + } + + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Cannot remove members from the Everyone Role + if (roleID != UUID.Zero) + { + EnsureRoleNotSelectedByMember(groupID, roleID, agentID); + + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString()); + } + } + + public List FindGroups(UUID requestingAgentID, string search) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List findings = new List(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", "Group" }, + { "Key", search }, + { "Fuzzy", "1" } + }; + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = entryMap["OwnerID"].AsUUID(); + data.groupName = entryMap["Key"].AsString(); + + // TODO: is there a better way to do this? + Dictionary Members; + if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members)) + { + data.members = Members.Count; + } + else + { + data.members = 0; + } + + // TODO: sort results? + // data.searchOrder = order; + + findings.Add(data); + } + } + + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData data = new GroupMembershipData(); + + /////////////////////////////// + // Agent Specific Information: + // + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); + } + + OSDMap UserGroupMemberInfo; + if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) + { + data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); + data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); + data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); + data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); + + /////////////////////////////// + // Role Specific Information: + // + + OSDMap GroupRoleInfo; + if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) + { + data.GroupTitle = GroupRoleInfo["Title"].AsString(); + data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); + } + } + + /////////////////////////////// + // Group Specific Information: + // + OSDMap GroupInfo; + string GroupName; + if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) + { + data.GroupID = groupID; + data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); + data.Charter = GroupInfo["Charter"].AsString(); + data.FounderID = GroupInfo["FounderID"].AsUUID(); + data.GroupName = GroupName; + data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); + data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); + data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); + data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); + data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); + } + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Zero; + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + GroupID = UserActiveGroup["GroupID"].AsUUID(); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); + } + + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List memberships = new List(); + + Dictionary GroupMemberShips; + if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips)) + { + foreach (string key in GroupMemberShips.Keys) + { + memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); + } + } + + return memberships; + } + + public List GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } + } + return Roles; + } + + public List GetGroupRoles(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach (KeyValuePair role in GroupRoles) + { + GroupRolesData data = new GroupRolesData(); + + data.RoleID = UUID.Parse(role.Key); + + data.Name = role.Value["Name"].AsString(); + data.Description = role.Value["Description"].AsString(); + data.Title = role.Value["Title"].AsString(); + data.Powers = role.Value["Powers"].AsULong(); + + Dictionary GroupRoleMembers; + if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers)) + { + data.Members = GroupRoleMembers.Count; + } + else + { + data.Members = 0; + } + + Roles.Add(data); + } + } + + return Roles; + + } + + + + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + OSDMap GroupInfo; + string GroupName; + UUID GroupOwnerRoleID = UUID.Zero; + if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo)) + { + return members; + } + GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID(); + + // Locally cache group roles, since we'll be needing this data for each member + Dictionary GroupRoles; + SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles); + + // Locally cache list of group owners + Dictionary GroupOwners; + SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners); + + + Dictionary GroupMembers; + if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers)) + { + foreach (KeyValuePair member in GroupMembers) + { + GroupMembersData data = new GroupMembersData(); + + data.AgentID = member.Key; + + UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID(); + + data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean(); + data.ListInProfile = member.Value["ListInProfile"].AsBoolean(); + data.Contribution = member.Value["Contribution"].AsInteger(); + + data.IsOwner = GroupOwners.ContainsKey(member.Key); + + OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()]; + data.Title = GroupRoleInfo["Title"].AsString(); + data.AgentPowers = GroupRoleInfo["Powers"].AsULong(); + + members.Add(data); + } + } + + return members; + + } + + public List GetGroupRoleMembers(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach( KeyValuePair Role in GroupRoles ) + { + Dictionary GroupRoleMembers; + if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) + { + foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = GroupRoleMember.Key; + data.RoleID = UUID.Parse(Role.Key); + + members.Add(data); + } + } + } + } + + return members; + } + + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List values = new List(); + + Dictionary Notices; + if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices)) + { + foreach (KeyValuePair Notice in Notices) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse(Notice.Key); + data.Timestamp = Notice.Value["TimeStamp"].AsUInteger(); + data.FromName = Notice.Value["FromName"].AsString(); + data.Subject = Notice.Value["Subject"].AsString(); + data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0; + + //TODO: Figure out how to get this + data.AssetType = 0; + + values.Add(data); + } + } + + return values; + + } + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupNotice; + UUID GroupID; + if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) + { + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = GroupID; + data.Message = GroupNotice["Message"].AsString(); + data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(); + data.noticeData.NoticeID = noticeID; + data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger(); + data.noticeData.FromName = GroupNotice["FromName"].AsString(); + data.noticeData.Subject = GroupNotice["Subject"].AsString(); + data.noticeData.HasAttachment = data.BinaryBucket.Length > 0; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + return null; + } + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Notice = new OSDMap(); + Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch()); + Notice["FromName"] = OSD.FromString(fromName); + Notice["Subject"] = OSD.FromString(subject); + Notice["Message"] = OSD.FromString(message); + Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); + + SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); + + } + #endregion + + + private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If member's SelectedRole is roleID, change their selected role to Everyone + // before removing them from the role + OSDMap UserGroupInfo; + if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo)) + { + if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID) + { + UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero); + } + SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo); + } + } + + + #region Simian Util Methods + private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + string value = OSDParser.SerializeJsonString(map); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "AddGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key }, + { "Value", value} + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]); + return false; + } + } + + /// + /// Returns the first of possibly many entries for Owner/Type pair + /// + private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + key = null; + map = null; + return false; + } + private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + ownerID = UUID.Zero; + map = null; + return false; + } + + private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count == 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + map = null; + return false; + } + + private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + private bool SimianGetGenericEntries(string type, string key, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key } + }; + + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + + private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key } + }; + + + OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + if (response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]); + return false; + } + } + #endregion + } + +} + diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 964d0bb..ab343c8 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -40,16 +40,16 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; +using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | @@ -68,6 +68,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupReadKey = string.Empty; private string m_groupWriteKey = string.Empty; + private IUserAccountService m_accountService = null; + #region IRegionModuleBase Members @@ -118,6 +120,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; } @@ -131,13 +136,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (m_connectorEnabled) + { + + if (m_accountService == null) + { + m_accountService = scene.UserAccountService; + } + + scene.RegisterModuleInterface(this); + } } public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (scene.RequestModuleInterface() == this) + { scene.UnregisterModuleInterface(this); + } } public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) @@ -157,14 +173,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - - #region IGroupsServicesConnector Members /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { @@ -236,7 +250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); if (respData.Contains("error")) { @@ -248,7 +262,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { @@ -262,10 +276,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - XmlRpcCall(requestID, "groups.updateGroup", param); + XmlRpcCall(requestingAgentID, "groups.updateGroup", param); } - public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -276,19 +290,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.addRoleToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addRoleToGroup", param); } - public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -308,10 +322,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.updateGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.updateGroupRole", param); } - public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); if (GroupID != UUID.Zero) @@ -323,7 +337,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -334,12 +348,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -347,38 +361,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return new GroupProfileData(); } - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; - } - - - public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void SetAgentActiveGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); + XmlRpcCall(requestingAgentID, "groups.setAgentActiveGroup", param); } - public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + public void SetAgentGroupInfo(UUID requestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); @@ -386,11 +397,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); @@ -398,16 +409,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupInvite", param); } - public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { @@ -423,60 +434,59 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return inviteInfo; } - public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentToGroupInvite", param); } - public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroup", param); } - public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroup", param); } - public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupRole", param); } - public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroupRole", param); } - - public List FindGroups(GroupRequestID requestID, string search) + public List FindGroups(UUID requestingAgentID, string search) { Hashtable param = new Hashtable(); param["Search"] = search; - Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.findGroups", param); List findings = new List(); @@ -498,13 +508,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return findings; } - public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMembership", param); if (respData.Contains("error")) { @@ -516,12 +526,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentActiveMembership", param); if (respData.Contains("error")) { @@ -531,13 +541,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - - public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMemberships", param); List memberships = new List(); @@ -552,13 +561,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return memberships; } - public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public List GetAgentGroupRoles(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentRoles", param); List Roles = new List(); @@ -584,12 +593,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoles", param); List Roles = new List(); @@ -617,12 +626,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupMembers", param); List members = new List(); @@ -650,12 +659,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoleMembers", param); List members = new List(); @@ -674,12 +683,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return members; } - public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotices", param); List values = new List(); @@ -701,12 +710,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return values; } - public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); if (respData.Contains("error")) @@ -732,7 +741,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -745,7 +754,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - XmlRpcCall(requestID, "groups.addGroupNotice", param); + XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } #endregion @@ -778,7 +787,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { - GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -797,6 +805,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) { GroupMembershipData data = new GroupMembershipData(); @@ -829,6 +838,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; } @@ -837,15 +847,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Encapsulate the XmlRpc call to standardize security and error handling. /// - private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) + private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - if (requestID == null) - { - requestID = new GroupRequestID(); - } - param.Add("RequestingAgentID", requestID.AgentID.ToString()); - param.Add("RequestingAgentUserService", requestID.UserServiceURL); - param.Add("RequestingSessionID", requestID.SessionID.ToString()); + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); param.Add("ReadKey", m_groupReadKey); @@ -936,15 +945,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + + /// + /// Group Request Tokens are an attempt to allow the groups service to authenticate + /// requests. Currently uses UserService, AgentID, and SessionID + /// TODO: Find a better way to do this. + /// + /// + /// + private void GetClientGroupRequestID(UUID AgentID, out string UserServiceURL, out UUID SessionID) + { + UserServiceURL = ""; + SessionID = UUID.Zero; - } - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; + // Need to rework this based on changes to User Services + /* + UserAccount userAccount = m_accountService.GetUserAccount(UUID.Zero,AgentID); + if (userAccount == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a UserServiceURL for {0}", AgentID); + + } + else if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + UserServiceURL = fupd.UserServerURI; + SessionID = fupd.CurrentAgent.SessionID; + + } + else + { + // They're a local user, use this: + UserServiceURL = m_commManager.NetworkServersInfo.UserURL; + SessionID = userProfile.CurrentAgent.SessionID; + } + */ + } + } } -- cgit v1.1 From 6fdd5bfe2d0ac1313d94466b5c8a87ef07768f29 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 5 May 2010 16:03:20 +0100 Subject: Revert "Patch from mcortez: Update groups, add ALPHA Siman grid connector for groups" The patch was for 0.7 This reverts commit 608bb0dfefbbc97aded6d1357dd9d350053411fb. --- .../Avatar/XmlRpcGroups/GroupsModule.cs | 341 +++--- .../XmlRpcGroups/IGroupsServicesConnector.cs | 62 +- .../SimianGroupsServicesConnectorModule.cs | 1278 -------------------- .../XmlRpcGroupsServicesConnectorModule.cs | 209 ++-- 4 files changed, 320 insertions(+), 1570 deletions(-) delete mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 6b942cb..8d32e66 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -43,8 +43,6 @@ using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; - using Caps = OpenSim.Framework.Capabilities.Caps; using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; @@ -89,6 +87,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsServicesConnector m_groupData = null; + class GroupRequestIDInfo + { + public GroupRequestID RequestID = new GroupRequestID(); + public DateTime LastUsedTMStamp = DateTime.MinValue; + } + private Dictionary m_clientRequestIDInfo = new Dictionary(); + private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes + private Timer m_clientRequestIDFlushTimer; + + // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; @@ -125,6 +133,30 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + m_clientRequestIDFlushTimer = new Timer(); + m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; + m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; + m_clientRequestIDFlushTimer.AutoReset = true; + m_clientRequestIDFlushTimer.Start(); + } + } + + void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) + { + lock (m_clientRequestIDInfo) + { + TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); + UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; + foreach (UUID key in CurrentKeys) + { + if (m_clientRequestIDInfo.ContainsKey(key)) + { + if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) + { + m_clientRequestIDInfo.Remove(key); + } + } + } } } @@ -202,6 +234,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); + + m_clientRequestIDFlushTimer.Stop(); } public Type ReplaceableInterface @@ -238,7 +272,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - // Send client thier groups information. + lock (m_clientRequestIDInfo) + { + if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) + { + // flush any old RequestID information + m_clientRequestIDInfo.Remove(client.AgentId); + } + } SendAgentGroupDataUpdate(client, client.AgentId); } @@ -246,7 +287,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray(); + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -285,17 +326,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } */ + void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - if (m_debugEnabled) - m_log.DebugFormat( - "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", - System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); } } @@ -309,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -322,13 +361,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) + private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string GroupName; - GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); + GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); if (group != null) { GroupName = group.GroupName; @@ -349,7 +388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); if (inviteInfo == null) { @@ -368,7 +407,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role - m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -392,14 +431,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee - m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); } } } @@ -413,7 +452,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) + if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -457,21 +496,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) { if (m_debugEnabled) { - UserAccount targetUser = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, member.AgentID); - if (targetUser != null) + UserProfileData targetUserProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(member.AgentID); + if (targetUserProfile != null) { - m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUser.FirstName + " " + targetUser.LastName, member.AcceptNotices); + m_log.DebugFormat("[GROUPS]: Prepping group notice {0} for agent: {1} who Accepts Notices ({2})", NoticeID, targetUserProfile.Name, member.AcceptNotices); } else { @@ -549,25 +588,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + return m_groupData.GetGroupRecord(null, GroupID, null); } - public GroupRecord GetGroupRecord(string name) - { - return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); - } - public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); // Changing active group changes title, active powers, all kinds of things // anyone who is in any region that can see this client, should probably be // updated with new group info. At a minimum, they should get ScenePresence // updated with new title. - UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); + UpdateAllClientsWithGroupInfo(remoteClient.AgentId); } /// @@ -577,9 +611,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); - List agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); List titles = new List(); foreach (GroupRolesData role in agentRoles) @@ -601,15 +636,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); - } - } + + List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); return data; @@ -619,25 +647,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID); + List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); return data; + } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); - - if (m_debugEnabled) - { - foreach (GroupRoleMembersData member in data) - { - m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); - } - } + List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); + return data; + + } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) @@ -646,16 +670,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupProfileData profile = new GroupProfileData(); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); if (groupInfo != null) { profile.AllowPublish = groupInfo.AllowPublish; profile.Charter = groupInfo.Charter; profile.FounderID = groupInfo.FounderID; profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID).Count; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; profile.InsigniaID = groupInfo.GroupPicture; profile.MaturePublish = groupInfo.MaturePublish; profile.MembershipFee = groupInfo.MembershipFee; @@ -666,7 +691,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups profile.ShowInList = groupInfo.ShowInList; } - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); if (memberInfo != null) { profile.MemberTitle = memberInfo.GroupTitle; @@ -680,46 +705,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(UUID.Zero, agentID).ToArray(); + return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) - m_log.DebugFormat( - "[GROUPS]: {0} called with groupID={1}, agentID={2}", - System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); + if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); + return m_groupData.GetAgentGroupMembership(null, agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // Note: Permissions checking for modification rights is handled by the Groups Server/Service - m_groupData.UpdateGroup(GetRequestingAgentID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + // TODO: Security Check? + + m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { - // Note: Permissions checking for modification rights is handled by the Groups Server/Service + // TODO: Security Check? if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentGroupInfo(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, acceptNotices, listInProfile); + m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; } // is there is a money module present ? - IMoneyModule money = remoteClient.Scene.RequestModuleInterface(); + IMoneyModule money=remoteClient.Scene.RequestModuleInterface(); if (money != null) { // do the transaction, that is if the agent has got sufficient funds @@ -727,14 +752,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); return UUID.Zero; } - money.ApplyGroupCreationCharge(GetRequestingAgentID(remoteClient)); + money.ApplyGroupCreationCharge(remoteClient.AgentId); } - UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); + UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); return groupID; } @@ -745,7 +770,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // ToDo: check if agent is a member of group and is allowed to see notices? - return m_groupData.GetGroupNotices(GetRequestingAgentID(remoteClient), groupID).ToArray(); + return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); } /// @@ -755,7 +780,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(UUID.Zero, avatarID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); if (membership != null) { return membership.GroupTitle; @@ -770,13 +795,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, titleRoleID); + m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too - // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) + // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) - UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); + UpdateAllClientsWithGroupInfo(remoteClient.AgentId); } @@ -786,14 +811,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Security Checks are handled in the Groups Service. + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(GetRequestingAgentID(remoteClient), groupID, UUID.Random(), name, description, title, powers); + m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID); + m_groupData.RemoveGroupRole(grID, groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: @@ -804,7 +831,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupPowers gp = (GroupPowers)powers; m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); } - m_groupData.UpdateGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID, name, description, title, powers); + m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: @@ -815,7 +842,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) @@ -823,16 +850,18 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + switch (changes) { case 0: // Add - m_groupData.AddAgentToGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); + m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); break; case 1: // Remove - m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); + m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); break; default: @@ -841,23 +870,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupNoticeInfo data = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), groupNoticeID); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); + + GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.toAgentID = remoteClient.AgentId.Guid; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; msg.message = data.noticeData.Subject + "|" + data.Message; @@ -869,7 +900,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = data.BinaryBucket; - OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); + OutgoingInstantMessage(msg, remoteClient.AgentId); } } @@ -889,7 +920,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; - GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID); + GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); if (info != null) { msg.fromAgentID = info.GroupID.Guid; @@ -916,7 +947,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) @@ -924,19 +955,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); + m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); remoteClient.SendLeaveGroupReply(groupID, true); @@ -944,32 +975,34 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // SL sends out notifcations to the group messaging session that the person has left // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); + SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + GroupRequestID grID = GetClientGroupRequestID(remoteClient); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); + remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); - UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, ejecteeID); - if ((groupInfo == null) || (account == null)) + if ((groupInfo == null) || (userProfile == null)) { return; - } + } + // Send Message to Ejectee GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -995,13 +1028,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; - msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.fromAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = remoteClient.AgentId.Guid; msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; - if (account != null) + if (userProfile != null) { - msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, account.FirstName + " " + account.LastName); + msg.message = string.Format("{2} has been ejected from '{1}' by {0}.", remoteClient.Name, groupInfo.GroupName, userProfile.Name); } else { @@ -1014,7 +1047,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); + OutgoingInstantMessage(msg, remoteClient.AgentId); // SL sends out messages to everyone in the group @@ -1028,12 +1061,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); + GroupRequestID grid = GetClientGroupRequestID(remoteClient); - m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); if (inviteInfo != null) { @@ -1045,7 +1079,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + // msg.fromAgentID = remoteClient.AgentId.Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1098,6 +1132,57 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return child; } + private GroupRequestID GetClientGroupRequestID(IClientAPI client) + { + if (client == null) + { + return new GroupRequestID(); + } + + lock (m_clientRequestIDInfo) + { + if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) + { + GroupRequestIDInfo info = new GroupRequestIDInfo(); + info.RequestID.AgentID = client.AgentId; + info.RequestID.SessionID = client.SessionId; + + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); + if (userProfile == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); + + // Default to local user service and hope for the best? + info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + + } + else if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + info.RequestID.UserServiceURL = fupd.UserServerURI; + } + else + { + // They're a local user, use this: + info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; + } + + m_clientRequestIDInfo.Add(client.AgentId, info); + } + + m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; + + return m_clientRequestIDInfo[client.AgentId].RequestID; + } +// Unreachable code! +// return new GroupRequestID(); + } + /// /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. /// @@ -1116,7 +1201,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups foreach (GroupMembershipData membership in data) { - if (GetRequestingAgentID(remoteClient) != dataForAgentID) + if (remoteClient.AgentId != dataForAgentID) { if (!membership.ListInProfile) { @@ -1144,18 +1229,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups OSDMap llDataStruct = new OSDMap(3); llDataStruct.Add("AgentData", AgentData); llDataStruct.Add("GroupData", GroupData); - llDataStruct.Add("NewGroupData", NewGroupData); - - if (m_debugEnabled) - { - m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); - } + llDataStruct.Add("NewGroupData", NewGroupData); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) { - queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), GetRequestingAgentID(remoteClient)); + queue.Enqueue(EventQueueHelper.buildEvent("AgentGroupDataUpdate", llDataStruct), remoteClient.AgentId); } } @@ -1228,7 +1308,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) { - List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); + List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); GroupMembershipData[] membershipArray; if (requestingClient.AgentId != dataForAgentID) @@ -1250,7 +1330,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); foreach (GroupMembershipData membership in membershipArray) { - m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2} - {3}", dataForAgentID, membership.GroupName, membership.GroupTitle, membership.GroupPowers); + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); } } @@ -1262,12 +1342,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // TODO: All the client update functions need to be reexamined because most do too much and send too much stuff - UserAccount account = m_sceneList[0].UserAccountService.GetUserAccount(remoteClient.Scene.RegionInfo.ScopeID, dataForAgentID); + UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(dataForAgentID); string firstname, lastname; - if (account != null) + if (userProfile != null) { - firstname = account.FirstName; - lastname = account.LastName; + firstname = userProfile.FirstName; + lastname = userProfile.SurName; } else { @@ -1308,24 +1388,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // } - #endregion - - private UUID GetRequestingAgentID(IClientAPI client) - { - UUID requestingAgentID = UUID.Zero; - if (client != null) - { - requestingAgentID = client.AgentId; - } - return requestingAgentID; - } + #endregion } - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 6487967..9e0fa2d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,41 +36,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { interface IGroupsServicesConnector { - UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); - List FindGroups(UUID RequestingAgentID, string search); - List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); + UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); + List FindGroups(GroupRequestID requestID, string search); + List GetGroupMembers(GroupRequestID requestID, UUID GroupID); - void AddGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID); - List GetGroupRoles(UUID RequestingAgentID, UUID GroupID); - List GetGroupRoleMembers(UUID RequestingAgentID, UUID GroupID); + void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); + List GetGroupRoles(GroupRequestID requestID, UUID GroupID); + List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); - void AddAgentToGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - void AddAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); - void RemoveAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void AddAgentToGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void SetAgentActiveGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(UUID RequestingAgentID, UUID AgentID); + void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); - void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); - GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); + void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); - List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); + GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); + + void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); + List GetGroupNotices(GroupRequestID requestID, UUID GroupID); } public class GroupInviteInfo @@ -80,4 +81,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public UUID AgentID = UUID.Zero; public UUID InviteID = UUID.Zero; } + + public class GroupRequestID + { + public UUID AgentID = UUID.Zero; + public string UserServiceURL = string.Empty; + public UUID SessionID = UUID.Zero; + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs deleted file mode 100644 index 590753e..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ /dev/null @@ -1,1278 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Reflection; - -using Nwc.XmlRpc; - -using log4net; -using Mono.Addins; -using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Services.Interfaces; - -/*************************************************************************** - * Simian Data Map - * =============== - * - * OwnerID -> Type -> Key - * ----------------------- - * - * UserID -> Group -> ActiveGroup - * + GroupID - * - * UserID -> GroupMember -> GroupID - * + SelectedRoleID [UUID] - * + AcceptNotices [bool] - * + ListInProfile [bool] - * + Contribution [int] - * - * UserID -> GroupRole[GroupID] -> RoleID - * - * GroupID -> Group -> GroupName - * + Charter - * + ShowInList - * + InsigniaID - * + MembershipFee - * + OpenEnrollment - * + AllowPublish - * + MaturePublish - * + FounderID - * + EveryonePowers - * + OwnerRoleID - * + OwnersPowers - * - * GroupID -> GroupRole -> RoleID - * + Name - * + Description - * + Title - * + Powers - * - * GroupID -> GroupMemberInvite -> InviteID - * + AgentID - * + RoleID - * - * GroupID -> GroupNotice -> NoticeID - * + TimeStamp [uint] - * + FromName [string] - * + Subject [string] - * + Message [string] - * + BinaryBucket [byte[]] - * - * */ - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; - - // Would this be cleaner as (GroupPowers)ulong.MaxValue; - public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable - | GroupPowers.AllowEditLand - | GroupPowers.AllowFly - | GroupPowers.AllowLandmark - | GroupPowers.AllowRez - | GroupPowers.AllowSetHome - | GroupPowers.AllowVoiceChat - | GroupPowers.AssignMember - | GroupPowers.AssignMemberLimited - | GroupPowers.ChangeActions - | GroupPowers.ChangeIdentity - | GroupPowers.ChangeMedia - | GroupPowers.ChangeOptions - | GroupPowers.CreateRole - | GroupPowers.DeedObject - | GroupPowers.DeleteRole - | GroupPowers.Eject - | GroupPowers.FindPlaces - | GroupPowers.Invite - | GroupPowers.JoinChat - | GroupPowers.LandChangeIdentity - | GroupPowers.LandDeed - | GroupPowers.LandDivideJoin - | GroupPowers.LandEdit - | GroupPowers.LandEjectAndFreeze - | GroupPowers.LandGardening - | GroupPowers.LandManageAllowed - | GroupPowers.LandManageBanned - | GroupPowers.LandManagePasses - | GroupPowers.LandOptions - | GroupPowers.LandRelease - | GroupPowers.LandSetSale - | GroupPowers.ModerateChat - | GroupPowers.ObjectManipulate - | GroupPowers.ObjectSetForSale - | GroupPowers.ReceiveNotices - | GroupPowers.RemoveMember - | GroupPowers.ReturnGroupOwned - | GroupPowers.ReturnGroupSet - | GroupPowers.ReturnNonGroup - | GroupPowers.RoleProperties - | GroupPowers.SendNotices - | GroupPowers.SetLandingPoint - | GroupPowers.StartProposal - | GroupPowers.VoteOnProposal; - - private bool m_connectorEnabled = false; - - private string m_serviceURL = string.Empty; - - private bool m_debugEnabled = false; - - // private IUserAccountService m_accountService = null; - - - #region IRegionModuleBase Members - - public string Name - { - get { return "SimianGroupsServicesConnector"; } - } - - // this module is not intended to be replaced, but there should only be 1 of them. - public Type ReplaceableInterface - { - get { return null; } - } - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - if (groupsConfig == null) - { - // Do not run this module by default. - return; - } - else - { - // if groups aren't enabled, we're not needed. - // if we're not specified as the connector to use, then we're not wanted - if ((groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) - { - m_connectorEnabled = false; - return; - } - - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) - { - m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); - m_connectorEnabled = false; - return; - } - - // If we got all the config options we need, lets start'er'up - m_connectorEnabled = true; - - m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - - } - } - - public void Close() - { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); - } - - public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) - { - if (m_connectorEnabled) - { - scene.RegisterModuleInterface(this); - } - } - - public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) - { - if (scene.RequestModuleInterface() == this) - { - scene.UnregisterModuleInterface(this); - } - } - - public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) - { - // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info - // scene.EventManager.OnNewClient += OnNewClient; - } - - #endregion - - #region ISharedRegionModule Members - - public void PostInitialise() - { - // NoOp - } - - #endregion - - - - - #region IGroupsServicesConnector Members - - /// - /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. - /// - public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, - int membershipFee, bool openEnrollment, bool allowPublish, - bool maturePublish, UUID founderID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UUID GroupID = UUID.Random(); - UUID OwnerRoleID = UUID.Random(); - - OSDMap GroupInfoMap = new OSDMap(); - GroupInfoMap["Charter"] = OSD.FromString(charter); - GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); - GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); - GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); - GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); - GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); - GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); - GroupInfoMap["FounderID"] = OSD.FromUUID(founderID); - GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers); - GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); - GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); - - if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) - { - AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); - AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); - - AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); - - return GroupID; - } - else - { - return UUID.Zero; - } - } - - - public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, - UUID insigniaID, int membershipFee, bool openEnrollment, - bool allowPublish, bool maturePublish) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Check to make sure requestingAgentID has permission to update group - - string GroupName; - OSDMap GroupInfoMap; - if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) - { - GroupInfoMap["Charter"] = OSD.FromString(charter); - GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); - GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); - GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); - GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); - GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); - GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); - - SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap); - } - - } - - - public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, - string title, ulong powers) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupRoleInfo = new OSDMap(); - GroupRoleInfo["Name"] = OSD.FromString(name); - GroupRoleInfo["Description"] = OSD.FromString(description); - GroupRoleInfo["Title"] = OSD.FromString(title); - GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); - - // TODO: Add security, make sure that requestingAgentID has permision to add roles - SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); - } - - public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Add security - - // Can't delete the Everyone Role - if (roleID != UUID.Zero) - { - // Remove all GroupRole Members from Role - Dictionary GroupRoleMembers; - string GroupRoleMemberType = "GroupRole" + groupID.ToString(); - if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) - { - foreach(UUID UserID in GroupRoleMembers.Keys) - { - EnsureRoleNotSelectedByMember(groupID, roleID, UserID); - - SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString()); - } - } - - // Remove role - SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString()); - } - } - - - public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, - string title, ulong powers) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Security, check that requestingAgentID is allowed to update group roles - - OSDMap GroupRoleInfo; - if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo)) - { - if (name != null) - { - GroupRoleInfo["Name"] = OSD.FromString(name); - } - if (description != null) - { - GroupRoleInfo["Description"] = OSD.FromString(description); - } - if (title != null) - { - GroupRoleInfo["Title"] = OSD.FromString(title); - } - GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); - - } - - - SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); - } - - public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupInfoMap = null; - if (groupID != UUID.Zero) - { - if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap)) - { - return null; - } - } - else if ((groupName != null) && (groupName != string.Empty)) - { - if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) - { - return null; - } - } - - GroupRecord GroupInfo = new GroupRecord(); - - GroupInfo.GroupID = groupID; - GroupInfo.GroupName = groupName; - GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); - GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); - GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID(); - GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger(); - GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean(); - GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean(); - GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean(); - GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID(); - GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID(); - - return GroupInfo; - - } - - public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap groupProfile; - string groupName; - if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile)) - { - // GroupProfileData is not nullable - return new GroupProfileData(); - } - - GroupProfileData MemberGroupProfile = new GroupProfileData(); - MemberGroupProfile.GroupID = groupID; - MemberGroupProfile.Name = groupName; - - if (groupProfile["Charter"] != null) - { - MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); - } - - MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; - MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); - MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); - MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean(); - MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); - MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); - MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; - MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); - - Dictionary Members; - if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) - { - MemberGroupProfile.GroupMembershipCount = Members.Count; - } - - Dictionary Roles; - if (SimianGetGenericEntries(groupID, "GroupRole", out Roles)) - { - MemberGroupProfile.GroupRolesCount = Roles.Count; - } - - // TODO: Get Group Money balance from somewhere - // group.Money = 0; - - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID); - - MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; - MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; - - return MemberGroupProfile; - } - - public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap ActiveGroup = new OSDMap(); - ActiveGroup.Add("GroupID", OSD.FromUUID(groupID)); - SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup); - } - - public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupMemberInfo; - if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) - { - GroupMemberInfo = new OSDMap(); - } - - GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID); - SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); - } - - public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupMemberInfo; - if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) - { - GroupMemberInfo = new OSDMap(); - } - - GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); - GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); - GroupMemberInfo["Contribution"] = OSD.FromInteger(0); - GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero); - SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); - } - - public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap Invite = new OSDMap(); - Invite["AgentID"] = OSD.FromUUID(agentID); - Invite["RoleID"] = OSD.FromUUID(roleID); - - SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite); - } - - public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupMemberInvite; - UUID GroupID; - if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite)) - { - return null; - } - - GroupInviteInfo inviteInfo = new GroupInviteInfo(); - inviteInfo.InviteID = inviteID; - inviteInfo.GroupID = GroupID; - inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID(); - inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID(); - - return inviteInfo; - } - - public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID); - SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString()); - } - - public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Setup Agent/Group information - SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true); - - // Add agent to Everyone Group - AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero); - - // Add agent to Specified Role - AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID); - - // Set selected role in this group to specified role - SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID); - } - - public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // If current active group is the group the agent is being removed from, change their group to UUID.Zero - GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID); - if (memberActiveMembership.GroupID == groupID) - { - SetAgentActiveGroup(agentID, agentID, UUID.Zero); - } - - // Remove Group Member information for this group - SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); - - // By using a Simian Generics Type consisting of a prefix and a groupID, - // combined with RoleID as key allows us to get a list of roles a particular member - // of a group is assigned to. - string GroupRoleMemberType = "GroupRole" + groupID.ToString(); - - // Take Agent out of all other group roles - Dictionary GroupRoles; - if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles)) - { - foreach (string roleID in GroupRoles.Keys) - { - SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID); - } - } - } - - public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap()); - } - - public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Cannot remove members from the Everyone Role - if (roleID != UUID.Zero) - { - EnsureRoleNotSelectedByMember(groupID, roleID, agentID); - - string GroupRoleMemberType = "GroupRole" + groupID.ToString(); - SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString()); - } - } - - public List FindGroups(UUID requestingAgentID, string search) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List findings = new List(); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "Type", "Group" }, - { "Key", search }, - { "Fuzzy", "1" } - }; - - - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); - if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)response["Entries"]; - foreach (OSDMap entryMap in entryArray) - { - DirGroupsReplyData data = new DirGroupsReplyData(); - data.groupID = entryMap["OwnerID"].AsUUID(); - data.groupName = entryMap["Key"].AsString(); - - // TODO: is there a better way to do this? - Dictionary Members; - if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members)) - { - data.members = Members.Count; - } - else - { - data.members = 0; - } - - // TODO: sort results? - // data.searchOrder = order; - - findings.Add(data); - } - } - - - return findings; - } - - public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupMembershipData data = new GroupMembershipData(); - - /////////////////////////////// - // Agent Specific Information: - // - OSDMap UserActiveGroup; - if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) - { - data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); - } - - OSDMap UserGroupMemberInfo; - if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) - { - data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); - data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); - data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); - data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); - - /////////////////////////////// - // Role Specific Information: - // - - OSDMap GroupRoleInfo; - if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) - { - data.GroupTitle = GroupRoleInfo["Title"].AsString(); - data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); - } - } - - /////////////////////////////// - // Group Specific Information: - // - OSDMap GroupInfo; - string GroupName; - if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) - { - data.GroupID = groupID; - data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); - data.Charter = GroupInfo["Charter"].AsString(); - data.FounderID = GroupInfo["FounderID"].AsUUID(); - data.GroupName = GroupName; - data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); - data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); - data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); - data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); - data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); - } - - return data; - } - - public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UUID GroupID = UUID.Zero; - OSDMap UserActiveGroup; - if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) - { - GroupID = UserActiveGroup["GroupID"].AsUUID(); - } - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); - return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); - } - - public List GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List memberships = new List(); - - Dictionary GroupMemberShips; - if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips)) - { - foreach (string key in GroupMemberShips.Keys) - { - memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); - } - } - - return memberships; - } - - public List GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List Roles = new List(); - - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - Dictionary MemberRoles; - if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) - { - foreach (KeyValuePair kvp in MemberRoles) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = UUID.Parse(kvp.Key); - data.Name = GroupRoles[kvp.Key]["Name"].AsString(); - data.Description = GroupRoles[kvp.Key]["Description"].AsString(); - data.Title = GroupRoles[kvp.Key]["Title"].AsString(); - data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); - - Roles.Add(data); - } - } - } - return Roles; - } - - public List GetGroupRoles(UUID requestingAgentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List Roles = new List(); - - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - foreach (KeyValuePair role in GroupRoles) - { - GroupRolesData data = new GroupRolesData(); - - data.RoleID = UUID.Parse(role.Key); - - data.Name = role.Value["Name"].AsString(); - data.Description = role.Value["Description"].AsString(); - data.Title = role.Value["Title"].AsString(); - data.Powers = role.Value["Powers"].AsULong(); - - Dictionary GroupRoleMembers; - if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers)) - { - data.Members = GroupRoleMembers.Count; - } - else - { - data.Members = 0; - } - - Roles.Add(data); - } - } - - return Roles; - - } - - - - public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List members = new List(); - - OSDMap GroupInfo; - string GroupName; - UUID GroupOwnerRoleID = UUID.Zero; - if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo)) - { - return members; - } - GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID(); - - // Locally cache group roles, since we'll be needing this data for each member - Dictionary GroupRoles; - SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles); - - // Locally cache list of group owners - Dictionary GroupOwners; - SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners); - - - Dictionary GroupMembers; - if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers)) - { - foreach (KeyValuePair member in GroupMembers) - { - GroupMembersData data = new GroupMembersData(); - - data.AgentID = member.Key; - - UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID(); - - data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean(); - data.ListInProfile = member.Value["ListInProfile"].AsBoolean(); - data.Contribution = member.Value["Contribution"].AsInteger(); - - data.IsOwner = GroupOwners.ContainsKey(member.Key); - - OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()]; - data.Title = GroupRoleInfo["Title"].AsString(); - data.AgentPowers = GroupRoleInfo["Powers"].AsULong(); - - members.Add(data); - } - } - - return members; - - } - - public List GetGroupRoleMembers(UUID requestingAgentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List members = new List(); - - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - foreach( KeyValuePair Role in GroupRoles ) - { - Dictionary GroupRoleMembers; - if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) - { - foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) - { - GroupRoleMembersData data = new GroupRoleMembersData(); - - data.MemberID = GroupRoleMember.Key; - data.RoleID = UUID.Parse(Role.Key); - - members.Add(data); - } - } - } - } - - return members; - } - - public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List values = new List(); - - Dictionary Notices; - if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices)) - { - foreach (KeyValuePair Notice in Notices) - { - GroupNoticeData data = new GroupNoticeData(); - data.NoticeID = UUID.Parse(Notice.Key); - data.Timestamp = Notice.Value["TimeStamp"].AsUInteger(); - data.FromName = Notice.Value["FromName"].AsString(); - data.Subject = Notice.Value["Subject"].AsString(); - data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0; - - //TODO: Figure out how to get this - data.AssetType = 0; - - values.Add(data); - } - } - - return values; - - } - public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupNotice; - UUID GroupID; - if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) - { - GroupNoticeInfo data = new GroupNoticeInfo(); - data.GroupID = GroupID; - data.Message = GroupNotice["Message"].AsString(); - data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(); - data.noticeData.NoticeID = noticeID; - data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger(); - data.noticeData.FromName = GroupNotice["FromName"].AsString(); - data.noticeData.Subject = GroupNotice["Subject"].AsString(); - data.noticeData.HasAttachment = data.BinaryBucket.Length > 0; - data.noticeData.AssetType = 0; - - if (data.Message == null) - { - data.Message = string.Empty; - } - - return data; - } - return null; - } - public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap Notice = new OSDMap(); - Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch()); - Notice["FromName"] = OSD.FromString(fromName); - Notice["Subject"] = OSD.FromString(subject); - Notice["Message"] = OSD.FromString(message); - Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); - - SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); - - } - #endregion - - - private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // If member's SelectedRole is roleID, change their selected role to Everyone - // before removing them from the role - OSDMap UserGroupInfo; - if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo)) - { - if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID) - { - UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero); - } - SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo); - } - } - - - #region Simian Util Methods - private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); - - string value = OSDParser.SerializeJsonString(map); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value); - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "AddGeneric" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type }, - { "Key", key }, - { "Value", value} - }; - - - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); - if (Response["Success"].AsBoolean()) - { - return true; - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]); - return false; - } - } - - /// - /// Returns the first of possibly many entries for Owner/Type pair - /// - private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type); - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type } - }; - - - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); - if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); - } - key = null; - map = null; - return false; - } - private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); - - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "Type", type }, - { "Key", key} - }; - - - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); - if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - ownerID = entryMap["OwnerID"].AsUUID(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); - } - ownerID = UUID.Zero; - map = null; - return false; - } - - private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type }, - { "Key", key} - }; - - - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); - if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count == 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); - } - map = null; - return false; - } - - private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary maps) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type } - }; - - - - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); - if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) - { - maps = new Dictionary(); - - OSDArray entryArray = (OSDArray)response["Entries"]; - foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if(maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - - return true; - } - else - { - maps = null; - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]); - } - return false; - } - private bool SimianGetGenericEntries(string type, string key, out Dictionary maps) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "Type", type }, - { "Key", key } - }; - - - - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); - if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) - { - maps = new Dictionary(); - - OSDArray entryArray = (OSDArray)response["Entries"]; - foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if (maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - return true; - } - else - { - maps = null; - m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]); - } - return false; - } - - private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "RemoveGeneric" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type }, - { "Key", key } - }; - - - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); - if (response["Success"].AsBoolean()) - { - return true; - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]); - return false; - } - } - #endregion - } - -} - diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index ab343c8..964d0bb 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -40,16 +40,16 @@ using OpenMetaverse; using OpenMetaverse.StructuredData; using OpenSim.Framework; -using OpenSim.Framework.Communications; using OpenSim.Region.Framework.Interfaces; -using OpenSim.Services.Interfaces; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = + LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | @@ -68,8 +68,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupReadKey = string.Empty; private string m_groupWriteKey = string.Empty; - private IUserAccountService m_accountService = null; - #region IRegionModuleBase Members @@ -120,9 +118,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); - - - // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; } @@ -136,24 +131,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (m_connectorEnabled) - { - - if (m_accountService == null) - { - m_accountService = scene.UserAccountService; - } - - scene.RegisterModuleInterface(this); - } } public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (scene.RequestModuleInterface() == this) - { scene.UnregisterModuleInterface(this); - } } public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) @@ -173,12 +157,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + + #region IGroupsServicesConnector Members /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, + public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { @@ -250,7 +236,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); + Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); if (respData.Contains("error")) { @@ -262,7 +248,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, + public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { @@ -276,10 +262,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - XmlRpcCall(requestingAgentID, "groups.updateGroup", param); + XmlRpcCall(requestID, "groups.updateGroup", param); } - public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -290,19 +276,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - XmlRpcCall(requestingAgentID, "groups.addRoleToGroup", param); + XmlRpcCall(requestID, "groups.addRoleToGroup", param); } - public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) + public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); + XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -322,10 +308,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - XmlRpcCall(requestingAgentID, "groups.updateGroupRole", param); + XmlRpcCall(requestID, "groups.updateGroupRole", param); } - public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID GroupID, string GroupName) + public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); if (GroupID != UUID.Zero) @@ -337,7 +323,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -348,12 +334,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID) + public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -361,35 +347,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return new GroupProfileData(); } - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; + } - public void SetAgentActiveGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) + + + public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestingAgentID, "groups.setAgentActiveGroup", param); + XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); } - public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); } - public void SetAgentGroupInfo(UUID requestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); @@ -397,11 +386,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); } - public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); @@ -409,16 +398,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - XmlRpcCall(requestingAgentID, "groups.addAgentToGroupInvite", param); + XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); } - public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentToGroupInvite", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { @@ -434,59 +423,60 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return inviteInfo; } - public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - XmlRpcCall(requestingAgentID, "groups.removeAgentToGroupInvite", param); + XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); } - public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestingAgentID, "groups.addAgentToGroup", param); + XmlRpcCall(requestID, "groups.addAgentToGroup", param); } - public void RemoveAgentFromGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) + public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroup", param); + XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); } - public void AddAgentToGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestingAgentID, "groups.addAgentToGroupRole", param); + XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); } - public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroupRole", param); + XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); } - public List FindGroups(UUID requestingAgentID, string search) + + public List FindGroups(GroupRequestID requestID, string search) { Hashtable param = new Hashtable(); param["Search"] = search; - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.findGroups", param); + Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); List findings = new List(); @@ -508,13 +498,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return findings; } - public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID AgentID, UUID GroupID) + public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMembership", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); if (respData.Contains("error")) { @@ -526,12 +516,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID AgentID) + public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentActiveMembership", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); if (respData.Contains("error")) { @@ -541,12 +531,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - public List GetAgentGroupMemberships(UUID requestingAgentID, UUID AgentID) + + public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMemberships", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); List memberships = new List(); @@ -561,13 +552,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return memberships; } - public List GetAgentGroupRoles(UUID requestingAgentID, UUID AgentID, UUID GroupID) + public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentRoles", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); List Roles = new List(); @@ -593,12 +584,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) + public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoles", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); List Roles = new List(); @@ -626,12 +617,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) + public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupMembers", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); List members = new List(); @@ -659,12 +650,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) + public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoleMembers", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); List members = new List(); @@ -683,12 +674,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return members; } - public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) + public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotices", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); List values = new List(); @@ -710,12 +701,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return values; } - public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) + public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); + Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); if (respData.Contains("error")) @@ -741,7 +732,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -754,7 +745,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); + XmlRpcCall(requestID, "groups.addGroupNotice", param); } #endregion @@ -787,6 +778,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { + GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -805,7 +797,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } - private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) { GroupMembershipData data = new GroupMembershipData(); @@ -838,7 +829,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1"); - return data; } @@ -847,14 +837,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Encapsulate the XmlRpc call to standardize security and error handling. /// - private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) + private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) { - string UserService; - UUID SessionID; - GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - param.Add("requestingAgentID", requestingAgentID.ToString()); - param.Add("RequestingAgentUserService", UserService); - param.Add("RequestingSessionID", SessionID.ToString()); + if (requestID == null) + { + requestID = new GroupRequestID(); + } + param.Add("RequestingAgentID", requestID.AgentID.ToString()); + param.Add("RequestingAgentUserService", requestID.UserServiceURL); + param.Add("RequestingSessionID", requestID.SessionID.ToString()); param.Add("ReadKey", m_groupReadKey); @@ -945,49 +936,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } - - /// - /// Group Request Tokens are an attempt to allow the groups service to authenticate - /// requests. Currently uses UserService, AgentID, and SessionID - /// TODO: Find a better way to do this. - /// - /// - /// - private void GetClientGroupRequestID(UUID AgentID, out string UserServiceURL, out UUID SessionID) - { - UserServiceURL = ""; - SessionID = UUID.Zero; - - - // Need to rework this based on changes to User Services - /* - UserAccount userAccount = m_accountService.GetUserAccount(UUID.Zero,AgentID); - if (userAccount == null) - { - // This should be impossible. If I've been passed a reference to a client - // that client should be registered with the UserService. So something - // is horribly wrong somewhere. - - m_log.WarnFormat("[GROUPS]: Could not find a UserServiceURL for {0}", AgentID); - } - else if (userProfile is ForeignUserProfileData) - { - // They aren't from around here - ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; - UserServiceURL = fupd.UserServerURI; - SessionID = fupd.CurrentAgent.SessionID; + } - } - else - { - // They're a local user, use this: - UserServiceURL = m_commManager.NetworkServersInfo.UserURL; - SessionID = userProfile.CurrentAgent.SessionID; - } - */ - } - + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; } } -- cgit v1.1 From 8a69070b513f821bf295c32ad771d5f5009bec61 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 Apr 2010 16:14:02 -0700 Subject: back port groups changes --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 266 ++-- .../Avatar/XmlRpcGroups/GroupsModule.cs | 299 ++--- .../XmlRpcGroups/IGroupsServicesConnector.cs | 66 +- .../SimianGroupsServicesConnectorModule.cs | 1329 ++++++++++++++++++++ .../XmlRpcGroupsServicesConnectorModule.cs | 281 +++-- 5 files changed, 1798 insertions(+), 443 deletions(-) create mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 00fe5df..06aad91 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -28,41 +28,30 @@ using System; using System.Collections.Generic; using System.Reflection; - - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsMessagingModule : ISharedRegionModule + public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); private IMessageTransferModule m_msgTransferModule = null; - private IGroupsModule m_groupsModule = null; - - // TODO: Move this off to the Groups Server - public Dictionary> m_agentsInGroupSession = new Dictionary>(); - public Dictionary> m_agentsDroppedSession = new Dictionary>(); - + private IGroupsServicesConnector m_groupData = null; // Config Options private bool m_groupMessagingEnabled = false; @@ -108,8 +97,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - // NoOp + if (!m_groupMessagingEnabled) + return; + + scene.RegisterModuleInterface(this); } + public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -117,12 +110,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupsModule = scene.RequestModuleInterface(); + m_groupData = scene.RequestModuleInterface(); // No groups module, no groups messaging - if (m_groupsModule == null) + if (m_groupData == null) { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -144,7 +137,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - } public void RemoveRegion(Scene scene) @@ -172,7 +164,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Clear(); - m_groupsModule = null; + m_groupData = null; m_msgTransferModule = null; } @@ -197,6 +189,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + /// + /// Not really needed, but does confirm that the group exists. + /// + public bool StartGroupChatSession(UUID agentID, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); + + if (groupInfo != null) + { + return true; + } + else + { + return false; + } + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) + { + if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = groupID.Guid; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.offline = im.offline; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + msg.fromAgentID = im.fromAgentID; + msg.fromGroup = true; + + msg.toAgentID = member.AgentID.Guid; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } + } + } + #region SimGridEventHandlers private void OnNewClient(IClientAPI client) @@ -236,42 +297,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + UUID AgentID = new UUID(msg.fromAgentID); + UUID GroupID = new UUID(msg.imSessionID); + switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionDrop: - RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionSend: - if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) - && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) + && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) + ) { // Agent not in session and hasn't dropped from session // Add them to the session for now, and Invite them - AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); IClientAPI activeClient = GetActiveClient(toAgentID); if (activeClient != null) { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); IEventQueue eq = activeClient.Scene.RequestModuleInterface(); eq.ChatterboxInvitation( - groupID + GroupID , groupInfo.GroupName , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) + , msg.message + , new UUID(msg.toAgentID) , msg.fromAgentName , msg.dialog , msg.timestamp @@ -285,7 +350,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) + new UUID(GroupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) , false //canVoiceChat @@ -295,7 +360,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. @@ -321,56 +386,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region ClientEvents - - private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) - { - if (m_agentsInGroupSession.ContainsKey(sessionID)) - { - // If in session remove - if (m_agentsInGroupSession[sessionID].Contains(agentID)) - { - m_agentsInGroupSession[sessionID].Remove(agentID); - } - - // If not in dropped list, add - if (!m_agentsDroppedSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); - m_agentsDroppedSession[sessionID].Add(agentID); - } - } - } - - private void AddAgentToGroupSession(Guid agentID, Guid sessionID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupSessionTracking(sessionID); - - // If nessesary, remove from dropped list - if (m_agentsDroppedSession[sessionID].Contains(agentID)) - { - m_agentsDroppedSession[sessionID].Remove(agentID); - } - - // If nessesary, add to in session list - if (!m_agentsInGroupSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); - m_agentsInGroupSession[sessionID].Add(agentID); - } - } - - private void CreateGroupSessionTracking(Guid sessionID) - { - if (!m_agentsInGroupSession.ContainsKey(sessionID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); - m_agentsInGroupSession.Add(sessionID, new List()); - m_agentsDroppedSession.Add(sessionID, new List()); - } - } + #region ClientEvents private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -383,21 +400,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { - UUID groupID = new UUID(im.toAgentID); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); - - AddAgentToGroupSession(im.fromAgentID, im.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); queue.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(im.fromAgentID) + GroupID + , AgentID , new UUID(im.toAgentID) , false //canVoiceChat , false //isModerator @@ -409,64 +428,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - UUID groupID = new UUID(im.toAgentID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); - SendMessageToGroup(im, groupID); + //If this agent is sending a message, then they want to be in the session + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); + + SendMessageToGroup(im, GroupID); } } #endregion - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) - { - // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); - continue; - } - - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - else - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); - } - } - } - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -518,6 +494,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private IClientAPI GetActiveClient(UUID agentID) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); + IClientAPI child = null; // Try root avatar first @@ -529,16 +507,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } // If we didn't find a root, then just return whichever child we found, or null if none + if (child == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 8d32e66..edd5af7 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -87,16 +87,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private IGroupsServicesConnector m_groupData = null; - class GroupRequestIDInfo - { - public GroupRequestID RequestID = new GroupRequestID(); - public DateTime LastUsedTMStamp = DateTime.MinValue; - } - private Dictionary m_clientRequestIDInfo = new Dictionary(); - private const int m_clientRequestIDFlushTimeOut = 300000; // Every 5 minutes - private Timer m_clientRequestIDFlushTimer; - - // Configuration settings private bool m_groupsEnabled = false; private bool m_groupNoticesEnabled = true; @@ -133,30 +123,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupNoticesEnabled = groupsConfig.GetBoolean("NoticesEnabled", true); m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - m_clientRequestIDFlushTimer = new Timer(); - m_clientRequestIDFlushTimer.Interval = m_clientRequestIDFlushTimeOut; - m_clientRequestIDFlushTimer.Elapsed += FlushClientRequestIDInfoCache; - m_clientRequestIDFlushTimer.AutoReset = true; - m_clientRequestIDFlushTimer.Start(); - } - } - - void FlushClientRequestIDInfoCache(object sender, ElapsedEventArgs e) - { - lock (m_clientRequestIDInfo) - { - TimeSpan cacheTimeout = new TimeSpan(0,0, m_clientRequestIDFlushTimeOut / 1000); - UUID[] CurrentKeys = new UUID[m_clientRequestIDInfo.Count]; - foreach (UUID key in CurrentKeys) - { - if (m_clientRequestIDInfo.ContainsKey(key)) - { - if (DateTime.Now - m_clientRequestIDInfo[key].LastUsedTMStamp > cacheTimeout) - { - m_clientRequestIDInfo.Remove(key); - } - } - } } } @@ -234,8 +200,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; if (m_debugEnabled) m_log.Debug("[GROUPS]: Shutting down Groups module."); - - m_clientRequestIDFlushTimer.Stop(); } public Type ReplaceableInterface @@ -272,14 +236,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Used for Notices and Group Invites/Accept/Reject client.OnInstantMessage += OnInstantMessage; - lock (m_clientRequestIDInfo) - { - if (m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - // flush any old RequestID information - m_clientRequestIDInfo.Remove(client.AgentId); - } - } + // Send client thier groups information. SendAgentGroupDataUpdate(client, client.AgentId); } @@ -287,7 +244,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(remoteClient), avatarID).ToArray(); + //GroupMembershipData[] avatarGroups = m_groupData.GetAgentGroupMemberships(GetRequestingAgentID(remoteClient), avatarID).ToArray(); GroupMembershipData[] avatarGroups = GetProfileListedGroupMemberships(remoteClient, avatarID); remoteClient.SendAvatarGroupsReply(avatarID, avatarGroups); } @@ -331,10 +288,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with queryText({1}) queryFlags({2}) queryStart({3})", + System.Reflection.MethodBase.GetCurrentMethod().Name, queryText, (DirFindFlags)queryFlags, queryStart); // TODO: This currently ignores pretty much all the query flags including Mature and sort order - remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetClientGroupRequestID(remoteClient), queryText).ToArray()); + remoteClient.SendDirGroupsReply(queryID, m_groupData.FindGroups(GetRequestingAgentID(remoteClient), queryText).ToArray()); } } @@ -348,7 +308,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups string activeGroupName = string.Empty; ulong activeGroupPowers = (ulong)GroupPowers.None; - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetClientGroupRequestID(remoteClient), dataForAgentID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient), dataForAgentID); if (membership != null) { activeGroupID = membership.GroupID; @@ -361,13 +321,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups SendScenePresenceUpdate(dataForAgentID, activeGroupTitle); } - private void HandleUUIDGroupNameRequest(UUID GroupID,IClientAPI remoteClient) + private void HandleUUIDGroupNameRequest(UUID GroupID, IClientAPI remoteClient) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string GroupName; - GroupRecord group = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null); + GroupRecord group = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null); if (group != null) { GroupName = group.GroupName; @@ -388,7 +348,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); if (inviteInfo == null) { @@ -407,7 +367,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received an accept invite notice."); // and the sessionid is the role - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID, inviteInfo.RoleID); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; @@ -431,14 +391,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // TODO: If the inviter is still online, they need an agent dataupdate // and maybe group membership updates for the invitee - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Received a reject invite notice."); - m_groupData.RemoveAgentToGroupInvite(GetClientGroupRequestID(remoteClient), inviteID); + m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentID(remoteClient), inviteID); } } } @@ -452,7 +412,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } UUID GroupID = new UUID(im.toAgentID); - if (m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), GroupID, null) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); @@ -496,14 +456,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - m_groupData.AddGroupNotice(GetClientGroupRequestID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); + m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices - foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), GroupID)) + foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), GroupID)) { if (m_debugEnabled) { @@ -549,7 +509,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { - UUID groupID = new UUID(im.fromAgentID); + UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); } } @@ -588,20 +548,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public GroupRecord GetGroupRecord(UUID GroupID) { - return m_groupData.GetGroupRecord(null, GroupID, null); + return m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); } + public GroupRecord GetGroupRecord(string name) + { + return m_groupData.GetGroupRecord(UUID.Zero, UUID.Zero, name); + } + public void ActivateGroup(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.SetAgentActiveGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); // Changing active group changes title, active powers, all kinds of things // anyone who is in any region that can see this client, should probably be // updated with new group info. At a minimum, they should get ScenePresence // updated with new title. - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } /// @@ -611,10 +576,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - List agentRoles = m_groupData.GetAgentGroupRoles(grID, remoteClient.AgentId, groupID); - GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + List agentRoles = m_groupData.GetAgentGroupRoles(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); + GroupMembershipData agentMembership = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); List titles = new List(); foreach (GroupRolesData role in agentRoles) @@ -636,8 +600,15 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public List GroupMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + List data = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID); - List data = m_groupData.GetGroupMembers(GetClientGroupRequestID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - IsOwner({1})", member.AgentID, member.IsOwner); + } + } return data; @@ -647,21 +618,25 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoles(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID); return data; - } public List GroupRoleMembersRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - List data = m_groupData.GetGroupRoleMembers(GetClientGroupRequestID(remoteClient), groupID); + List data = m_groupData.GetGroupRoleMembers(GetRequestingAgentID(remoteClient), groupID); + if (m_debugEnabled) + { + foreach (GroupRoleMembersData member in data) + { + m_log.DebugFormat("[GROUPS]: Member({0}) - Role({1})", member.MemberID, member.RoleID); + } + } return data; - - } public GroupProfileData GroupProfileRequest(IClientAPI remoteClient, UUID groupID) @@ -670,17 +645,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupProfileData profile = new GroupProfileData(); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - GroupRecord groupInfo = m_groupData.GetGroupRecord(GetClientGroupRequestID(remoteClient), groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); if (groupInfo != null) { profile.AllowPublish = groupInfo.AllowPublish; profile.Charter = groupInfo.Charter; profile.FounderID = groupInfo.FounderID; profile.GroupID = groupID; - profile.GroupMembershipCount = m_groupData.GetGroupMembers(grID, groupID).Count; - profile.GroupRolesCount = m_groupData.GetGroupRoles(grID, groupID).Count; + profile.GroupMembershipCount = m_groupData.GetGroupMembers(GetRequestingAgentID(remoteClient), groupID).Count; + profile.GroupRolesCount = m_groupData.GetGroupRoles(GetRequestingAgentID(remoteClient), groupID).Count; profile.InsigniaID = groupInfo.GroupPicture; profile.MaturePublish = groupInfo.MaturePublish; profile.MembershipFee = groupInfo.MembershipFee; @@ -691,7 +665,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups profile.ShowInList = groupInfo.ShowInList; } - GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(grID, remoteClient.AgentId, groupID); + GroupMembershipData memberInfo = m_groupData.GetAgentGroupMembership(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); if (memberInfo != null) { profile.MemberTitle = memberInfo.GroupTitle; @@ -705,40 +679,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - return m_groupData.GetAgentGroupMemberships(null, agentID).ToArray(); + return m_groupData.GetAgentGroupMemberships(UUID.Zero, agentID).ToArray(); } public GroupMembershipData GetMembershipData(UUID groupID, UUID agentID) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + if (m_debugEnabled) + m_log.DebugFormat( + "[GROUPS]: {0} called with groupID={1}, agentID={2}", + System.Reflection.MethodBase.GetCurrentMethod().Name, groupID, agentID); - return m_groupData.GetAgentGroupMembership(null, agentID, groupID); + return m_groupData.GetAgentGroupMembership(UUID.Zero, agentID, groupID); } public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Security Check? - - m_groupData.UpdateGroup(GetClientGroupRequestID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); + // Note: Permissions checking for modification rights is handled by the Groups Server/Service + m_groupData.UpdateGroup(GetRequestingAgentID(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish); } public void SetGroupAcceptNotices(IClientAPI remoteClient, UUID groupID, bool acceptNotices, bool listInProfile) { - // TODO: Security Check? + // Note: Permissions checking for modification rights is handled by the Groups Server/Service if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentGroupInfo(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, acceptNotices, listInProfile); + m_groupData.SetAgentGroupInfo(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, acceptNotices, listInProfile); } public UUID CreateGroup(IClientAPI remoteClient, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - if (m_groupData.GetGroupRecord(grID, UUID.Zero, name) != null) + if (m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), UUID.Zero, name) != null) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "A group with the same name already exists."); return UUID.Zero; @@ -754,12 +728,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } money.ApplyGroupCreationCharge(remoteClient.AgentId); } - UUID groupID = m_groupData.CreateGroup(grID, name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, remoteClient.AgentId); + UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); remoteClient.SendCreateGroupReply(groupID, true, "Group created successfullly"); // Update the founder with new group information. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); return groupID; } @@ -770,7 +744,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // ToDo: check if agent is a member of group and is allowed to see notices? - return m_groupData.GetGroupNotices(GetClientGroupRequestID(remoteClient), groupID).ToArray(); + return m_groupData.GetGroupNotices(GetRequestingAgentID(remoteClient), groupID).ToArray(); } /// @@ -780,7 +754,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupMembershipData membership = m_groupData.GetAgentActiveMembership(null, avatarID); + GroupMembershipData membership = m_groupData.GetAgentActiveMembership(UUID.Zero, avatarID); if (membership != null) { return membership.GroupTitle; @@ -795,13 +769,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.SetAgentActiveGroupRole(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, titleRoleID); + m_groupData.SetAgentActiveGroupRole(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, titleRoleID); // TODO: Not sure what all is needed here, but if the active group role change is for the group // the client currently has set active, then we need to do a scene presence update too - // if (m_groupData.GetAgentActiveMembership(remoteClient.AgentId).GroupID == GroupID) + // if (m_groupData.GetAgentActiveMembership(GetRequestingAgentID(remoteClient)).GroupID == GroupID) - UpdateAllClientsWithGroupInfo(remoteClient.AgentId); + UpdateAllClientsWithGroupInfo(GetRequestingAgentID(remoteClient)); } @@ -811,16 +785,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Security Checks are handled in the Groups Service. - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: - m_groupData.AddGroupRole(grID, groupID, UUID.Random(), name, description, title, powers); + m_groupData.AddGroupRole(GetRequestingAgentID(remoteClient), groupID, UUID.Random(), name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.Delete: - m_groupData.RemoveGroupRole(grID, groupID, roleID); + m_groupData.RemoveGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: @@ -831,7 +803,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GroupPowers gp = (GroupPowers)powers; m_log.DebugFormat("[GROUPS]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); } - m_groupData.UpdateGroupRole(grID, groupID, roleID, name, description, title, powers); + m_groupData.UpdateGroupRole(GetRequestingAgentID(remoteClient), groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: @@ -842,7 +814,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupRoleChanges(IClientAPI remoteClient, UUID groupID, UUID roleID, UUID memberID, uint changes) @@ -850,18 +822,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Todo: Security check - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - switch (changes) { case 0: // Add - m_groupData.AddAgentToGroupRole(grID, memberID, groupID, roleID); + m_groupData.AddAgentToGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; case 1: // Remove - m_groupData.RemoveAgentFromGroupRole(grID, memberID, groupID, roleID); + m_groupData.RemoveAgentFromGroupRole(GetRequestingAgentID(remoteClient), memberID, groupID, roleID); break; default: @@ -870,25 +840,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } // TODO: This update really should send out updates for everyone in the role that just got changed. - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void GroupNoticeRequest(IClientAPI remoteClient, UUID groupNoticeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); - - GroupNoticeInfo data = m_groupData.GetGroupNotice(grID, groupNoticeID); + GroupNoticeInfo data = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), groupNoticeID); if (data != null) { - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, data.GroupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = data.GroupID.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; msg.message = data.noticeData.Subject + "|" + data.Message; @@ -900,7 +868,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = data.BinaryBucket; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); } } @@ -920,7 +888,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; - GroupNoticeInfo info = m_groupData.GetGroupNotice(null, groupNoticeID); + GroupNoticeInfo info = m_groupData.GetGroupNotice(agentID, groupNoticeID); if (info != null) { msg.fromAgentID = info.GroupID.Guid; @@ -947,7 +915,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Send agent information about his groups - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) @@ -955,19 +923,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Should check to see if OpenEnrollment, or if there's an outstanding invitation - m_groupData.AddAgentToGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID, UUID.Zero); + m_groupData.AddAgentToGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID, UUID.Zero); remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void LeaveGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupData.RemoveAgentFromGroup(GetClientGroupRequestID(remoteClient), remoteClient.AgentId, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), GetRequestingAgentID(remoteClient), groupID); remoteClient.SendLeaveGroupReply(groupID, true); @@ -975,21 +943,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // SL sends out notifcations to the group messaging session that the person has left // Should this also update everyone who is in the group? - SendAgentGroupDataUpdate(remoteClient, remoteClient.AgentId); + SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); } public void EjectGroupMemberRequest(IClientAPI remoteClient, UUID groupID, UUID ejecteeID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - GroupRequestID grID = GetClientGroupRequestID(remoteClient); // Todo: Security check? - m_groupData.RemoveAgentFromGroup(grID, ejecteeID, groupID); + m_groupData.RemoveAgentFromGroup(GetRequestingAgentID(remoteClient), ejecteeID, groupID); - remoteClient.SendEjectGroupMemberReply(remoteClient.AgentId, groupID, true); + remoteClient.SendEjectGroupMemberReply(GetRequestingAgentID(remoteClient), groupID, true); - GroupRecord groupInfo = m_groupData.GetGroupRecord(grID, groupID, null); + GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), groupID, null); UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(ejecteeID); if ((groupInfo == null) || (userProfile == null)) @@ -1002,7 +969,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; // msg.fromAgentID = info.GroupID; msg.toAgentID = ejecteeID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1028,8 +995,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; - msg.fromAgentID = remoteClient.AgentId.Guid; - msg.toAgentID = remoteClient.AgentId.Guid; + msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; + msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; msg.timestamp = 0; msg.fromAgentName = remoteClient.Name; if (userProfile != null) @@ -1047,7 +1014,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.Position = Vector3.Zero; msg.RegionID = remoteClient.Scene.RegionInfo.RegionID.Guid; msg.binaryBucket = new byte[0]; - OutgoingInstantMessage(msg, remoteClient.AgentId); + OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); // SL sends out messages to everyone in the group @@ -1061,13 +1028,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Todo: Security check, probably also want to send some kind of notification UUID InviteID = UUID.Random(); - GroupRequestID grid = GetClientGroupRequestID(remoteClient); - m_groupData.AddAgentToGroupInvite(grid, InviteID, groupID, roleID, invitedAgentID); + m_groupData.AddAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID, groupID, roleID, invitedAgentID); // Check to see if the invite went through, if it did not then it's possible // the remoteClient did not validate or did not have permission to invite. - GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(grid, InviteID); + GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentID(remoteClient), InviteID); if (inviteInfo != null) { @@ -1079,7 +1045,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups msg.imSessionID = inviteUUID; - // msg.fromAgentID = remoteClient.AgentId.Guid; + // msg.fromAgentID = GetRequestingAgentID(remoteClient).Guid; msg.fromAgentID = groupID.Guid; msg.toAgentID = invitedAgentID.Guid; //msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); @@ -1132,57 +1098,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return child; } - private GroupRequestID GetClientGroupRequestID(IClientAPI client) - { - if (client == null) - { - return new GroupRequestID(); - } - - lock (m_clientRequestIDInfo) - { - if (!m_clientRequestIDInfo.ContainsKey(client.AgentId)) - { - GroupRequestIDInfo info = new GroupRequestIDInfo(); - info.RequestID.AgentID = client.AgentId; - info.RequestID.SessionID = client.SessionId; - - UserProfileData userProfile = m_sceneList[0].CommsManager.UserService.GetUserProfile(client.AgentId); - if (userProfile == null) - { - // This should be impossible. If I've been passed a reference to a client - // that client should be registered with the UserService. So something - // is horribly wrong somewhere. - - m_log.WarnFormat("[GROUPS]: Could not find a user profile for {0} / {1}", client.Name, client.AgentId); - - // Default to local user service and hope for the best? - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - - } - else if (userProfile is ForeignUserProfileData) - { - // They aren't from around here - ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; - info.RequestID.UserServiceURL = fupd.UserServerURI; - } - else - { - // They're a local user, use this: - info.RequestID.UserServiceURL = m_sceneList[0].CommsManager.NetworkServersInfo.UserURL; - } - - m_clientRequestIDInfo.Add(client.AgentId, info); - } - - m_clientRequestIDInfo[client.AgentId].LastUsedTMStamp = DateTime.Now; - - return m_clientRequestIDInfo[client.AgentId].RequestID; - } -// Unreachable code! -// return new GroupRequestID(); - } - /// /// Send 'remoteClient' the group membership 'data' for agent 'dataForAgentID'. /// @@ -1231,6 +1146,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups llDataStruct.Add("GroupData", GroupData); llDataStruct.Add("NewGroupData", NewGroupData); + if (m_debugEnabled) + { + m_log.InfoFormat("[GROUPS]: {0}", OSDParser.SerializeJsonString(llDataStruct)); + } + IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); if (queue != null) @@ -1308,7 +1228,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private GroupMembershipData[] GetProfileListedGroupMemberships(IClientAPI requestingClient, UUID dataForAgentID) { - List membershipData = m_groupData.GetAgentGroupMemberships(GetClientGroupRequestID(requestingClient), dataForAgentID); + List membershipData = m_groupData.GetAgentGroupMemberships(requestingClient.AgentId, dataForAgentID); GroupMembershipData[] membershipArray; if (requestingClient.AgentId != dataForAgentID) @@ -1330,7 +1250,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS]: Get group membership information for {0} requested by {1}", dataForAgentID, requestingClient.AgentId); foreach (GroupMembershipData membership in membershipArray) { - m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2}", dataForAgentID, membership.GroupName, membership.GroupTitle); + m_log.InfoFormat("[GROUPS]: {0} :: {1} - {2} - {3}", dataForAgentID, membership.GroupName, membership.GroupTitle, membership.GroupPowers); } } @@ -1389,6 +1309,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } #endregion + + private UUID GetRequestingAgentID(IClientAPI client) + { + UUID requestingAgentID = UUID.Zero; + if (client != null) + { + requestingAgentID = client.AgentId; + } + return requestingAgentID; + } } + public class GroupNoticeInfo + { + public GroupNoticeData noticeData = new GroupNoticeData(); + public UUID GroupID = UUID.Zero; + public string Message = string.Empty; + public byte[] BinaryBucket = new byte[0]; + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 9e0fa2d..a046e09 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -36,42 +36,47 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { interface IGroupsServicesConnector { - UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); - void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); - GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName); - List FindGroups(GroupRequestID requestID, string search); - List GetGroupMembers(GroupRequestID requestID, UUID GroupID); + UUID CreateGroup(UUID RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID); + void UpdateGroup(UUID RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish); + GroupRecord GetGroupRecord(UUID RequestingAgentID, UUID GroupID, string GroupName); + List FindGroups(UUID RequestingAgentID, string search); + List GetGroupMembers(UUID RequestingAgentID, UUID GroupID); - void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); - void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID); - List GetGroupRoles(GroupRequestID requestID, UUID GroupID); - List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID); + void AddGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void UpdateGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers); + void RemoveGroupRole(UUID RequestingAgentID, UUID groupID, UUID roleID); + List GetGroupRoles(UUID RequestingAgentID, UUID GroupID); + List GetGroupRoleMembers(UUID RequestingAgentID, UUID GroupID); - void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void AddAgentToGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); - GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); - void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID); + void AddAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID); + GroupInviteInfo GetAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void RemoveAgentToGroupInvite(UUID RequestingAgentID, UUID inviteID); + void AddAgentToGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void RemoveAgentFromGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + List GetAgentGroupRoles(UUID RequestingAgentID, UUID AgentID, UUID GroupID); - void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID); + void SetAgentActiveGroup(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + GroupMembershipData GetAgentActiveMembership(UUID RequestingAgentID, UUID AgentID); - void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID); - GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID); + void SetAgentActiveGroupRole(UUID RequestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID); + void SetAgentGroupInfo(UUID RequestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); - void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID); - void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile); + GroupMembershipData GetAgentGroupMembership(UUID RequestingAgentID, UUID AgentID, UUID GroupID); + List GetAgentGroupMemberships(UUID RequestingAgentID, UUID AgentID); - GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID); - List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID); + void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); + GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); + List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); - void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); - GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID); - List GetGroupNotices(GroupRequestID requestID, UUID GroupID); + void ResetAgentGroupChatSessions(UUID agentID); + bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); + bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); + void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); + void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } public class GroupInviteInfo @@ -81,11 +86,4 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public UUID AgentID = UUID.Zero; public UUID InviteID = UUID.Zero; } - - public class GroupRequestID - { - public UUID AgentID = UUID.Zero; - public string UserServiceURL = string.Empty; - public UUID SessionID = UUID.Zero; - } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs new file mode 100644 index 0000000..669373f --- /dev/null +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -0,0 +1,1329 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; + +using Nwc.XmlRpc; + +using log4net; +using Mono.Addins; +using Nini.Config; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; + +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; + +/*************************************************************************** + * Simian Data Map + * =============== + * + * OwnerID -> Type -> Key + * ----------------------- + * + * UserID -> Group -> ActiveGroup + * + GroupID + * + * UserID -> GroupSessionDropped -> GroupID + * UserID -> GroupSessionInvited -> GroupID + * + * UserID -> GroupMember -> GroupID + * + SelectedRoleID [UUID] + * + AcceptNotices [bool] + * + ListInProfile [bool] + * + Contribution [int] + * + * UserID -> GroupRole[GroupID] -> RoleID + * + * + * GroupID -> Group -> GroupName + * + Charter + * + ShowInList + * + InsigniaID + * + MembershipFee + * + OpenEnrollment + * + AllowPublish + * + MaturePublish + * + FounderID + * + EveryonePowers + * + OwnerRoleID + * + OwnersPowers + * + * GroupID -> GroupRole -> RoleID + * + Name + * + Description + * + Title + * + Powers + * + * GroupID -> GroupMemberInvite -> InviteID + * + AgentID + * + RoleID + * + * GroupID -> GroupNotice -> NoticeID + * + TimeStamp [uint] + * + FromName [string] + * + Subject [string] + * + Message [string] + * + BinaryBucket [byte[]] + * + * */ + +namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] + public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | + GroupPowers.Accountable | + GroupPowers.JoinChat | + GroupPowers.AllowVoiceChat | + GroupPowers.ReceiveNotices | + GroupPowers.StartProposal | + GroupPowers.VoteOnProposal; + + // Would this be cleaner as (GroupPowers)ulong.MaxValue; + public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable + | GroupPowers.AllowEditLand + | GroupPowers.AllowFly + | GroupPowers.AllowLandmark + | GroupPowers.AllowRez + | GroupPowers.AllowSetHome + | GroupPowers.AllowVoiceChat + | GroupPowers.AssignMember + | GroupPowers.AssignMemberLimited + | GroupPowers.ChangeActions + | GroupPowers.ChangeIdentity + | GroupPowers.ChangeMedia + | GroupPowers.ChangeOptions + | GroupPowers.CreateRole + | GroupPowers.DeedObject + | GroupPowers.DeleteRole + | GroupPowers.Eject + | GroupPowers.FindPlaces + | GroupPowers.Invite + | GroupPowers.JoinChat + | GroupPowers.LandChangeIdentity + | GroupPowers.LandDeed + | GroupPowers.LandDivideJoin + | GroupPowers.LandEdit + | GroupPowers.LandEjectAndFreeze + | GroupPowers.LandGardening + | GroupPowers.LandManageAllowed + | GroupPowers.LandManageBanned + | GroupPowers.LandManagePasses + | GroupPowers.LandOptions + | GroupPowers.LandRelease + | GroupPowers.LandSetSale + | GroupPowers.ModerateChat + | GroupPowers.ObjectManipulate + | GroupPowers.ObjectSetForSale + | GroupPowers.ReceiveNotices + | GroupPowers.RemoveMember + | GroupPowers.ReturnGroupOwned + | GroupPowers.ReturnGroupSet + | GroupPowers.ReturnNonGroup + | GroupPowers.RoleProperties + | GroupPowers.SendNotices + | GroupPowers.SetLandingPoint + | GroupPowers.StartProposal + | GroupPowers.VoteOnProposal; + + private bool m_connectorEnabled = false; + + private string m_groupsServerURI = string.Empty; + + private bool m_debugEnabled = false; + + // private IUserAccountService m_accountService = null; + + + #region IRegionModuleBase Members + + public string Name + { + get { return "SimianGroupsServicesConnector"; } + } + + // this module is not intended to be replaced, but there should only be 1 of them. + public Type ReplaceableInterface + { + get { return null; } + } + + public void Initialise(IConfigSource config) + { + IConfig groupsConfig = config.Configs["Groups"]; + + if (groupsConfig == null) + { + // Do not run this module by default. + return; + } + else + { + // if groups aren't enabled, we're not needed. + // if we're not specified as the connector to use, then we're not wanted + if ((groupsConfig.GetBoolean("Enabled", false) == false) + || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) + { + m_connectorEnabled = false; + return; + } + + m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) + { + m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); + m_connectorEnabled = false; + return; + } + + // If we got all the config options we need, lets start'er'up + m_connectorEnabled = true; + + m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); + + } + } + + public void Close() + { + m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + } + + public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (m_connectorEnabled) + { + scene.RegisterModuleInterface(this); + } + } + + public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) + { + if (scene.RequestModuleInterface() == this) + { + scene.UnregisterModuleInterface(this); + } + } + + public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) + { + // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info + // scene.EventManager.OnNewClient += OnNewClient; + } + + #endregion + + #region ISharedRegionModule Members + + public void PostInitialise() + { + // NoOp + } + + #endregion + + + + + #region IGroupsServicesConnector Members + + /// + /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. + /// + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, + int membershipFee, bool openEnrollment, bool allowPublish, + bool maturePublish, UUID founderID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Random(); + UUID OwnerRoleID = UUID.Random(); + + OSDMap GroupInfoMap = new OSDMap(); + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + GroupInfoMap["FounderID"] = OSD.FromUUID(founderID); + GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers); + GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); + GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); + + if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) + { + AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); + AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); + + AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); + + return GroupID; + } + else + { + return UUID.Zero; + } + } + + + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, + UUID insigniaID, int membershipFee, bool openEnrollment, + bool allowPublish, bool maturePublish) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + // TODO: Check to make sure requestingAgentID has permission to update group + + string GroupName; + OSDMap GroupInfoMap; + if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) + { + GroupInfoMap["Charter"] = OSD.FromString(charter); + GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); + GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); + GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); + GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); + GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); + GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); + + SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap); + } + + } + + + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupRoleInfo = new OSDMap(); + GroupRoleInfo["Name"] = OSD.FromString(name); + GroupRoleInfo["Description"] = OSD.FromString(description); + GroupRoleInfo["Title"] = OSD.FromString(title); + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + // TODO: Add security, make sure that requestingAgentID has permision to add roles + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Add security + + // Can't delete the Everyone Role + if (roleID != UUID.Zero) + { + // Remove all GroupRole Members from Role + Dictionary GroupRoleMembers; + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) + { + foreach(UUID UserID in GroupRoleMembers.Keys) + { + EnsureRoleNotSelectedByMember(groupID, roleID, UserID); + + SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString()); + } + } + + // Remove role + SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString()); + } + } + + + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, + string title, ulong powers) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // TODO: Security, check that requestingAgentID is allowed to update group roles + + OSDMap GroupRoleInfo; + if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo)) + { + if (name != null) + { + GroupRoleInfo["Name"] = OSD.FromString(name); + } + if (description != null) + { + GroupRoleInfo["Description"] = OSD.FromString(description); + } + if (title != null) + { + GroupRoleInfo["Title"] = OSD.FromString(title); + } + GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); + + } + + + SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); + } + + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupInfoMap = null; + if (groupID != UUID.Zero) + { + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap)) + { + return null; + } + } + else if ((groupName != null) && (groupName != string.Empty)) + { + if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) + { + return null; + } + } + + GroupRecord GroupInfo = new GroupRecord(); + + GroupInfo.GroupID = groupID; + GroupInfo.GroupName = groupName; + GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); + GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); + GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID(); + GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger(); + GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean(); + GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean(); + GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean(); + GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID(); + GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID(); + + return GroupInfo; + + } + + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap groupProfile; + string groupName; + if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile)) + { + // GroupProfileData is not nullable + return new GroupProfileData(); + } + + GroupProfileData MemberGroupProfile = new GroupProfileData(); + MemberGroupProfile.GroupID = groupID; + MemberGroupProfile.Name = groupName; + + if (groupProfile["Charter"] != null) + { + MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); + } + + MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; + MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); + MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); + MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean(); + MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); + MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); + MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; + MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); + + Dictionary Members; + if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) + { + MemberGroupProfile.GroupMembershipCount = Members.Count; + } + + Dictionary Roles; + if (SimianGetGenericEntries(groupID, "GroupRole", out Roles)) + { + MemberGroupProfile.GroupRolesCount = Roles.Count; + } + + // TODO: Get Group Money balance from somewhere + // group.Money = 0; + + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID); + + MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; + MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; + + return MemberGroupProfile; + } + + public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap ActiveGroup = new OSDMap(); + ActiveGroup.Add("GroupID", OSD.FromUUID(groupID)); + SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup); + } + + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInfo; + if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) + { + GroupMemberInfo = new OSDMap(); + } + + GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); + GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); + GroupMemberInfo["Contribution"] = OSD.FromInteger(0); + GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero); + SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); + } + + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Invite = new OSDMap(); + Invite["AgentID"] = OSD.FromUUID(agentID); + Invite["RoleID"] = OSD.FromUUID(roleID); + + SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite); + } + + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupMemberInvite; + UUID GroupID; + if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite)) + { + return null; + } + + GroupInviteInfo inviteInfo = new GroupInviteInfo(); + inviteInfo.InviteID = inviteID; + inviteInfo.GroupID = GroupID; + inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID(); + inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID(); + + return inviteInfo; + } + + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID); + SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString()); + } + + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Setup Agent/Group information + SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true); + + // Add agent to Everyone Group + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero); + + // Add agent to Specified Role + AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + + // Set selected role in this group to specified role + SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID); + } + + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If current active group is the group the agent is being removed from, change their group to UUID.Zero + GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID); + if (memberActiveMembership.GroupID == groupID) + { + SetAgentActiveGroup(agentID, agentID, UUID.Zero); + } + + // Remove Group Member information for this group + SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); + + // By using a Simian Generics Type consisting of a prefix and a groupID, + // combined with RoleID as key allows us to get a list of roles a particular member + // of a group is assigned to. + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + + // Take Agent out of all other group roles + Dictionary GroupRoles; + if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles)) + { + foreach (string roleID in GroupRoles.Keys) + { + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID); + } + } + } + + public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap()); + } + + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // Cannot remove members from the Everyone Role + if (roleID != UUID.Zero) + { + EnsureRoleNotSelectedByMember(groupID, roleID, agentID); + + string GroupRoleMemberType = "GroupRole" + groupID.ToString(); + SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString()); + } + } + + public List FindGroups(UUID requestingAgentID, string search) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List findings = new List(); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", "Group" }, + { "Key", search }, + { "Fuzzy", "1" } + }; + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + DirGroupsReplyData data = new DirGroupsReplyData(); + data.groupID = entryMap["OwnerID"].AsUUID(); + data.groupName = entryMap["Key"].AsString(); + + // TODO: is there a better way to do this? + Dictionary Members; + if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members)) + { + data.members = Members.Count; + } + else + { + data.members = 0; + } + + // TODO: sort results? + // data.searchOrder = order; + + findings.Add(data); + } + } + + + return findings; + } + + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupMembershipData data = new GroupMembershipData(); + + /////////////////////////////// + // Agent Specific Information: + // + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); + } + + OSDMap UserGroupMemberInfo; + if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) + { + data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); + data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); + data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); + data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); + + /////////////////////////////// + // Role Specific Information: + // + + OSDMap GroupRoleInfo; + if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) + { + data.GroupTitle = GroupRoleInfo["Title"].AsString(); + data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); + } + } + + /////////////////////////////// + // Group Specific Information: + // + OSDMap GroupInfo; + string GroupName; + if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) + { + data.GroupID = groupID; + data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); + data.Charter = GroupInfo["Charter"].AsString(); + data.FounderID = GroupInfo["FounderID"].AsUUID(); + data.GroupName = GroupName; + data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); + data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); + data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); + data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); + data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); + } + + return data; + } + + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + UUID GroupID = UUID.Zero; + OSDMap UserActiveGroup; + if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) + { + GroupID = UserActiveGroup["GroupID"].AsUUID(); + } + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); + return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); + } + + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List memberships = new List(); + + Dictionary GroupMemberShips; + if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips)) + { + foreach (string key in GroupMemberShips.Keys) + { + memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); + } + } + + return memberships; + } + + public List GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + Dictionary MemberRoles; + if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) + { + foreach (KeyValuePair kvp in MemberRoles) + { + GroupRolesData data = new GroupRolesData(); + data.RoleID = UUID.Parse(kvp.Key); + data.Name = GroupRoles[kvp.Key]["Name"].AsString(); + data.Description = GroupRoles[kvp.Key]["Description"].AsString(); + data.Title = GroupRoles[kvp.Key]["Title"].AsString(); + data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); + + Roles.Add(data); + } + } + } + return Roles; + } + + public List GetGroupRoles(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List Roles = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach (KeyValuePair role in GroupRoles) + { + GroupRolesData data = new GroupRolesData(); + + data.RoleID = UUID.Parse(role.Key); + + data.Name = role.Value["Name"].AsString(); + data.Description = role.Value["Description"].AsString(); + data.Title = role.Value["Title"].AsString(); + data.Powers = role.Value["Powers"].AsULong(); + + Dictionary GroupRoleMembers; + if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers)) + { + data.Members = GroupRoleMembers.Count; + } + else + { + data.Members = 0; + } + + Roles.Add(data); + } + } + + return Roles; + + } + + + + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + OSDMap GroupInfo; + string GroupName; + UUID GroupOwnerRoleID = UUID.Zero; + if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo)) + { + return members; + } + GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID(); + + // Locally cache group roles, since we'll be needing this data for each member + Dictionary GroupRoles; + SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles); + + // Locally cache list of group owners + Dictionary GroupOwners; + SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners); + + + Dictionary GroupMembers; + if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers)) + { + foreach (KeyValuePair member in GroupMembers) + { + GroupMembersData data = new GroupMembersData(); + + data.AgentID = member.Key; + + UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID(); + + data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean(); + data.ListInProfile = member.Value["ListInProfile"].AsBoolean(); + data.Contribution = member.Value["Contribution"].AsInteger(); + + data.IsOwner = GroupOwners.ContainsKey(member.Key); + + OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()]; + data.Title = GroupRoleInfo["Title"].AsString(); + data.AgentPowers = GroupRoleInfo["Powers"].AsULong(); + + members.Add(data); + } + } + + return members; + + } + + public List GetGroupRoleMembers(UUID requestingAgentID, UUID groupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List members = new List(); + + Dictionary GroupRoles; + if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) + { + foreach( KeyValuePair Role in GroupRoles ) + { + Dictionary GroupRoleMembers; + if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) + { + foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) + { + GroupRoleMembersData data = new GroupRoleMembersData(); + + data.MemberID = GroupRoleMember.Key; + data.RoleID = UUID.Parse(Role.Key); + + members.Add(data); + } + } + } + } + + return members; + } + + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + List values = new List(); + + Dictionary Notices; + if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices)) + { + foreach (KeyValuePair Notice in Notices) + { + GroupNoticeData data = new GroupNoticeData(); + data.NoticeID = UUID.Parse(Notice.Key); + data.Timestamp = Notice.Value["TimeStamp"].AsUInteger(); + data.FromName = Notice.Value["FromName"].AsString(); + data.Subject = Notice.Value["Subject"].AsString(); + data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0; + + //TODO: Figure out how to get this + data.AssetType = 0; + + values.Add(data); + } + } + + return values; + + } + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap GroupNotice; + UUID GroupID; + if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) + { + GroupNoticeInfo data = new GroupNoticeInfo(); + data.GroupID = GroupID; + data.Message = GroupNotice["Message"].AsString(); + data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(); + data.noticeData.NoticeID = noticeID; + data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger(); + data.noticeData.FromName = GroupNotice["FromName"].AsString(); + data.noticeData.Subject = GroupNotice["Subject"].AsString(); + data.noticeData.HasAttachment = data.BinaryBucket.Length > 0; + data.noticeData.AssetType = 0; + + if (data.Message == null) + { + data.Message = string.Empty; + } + + return data; + } + return null; + } + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + OSDMap Notice = new OSDMap(); + Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch()); + Notice["FromName"] = OSD.FromString(fromName); + Notice["Subject"] = OSD.FromString(subject); + Notice["Message"] = OSD.FromString(message); + Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); + + SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); + + } + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + Dictionary agentSessions; + + if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); + } + } + + if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); + } + } + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + #endregion + + private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + // If member's SelectedRole is roleID, change their selected role to Everyone + // before removing them from the role + OSDMap UserGroupInfo; + if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo)) + { + if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID) + { + UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero); + } + SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo); + } + } + + + #region Simian Util Methods + private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + string value = OSDParser.SerializeJsonString(map); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "AddGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key }, + { "Value", value} + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]); + return false; + } + } + + /// + /// Returns the first of possibly many entries for Owner/Type pair + /// + private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + key = null; + map = null; + return false; + } + private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count >= 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + ownerID = entryMap["OwnerID"].AsUUID(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + ownerID = UUID.Zero; + map = null; + return false; + } + + private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection RequestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key} + }; + + + OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); + if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) + { + OSDArray entryArray = (OSDArray)Response["Entries"]; + if (entryArray.Count == 1) + { + OSDMap entryMap = entryArray[0] as OSDMap; + key = entryMap["Key"].AsString(); + map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); + + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + + return true; + } + else + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); + } + map = null; + return false; + } + + private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type } + }; + + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if(maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + private bool SimianGetGenericEntries(string type, string key, out Dictionary maps) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "GetGenerics" }, + { "Type", type }, + { "Key", key } + }; + + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) + { + maps = new Dictionary(); + + OSDArray entryArray = (OSDArray)response["Entries"]; + foreach (OSDMap entryMap in entryArray) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); + maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); + } + if (maps.Count == 0) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); + } + return true; + } + else + { + maps = null; + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]); + } + return false; + } + + private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key) + { + if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); + + NameValueCollection requestArgs = new NameValueCollection + { + { "RequestMethod", "RemoveGeneric" }, + { "OwnerID", ownerID.ToString() }, + { "Type", type }, + { "Key", key } + }; + + + OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + if (response["Success"].AsBoolean()) + { + return true; + } + else + { + m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]); + return false; + } + } + #endregion + + } + +} + diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index 964d0bb..2a60b00 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -47,9 +47,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] public class XmlRpcGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector { - private static readonly ILog m_log = - LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | GroupPowers.Accountable | @@ -61,7 +59,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_disableKeepAlive = false; @@ -69,6 +67,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupWriteKey = string.Empty; + // Used to track which agents are have dropped from a group chat session + // Should be reset per agent, on logon + // TODO: move this to Flotsam XmlRpc Service + // SessionID, List + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + + #region IRegionModuleBase Members public string Name @@ -104,11 +110,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) { - m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -118,6 +124,9 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); + + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; } @@ -131,13 +140,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (m_connectorEnabled) + { scene.RegisterModuleInterface(this); + } } public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) { if (scene.RequestModuleInterface() == this) + { scene.UnregisterModuleInterface(this); + } } public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) @@ -157,14 +170,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - - #region IGroupsServicesConnector Members /// /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. /// - public UUID CreateGroup(GroupRequestID requestID, string name, string charter, bool showInList, UUID insigniaID, + public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish, UUID founderID) { @@ -236,7 +247,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - Hashtable respData = XmlRpcCall(requestID, "groups.createGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.createGroup", param); if (respData.Contains("error")) { @@ -248,7 +259,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return UUID.Parse((string)respData["GroupID"]); } - public void UpdateGroup(GroupRequestID requestID, UUID groupID, string charter, bool showInList, + public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { @@ -262,10 +273,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AllowPublish"] = allowPublish == true ? 1 : 0; param["MaturePublish"] = maturePublish == true ? 1 : 0; - XmlRpcCall(requestID, "groups.updateGroup", param); + XmlRpcCall(requestingAgentID, "groups.updateGroup", param); } - public void AddGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -276,19 +287,19 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Title"] = title; param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.addRoleToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addRoleToGroup", param); } - public void RemoveGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID) + public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) { Hashtable param = new Hashtable(); param["GroupID"] = groupID.ToString(); param["RoleID"] = roleID.ToString(); - XmlRpcCall(requestID, "groups.removeRoleFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeRoleFromGroup", param); } - public void UpdateGroupRole(GroupRequestID requestID, UUID groupID, UUID roleID, string name, string description, + public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers) { Hashtable param = new Hashtable(); @@ -308,10 +319,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } param["Powers"] = powers.ToString(); - XmlRpcCall(requestID, "groups.updateGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.updateGroupRole", param); } - public GroupRecord GetGroupRecord(GroupRequestID requestID, UUID GroupID, string GroupName) + public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID GroupID, string GroupName) { Hashtable param = new Hashtable(); if (GroupID != UUID.Zero) @@ -323,7 +334,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["Name"] = GroupName.ToString(); } - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -334,12 +345,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public GroupProfileData GetMemberGroupProfile(GroupRequestID requestID, UUID GroupID, UUID AgentID) + public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID GroupID, UUID AgentID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroup", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroup", param); if (respData.Contains("error")) { @@ -347,38 +358,35 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return new GroupProfileData(); } - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestID, AgentID, GroupID); + GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, AgentID, GroupID); GroupProfileData MemberGroupProfile = GroupProfileHashtableToGroupProfileData(respData); MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; return MemberGroupProfile; - } - - - public void SetAgentActiveGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void SetAgentActiveGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.setAgentActiveGroup", param); + XmlRpcCall(requestingAgentID, "groups.setAgentActiveGroup", param); } - public void SetAgentActiveGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["SelectedRoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void SetAgentGroupInfo(GroupRequestID requestID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) + public void SetAgentGroupInfo(UUID requestingAgentID, UUID AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); @@ -386,11 +394,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["AcceptNotices"] = AcceptNotices ? "1" : "0"; param["ListInProfile"] = ListInProfile ? "1" : "0"; - XmlRpcCall(requestID, "groups.setAgentGroupInfo", param); + XmlRpcCall(requestingAgentID, "groups.setAgentGroupInfo", param); } - public void AddAgentToGroupInvite(GroupRequestID requestID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) + public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); @@ -398,16 +406,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["RoleID"] = roleID.ToString(); param["GroupID"] = groupID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupInvite", param); } - public GroupInviteInfo GetAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentToGroupInvite", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentToGroupInvite", param); if (respData.Contains("error")) { @@ -423,60 +431,59 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return inviteInfo; } - public void RemoveAgentToGroupInvite(GroupRequestID requestID, UUID inviteID) + public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) { Hashtable param = new Hashtable(); param["InviteID"] = inviteID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentToGroupInvite", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentToGroupInvite", param); } - public void AddAgentToGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroup", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroup", param); } - public void RemoveAgentFromGroup(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public void RemoveAgentFromGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroup", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroup", param); } - public void AddAgentToGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void AddAgentToGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.addAgentToGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.addAgentToGroupRole", param); } - public void RemoveAgentFromGroupRole(GroupRequestID requestID, UUID AgentID, UUID GroupID, UUID RoleID) + public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); param["RoleID"] = RoleID.ToString(); - XmlRpcCall(requestID, "groups.removeAgentFromGroupRole", param); + XmlRpcCall(requestingAgentID, "groups.removeAgentFromGroupRole", param); } - - public List FindGroups(GroupRequestID requestID, string search) + public List FindGroups(UUID requestingAgentID, string search) { Hashtable param = new Hashtable(); param["Search"] = search; - Hashtable respData = XmlRpcCall(requestID, "groups.findGroups", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.findGroups", param); List findings = new List(); @@ -498,13 +505,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return findings; } - public GroupMembershipData GetAgentGroupMembership(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMembership", param); if (respData.Contains("error")) { @@ -516,12 +523,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public GroupMembershipData GetAgentActiveMembership(GroupRequestID requestID, UUID AgentID) + public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentActiveMembership", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentActiveMembership", param); if (respData.Contains("error")) { @@ -531,13 +538,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return HashTableToGroupMembershipData(respData); } - - public List GetAgentGroupMemberships(GroupRequestID requestID, UUID AgentID) + public List GetAgentGroupMemberships(UUID requestingAgentID, UUID AgentID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentGroupMemberships", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentGroupMemberships", param); List memberships = new List(); @@ -552,13 +558,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return memberships; } - public List GetAgentGroupRoles(GroupRequestID requestID, UUID AgentID, UUID GroupID) + public List GetAgentGroupRoles(UUID requestingAgentID, UUID AgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["AgentID"] = AgentID.ToString(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getAgentRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getAgentRoles", param); List Roles = new List(); @@ -584,12 +590,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoles(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoles(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoles", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoles", param); List Roles = new List(); @@ -617,12 +623,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - public List GetGroupMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupMembers", param); List members = new List(); @@ -650,12 +656,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } - public List GetGroupRoleMembers(GroupRequestID requestID, UUID GroupID) + public List GetGroupRoleMembers(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupRoleMembers", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupRoleMembers", param); List members = new List(); @@ -674,12 +680,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return members; } - public List GetGroupNotices(GroupRequestID requestID, UUID GroupID) + public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) { Hashtable param = new Hashtable(); param["GroupID"] = GroupID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotices", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotices", param); List values = new List(); @@ -701,12 +707,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return values; } - public GroupNoticeInfo GetGroupNotice(GroupRequestID requestID, UUID noticeID) + public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) { Hashtable param = new Hashtable(); param["NoticeID"] = noticeID.ToString(); - Hashtable respData = XmlRpcCall(requestID, "groups.getGroupNotice", param); + Hashtable respData = XmlRpcCall(requestingAgentID, "groups.getGroupNotice", param); if (respData.Contains("error")) @@ -732,7 +738,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return data; } - public void AddGroupNotice(GroupRequestID requestID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) + public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) { string binBucket = OpenMetaverse.Utils.BytesToHexString(binaryBucket, ""); @@ -745,7 +751,70 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups param["BinaryBucket"] = binBucket; param["TimeStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString(); - XmlRpcCall(requestID, "groups.addGroupNotice", param); + XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); + } + + + + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + { + agentList.Remove(agentID); + } + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking this group, and we can find them in the tracking, then they've been invited + return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) + && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking drops for this group, + // and we find them, well... then they've dropped + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + // If not in dropped list, add + if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); + } + } + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupChatSessionTracking(groupID); + + // If nessesary, remove from dropped list + if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); + } + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + } #endregion @@ -778,7 +847,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private GroupRecord GroupProfileHashtableToGroupRecord(Hashtable groupProfile) { - GroupRecord group = new GroupRecord(); group.GroupID = UUID.Parse((string)groupProfile["GroupID"]); group.GroupName = groupProfile["Name"].ToString(); @@ -797,6 +865,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return group; } + private static GroupMembershipData HashTableToGroupMembershipData(Hashtable respData) { GroupMembershipData data = new GroupMembershipData(); @@ -829,6 +898,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups data.MembershipFee = int.Parse((string)respData["MembershipFee"]); data.OpenEnrollment = ((string)respData["OpenEnrollment"] == "1"); data.ShowInList = ((string)respData["ShowInList"] == "1"); + return data; } @@ -837,15 +907,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Encapsulate the XmlRpc call to standardize security and error handling. /// - private Hashtable XmlRpcCall(GroupRequestID requestID, string function, Hashtable param) + private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - if (requestID == null) - { - requestID = new GroupRequestID(); - } - param.Add("RequestingAgentID", requestID.AgentID.ToString()); - param.Add("RequestingAgentUserService", requestID.UserServiceURL); - param.Add("RequestingSessionID", requestID.SessionID.ToString()); + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); param.Add("ReadKey", m_groupReadKey); @@ -862,7 +931,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups try { - resp = req.Send(m_serviceURL, 10000); + resp = req.Send(m_groupsServerURI, 10000); } catch (Exception e) { @@ -936,15 +1005,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } + + /// + /// Group Request Tokens are an attempt to allow the groups service to authenticate + /// requests. + /// TODO: This broke after the big grid refactor, either find a better way, or discard this + /// + /// + /// + private void GetClientGroupRequestID(UUID AgentID, out string UserServiceURL, out UUID SessionID) + { + UserServiceURL = ""; + SessionID = UUID.Zero; - } - public class GroupNoticeInfo - { - public GroupNoticeData noticeData = new GroupNoticeData(); - public UUID GroupID = UUID.Zero; - public string Message = string.Empty; - public byte[] BinaryBucket = new byte[0]; + // Need to rework this based on changes to User Services + /* + UserAccount userAccount = m_accountService.GetUserAccount(UUID.Zero,AgentID); + if (userAccount == null) + { + // This should be impossible. If I've been passed a reference to a client + // that client should be registered with the UserService. So something + // is horribly wrong somewhere. + + m_log.WarnFormat("[GROUPS]: Could not find a UserServiceURL for {0}", AgentID); + + } + else if (userProfile is ForeignUserProfileData) + { + // They aren't from around here + ForeignUserProfileData fupd = (ForeignUserProfileData)userProfile; + UserServiceURL = fupd.UserServerURI; + SessionID = fupd.CurrentAgent.SessionID; + + } + else + { + // They're a local user, use this: + UserServiceURL = m_commManager.NetworkServersInfo.UserURL; + SessionID = userProfile.CurrentAgent.SessionID; + } + */ + } + } } -- cgit v1.1 From 91cfce3758a7021f483bb653371693cc3d64580a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 8 Apr 2010 16:14:02 -0700 Subject: back port groups changes Signed-off-by: Melanie --- .../Framework/Interfaces/IGroupsMessagingModule.cs | 73 ++ .../SimianGroupsServicesConnectorModule.cs | 1329 -------------------- 2 files changed, 73 insertions(+), 1329 deletions(-) create mode 100644 OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs delete mode 100644 OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs b/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs new file mode 100644 index 0000000..f158236 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IGroupsMessagingModule.cs @@ -0,0 +1,73 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Interfaces +{ + /// + /// Provide mechanisms for messaging groups. + /// + /// + /// TODO: Provide a mechanism for receiving group messages as well as sending them + /// + public interface IGroupsMessagingModule + { + /// + /// Start a group chat session. + /// + /// You must call this before calling SendMessageToGroup(). If a chat session for this group is already taking + /// place then the agent will added to that session. + /// + /// A UUID that represents the agent being added. If you are agentless (e.g. you are + /// a region module), then you can use any random ID. + /// + /// + /// The ID for the group to join. Currently, the session ID used is identical to the + /// group ID. + /// + /// + /// True if the chat session was started successfully, false otherwise. + /// + bool StartGroupChatSession(UUID agentID, UUID groupID); + + /// + /// Send a message to an entire group. + /// + /// + /// The message itself. The fields that must be populated are + /// + /// imSessionID - Populate this with the group ID (session ID and group ID are currently identical) + /// fromAgentName - Populate this with whatever arbitrary name you want to show up in the chat dialog + /// message - The message itself + /// dialog - This must be (byte)InstantMessageDialog.SessionSend + /// + /// + void SendMessageToGroup(GridInstantMessage im, UUID groupID); + } +} \ No newline at end of file diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs deleted file mode 100644 index 669373f..0000000 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ /dev/null @@ -1,1329 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Reflection; - -using Nwc.XmlRpc; - -using log4net; -using Mono.Addins; -using Nini.Config; - -using OpenMetaverse; -using OpenMetaverse.StructuredData; - -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Services.Interfaces; - -/*************************************************************************** - * Simian Data Map - * =============== - * - * OwnerID -> Type -> Key - * ----------------------- - * - * UserID -> Group -> ActiveGroup - * + GroupID - * - * UserID -> GroupSessionDropped -> GroupID - * UserID -> GroupSessionInvited -> GroupID - * - * UserID -> GroupMember -> GroupID - * + SelectedRoleID [UUID] - * + AcceptNotices [bool] - * + ListInProfile [bool] - * + Contribution [int] - * - * UserID -> GroupRole[GroupID] -> RoleID - * - * - * GroupID -> Group -> GroupName - * + Charter - * + ShowInList - * + InsigniaID - * + MembershipFee - * + OpenEnrollment - * + AllowPublish - * + MaturePublish - * + FounderID - * + EveryonePowers - * + OwnerRoleID - * + OwnersPowers - * - * GroupID -> GroupRole -> RoleID - * + Name - * + Description - * + Title - * + Powers - * - * GroupID -> GroupMemberInvite -> InviteID - * + AgentID - * + RoleID - * - * GroupID -> GroupNotice -> NoticeID - * + TimeStamp [uint] - * + FromName [string] - * + Subject [string] - * + Message [string] - * + BinaryBucket [byte[]] - * - * */ - -namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups -{ - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class SimianGroupsServicesConnectorModule : ISharedRegionModule, IGroupsServicesConnector - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - public const GroupPowers m_DefaultEveryonePowers = GroupPowers.AllowSetHome | - GroupPowers.Accountable | - GroupPowers.JoinChat | - GroupPowers.AllowVoiceChat | - GroupPowers.ReceiveNotices | - GroupPowers.StartProposal | - GroupPowers.VoteOnProposal; - - // Would this be cleaner as (GroupPowers)ulong.MaxValue; - public const GroupPowers m_DefaultOwnerPowers = GroupPowers.Accountable - | GroupPowers.AllowEditLand - | GroupPowers.AllowFly - | GroupPowers.AllowLandmark - | GroupPowers.AllowRez - | GroupPowers.AllowSetHome - | GroupPowers.AllowVoiceChat - | GroupPowers.AssignMember - | GroupPowers.AssignMemberLimited - | GroupPowers.ChangeActions - | GroupPowers.ChangeIdentity - | GroupPowers.ChangeMedia - | GroupPowers.ChangeOptions - | GroupPowers.CreateRole - | GroupPowers.DeedObject - | GroupPowers.DeleteRole - | GroupPowers.Eject - | GroupPowers.FindPlaces - | GroupPowers.Invite - | GroupPowers.JoinChat - | GroupPowers.LandChangeIdentity - | GroupPowers.LandDeed - | GroupPowers.LandDivideJoin - | GroupPowers.LandEdit - | GroupPowers.LandEjectAndFreeze - | GroupPowers.LandGardening - | GroupPowers.LandManageAllowed - | GroupPowers.LandManageBanned - | GroupPowers.LandManagePasses - | GroupPowers.LandOptions - | GroupPowers.LandRelease - | GroupPowers.LandSetSale - | GroupPowers.ModerateChat - | GroupPowers.ObjectManipulate - | GroupPowers.ObjectSetForSale - | GroupPowers.ReceiveNotices - | GroupPowers.RemoveMember - | GroupPowers.ReturnGroupOwned - | GroupPowers.ReturnGroupSet - | GroupPowers.ReturnNonGroup - | GroupPowers.RoleProperties - | GroupPowers.SendNotices - | GroupPowers.SetLandingPoint - | GroupPowers.StartProposal - | GroupPowers.VoteOnProposal; - - private bool m_connectorEnabled = false; - - private string m_groupsServerURI = string.Empty; - - private bool m_debugEnabled = false; - - // private IUserAccountService m_accountService = null; - - - #region IRegionModuleBase Members - - public string Name - { - get { return "SimianGroupsServicesConnector"; } - } - - // this module is not intended to be replaced, but there should only be 1 of them. - public Type ReplaceableInterface - { - get { return null; } - } - - public void Initialise(IConfigSource config) - { - IConfig groupsConfig = config.Configs["Groups"]; - - if (groupsConfig == null) - { - // Do not run this module by default. - return; - } - else - { - // if groups aren't enabled, we're not needed. - // if we're not specified as the connector to use, then we're not wanted - if ((groupsConfig.GetBoolean("Enabled", false) == false) - || (groupsConfig.GetString("ServicesConnectorModule", "Default") != Name)) - { - m_connectorEnabled = false; - return; - } - - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); - - m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); - if ((m_groupsServerURI == null) || - (m_groupsServerURI == string.Empty)) - { - m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); - m_connectorEnabled = false; - return; - } - - // If we got all the config options we need, lets start'er'up - m_connectorEnabled = true; - - m_debugEnabled = groupsConfig.GetBoolean("DebugEnabled", true); - - } - } - - public void Close() - { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); - } - - public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) - { - if (m_connectorEnabled) - { - scene.RegisterModuleInterface(this); - } - } - - public void RemoveRegion(OpenSim.Region.Framework.Scenes.Scene scene) - { - if (scene.RequestModuleInterface() == this) - { - scene.UnregisterModuleInterface(this); - } - } - - public void RegionLoaded(OpenSim.Region.Framework.Scenes.Scene scene) - { - // TODO: May want to consider listenning for Agent Connections so we can pre-cache group info - // scene.EventManager.OnNewClient += OnNewClient; - } - - #endregion - - #region ISharedRegionModule Members - - public void PostInitialise() - { - // NoOp - } - - #endregion - - - - - #region IGroupsServicesConnector Members - - /// - /// Create a Group, including Everyone and Owners Role, place FounderID in both groups, select Owner as selected role, and newly created group as agent's active role. - /// - public UUID CreateGroup(UUID requestingAgentID, string name, string charter, bool showInList, UUID insigniaID, - int membershipFee, bool openEnrollment, bool allowPublish, - bool maturePublish, UUID founderID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UUID GroupID = UUID.Random(); - UUID OwnerRoleID = UUID.Random(); - - OSDMap GroupInfoMap = new OSDMap(); - GroupInfoMap["Charter"] = OSD.FromString(charter); - GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); - GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); - GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); - GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); - GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); - GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); - GroupInfoMap["FounderID"] = OSD.FromUUID(founderID); - GroupInfoMap["EveryonePowers"] = OSD.FromULong((ulong)m_DefaultEveryonePowers); - GroupInfoMap["OwnerRoleID"] = OSD.FromUUID(OwnerRoleID); - GroupInfoMap["OwnersPowers"] = OSD.FromULong((ulong)m_DefaultOwnerPowers); - - if(SimianAddGeneric(GroupID, "Group", name, GroupInfoMap)) - { - AddGroupRole(requestingAgentID, GroupID, UUID.Zero, "Everyone", "Members of " + name, "Member of " + name, (ulong)m_DefaultEveryonePowers); - AddGroupRole(requestingAgentID, GroupID, OwnerRoleID, "Owners", "Owners of " + name, "Owner of " + name, (ulong)m_DefaultOwnerPowers); - - AddAgentToGroup(requestingAgentID, requestingAgentID, GroupID, OwnerRoleID); - - return GroupID; - } - else - { - return UUID.Zero; - } - } - - - public void UpdateGroup(UUID requestingAgentID, UUID groupID, string charter, bool showInList, - UUID insigniaID, int membershipFee, bool openEnrollment, - bool allowPublish, bool maturePublish) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - // TODO: Check to make sure requestingAgentID has permission to update group - - string GroupName; - OSDMap GroupInfoMap; - if( SimianGetFirstGenericEntry(groupID, "GroupInfo", out GroupName, out GroupInfoMap) ) - { - GroupInfoMap["Charter"] = OSD.FromString(charter); - GroupInfoMap["ShowInList"] = OSD.FromBoolean(showInList); - GroupInfoMap["InsigniaID"] = OSD.FromUUID(insigniaID); - GroupInfoMap["MembershipFee"] = OSD.FromInteger(0); - GroupInfoMap["OpenEnrollment"] = OSD.FromBoolean(openEnrollment); - GroupInfoMap["AllowPublish"] = OSD.FromBoolean(allowPublish); - GroupInfoMap["MaturePublish"] = OSD.FromBoolean(maturePublish); - - SimianAddGeneric(groupID, "Group", GroupName, GroupInfoMap); - } - - } - - - public void AddGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, - string title, ulong powers) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupRoleInfo = new OSDMap(); - GroupRoleInfo["Name"] = OSD.FromString(name); - GroupRoleInfo["Description"] = OSD.FromString(description); - GroupRoleInfo["Title"] = OSD.FromString(title); - GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); - - // TODO: Add security, make sure that requestingAgentID has permision to add roles - SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); - } - - public void RemoveGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Add security - - // Can't delete the Everyone Role - if (roleID != UUID.Zero) - { - // Remove all GroupRole Members from Role - Dictionary GroupRoleMembers; - string GroupRoleMemberType = "GroupRole" + groupID.ToString(); - if (SimianGetGenericEntries(GroupRoleMemberType, roleID.ToString(), out GroupRoleMembers)) - { - foreach(UUID UserID in GroupRoleMembers.Keys) - { - EnsureRoleNotSelectedByMember(groupID, roleID, UserID); - - SimianRemoveGenericEntry(UserID, GroupRoleMemberType, roleID.ToString()); - } - } - - // Remove role - SimianRemoveGenericEntry(groupID, "GroupRole", roleID.ToString()); - } - } - - - public void UpdateGroupRole(UUID requestingAgentID, UUID groupID, UUID roleID, string name, string description, - string title, ulong powers) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // TODO: Security, check that requestingAgentID is allowed to update group roles - - OSDMap GroupRoleInfo; - if (SimianGetGenericEntry(groupID, "GroupRole", roleID.ToString(), out GroupRoleInfo)) - { - if (name != null) - { - GroupRoleInfo["Name"] = OSD.FromString(name); - } - if (description != null) - { - GroupRoleInfo["Description"] = OSD.FromString(description); - } - if (title != null) - { - GroupRoleInfo["Title"] = OSD.FromString(title); - } - GroupRoleInfo["Powers"] = OSD.FromULong((ulong)powers); - - } - - - SimianAddGeneric(groupID, "GroupRole", roleID.ToString(), GroupRoleInfo); - } - - public GroupRecord GetGroupRecord(UUID requestingAgentID, UUID groupID, string groupName) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupInfoMap = null; - if (groupID != UUID.Zero) - { - if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out GroupInfoMap)) - { - return null; - } - } - else if ((groupName != null) && (groupName != string.Empty)) - { - if (!SimianGetFirstGenericEntry("Group", groupName, out groupID, out GroupInfoMap)) - { - return null; - } - } - - GroupRecord GroupInfo = new GroupRecord(); - - GroupInfo.GroupID = groupID; - GroupInfo.GroupName = groupName; - GroupInfo.Charter = GroupInfoMap["Charter"].AsString(); - GroupInfo.ShowInList = GroupInfoMap["ShowInList"].AsBoolean(); - GroupInfo.GroupPicture = GroupInfoMap["InsigniaID"].AsUUID(); - GroupInfo.MembershipFee = GroupInfoMap["MembershipFee"].AsInteger(); - GroupInfo.OpenEnrollment = GroupInfoMap["OpenEnrollment"].AsBoolean(); - GroupInfo.AllowPublish = GroupInfoMap["AllowPublish"].AsBoolean(); - GroupInfo.MaturePublish = GroupInfoMap["MaturePublish"].AsBoolean(); - GroupInfo.FounderID = GroupInfoMap["FounderID"].AsUUID(); - GroupInfo.OwnerRoleID = GroupInfoMap["OwnerRoleID"].AsUUID(); - - return GroupInfo; - - } - - public GroupProfileData GetMemberGroupProfile(UUID requestingAgentID, UUID groupID, UUID memberID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap groupProfile; - string groupName; - if (!SimianGetFirstGenericEntry(groupID, "Group", out groupName, out groupProfile)) - { - // GroupProfileData is not nullable - return new GroupProfileData(); - } - - GroupProfileData MemberGroupProfile = new GroupProfileData(); - MemberGroupProfile.GroupID = groupID; - MemberGroupProfile.Name = groupName; - - if (groupProfile["Charter"] != null) - { - MemberGroupProfile.Charter = groupProfile["Charter"].AsString(); - } - - MemberGroupProfile.ShowInList = groupProfile["ShowInList"].AsString() == "1"; - MemberGroupProfile.InsigniaID = groupProfile["InsigniaID"].AsUUID(); - MemberGroupProfile.MembershipFee = groupProfile["MembershipFee"].AsInteger(); - MemberGroupProfile.OpenEnrollment = groupProfile["OpenEnrollment"].AsBoolean(); - MemberGroupProfile.AllowPublish = groupProfile["AllowPublish"].AsBoolean(); - MemberGroupProfile.MaturePublish = groupProfile["MaturePublish"].AsBoolean(); - MemberGroupProfile.FounderID = groupProfile["FounderID"].AsUUID();; - MemberGroupProfile.OwnerRole = groupProfile["OwnerRoleID"].AsUUID(); - - Dictionary Members; - if (SimianGetGenericEntries("GroupMember",groupID.ToString(), out Members)) - { - MemberGroupProfile.GroupMembershipCount = Members.Count; - } - - Dictionary Roles; - if (SimianGetGenericEntries(groupID, "GroupRole", out Roles)) - { - MemberGroupProfile.GroupRolesCount = Roles.Count; - } - - // TODO: Get Group Money balance from somewhere - // group.Money = 0; - - GroupMembershipData MemberInfo = GetAgentGroupMembership(requestingAgentID, memberID, groupID); - - MemberGroupProfile.MemberTitle = MemberInfo.GroupTitle; - MemberGroupProfile.PowersMask = MemberInfo.GroupPowers; - - return MemberGroupProfile; - } - - public void SetAgentActiveGroup(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap ActiveGroup = new OSDMap(); - ActiveGroup.Add("GroupID", OSD.FromUUID(groupID)); - SimianAddGeneric(agentID, "Group", "ActiveGroup", ActiveGroup); - } - - public void SetAgentActiveGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupMemberInfo; - if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) - { - GroupMemberInfo = new OSDMap(); - } - - GroupMemberInfo["SelectedRoleID"] = OSD.FromUUID(roleID); - SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); - } - - public void SetAgentGroupInfo(UUID requestingAgentID, UUID agentID, UUID groupID, bool acceptNotices, bool listInProfile) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupMemberInfo; - if (!SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out GroupMemberInfo)) - { - GroupMemberInfo = new OSDMap(); - } - - GroupMemberInfo["AcceptNotices"] = OSD.FromBoolean(acceptNotices); - GroupMemberInfo["ListInProfile"] = OSD.FromBoolean(listInProfile); - GroupMemberInfo["Contribution"] = OSD.FromInteger(0); - GroupMemberInfo["SelectedRole"] = OSD.FromUUID(UUID.Zero); - SimianAddGeneric(agentID, "GroupMember", groupID.ToString(), GroupMemberInfo); - } - - public void AddAgentToGroupInvite(UUID requestingAgentID, UUID inviteID, UUID groupID, UUID roleID, UUID agentID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap Invite = new OSDMap(); - Invite["AgentID"] = OSD.FromUUID(agentID); - Invite["RoleID"] = OSD.FromUUID(roleID); - - SimianAddGeneric(groupID, "GroupMemberInvite", inviteID.ToString(), Invite); - } - - public GroupInviteInfo GetAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupMemberInvite; - UUID GroupID; - if (!SimianGetFirstGenericEntry("GroupMemberInvite", inviteID.ToString(), out GroupID, out GroupMemberInvite)) - { - return null; - } - - GroupInviteInfo inviteInfo = new GroupInviteInfo(); - inviteInfo.InviteID = inviteID; - inviteInfo.GroupID = GroupID; - inviteInfo.AgentID = GroupMemberInvite["AgentID"].AsUUID(); - inviteInfo.RoleID = GroupMemberInvite["RoleID"].AsUUID(); - - return inviteInfo; - } - - public void RemoveAgentToGroupInvite(UUID requestingAgentID, UUID inviteID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupInviteInfo invite = GetAgentToGroupInvite(requestingAgentID, inviteID); - SimianRemoveGenericEntry(invite.GroupID, "GroupMemberInvite", inviteID.ToString()); - } - - public void AddAgentToGroup(UUID requestingAgentID, UUID AgentID, UUID GroupID, UUID RoleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Setup Agent/Group information - SetAgentGroupInfo(requestingAgentID, AgentID, GroupID, true, true); - - // Add agent to Everyone Group - AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, UUID.Zero); - - // Add agent to Specified Role - AddAgentToGroupRole(requestingAgentID, AgentID, GroupID, RoleID); - - // Set selected role in this group to specified role - SetAgentActiveGroupRole(requestingAgentID, AgentID, GroupID, RoleID); - } - - public void RemoveAgentFromGroup(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // If current active group is the group the agent is being removed from, change their group to UUID.Zero - GroupMembershipData memberActiveMembership = GetAgentActiveMembership(requestingAgentID, agentID); - if (memberActiveMembership.GroupID == groupID) - { - SetAgentActiveGroup(agentID, agentID, UUID.Zero); - } - - // Remove Group Member information for this group - SimianRemoveGenericEntry(agentID, "GroupMember", groupID.ToString()); - - // By using a Simian Generics Type consisting of a prefix and a groupID, - // combined with RoleID as key allows us to get a list of roles a particular member - // of a group is assigned to. - string GroupRoleMemberType = "GroupRole" + groupID.ToString(); - - // Take Agent out of all other group roles - Dictionary GroupRoles; - if (SimianGetGenericEntries(agentID, GroupRoleMemberType, out GroupRoles)) - { - foreach (string roleID in GroupRoles.Keys) - { - SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID); - } - } - } - - public void AddAgentToGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - SimianAddGeneric(agentID, "GroupRole" + groupID.ToString(), roleID.ToString(), new OSDMap()); - } - - public void RemoveAgentFromGroupRole(UUID requestingAgentID, UUID agentID, UUID groupID, UUID roleID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // Cannot remove members from the Everyone Role - if (roleID != UUID.Zero) - { - EnsureRoleNotSelectedByMember(groupID, roleID, agentID); - - string GroupRoleMemberType = "GroupRole" + groupID.ToString(); - SimianRemoveGenericEntry(agentID, GroupRoleMemberType, roleID.ToString()); - } - } - - public List FindGroups(UUID requestingAgentID, string search) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List findings = new List(); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "Type", "Group" }, - { "Key", search }, - { "Fuzzy", "1" } - }; - - - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); - if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)response["Entries"]; - foreach (OSDMap entryMap in entryArray) - { - DirGroupsReplyData data = new DirGroupsReplyData(); - data.groupID = entryMap["OwnerID"].AsUUID(); - data.groupName = entryMap["Key"].AsString(); - - // TODO: is there a better way to do this? - Dictionary Members; - if (SimianGetGenericEntries("GroupMember", data.groupID.ToString(), out Members)) - { - data.members = Members.Count; - } - else - { - data.members = 0; - } - - // TODO: sort results? - // data.searchOrder = order; - - findings.Add(data); - } - } - - - return findings; - } - - public GroupMembershipData GetAgentGroupMembership(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - GroupMembershipData data = new GroupMembershipData(); - - /////////////////////////////// - // Agent Specific Information: - // - OSDMap UserActiveGroup; - if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) - { - data.Active = UserActiveGroup["GroupID"].AsUUID().Equals(groupID); - } - - OSDMap UserGroupMemberInfo; - if( SimianGetGenericEntry(agentID, "GroupMember", groupID.ToString(), out UserGroupMemberInfo) ) - { - data.AcceptNotices = UserGroupMemberInfo["AcceptNotices"].AsBoolean(); - data.Contribution = UserGroupMemberInfo["Contribution"].AsInteger(); - data.ListInProfile = UserGroupMemberInfo["ListInProfile"].AsBoolean(); - data.ActiveRole = UserGroupMemberInfo["SelectedRoleID"].AsUUID(); - - /////////////////////////////// - // Role Specific Information: - // - - OSDMap GroupRoleInfo; - if( SimianGetGenericEntry(groupID, "GroupRole", data.ActiveRole.ToString(), out GroupRoleInfo) ) - { - data.GroupTitle = GroupRoleInfo["Title"].AsString(); - data.GroupPowers = GroupRoleInfo["Powers"].AsULong(); - } - } - - /////////////////////////////// - // Group Specific Information: - // - OSDMap GroupInfo; - string GroupName; - if( SimianGetFirstGenericEntry(groupID, "Group", out GroupName, out GroupInfo) ) - { - data.GroupID = groupID; - data.AllowPublish = GroupInfo["AllowPublish"].AsBoolean(); - data.Charter = GroupInfo["Charter"].AsString(); - data.FounderID = GroupInfo["FounderID"].AsUUID(); - data.GroupName = GroupName; - data.GroupPicture = GroupInfo["InsigniaID"].AsUUID(); - data.MaturePublish = GroupInfo["MaturePublish"].AsBoolean(); - data.MembershipFee = GroupInfo["MembershipFee"].AsInteger(); - data.OpenEnrollment = GroupInfo["OpenEnrollment"].AsBoolean(); - data.ShowInList = GroupInfo["ShowInList"].AsBoolean(); - } - - return data; - } - - public GroupMembershipData GetAgentActiveMembership(UUID requestingAgentID, UUID agentID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - UUID GroupID = UUID.Zero; - OSDMap UserActiveGroup; - if (SimianGetGenericEntry(agentID, "Group", "ActiveGroup", out UserActiveGroup)) - { - GroupID = UserActiveGroup["GroupID"].AsUUID(); - } - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Active GroupID : {0}", GroupID.ToString()); - return GetAgentGroupMembership(requestingAgentID, agentID, GroupID); - } - - public List GetAgentGroupMemberships(UUID requestingAgentID, UUID agentID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List memberships = new List(); - - Dictionary GroupMemberShips; - if (SimianGetGenericEntries(agentID, "GroupMember", out GroupMemberShips)) - { - foreach (string key in GroupMemberShips.Keys) - { - memberships.Add(GetAgentGroupMembership(requestingAgentID, agentID, UUID.Parse(key))); - } - } - - return memberships; - } - - public List GetAgentGroupRoles(UUID requestingAgentID, UUID agentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List Roles = new List(); - - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - Dictionary MemberRoles; - if (SimianGetGenericEntries(agentID, "GroupRole" + groupID.ToString(), out MemberRoles)) - { - foreach (KeyValuePair kvp in MemberRoles) - { - GroupRolesData data = new GroupRolesData(); - data.RoleID = UUID.Parse(kvp.Key); - data.Name = GroupRoles[kvp.Key]["Name"].AsString(); - data.Description = GroupRoles[kvp.Key]["Description"].AsString(); - data.Title = GroupRoles[kvp.Key]["Title"].AsString(); - data.Powers = GroupRoles[kvp.Key]["Powers"].AsULong(); - - Roles.Add(data); - } - } - } - return Roles; - } - - public List GetGroupRoles(UUID requestingAgentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List Roles = new List(); - - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - foreach (KeyValuePair role in GroupRoles) - { - GroupRolesData data = new GroupRolesData(); - - data.RoleID = UUID.Parse(role.Key); - - data.Name = role.Value["Name"].AsString(); - data.Description = role.Value["Description"].AsString(); - data.Title = role.Value["Title"].AsString(); - data.Powers = role.Value["Powers"].AsULong(); - - Dictionary GroupRoleMembers; - if (SimianGetGenericEntries("GroupRole" + groupID.ToString(), role.Key, out GroupRoleMembers)) - { - data.Members = GroupRoleMembers.Count; - } - else - { - data.Members = 0; - } - - Roles.Add(data); - } - } - - return Roles; - - } - - - - public List GetGroupMembers(UUID requestingAgentID, UUID GroupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List members = new List(); - - OSDMap GroupInfo; - string GroupName; - UUID GroupOwnerRoleID = UUID.Zero; - if (!SimianGetFirstGenericEntry(GroupID, "Group", out GroupName, out GroupInfo)) - { - return members; - } - GroupOwnerRoleID = GroupInfo["OwnerRoleID"].AsUUID(); - - // Locally cache group roles, since we'll be needing this data for each member - Dictionary GroupRoles; - SimianGetGenericEntries(GroupID, "GroupRole", out GroupRoles); - - // Locally cache list of group owners - Dictionary GroupOwners; - SimianGetGenericEntries("GroupRole" + GroupID.ToString(), GroupOwnerRoleID.ToString(), out GroupOwners); - - - Dictionary GroupMembers; - if (SimianGetGenericEntries("GroupMember", GroupID.ToString(), out GroupMembers)) - { - foreach (KeyValuePair member in GroupMembers) - { - GroupMembersData data = new GroupMembersData(); - - data.AgentID = member.Key; - - UUID SelectedRoleID = member.Value["SelectedRoleID"].AsUUID(); - - data.AcceptNotices = member.Value["AcceptNotices"].AsBoolean(); - data.ListInProfile = member.Value["ListInProfile"].AsBoolean(); - data.Contribution = member.Value["Contribution"].AsInteger(); - - data.IsOwner = GroupOwners.ContainsKey(member.Key); - - OSDMap GroupRoleInfo = GroupRoles[SelectedRoleID.ToString()]; - data.Title = GroupRoleInfo["Title"].AsString(); - data.AgentPowers = GroupRoleInfo["Powers"].AsULong(); - - members.Add(data); - } - } - - return members; - - } - - public List GetGroupRoleMembers(UUID requestingAgentID, UUID groupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List members = new List(); - - Dictionary GroupRoles; - if (SimianGetGenericEntries(groupID, "GroupRole", out GroupRoles)) - { - foreach( KeyValuePair Role in GroupRoles ) - { - Dictionary GroupRoleMembers; - if( SimianGetGenericEntries("GroupRole"+groupID.ToString(), Role.Key, out GroupRoleMembers) ) - { - foreach( KeyValuePair GroupRoleMember in GroupRoleMembers ) - { - GroupRoleMembersData data = new GroupRoleMembersData(); - - data.MemberID = GroupRoleMember.Key; - data.RoleID = UUID.Parse(Role.Key); - - members.Add(data); - } - } - } - } - - return members; - } - - public List GetGroupNotices(UUID requestingAgentID, UUID GroupID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - List values = new List(); - - Dictionary Notices; - if (SimianGetGenericEntries(GroupID, "GroupNotice", out Notices)) - { - foreach (KeyValuePair Notice in Notices) - { - GroupNoticeData data = new GroupNoticeData(); - data.NoticeID = UUID.Parse(Notice.Key); - data.Timestamp = Notice.Value["TimeStamp"].AsUInteger(); - data.FromName = Notice.Value["FromName"].AsString(); - data.Subject = Notice.Value["Subject"].AsString(); - data.HasAttachment = Notice.Value["BinaryBucket"].AsBinary().Length > 0; - - //TODO: Figure out how to get this - data.AssetType = 0; - - values.Add(data); - } - } - - return values; - - } - public GroupNoticeInfo GetGroupNotice(UUID requestingAgentID, UUID noticeID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap GroupNotice; - UUID GroupID; - if (SimianGetFirstGenericEntry("GroupNotice", noticeID.ToString(), out GroupID, out GroupNotice)) - { - GroupNoticeInfo data = new GroupNoticeInfo(); - data.GroupID = GroupID; - data.Message = GroupNotice["Message"].AsString(); - data.BinaryBucket = GroupNotice["BinaryBucket"].AsBinary(); - data.noticeData.NoticeID = noticeID; - data.noticeData.Timestamp = GroupNotice["TimeStamp"].AsUInteger(); - data.noticeData.FromName = GroupNotice["FromName"].AsString(); - data.noticeData.Subject = GroupNotice["Subject"].AsString(); - data.noticeData.HasAttachment = data.BinaryBucket.Length > 0; - data.noticeData.AssetType = 0; - - if (data.Message == null) - { - data.Message = string.Empty; - } - - return data; - } - return null; - } - public void AddGroupNotice(UUID requestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - OSDMap Notice = new OSDMap(); - Notice["TimeStamp"] = OSD.FromUInteger((uint)Util.UnixTimeSinceEpoch()); - Notice["FromName"] = OSD.FromString(fromName); - Notice["Subject"] = OSD.FromString(subject); - Notice["Message"] = OSD.FromString(message); - Notice["BinaryBucket"] = OSD.FromBinary(binaryBucket); - - SimianAddGeneric(groupID, "GroupNotice", noticeID.ToString(), Notice); - - } - #endregion - - #region GroupSessionTracking - - public void ResetAgentGroupChatSessions(UUID agentID) - { - Dictionary agentSessions; - - if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) - { - foreach (string GroupID in agentSessions.Keys) - { - SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); - } - } - - if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) - { - foreach (string GroupID in agentSessions.Keys) - { - SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); - } - } - } - - public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) - { - OSDMap session; - return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); - } - - public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) - { - SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); - } - - public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); - } - - public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) - { - OSDMap session; - return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); - } - - #endregion - - private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - // If member's SelectedRole is roleID, change their selected role to Everyone - // before removing them from the role - OSDMap UserGroupInfo; - if (SimianGetGenericEntry(userID, "GroupMember", groupID.ToString(), out UserGroupInfo)) - { - if (UserGroupInfo["SelectedRoleID"].AsUUID() == roleID) - { - UserGroupInfo["SelectedRoleID"] = OSD.FromUUID(UUID.Zero); - } - SimianAddGeneric(userID, "GroupMember", groupID.ToString(), UserGroupInfo); - } - } - - - #region Simian Util Methods - private bool SimianAddGeneric(UUID ownerID, string type, string key, OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); - - string value = OSDParser.SerializeJsonString(map); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] value: {0}", value); - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "AddGeneric" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type }, - { "Key", key }, - { "Value", value} - }; - - - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); - if (Response["Success"].AsBoolean()) - { - return true; - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, Response["Message"]); - return false; - } - } - - /// - /// Returns the first of possibly many entries for Owner/Type pair - /// - private bool SimianGetFirstGenericEntry(UUID ownerID, string type, out string key, out OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type); - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type } - }; - - - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); - if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); - } - key = null; - map = null; - return false; - } - private bool SimianGetFirstGenericEntry(string type, string key, out UUID ownerID, out OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); - - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "Type", type }, - { "Key", key} - }; - - - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); - if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count >= 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - ownerID = entryMap["OwnerID"].AsUUID(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); - } - ownerID = UUID.Zero; - map = null; - return false; - } - - private bool SimianGetGenericEntry(UUID ownerID, string type, string key, out OSDMap map) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); - - NameValueCollection RequestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type }, - { "Key", key} - }; - - - OSDMap Response = WebUtil.PostToService(m_groupsServerURI, RequestArgs); - if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) - { - OSDArray entryArray = (OSDArray)Response["Entries"]; - if (entryArray.Count == 1) - { - OSDMap entryMap = entryArray[0] as OSDMap; - key = entryMap["Key"].AsString(); - map = (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString()); - - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - - return true; - } - else - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", Response["Message"]); - } - map = null; - return false; - } - - private bool SimianGetGenericEntries(UUID ownerID, string type, out Dictionary maps) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name,ownerID, type); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type } - }; - - - - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); - if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) - { - maps = new Dictionary(); - - OSDArray entryArray = (OSDArray)response["Entries"]; - foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - maps.Add(entryMap["Key"].AsString(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if(maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - - return true; - } - else - { - maps = null; - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error retrieving group info ({0})", response["Message"]); - } - return false; - } - private bool SimianGetGenericEntries(string type, string key, out Dictionary maps) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2})", System.Reflection.MethodBase.GetCurrentMethod().Name, type, key); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "GetGenerics" }, - { "Type", type }, - { "Key", key } - }; - - - - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); - if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) - { - maps = new Dictionary(); - - OSDArray entryArray = (OSDArray)response["Entries"]; - foreach (OSDMap entryMap in entryArray) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Generics Result {0}", entryMap["Value"].AsString()); - maps.Add(entryMap["OwnerID"].AsUUID(), (OSDMap)OSDParser.DeserializeJson(entryMap["Value"].AsString())); - } - if (maps.Count == 0) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] No Generics Results"); - } - return true; - } - else - { - maps = null; - m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR]: Error retrieving group info ({0})", response["Message"]); - } - return false; - } - - private bool SimianRemoveGenericEntry(UUID ownerID, string type, string key) - { - if (m_debugEnabled) m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] {0} called ({1},{2},{3})", System.Reflection.MethodBase.GetCurrentMethod().Name, ownerID, type, key); - - NameValueCollection requestArgs = new NameValueCollection - { - { "RequestMethod", "RemoveGeneric" }, - { "OwnerID", ownerID.ToString() }, - { "Type", type }, - { "Key", key } - }; - - - OSDMap response = WebUtil.PostToService(m_groupsServerURI, requestArgs); - if (response["Success"].AsBoolean()) - { - return true; - } - else - { - m_log.WarnFormat("[SIMIAN GROUPS CONNECTOR]: Error {0}, {1}, {2}, {3}", ownerID, type, key, response["Message"]); - return false; - } - } - #endregion - - } - -} - -- cgit v1.1 From e0f9b1a69994be3e5771ebdcb0f2c253f67150db Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 5 May 2010 21:12:02 +0200 Subject: Removed a test for a "can't happen" case. ParentGroup is never null anymore. --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d216eff..6ab3c62 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2033,14 +2033,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); - if (part.ParentGroup == null) - { - if ((targetPos.z < ground) && disable_underground_movement) - targetPos.z = ground; - LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); - part.UpdateOffSet(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); - } - else if (part.ParentGroup.RootPart == part) + if (part.ParentGroup.RootPart == part) { if ((targetPos.z < ground) && disable_underground_movement) targetPos.z = ground; @@ -2050,7 +2043,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - //it's late... i think this is right ? if (llVecDist(new LSL_Vector(0,0,0), targetPos) <= 10.0f) { part.OffsetPosition = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z); -- cgit v1.1 From 65775b87e5000a07634240ab8ce39aaecd30d1e6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 5 May 2010 23:06:36 +0200 Subject: Add a XMLRPC method to remotely set the login level for the LLLoginService. This requires a special XMLRPC call, which has to supply the credentials of a god user (User level >= 200). Disabled by default. Also Adds a configuration option to set the initial permitted login level. --- OpenSim/Server/Handlers/Login/LLLoginHandlers.cs | 37 +++++++++++++++ .../Handlers/Login/LLLoginServiceInConnector.cs | 1 + OpenSim/Services/Interfaces/ILoginService.cs | 1 + OpenSim/Services/LLLoginService/LLLoginService.cs | 53 ++++++++++++++++++++++ 4 files changed, 92 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs index daf2704..83b3e31 100644 --- a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs +++ b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs @@ -99,6 +99,43 @@ namespace OpenSim.Server.Handlers.Login } + public XmlRpcResponse HandleXMLRPCSetLoginLevel(XmlRpcRequest request, IPEndPoint remoteClient) + { + Hashtable requestData = (Hashtable)request.Params[0]; + + if (requestData != null) + { + if (requestData.ContainsKey("first") && requestData["first"] != null && + requestData.ContainsKey("last") && requestData["last"] != null && + requestData.ContainsKey("level") && requestData["level"] != null && + requestData.ContainsKey("passwd") && requestData["passwd"] != null) + { + string first = requestData["first"].ToString(); + string last = requestData["last"].ToString(); + string passwd = requestData["passwd"].ToString(); + int level = Int32.Parse(requestData["level"].ToString()); + + m_log.InfoFormat("[LOGIN]: XMLRPC Set Level to {2} Requested by {0} {1}", first, last, level); + + Hashtable reply = m_LocalService.SetLevel(first, last, passwd, level, remoteClient); + + XmlRpcResponse response = new XmlRpcResponse(); + response.Value = reply; + + return response; + + } + } + + XmlRpcResponse failResponse = new XmlRpcResponse(); + Hashtable failHash = new Hashtable(); + failHash["success"] = "false"; + failResponse.Value = failHash; + + return failResponse; + + } + public OSD HandleLLSDLogin(OSD request, IPEndPoint remoteClient) { if (request.Type == OSDType.Map) diff --git a/OpenSim/Server/Handlers/Login/LLLoginServiceInConnector.cs b/OpenSim/Server/Handlers/Login/LLLoginServiceInConnector.cs index e24055b..67e8392 100644 --- a/OpenSim/Server/Handlers/Login/LLLoginServiceInConnector.cs +++ b/OpenSim/Server/Handlers/Login/LLLoginServiceInConnector.cs @@ -88,6 +88,7 @@ namespace OpenSim.Server.Handlers.Login { LLLoginHandlers loginHandlers = new LLLoginHandlers(m_LoginService); server.AddXmlRPCHandler("login_to_simulator", loginHandlers.HandleXMLRPCLogin, false); + server.AddXmlRPCHandler("set_login_level", loginHandlers.HandleXMLRPCSetLoginLevel, false); server.SetDefaultLLSDHandler(loginHandlers.HandleLLSDLogin); } diff --git a/OpenSim/Services/Interfaces/ILoginService.cs b/OpenSim/Services/Interfaces/ILoginService.cs index 49efbe2..513ab4a 100644 --- a/OpenSim/Services/Interfaces/ILoginService.cs +++ b/OpenSim/Services/Interfaces/ILoginService.cs @@ -48,6 +48,7 @@ namespace OpenSim.Services.Interfaces public interface ILoginService { LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP); + Hashtable SetLevel(string firstName, string lastName, string passwd, int level, IPEndPoint clientIP); } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 5301140..5b950e0 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections; using System.Collections.Generic; using System.Net; using System.Reflection; @@ -70,6 +71,7 @@ namespace OpenSim.Services.LLLoginService private bool m_RequireInventory; protected int m_MinLoginLevel; private string m_GatekeeperURL; + private bool m_AllowRemoteSetLoginLevel; IConfig m_LoginServerConfig; @@ -93,6 +95,8 @@ namespace OpenSim.Services.LLLoginService m_DefaultRegionName = m_LoginServerConfig.GetString("DefaultRegion", String.Empty); m_WelcomeMessage = m_LoginServerConfig.GetString("WelcomeMessage", "Welcome to OpenSim!"); m_RequireInventory = m_LoginServerConfig.GetBoolean("RequireInventory", true); + m_AllowRemoteSetLoginLevel = m_LoginServerConfig.GetBoolean("AllowRemoteSetLoginLevel", false); + m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0); m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); // These are required; the others aren't @@ -147,6 +151,55 @@ namespace OpenSim.Services.LLLoginService { } + public Hashtable SetLevel(string firstName, string lastName, string passwd, int level, IPEndPoint clientIP) + { + Hashtable response = new Hashtable(); + response["success"] = "false"; + + if (!m_AllowRemoteSetLoginLevel) + return response; + + try + { + UserAccount account = m_UserAccountService.GetUserAccount(UUID.Zero, firstName, lastName); + if (account == null) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Set Level failed, user {0} {1} not found", firstName, lastName); + return response; + } + + if (account.UserLevel < 200) + { + m_log.InfoFormat("[LLOGIN SERVICE]: Set Level failed, reason: user level too low"); + return response; + } + + // + // Authenticate this user + // + // We don't support clear passwords here + // + string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30); + UUID secureSession = UUID.Zero; + if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession))) + { + m_log.InfoFormat("[LLOGIN SERVICE]: SetLevel failed, reason: authentication failed"); + return response; + } + } + catch (Exception e) + { + m_log.Error("[LLOGIN SERVICE]: SetLevel failed, exception " + e.ToString()); + return response; + } + + m_MinLoginLevel = level; + m_log.InfoFormat("[LLOGIN SERVICE]: Login level set to {0} by {1} {2}", level, firstName, lastName); + + response["success"] = true; + return response; + } + public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP) { bool success = false; -- cgit v1.1 From 733a07e061cdcb6095677758a264ba976bb94b93 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 6 May 2010 00:34:49 +0200 Subject: Plumb the viewer version string through into AgentCircuitData. Now all that is left os to figure out what black magic turns AgentCircuitData into AgentData and then copy that into the ScenePresence, where m_Viewer is already added with this commit and waits for the data. --- OpenSim/Framework/AgentCircuitData.cs | 11 +++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 ++++++ OpenSim/Server/Handlers/Login/LLLoginHandlers.cs | 4 ++-- OpenSim/Services/Interfaces/ILoginService.cs | 2 +- OpenSim/Services/LLLoginService/LLLoginService.cs | 13 +++++++------ 5 files changed, 27 insertions(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index 353e5bf..783a833 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -108,6 +108,11 @@ namespace OpenSim.Framework public string ServiceSessionID = string.Empty; /// + /// Viewer's version string + /// + public string Viewer; + + /// /// Position the Agent's Avatar starts in the region /// public Vector3 startpos; @@ -136,6 +141,7 @@ namespace OpenSim.Framework BaseFolder = new UUID(cAgent.BaseFolder); CapsPath = cAgent.CapsPath; ChildrenCapSeeds = cAgent.ChildrenCapSeeds; + Viewer = cAgent.Viewer; } /// @@ -173,6 +179,7 @@ namespace OpenSim.Framework args["service_session_id"] = OSD.FromString(ServiceSessionID); args["start_pos"] = OSD.FromString(startpos.ToString()); args["appearance_serial"] = OSD.FromInteger(Appearance.Serial); + args["viewer"] = OSD.FromString(Viewer); if (Appearance != null) { @@ -272,6 +279,8 @@ namespace OpenSim.Framework SessionID = args["session_id"].AsUUID(); if (args["service_session_id"] != null) ServiceSessionID = args["service_session_id"].AsString(); + if (args["viewer"] != null) + Viewer = args["viewer"].AsString(); if (args["start_pos"] != null) Vector3.TryParse(args["start_pos"].AsString(), out startpos); @@ -339,6 +348,7 @@ namespace OpenSim.Framework public float startposx; public float startposy; public float startposz; + public string Viewer; public sAgentCircuitData() { @@ -360,6 +370,7 @@ namespace OpenSim.Framework BaseFolder = cAgent.BaseFolder.Guid; CapsPath = cAgent.CapsPath; ChildrenCapSeeds = cAgent.ChildrenCapSeeds; + Viewer = cAgent.Viewer; } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 562232c..987180b 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -227,6 +227,7 @@ namespace OpenSim.Region.Framework.Scenes private int m_lastColCount = -1; //KF: Look for Collision chnages private int m_updateCount = 0; //KF: Update Anims for a while private static readonly int UPDATE_COUNT = 10; // how many frames to update for + private string m_Viewer = String.Empty; private const int NumMovementsBetweenRayCast = 5; @@ -664,6 +665,11 @@ namespace OpenSim.Region.Framework.Scenes set { m_flyDisabled = value; } } + public string Viewer + { + get { return m_Viewer; } + } + #endregion #region Constructor(s) diff --git a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs index 83b3e31..c9bf996 100644 --- a/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs +++ b/OpenSim/Server/Handlers/Login/LLLoginHandlers.cs @@ -86,7 +86,7 @@ namespace OpenSim.Server.Handlers.Login m_log.InfoFormat("[LOGIN]: XMLRPC Login Requested for {0} {1}, starting in {2}, using {3}", first, last, startLocation, clientVersion); LoginResponse reply = null; - reply = m_LocalService.Login(first, last, passwd, startLocation, scopeID, remoteClient); + reply = m_LocalService.Login(first, last, passwd, startLocation, scopeID, clientVersion, remoteClient); XmlRpcResponse response = new XmlRpcResponse(); response.Value = reply.ToHashtable(); @@ -157,7 +157,7 @@ namespace OpenSim.Server.Handlers.Login m_log.Info("[LOGIN]: LLSD Login Requested for: '" + map["first"].AsString() + "' '" + map["last"].AsString() + "' / " + startLocation); LoginResponse reply = null; - reply = m_LocalService.Login(map["first"].AsString(), map["last"].AsString(), map["passwd"].AsString(), startLocation, scopeID, remoteClient); + reply = m_LocalService.Login(map["first"].AsString(), map["last"].AsString(), map["passwd"].AsString(), startLocation, scopeID, String.Empty, remoteClient); return reply.ToOSDMap(); } diff --git a/OpenSim/Services/Interfaces/ILoginService.cs b/OpenSim/Services/Interfaces/ILoginService.cs index 513ab4a..9e57339 100644 --- a/OpenSim/Services/Interfaces/ILoginService.cs +++ b/OpenSim/Services/Interfaces/ILoginService.cs @@ -47,7 +47,7 @@ namespace OpenSim.Services.Interfaces public interface ILoginService { - LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP); + LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, string clientVersion, IPEndPoint clientIP); Hashtable SetLevel(string firstName, string lastName, string passwd, int level, IPEndPoint clientIP); } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 5b950e0..9efdd11 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -200,7 +200,7 @@ namespace OpenSim.Services.LLLoginService return response; } - public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, IPEndPoint clientIP) + public LoginResponse Login(string firstName, string lastName, string passwd, string startLocation, UUID scopeID, string clientVersion, IPEndPoint clientIP) { bool success = false; UUID session = UUID.Random(); @@ -326,7 +326,7 @@ namespace OpenSim.Services.LLLoginService // Instantiate/get the simulation interface and launch an agent at the destination // string reason = string.Empty; - AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, out where, out reason); + AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, out where, out reason); if (aCircuit == null) { @@ -592,7 +592,7 @@ namespace OpenSim.Services.LLLoginService } protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, - UUID session, UUID secureSession, Vector3 position, string currentWhere, out string where, out string reason) + UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, out string where, out string reason) { where = currentWhere; ISimulationService simConnector = null; @@ -632,7 +632,7 @@ namespace OpenSim.Services.LLLoginService if (m_UserAgentService == null && simConnector != null) { circuitCode = (uint)Util.RandomClass.Next(); ; - aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position); + aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer); success = LaunchAgentDirectly(simConnector, destination, aCircuit, out reason); if (!success && m_GridService != null) { @@ -657,7 +657,7 @@ namespace OpenSim.Services.LLLoginService if (m_UserAgentService != null) { circuitCode = (uint)Util.RandomClass.Next(); ; - aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position); + aCircuit = MakeAgent(destination, account, avatar, session, secureSession, circuitCode, position, viewer); success = LaunchAgentIndirectly(gatekeeper, destination, aCircuit, out reason); if (!success && m_GridService != null) { @@ -686,7 +686,7 @@ namespace OpenSim.Services.LLLoginService } private AgentCircuitData MakeAgent(GridRegion region, UserAccount account, - AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position) + AvatarData avatar, UUID session, UUID secureSession, uint circuit, Vector3 position, string viewer) { AgentCircuitData aCircuit = new AgentCircuitData(); @@ -707,6 +707,7 @@ namespace OpenSim.Services.LLLoginService aCircuit.SecureSessionID = secureSession; aCircuit.SessionID = session; aCircuit.startpos = position; + aCircuit.Viewer = viewer; SetServiceURLs(aCircuit, account); return aCircuit; -- cgit v1.1 From 2d9a20529d6818093747eb764d86efa11f3874d5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 6 May 2010 00:54:21 +0200 Subject: Plumb Viewer version into ScenePresence for initial login. It's still not carried along --- OpenSim/Region/Framework/Scenes/Scene.cs | 1 + OpenSim/Region/Framework/Scenes/ScenePresence.cs | 1 + 2 files changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 0ca5948..bebd463 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2680,6 +2680,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence sp = CreateAndAddScenePresence(client); if (aCircuit != null) sp.Appearance = aCircuit.Appearance; + sp.Viewer = aCircuit.Viewer; // HERE!!! Do the initial attachments right here // first agent upon login is a root agent by design. diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 987180b..f649dfe 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -668,6 +668,7 @@ namespace OpenSim.Region.Framework.Scenes public string Viewer { get { return m_Viewer; } + set { m_Viewer = value; } } #endregion -- cgit v1.1 From 02dea4ce580a08a9a4119ed063ed36704bb44825 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 6 May 2010 02:02:12 +0200 Subject: Remove the m_Viewer variable and make the property a shortcut to the proper field in AgentCircuitData instead --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 +---- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 897fda6..0ca5948 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2679,10 +2679,7 @@ namespace OpenSim.Region.Framework.Scenes ScenePresence sp = CreateAndAddScenePresence(client); if (aCircuit != null) - { sp.Appearance = aCircuit.Appearance; - sp.Viewer = aCircuit.Viewer; - } // HERE!!! Do the initial attachments right here // first agent upon login is a root agent by design. diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f649dfe..cb24784 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -227,8 +227,6 @@ namespace OpenSim.Region.Framework.Scenes private int m_lastColCount = -1; //KF: Look for Collision chnages private int m_updateCount = 0; //KF: Update Anims for a while private static readonly int UPDATE_COUNT = 10; // how many frames to update for - private string m_Viewer = String.Empty; - private const int NumMovementsBetweenRayCast = 5; private bool CameraConstraintActive; @@ -667,8 +665,7 @@ namespace OpenSim.Region.Framework.Scenes public string Viewer { - get { return m_Viewer; } - set { m_Viewer = value; } + get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } } #endregion -- cgit v1.1 From 69d0201d4c3c62cda339eda35c15978837a7e2a3 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 6 May 2010 16:38:23 +0100 Subject: Revert "Patch from mcortez: Update groups, add ALPHA Siman grid connector for groups" Causes an exception within HttpServer, headers have already been sent. This reverts commit 8187fccd258bf0936d3db8663844e07a7b81e9fc. --- .../Avatar/XmlRpcGroups/GroupsMessagingModule.cs | 274 ++++++++++----------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 3 +- .../XmlRpcGroups/IGroupsServicesConnector.cs | 6 + .../SimianGroupsServicesConnectorModule.cs | 142 +++++++++-- .../XmlRpcGroupsServicesConnectorModule.cs | 217 ++++++++++++---- 5 files changed, 436 insertions(+), 206 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs index 00fe5df..185d44d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsMessagingModule.cs @@ -28,41 +28,30 @@ using System; using System.Collections.Generic; using System.Reflection; - - using log4net; using Mono.Addins; using Nini.Config; - using OpenMetaverse; using OpenMetaverse.StructuredData; - using OpenSim.Framework; using OpenSim.Region.CoreModules.Framework.EventQueue; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; - using Caps = OpenSim.Framework.Capabilities.Caps; namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class GroupsMessagingModule : ISharedRegionModule + public class GroupsMessagingModule : ISharedRegionModule, IGroupsMessagingModule { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private List m_sceneList = new List(); private IMessageTransferModule m_msgTransferModule = null; - private IGroupsModule m_groupsModule = null; - - // TODO: Move this off to the Groups Server - public Dictionary> m_agentsInGroupSession = new Dictionary>(); - public Dictionary> m_agentsDroppedSession = new Dictionary>(); - + private IGroupsServicesConnector m_groupData = null; // Config Options private bool m_groupMessagingEnabled = false; @@ -108,8 +97,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void AddRegion(Scene scene) { - // NoOp + if (!m_groupMessagingEnabled) + return; + + scene.RegisterModuleInterface(this); } + public void RegionLoaded(Scene scene) { if (!m_groupMessagingEnabled) @@ -117,12 +110,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - m_groupsModule = scene.RequestModuleInterface(); + m_groupData = scene.RequestModuleInterface(); // No groups module, no groups messaging - if (m_groupsModule == null) + if (m_groupData == null) { - m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsModule, GroupsMessagingModule is now disabled."); + m_log.Error("[GROUPS-MESSAGING]: Could not get IGroupsServicesConnector, GroupsMessagingModule is now disabled."); Close(); m_groupMessagingEnabled = false; return; @@ -144,7 +137,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - + scene.EventManager.OnClientLogin += OnClientLogin; } public void RemoveRegion(Scene scene) @@ -172,7 +165,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_sceneList.Clear(); - m_groupsModule = null; + m_groupData = null; m_msgTransferModule = null; } @@ -197,8 +190,84 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion + /// + /// Not really needed, but does confirm that the group exists. + /// + public bool StartGroupChatSession(UUID agentID, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(agentID, groupID, null); + + if (groupInfo != null) + { + return true; + } + else + { + return false; + } + } + + public void SendMessageToGroup(GridInstantMessage im, UUID groupID) + { + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); + + + foreach (GroupMembersData member in m_groupData.GetGroupMembers(UUID.Zero, groupID)) + { + if (m_groupData.hasAgentDroppedGroupChatSession(member.AgentID, groupID)) + { + // Don't deliver messages to people who have dropped this session + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); + continue; + } + + // Copy Message + GridInstantMessage msg = new GridInstantMessage(); + msg.imSessionID = groupID.Guid; + msg.fromAgentName = im.fromAgentName; + msg.message = im.message; + msg.dialog = im.dialog; + msg.offline = im.offline; + msg.ParentEstateID = im.ParentEstateID; + msg.Position = im.Position; + msg.RegionID = im.RegionID; + msg.binaryBucket = im.binaryBucket; + msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); + + msg.fromAgentID = im.fromAgentID; + msg.fromGroup = true; + + msg.toAgentID = member.AgentID.Guid; + + IClientAPI client = GetActiveClient(member.AgentID); + if (client == null) + { + // If they're not local, forward across the grid + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); + m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); + } + else + { + // Deliver locally, directly + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); + ProcessMessageFromGroupSession(msg); + } + } + } + #region SimGridEventHandlers + void OnClientLogin(IClientAPI client) + { + if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); + + + } + private void OnNewClient(IClientAPI client) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: OnInstantMessage registered for {0}", client.Name); @@ -236,42 +305,46 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Session message from {0} going to agent {1}", msg.fromAgentName, msg.toAgentID); + UUID AgentID = new UUID(msg.fromAgentID); + UUID GroupID = new UUID(msg.imSessionID); + switch (msg.dialog) { case (byte)InstantMessageDialog.SessionAdd: - AddAgentToGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionDrop: - RemoveAgentFromGroupSession(msg.fromAgentID, msg.imSessionID); + m_groupData.AgentDroppedFromGroupChatSession(AgentID, GroupID); break; case (byte)InstantMessageDialog.SessionSend: - if (!m_agentsInGroupSession.ContainsKey(msg.toAgentID) - && !m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID) + && !m_groupData.hasAgentBeenInvitedToGroupChatSession(AgentID, GroupID) + ) { // Agent not in session and hasn't dropped from session // Add them to the session for now, and Invite them - AddAgentToGroupSession(msg.toAgentID, msg.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); UUID toAgentID = new UUID(msg.toAgentID); IClientAPI activeClient = GetActiveClient(toAgentID); if (activeClient != null) { - UUID groupID = new UUID(msg.fromAgentID); - - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); if (groupInfo != null) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Sending chatterbox invite instant message"); // Force? open the group session dialog??? + // and simultanously deliver the message, so we don't need to do a seperate client.SendInstantMessage(msg); IEventQueue eq = activeClient.Scene.RequestModuleInterface(); eq.ChatterboxInvitation( - groupID + GroupID , groupInfo.GroupName , new UUID(msg.fromAgentID) - , msg.message, new UUID(msg.toAgentID) + , msg.message + , new UUID(msg.toAgentID) , msg.fromAgentName , msg.dialog , msg.timestamp @@ -285,7 +358,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ); eq.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) + new UUID(GroupID) , new UUID(msg.fromAgentID) , new UUID(msg.toAgentID) , false //canVoiceChat @@ -295,7 +368,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } } - else if (!m_agentsDroppedSession.ContainsKey(msg.toAgentID)) + else if (!m_groupData.hasAgentDroppedGroupChatSession(AgentID, GroupID)) { // User hasn't dropped, so they're in the session, // maybe we should deliver it. @@ -321,56 +394,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups #endregion - #region ClientEvents - - private void RemoveAgentFromGroupSession(Guid agentID, Guid sessionID) - { - if (m_agentsInGroupSession.ContainsKey(sessionID)) - { - // If in session remove - if (m_agentsInGroupSession[sessionID].Contains(agentID)) - { - m_agentsInGroupSession[sessionID].Remove(agentID); - } - - // If not in dropped list, add - if (!m_agentsDroppedSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Dropped {1} from session {0}", sessionID, agentID); - m_agentsDroppedSession[sessionID].Add(agentID); - } - } - } - - private void AddAgentToGroupSession(Guid agentID, Guid sessionID) - { - // Add Session Status if it doesn't exist for this session - CreateGroupSessionTracking(sessionID); - - // If nessesary, remove from dropped list - if (m_agentsDroppedSession[sessionID].Contains(agentID)) - { - m_agentsDroppedSession[sessionID].Remove(agentID); - } - - // If nessesary, add to in session list - if (!m_agentsInGroupSession[sessionID].Contains(agentID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Added {1} to session {0}", sessionID, agentID); - m_agentsInGroupSession[sessionID].Add(agentID); - } - } - - private void CreateGroupSessionTracking(Guid sessionID) - { - if (!m_agentsInGroupSession.ContainsKey(sessionID)) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Creating session tracking for : {0}", sessionID); - m_agentsInGroupSession.Add(sessionID, new List()); - m_agentsDroppedSession.Add(sessionID, new List()); - } - } + #region ClientEvents private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) @@ -383,21 +408,23 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Start group IM session if ((im.dialog == (byte)InstantMessageDialog.SessionGroupStart)) { - UUID groupID = new UUID(im.toAgentID); + if (m_debugEnabled) m_log.InfoFormat("[GROUPS-MESSAGING]: imSessionID({0}) toAgentID({1})", im.imSessionID, im.toAgentID); - GroupRecord groupInfo = m_groupsModule.GetGroupRecord(groupID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + GroupRecord groupInfo = m_groupData.GetGroupRecord(UUID.Zero, GroupID, null); + if (groupInfo != null) { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Start Group Session for {0}", groupInfo.GroupName); - - AddAgentToGroupSession(im.fromAgentID, im.imSessionID); + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, groupID); + ChatterBoxSessionStartReplyViaCaps(remoteClient, groupInfo.GroupName, GroupID); IEventQueue queue = remoteClient.Scene.RequestModuleInterface(); queue.ChatterBoxSessionAgentListUpdates( - new UUID(groupID) - , new UUID(im.fromAgentID) + GroupID + , AgentID , new UUID(im.toAgentID) , false //canVoiceChat , false //isModerator @@ -409,64 +436,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups // Send a message from locally connected client to a group if ((im.dialog == (byte)InstantMessageDialog.SessionSend)) { - UUID groupID = new UUID(im.toAgentID); + UUID GroupID = new UUID(im.imSessionID); + UUID AgentID = new UUID(im.fromAgentID); + + if (m_debugEnabled) + m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", GroupID, im.imSessionID.ToString()); - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Send message to session for group {0} with session ID {1}", groupID, im.imSessionID.ToString()); + //If this agent is sending a message, then they want to be in the session + m_groupData.AgentInvitedToGroupChatSession(AgentID, GroupID); - SendMessageToGroup(im, groupID); + SendMessageToGroup(im, GroupID); } } #endregion - private void SendMessageToGroup(GridInstantMessage im, UUID groupID) - { - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); - - foreach (GroupMembersData member in m_groupsModule.GroupMembersRequest(null, groupID)) - { - if (!m_agentsDroppedSession.ContainsKey(im.imSessionID) || m_agentsDroppedSession[im.imSessionID].Contains(member.AgentID.Guid)) - { - // Don't deliver messages to people who have dropped this session - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} has dropped session, not delivering to them", member.AgentID); - continue; - } - - // Copy Message - GridInstantMessage msg = new GridInstantMessage(); - msg.imSessionID = im.imSessionID; - msg.fromAgentName = im.fromAgentName; - msg.message = im.message; - msg.dialog = im.dialog; - msg.offline = im.offline; - msg.ParentEstateID = im.ParentEstateID; - msg.Position = im.Position; - msg.RegionID = im.RegionID; - msg.binaryBucket = im.binaryBucket; - msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); - - // Updat Pertinate fields to make it a "group message" - msg.fromAgentID = groupID.Guid; - msg.fromGroup = true; - - msg.toAgentID = member.AgentID.Guid; - - IClientAPI client = GetActiveClient(member.AgentID); - if (client == null) - { - // If they're not local, forward across the grid - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Delivering to {0} via Grid", member.AgentID); - m_msgTransferModule.SendInstantMessage(msg, delegate(bool success) { }); - } - else - { - // Deliver locally, directly - if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: Passing to ProcessMessageFromGroupSession to deliver to {0} locally", client.Name); - ProcessMessageFromGroupSession(msg); - } - } - } - void ChatterBoxSessionStartReplyViaCaps(IClientAPI remoteClient, string groupName, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[GROUPS-MESSAGING]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); @@ -518,6 +502,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private IClientAPI GetActiveClient(UUID agentID) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Looking for local client {0}", agentID); + IClientAPI child = null; // Try root avatar first @@ -529,16 +515,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups ScenePresence user = (ScenePresence)scene.Entities[agentID]; if (!user.IsChildAgent) { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found root agent for client : {0}", user.ControllingClient.Name); return user.ControllingClient; } else { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Found child agent for client : {0}", user.ControllingClient.Name); child = user.ControllingClient; } } } // If we didn't find a root, then just return whichever child we found, or null if none + if (child == null) + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Could not find local client for agent : {0}", agentID); + } + else + { + if (m_debugEnabled) m_log.WarnFormat("[GROUPS-MESSAGING]: Returning child agent for client : {0}", child.Name); + } return child; } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index b2b8110..56c0d98 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -176,7 +176,6 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups scene.EventManager.OnNewClient += OnNewClient; scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; - // The InstantMessageModule itself doesn't do this, // so lets see if things explode if we don't do it // scene.EventManager.OnClientClosed += OnClientClosed; @@ -510,7 +509,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { - UUID groupID = new UUID(im.fromAgentID); + UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs index 6487967..a046e09 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/IGroupsServicesConnector.cs @@ -71,6 +71,12 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups void AddGroupNotice(UUID RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message, byte[] binaryBucket); GroupNoticeInfo GetGroupNotice(UUID RequestingAgentID, UUID noticeID); List GetGroupNotices(UUID RequestingAgentID, UUID GroupID); + + void ResetAgentGroupChatSessions(UUID agentID); + bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID); + bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID); + void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID); + void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID); } public class GroupInviteInfo diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs index bc05b0f..9363205 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/SimianGroupsServicesConnectorModule.cs @@ -55,6 +55,9 @@ using OpenSim.Services.Interfaces; * UserID -> Group -> ActiveGroup * + GroupID * + * UserID -> GroupSessionDropped -> GroupID + * UserID -> GroupSessionInvited -> GroupID + * * UserID -> GroupMember -> GroupID * + SelectedRoleID [UUID] * + AcceptNotices [bool] @@ -63,6 +66,7 @@ using OpenSim.Services.Interfaces; * * UserID -> GroupRole[GroupID] -> RoleID * + * * GroupID -> Group -> GroupName * + Charter * + ShowInList @@ -159,10 +163,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_debugEnabled = false; + private ExpiringCache m_memoryCache; + private int m_cacheTimeout = 30; + // private IUserAccountService m_accountService = null; @@ -199,17 +206,33 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) { - m_log.ErrorFormat("Please specify a valid Simian Server URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid Simian Server for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } + + m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); + if (m_cacheTimeout == 0) + { + m_log.WarnFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Disabled."); + } + else + { + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR] Groups Cache Timeout set to {0}.", m_cacheTimeout); + } + + + + m_memoryCache = new ExpiringCache(); + + // If we got all the config options we need, lets start'er'up m_connectorEnabled = true; @@ -220,7 +243,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups public void Close() { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[SIMIAN-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -653,7 +676,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)response["Entries"]; @@ -998,6 +1021,52 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } #endregion + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + Dictionary agentSessions; + + if (SimianGetGenericEntries(agentID, "GroupSessionDropped", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionDropped", GroupID); + } + } + + if (SimianGetGenericEntries(agentID, "GroupSessionInvited", out agentSessions)) + { + foreach (string GroupID in agentSessions.Keys) + { + SimianRemoveGenericEntry(agentID, "GroupSessionInvited", GroupID); + } + } + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionDropped", groupID.ToString(), new OSDMap()); + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + SimianAddGeneric(agentID, "GroupSessionInvited", groupID.ToString(), new OSDMap()); + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + OSDMap session; + return SimianGetGenericEntry(agentID, "GroupSessionDropped", groupID.ToString(), out session); + } + + #endregion private void EnsureRoleNotSelectedByMember(UUID groupID, UUID roleID, UUID userID) { @@ -1036,7 +1105,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean()) { return true; @@ -1063,7 +1132,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1103,7 +1172,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1144,7 +1213,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap Response = WebUtil.PostToService(m_serviceURL, RequestArgs); + OSDMap Response = CachedPostRequest(RequestArgs); if (Response["Success"].AsBoolean() && Response["Entries"] is OSDArray) { OSDArray entryArray = (OSDArray)Response["Entries"]; @@ -1184,7 +1253,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); @@ -1222,7 +1291,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean() && response["Entries"] is OSDArray) { maps = new Dictionary(); @@ -1260,7 +1329,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups }; - OSDMap response = WebUtil.PostToService(m_serviceURL, requestArgs); + OSDMap response = CachedPostRequest(requestArgs); if (response["Success"].AsBoolean()) { return true; @@ -1272,6 +1341,49 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups } } #endregion + + #region CheesyCache + OSDMap CachedPostRequest(NameValueCollection requestArgs) + { + // Immediately forward the request if the cache is disabled. + if (m_cacheTimeout == 0) + { + return WebUtil.PostToService(m_groupsServerURI, requestArgs); + } + + // Check if this is an update or a request + if ( requestArgs["RequestMethod"] == "RemoveGeneric" + || requestArgs["RequestMethod"] == "AddGeneric" + ) + + { + // Any and all updates cause the cache to clear + m_memoryCache.Clear(); + + // Send update to server, return the response without caching it + return WebUtil.PostToService(m_groupsServerURI, requestArgs); + + } + + // If we're not doing an update, we must be requesting data + + // Create the cache key for the request and see if we have it cached + string CacheKey = WebUtil.BuildQueryString(requestArgs); + OSDMap response = null; + if (!m_memoryCache.TryGetValue(CacheKey, out response)) + { + // if it wasn't in the cache, pass the request to the Simian Grid Services + response = WebUtil.PostToService(m_groupsServerURI, requestArgs); + + // and cache the response + m_memoryCache.AddOrUpdate(CacheKey, response, TimeSpan.FromSeconds(m_cacheTimeout)); + } + + // return cached response + return response; + } + #endregion + } } diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs index ab343c8..79b9a16 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/XmlRpcGroupsServicesConnectorModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; +using System.Text; using Nwc.XmlRpc; @@ -61,7 +62,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private bool m_connectorEnabled = false; - private string m_serviceURL = string.Empty; + private string m_groupsServerURI = string.Empty; private bool m_disableKeepAlive = false; @@ -69,7 +70,17 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private string m_groupWriteKey = string.Empty; private IUserAccountService m_accountService = null; - + + private ExpiringCache m_memoryCache; + private int m_cacheTimeout = 30; + + // Used to track which agents are have dropped from a group chat session + // Should be reset per agent, on logon + // TODO: move this to Flotsam XmlRpc Service + // SessionID, List + private Dictionary> m_groupsAgentsDroppedFromChatSession = new Dictionary>(); + private Dictionary> m_groupsAgentsInvitedToChatSession = new Dictionary>(); + #region IRegionModuleBase Members @@ -104,13 +115,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return; } - m_log.InfoFormat("[GROUPS-CONNECTOR]: Initializing {0}", this.Name); + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Initializing {0}", this.Name); - m_serviceURL = groupsConfig.GetString("XmlRpcServiceURL", string.Empty); - if ((m_serviceURL == null) || - (m_serviceURL == string.Empty)) + m_groupsServerURI = groupsConfig.GetString("GroupsServerURI", string.Empty); + if ((m_groupsServerURI == null) || + (m_groupsServerURI == string.Empty)) { - m_log.ErrorFormat("Please specify a valid URL for XmlRpcServiceURL in OpenSim.ini, [Groups]"); + m_log.ErrorFormat("Please specify a valid URL for GroupsServerURI in OpenSim.ini, [Groups]"); m_connectorEnabled = false; return; } @@ -120,17 +131,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups m_groupReadKey = groupsConfig.GetString("XmlRpcServiceReadKey", string.Empty); m_groupWriteKey = groupsConfig.GetString("XmlRpcServiceWriteKey", string.Empty); - + m_cacheTimeout = groupsConfig.GetInt("GroupsCacheTimeout", 30); + if (m_cacheTimeout == 0) + { + m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Disabled."); + } + else + { + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Groups Cache Timeout set to {0}.", m_cacheTimeout); + } // If we got all the config options we need, lets start'er'up + m_memoryCache = new ExpiringCache(); m_connectorEnabled = true; } } public void Close() { - m_log.InfoFormat("[GROUPS-CONNECTOR]: Closing {0}", this.Name); + m_log.InfoFormat("[XMLRPC-GROUPS-CONNECTOR]: Closing {0}", this.Name); } public void AddRegion(OpenSim.Region.Framework.Scenes.Scene scene) @@ -756,6 +776,69 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups XmlRpcCall(requestingAgentID, "groups.addGroupNotice", param); } + + + + #endregion + + #region GroupSessionTracking + + public void ResetAgentGroupChatSessions(UUID agentID) + { + foreach (List agentList in m_groupsAgentsDroppedFromChatSession.Values) + { + agentList.Remove(agentID); + } + } + + public bool hasAgentBeenInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking this group, and we can find them in the tracking, then they've been invited + return m_groupsAgentsInvitedToChatSession.ContainsKey(groupID) + && m_groupsAgentsInvitedToChatSession[groupID].Contains(agentID); + } + + public bool hasAgentDroppedGroupChatSession(UUID agentID, UUID groupID) + { + // If we're tracking drops for this group, + // and we find them, well... then they've dropped + return m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID) + && m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID); + } + + public void AgentDroppedFromGroupChatSession(UUID agentID, UUID groupID) + { + if (m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + // If not in dropped list, add + if (!m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Add(agentID); + } + } + } + + public void AgentInvitedToGroupChatSession(UUID agentID, UUID groupID) + { + // Add Session Status if it doesn't exist for this session + CreateGroupChatSessionTracking(groupID); + + // If nessesary, remove from dropped list + if (m_groupsAgentsDroppedFromChatSession[groupID].Contains(agentID)) + { + m_groupsAgentsDroppedFromChatSession[groupID].Remove(agentID); + } + } + + private void CreateGroupChatSessionTracking(UUID groupID) + { + if (!m_groupsAgentsDroppedFromChatSession.ContainsKey(groupID)) + { + m_groupsAgentsDroppedFromChatSession.Add(groupID, new List()); + m_groupsAgentsInvitedToChatSession.Add(groupID, new List()); + } + + } #endregion #region XmlRpcHashtableMarshalling @@ -849,50 +932,84 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// private Hashtable XmlRpcCall(UUID requestingAgentID, string function, Hashtable param) { - string UserService; - UUID SessionID; - GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); - param.Add("requestingAgentID", requestingAgentID.ToString()); - param.Add("RequestingAgentUserService", UserService); - param.Add("RequestingSessionID", SessionID.ToString()); - + XmlRpcResponse resp = null; + string CacheKey = null; + + // Only bother with the cache if it isn't disabled. + if (m_cacheTimeout > 0) + { + if (!function.StartsWith("groups.get")) + { + // Any and all updates cause the cache to clear + m_memoryCache.Clear(); + } + else + { + StringBuilder sb = new StringBuilder(requestingAgentID + function); + foreach (object key in param.Keys) + { + if (param[key] != null) + { + sb.AppendFormat(",{0}:{1}", key.ToString(), param[key].ToString()); + } + } + + CacheKey = sb.ToString(); + m_memoryCache.TryGetValue(CacheKey, out resp); + } - param.Add("ReadKey", m_groupReadKey); - param.Add("WriteKey", m_groupWriteKey); + } + + if( resp == null ) + { + string UserService; + UUID SessionID; + GetClientGroupRequestID(requestingAgentID, out UserService, out SessionID); + param.Add("requestingAgentID", requestingAgentID.ToString()); + param.Add("RequestingAgentUserService", UserService); + param.Add("RequestingSessionID", SessionID.ToString()); - IList parameters = new ArrayList(); - parameters.Add(param); + param.Add("ReadKey", m_groupReadKey); + param.Add("WriteKey", m_groupWriteKey); - ConfigurableKeepAliveXmlRpcRequest req; - req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - XmlRpcResponse resp = null; + IList parameters = new ArrayList(); + parameters.Add(param); - try - { - resp = req.Send(m_serviceURL, 10000); - } - catch (Exception e) - { - + ConfigurableKeepAliveXmlRpcRequest req; + req = new ConfigurableKeepAliveXmlRpcRequest(function, parameters, m_disableKeepAlive); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", e.ToString()); - foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine },StringSplitOptions.None)) + try { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} ", ResponseLine); - } + resp = req.Send(m_groupsServerURI, 10000); - foreach (string key in param.Keys) + if ((m_cacheTimeout > 0) && (CacheKey != null)) + { + m_memoryCache.AddOrUpdate(CacheKey, resp, TimeSpan.FromSeconds(m_cacheTimeout)); + } + + } + catch (Exception e) { - m_log.WarnFormat("[XMLRPCGROUPDATA]: {0} :: {1}", key, param[key].ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: An error has occured while attempting to access the XmlRpcGroups server method: {0}", function); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", e.ToString()); + + foreach (string ResponseLine in req.RequestResponse.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) + { + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} ", ResponseLine); + } + + foreach (string key in param.Keys) + { + m_log.WarnFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", key, param[key].ToString()); + } + + Hashtable respData = new Hashtable(); + respData.Add("error", e.ToString()); + return respData; } - - Hashtable respData = new Hashtable(); - respData.Add("error", e.ToString()); - return respData; } if (resp.Value is Hashtable) @@ -906,21 +1023,21 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups return respData; } - m_log.ErrorFormat("[XMLRPCGROUPDATA]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: The XmlRpc server returned a {1} instead of a hashtable for {0}", function, resp.Value.GetType().ToString()); if (resp.Value is ArrayList) { ArrayList al = (ArrayList)resp.Value; - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Contains {0} elements", al.Count); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Contains {0} elements", al.Count); foreach (object o in al) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0} :: {1}", o.GetType().ToString(), o.ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0} :: {1}", o.GetType().ToString(), o.ToString()); } } else { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Function returned: {0}", resp.Value.ToString()); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Function returned: {0}", resp.Value.ToString()); } Hashtable error = new Hashtable(); @@ -930,16 +1047,16 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups private void LogRespDataToConsoleError(Hashtable respData) { - m_log.Error("[XMLRPCGROUPDATA]: Error:"); + m_log.Error("[XMLRPC-GROUPS-CONNECTOR]: Error:"); foreach (string key in respData.Keys) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: Key: {0}", key); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: Key: {0}", key); string[] lines = respData[key].ToString().Split(new char[] { '\n' }); foreach (string line in lines) { - m_log.ErrorFormat("[XMLRPCGROUPDATA]: {0}", line); + m_log.ErrorFormat("[XMLRPC-GROUPS-CONNECTOR]: {0}", line); } } @@ -948,8 +1065,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups /// /// Group Request Tokens are an attempt to allow the groups service to authenticate - /// requests. Currently uses UserService, AgentID, and SessionID - /// TODO: Find a better way to do this. + /// requests. + /// TODO: This broke after the big grid refactor, either find a better way, or discard this /// /// /// -- cgit v1.1 From add7abc1de2fce8db4c6d01cc4b5305bafa4bd87 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 7 May 2010 14:12:07 -0400 Subject: Fix Mouse+WASD makes Av rise; Fix PREJUMP. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 13 +++------- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 23 +++++++++++------ OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 30 +++++++++++++++------- 4 files changed, 40 insertions(+), 28 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index be0e985..b43caf2 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -56,7 +56,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation // protected string m_movementAnimation = "DEFAULT"; //KF: 'DEFAULT' does not exist! protected string m_movementAnimation = "CROUCH"; //KF: CROUCH ensures reliable Av Anim. init. private int m_animTickFall; - private int m_animTickJump; +// private int m_animTickJump; + public int m_animTickJump; // ScenePresence has to see this to control +Z force /// /// The scene presence that this animator applies to @@ -123,22 +124,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public void TrySetMovementAnimation(string anim) { -//Console.WriteLine("Updating movement animation to {0}", anim); - if (!m_scenePresence.IsChildAgent) { if (m_animations.TrySetDefaultAnimation( anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) { -//Console.WriteLine("TSMA {0} success.", anim); // 16384 is CHANGED_ANIMATION m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); SendAnimPack(); } - else - { -//Console.WriteLine("TSMA {0} fail.", anim); - } } } @@ -267,7 +261,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation m_animTickJump = Environment.TickCount; return "PREJUMP"; } - else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f) + else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 800.0f) { // Start actual jump if (m_animTickJump == -1) @@ -317,7 +311,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void UpdateMovementAnimations() { m_movementAnimation = GetMovementAnimation(); -//Console.WriteLine("UMA got {0}", m_movementAnimation); if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) { // This was the previous behavior before PREJUMP diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index db073e8..665fb4c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -613,7 +613,7 @@ namespace OpenSim.Region.Framework.Scenes m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); // TODO: Change default to true once the feature is supported m_usePreJump = startupConfig.GetBoolean("enableprejump", false); - + m_usePreJump = true; // Above line fails!? m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); if (RegionInfo.NonphysPrimMax > 0) { diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2603fe1..565438d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -665,7 +665,7 @@ namespace OpenSim.Region.Framework.Scenes CreateSceneViewer(); m_animator = new ScenePresenceAnimator(this); } - + private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() { m_rootRegionHandle = reginfo.RegionHandle; @@ -1459,7 +1459,6 @@ namespace OpenSim.Region.Framework.Scenes } i++; } - //Paupaw:Do Proper PID for Autopilot here if (bResetMoveToPosition) { @@ -2433,10 +2432,11 @@ namespace OpenSim.Region.Framework.Scenes Rotation = rotation; Vector3 direc = vec * rotation; direc.Normalize(); + PhysicsActor actor = m_physicsActor; + if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. direc *= 0.03f * 128f * m_speedModifier; - PhysicsActor actor = m_physicsActor; if (actor != null) { if (actor.Flying) @@ -2458,11 +2458,18 @@ namespace OpenSim.Region.Framework.Scenes { if (direc.Z > 2.0f) { - direc.Z *= 3.0f; - - // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. - Animator.TrySetMovementAnimation("PREJUMP"); - Animator.TrySetMovementAnimation("JUMP"); + if(m_animator.m_animTickJump == -1) + { + direc.Z *= 3.0f; // jump + } + else + { + direc.Z *= 0.1f; // prejump + } + /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs + Animator.TrySetMovementAnimation("PREJUMP"); + Animator.TrySetMovementAnimation("JUMP"); + */ } } } diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 7a5093b..38c38b6 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.Physics.OdePlugin // unique UUID of this character object public UUID m_uuid; public bool bad = false; - + public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, CollisionLocker dode, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) { m_uuid = UUID.Random(); @@ -892,7 +892,7 @@ namespace OpenSim.Region.Physics.OdePlugin // If the PID Controller isn't active then we set our force // calculating base velocity to the current position - + if (Body == IntPtr.Zero) return; @@ -972,8 +972,17 @@ namespace OpenSim.Region.Physics.OdePlugin // Prim to avatar collisions d.Vector3 pos = d.BodyGetPosition(Body); - vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2); - vec.Y = (_target_velocity.Y - vel.Y)*(PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2); + float errX = _zeroPosition.X - pos.X; + float errY = _zeroPosition.Y - pos.Y; + if( (Math.Abs(errX) > 0.1f) || (Math.Abs(errY) > 0.1f) ) + { + vec.X = (_target_velocity.X - vel.X) * (PID_D) + (errX) * (PID_P * 2); + vec.Y = (_target_velocity.Y - vel.Y) * (PID_D) + (errY) * (PID_P * 2); + } + else + { // close, jump to lateral destination + d.BodySetPosition(Body, _zeroPosition.X, _zeroPosition.Y, pos.Z); + } if (flying) { vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; @@ -1056,11 +1065,14 @@ namespace OpenSim.Region.Physics.OdePlugin } if (vec.IsFinite()) { - doForce(vec); - if (!_zeroFlag) - { - AlignAvatarTiltWithCurrentDirectionOfMovement(vec); - } + if (!vec.ApproxEquals(Vector3.Zero, 0.01f)) + { + doForce(vec); + if (!_zeroFlag) + { + AlignAvatarTiltWithCurrentDirectionOfMovement(vec); + } + } } else { -- cgit v1.1 From 2fe669448f8cfefe2ef6e046faec3c0e709a41e4 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 10 May 2010 05:43:16 -0700 Subject: Greatly improve login time for users with large friends lists by requesting all unknown UUID's in one go rather than individually --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 45 +++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index febd4ca..57dde76 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -67,7 +67,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return false; } } - + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected List m_Scenes = new List(); @@ -234,7 +234,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends newFriends.RegionID = UUID.Zero; m_Friends.Add(client.AgentId, newFriends); - + //StatusChange(client.AgentId, true); } @@ -289,7 +289,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Inform the friends that this user is online StatusChange(agentID, true); - + // Register that we need to send the list of online friends to this user lock (m_NeedsListOfFriends) if (!m_NeedsListOfFriends.Contains(agentID)) @@ -442,11 +442,44 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (((fi.MyFlags & 1) != 0) && (fi.TheirFlags != -1)) friendList.Add(fi); } + /* foreach (FriendInfo fi in friendList) { // Notify about this user status StatusNotify(fi, agentID, online); } + */ + + StatusNotifyMass(friendList, agentID, online); + } + } + + private void StatusNotifyMass(List friendList, UUID userID, bool online) + { + string[] friendIDs = new string[friendList.Count]; + int notlocal = 0; + for (int x = 0; x < friendList.Count; x++) + { + UUID friendID = UUID.Zero; + if (UUID.TryParse(friendList[x].Friend, out friendID)) + { + if (!LocalStatusNotification(userID, friendID, online)) + { + friendIDs[notlocal++] = friendID.ToString(); + } + } + } + + PresenceInfo[] friendSessions = PresenceService.GetAgents(friendIDs); + + for (int x = 0; x < friendSessions.GetLength(0); x++) + { + PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.StatusNotify(region, userID, new UUID(friendIDs[x]), online); + } } } @@ -459,7 +492,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // Try local if (LocalStatusNotification(userID, friendID, online)) return; - + // The friend is not here [as root]. Let's forward. PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); @@ -476,7 +509,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { if (im.dialog == (byte)OpenMetaverse.InstantMessageDialog.FriendshipOffered) - { + { // we got a friendship offer UUID principalID = new UUID(im.fromAgentID); UUID friendID = new UUID(im.toAgentID); @@ -688,7 +721,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends // we're done return true; } - + return false; } -- cgit v1.1 From ab716125d7aa80efe2b3904490f10fd045da94c7 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 10 May 2010 05:51:49 -0700 Subject: Correct an odd merge anomaly --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 8f84d81..5dc9c44 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -471,7 +471,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends for (int x = 0; x < friendSessions.GetLength(0); x++) { - PresenceInfo friendSession = PresenceInfo.GetOnlinePresence(friendSessions); + PresenceInfo friendSession = friendSessions[x]; if (friendSession != null) { GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); -- cgit v1.1 From 3cda854ef312a71f3ceab6cb8339a0d2d2fce803 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 10 May 2010 08:47:41 -0700 Subject: Fix overlooked readLock which was left open --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ff471e0..35134d6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -123,7 +123,7 @@ namespace OpenSim.Region.Framework.Scenes } if (m_partsLock.RecursiveWriteCount > 0) { - m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed."); + m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested (write lock exists on this thread). This should not happen and means something needs to be fixed."); m_partsLock.ExitWriteLock(); } @@ -1667,6 +1667,7 @@ namespace OpenSim.Region.Framework.Scenes remoteClient, m_scene.Permissions.GenerateClientFlags(remoteClient.AgentId, part.UUID)); } } + lockPartsForRead(false); } #region Copying -- cgit v1.1 From 14a86de115934e981e5c3e413821861434ccf5e8 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 10 May 2010 12:45:33 -0700 Subject: Fix another ReaderWriterLockSlim issue --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 62b44bd..c4cff12 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -840,12 +840,12 @@ namespace OpenSim.Region.Framework.Scenes } else { + m_items.LockItemsForRead(false); m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", itemID, m_part.Name, m_part.UUID); } - m_items.LockItemsForWrite(false); return -1; } -- cgit v1.1 From 40e05f41098bdedac7296d84c9aa8d915c5c9ede Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 11 May 2010 09:28:46 -0700 Subject: Spin the AddNewClient process off into a new thread to avoid locking up the LLUDPServer (and therefore the entire scene) --- OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 41e41e4..d9aecd8 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -909,7 +909,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP client.OnLogout += LogoutHandler; // Start the IClientAPI - client.Start(); + // Spin it off so that it doesn't clog up the LLUDPServer + Util.FireAndForget(delegate(object o) { client.Start(); }); } else { -- cgit v1.1 From 98bd3e1f3498600e9299252723a8365ce8fd77fd Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 12 May 2010 07:14:06 -0700 Subject: Don't convert UUID -> ToString for every friend (Minor optimisation based on profiler feedback) --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 5dc9c44..5339dee 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -201,9 +201,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends UserFriendData data = m_Friends[principalID]; + string searchFor = friendID.ToString(); foreach (FriendInfo fi in data.Friends) { - if (fi.Friend == friendID.ToString()) + if (fi.Friend == searchFor) return (uint)fi.TheirFlags; } return 0; -- cgit v1.1 From 7705012ee7b016f8e163c5e9586fef724b233932 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 12 May 2010 08:25:40 -0700 Subject: Optimise the heavily used GetScenePresences; eliminate the array->list conversion on every call and transition from hard locks to ReaderWriter locks. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 56 +++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index f43de20..c16ba12 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -70,6 +70,9 @@ namespace OpenSim.Region.Framework.Scenes protected Dictionary m_scenePresences = new Dictionary(); protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; + protected List m_scenePresenceList = new List(); + + protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); // SceneObjects is not currently populated or used. //public Dictionary SceneObjects; @@ -132,10 +135,16 @@ namespace OpenSim.Region.Framework.Scenes protected internal void Close() { - lock (m_scenePresences) + m_scenePresencesLock.EnterWriteLock(); + try { m_scenePresences.Clear(); m_scenePresenceArray = new ScenePresence[0]; + m_scenePresenceList = new List(); + } + finally + { + m_scenePresencesLock.ExitWriteLock(); } lock (m_dictionary_lock) @@ -542,7 +551,8 @@ namespace OpenSim.Region.Framework.Scenes Entities[presence.UUID] = presence; - lock (m_scenePresences) + m_scenePresencesLock.EnterWriteLock(); + try { if (!m_scenePresences.ContainsKey(presence.UUID)) { @@ -554,11 +564,12 @@ namespace OpenSim.Region.Framework.Scenes Array.Copy(m_scenePresenceArray, newArray, oldLength); newArray[oldLength] = presence; m_scenePresenceArray = newArray; + m_scenePresenceList = new List(m_scenePresenceArray); } else { m_scenePresences[presence.UUID] = presence; - + // Do a linear search through the array of ScenePresence references // and update the modified entry for (int i = 0; i < m_scenePresenceArray.Length; i++) @@ -569,8 +580,13 @@ namespace OpenSim.Region.Framework.Scenes break; } } + m_scenePresenceList = new List(m_scenePresenceArray); } } + finally + { + m_scenePresencesLock.ExitWriteLock(); + } } /// @@ -585,7 +601,8 @@ namespace OpenSim.Region.Framework.Scenes agentID); } - lock (m_scenePresences) + m_scenePresencesLock.EnterWriteLock(); + try { if (m_scenePresences.Remove(agentID)) { @@ -604,12 +621,17 @@ namespace OpenSim.Region.Framework.Scenes } } m_scenePresenceArray = newArray; + m_scenePresenceList = new List(m_scenePresenceArray); } else { m_log.WarnFormat("[SCENE] Tried to remove non-existent scene presence with agent ID {0} from scene ScenePresences list", agentID); } } + finally + { + m_scenePresencesLock.ExitWriteLock(); + } } protected internal void SwapRootChildAgent(bool direction_RC_CR_T_F) @@ -730,8 +752,15 @@ namespace OpenSim.Region.Framework.Scenes /// private List GetScenePresences() { - lock (m_scenePresences) - return new List(m_scenePresenceArray); + m_scenePresencesLock.EnterReadLock(); + try + { + return m_scenePresenceList; + } + finally + { + m_scenePresencesLock.ExitReadLock(); + } } /// @@ -742,10 +771,15 @@ namespace OpenSim.Region.Framework.Scenes protected internal ScenePresence GetScenePresence(UUID agentID) { ScenePresence sp; - lock (m_scenePresences) + m_scenePresencesLock.EnterReadLock(); + try { m_scenePresences.TryGetValue(agentID, out sp); } + finally + { + m_scenePresencesLock.ExitReadLock(); + } return sp; } @@ -780,10 +814,15 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) { - lock (m_scenePresences) + m_scenePresencesLock.EnterReadLock(); + try { m_scenePresences.TryGetValue(agentID, out avatar); } + finally + { + m_scenePresencesLock.ExitReadLock(); + } return (avatar != null); } @@ -1061,6 +1100,7 @@ namespace OpenSim.Region.Framework.Scenes Parallel.ForEach(GetScenePresences(), protectedAction); */ // For now, perform actiona serially + foreach (ScenePresence sp in GetScenePresences()) { try -- cgit v1.1 From fd37a21b59836143f50fdf994c691d65bd641d52 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 12 May 2010 08:34:47 -0700 Subject: Kill some locks that have crept into SOG --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 35134d6..a4b8944 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3651,7 +3651,8 @@ namespace OpenSim.Region.Framework.Scenes if (atRotTargets.Count > 0) { uint[] localids = new uint[0]; - lock (m_parts) + lockPartsForRead(true); + try { localids = new uint[m_parts.Count]; int cntr = 0; @@ -3661,6 +3662,10 @@ namespace OpenSim.Region.Framework.Scenes cntr++; } } + finally + { + lockPartsForRead(false); + } for (int ctr = 0; ctr < localids.Length; ctr++) { @@ -3679,7 +3684,8 @@ namespace OpenSim.Region.Framework.Scenes { //trigger not_at_target uint[] localids = new uint[0]; - lock (m_parts) + lockPartsForRead(true); + try { localids = new uint[m_parts.Count]; int cntr = 0; @@ -3689,6 +3695,10 @@ namespace OpenSim.Region.Framework.Scenes cntr++; } } + finally + { + lockPartsForRead(false); + } for (int ctr = 0; ctr < localids.Length; ctr++) { -- cgit v1.1 From 9079ad5ceb3cfb9ddb0c255289b288be40f6567e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 13 May 2010 12:40:18 -0700 Subject: Add some debug output to GetAgent to try and track down our presence problems --- OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs index 41ebeaf..9f86078 100644 --- a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs @@ -300,6 +300,14 @@ namespace OpenSim.Services.Connectors { pinfo = new PresenceInfo((Dictionary)replyData["result"]); } + else + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply (result not dictionary) received from presence server when querying for sessionID {0}", sessionID.ToString()); + } + } + else + { + m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply received from presence server when querying for sessionID {0}", sessionID.ToString()); } return pinfo; -- cgit v1.1 From 8f838c722da978da646fcef59a5af767840832bb Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 17 May 2010 14:14:19 -0700 Subject: When killing a zombie session, don't send the stop packet since it often has the effect of killing a newly connected client. --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 10 +++++++++- .../Client/Sirikata/ClientStack/SirikataClientView.cs | 5 +++++ OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs | 5 +++++ OpenSim/Framework/IClientAPI.cs | 1 + OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 18 +++++++++++++++--- OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | 5 +++++ OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- .../InternetRelayClientView/Server/IRCClientView.cs | 5 +++++ OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 5 +++++ OpenSim/Tests/Common/Mock/TestClient.cs | 4 ++++ 10 files changed, 55 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 1d6d4c1..12989f5 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -835,10 +835,18 @@ namespace OpenSim.Client.MXP.ClientStack public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { m_log.Info("[MXP ClientStack] Close Called"); // Tell the client to go - SendLogoutPacket(); + if (sendStop == true) + { + SendLogoutPacket(); + } // Let MXPPacketServer clean it up if (Session.SessionState != SessionState.Disconnected) diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index 43c64e9..c4b5c87 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -446,6 +446,11 @@ namespace OpenSim.Client.Sirikata.ClientStack public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { throw new System.NotImplementedException(); } diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 864b4f1..39a16bc 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -452,6 +452,11 @@ namespace OpenSim.Client.VWoHTTP.ClientStack public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { throw new System.NotImplementedException(); } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 01daeb1..c597d62 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1114,6 +1114,7 @@ namespace OpenSim.Framework void InPacket(object NewPack); void ProcessInPacket(Packet NewPack); void Close(); + void Close(bool sendStop); void Kick(string message); /// diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index d5fda9d..5670a78 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -502,18 +502,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Client Methods + /// /// Shut down the client view /// public void Close() { + Close(true); + } + + /// + /// Shut down the client view + /// + public void Close(bool sendStop) + { m_log.DebugFormat( "[CLIENT]: Close has been called for {0} attached to scene {1}", Name, m_scene.RegionInfo.RegionName); - // Send the STOP packet - DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); - OutPacket(disable, ThrottleOutPacketType.Unknown); + if (sendStop) + { + // Send the STOP packet + DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); + OutPacket(disable, ThrottleOutPacketType.Unknown); + } IsActive = false; diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 09611af..84385ad 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -831,6 +831,11 @@ namespace OpenSim.Region.Examples.SimpleModule public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { } public void Start() diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3d59615..1b08c50 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3489,7 +3489,7 @@ namespace OpenSim.Region.Framework.Scenes { // We have a zombie from a crashed session. Kill it. m_log.DebugFormat("[SCENE]: Zombie scene presence detected for {0} in {1}", agent.AgentID, RegionInfo.RegionName); - sp.ControllingClient.Close(); + sp.ControllingClient.Close(false); } } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 69e78b3..7c0fe4c 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -885,6 +885,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { Disconnect(); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 6360c99..4323c94 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -845,6 +845,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { } public void Start() diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index b07a072..05a8ff0 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -888,6 +888,10 @@ namespace OpenSim.Tests.Common.Mock public void Close() { + Close(true); + } + public void Close(bool sendStop) + { m_scene.RemoveClient(AgentId); } -- cgit v1.1 From 6bc7e3429f9ac6cb57fbaa695223c3d76c189f77 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 17 May 2010 14:14:19 -0700 Subject: Provide interface to prevent the client close function from sending the stop packet --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 10 +++++++++- .../Client/Sirikata/ClientStack/SirikataClientView.cs | 5 +++++ OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs | 5 +++++ OpenSim/Framework/IClientAPI.cs | 1 + OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 18 +++++++++++++++--- OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs | 5 +++++ .../InternetRelayClientView/Server/IRCClientView.cs | 5 +++++ OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs | 5 +++++ OpenSim/Tests/Common/Mock/TestClient.cs | 4 ++++ 9 files changed, 54 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 33017d6..658ddf0 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -827,10 +827,18 @@ namespace OpenSim.Client.MXP.ClientStack public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { m_log.Info("[MXP ClientStack] Close Called"); // Tell the client to go - SendLogoutPacket(); + if (sendStop == true) + { + SendLogoutPacket(); + } // Let MXPPacketServer clean it up if (Session.SessionState != SessionState.Disconnected) diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index 1bdc4f8..c2ddd36 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -439,6 +439,11 @@ namespace OpenSim.Client.Sirikata.ClientStack public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { throw new System.NotImplementedException(); } diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index f45cb44..df07807 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -446,6 +446,11 @@ namespace OpenSim.Client.VWoHTTP.ClientStack public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { throw new System.NotImplementedException(); } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index bcbc957..bc8ce1a 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1101,6 +1101,7 @@ namespace OpenSim.Framework void InPacket(object NewPack); void ProcessInPacket(Packet NewPack); void Close(); + void Close(bool sendStop); void Kick(string message); /// diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 5c774b5..960e0a2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -470,18 +470,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region Client Methods + /// /// Shut down the client view /// public void Close() { + Close(true); + } + + /// + /// Shut down the client view + /// + public void Close(bool sendStop) + { m_log.DebugFormat( "[CLIENT]: Close has been called for {0} attached to scene {1}", Name, m_scene.RegionInfo.RegionName); - // Send the STOP packet - DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); - OutPacket(disable, ThrottleOutPacketType.Unknown); + if (sendStop) + { + // Send the STOP packet + DisableSimulatorPacket disable = (DisableSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.DisableSimulator); + OutPacket(disable, ThrottleOutPacketType.Unknown); + } IsActive = false; diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index d2b0161..b074313 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -825,6 +825,11 @@ namespace OpenSim.Region.Examples.SimpleModule public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { } public void Start() diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 85e3fb3..0b6647d 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -877,6 +877,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { Disconnect(); } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index cf2076f..938293f 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -838,6 +838,11 @@ namespace OpenSim.Region.OptionalModules.World.NPC public void Close() { + Close(true); + } + + public void Close(bool sendStop) + { } public void Start() diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 68ac96a..752e9e1 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -882,6 +882,10 @@ namespace OpenSim.Tests.Common.Mock public void Close() { + Close(true); + } + public void Close(bool sendStop) + { m_scene.RemoveClient(AgentId); } -- cgit v1.1 From c25c40a3f913f623cbcb3c7dcea0cdbf65f3c2c2 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 17 May 2010 15:24:28 -0700 Subject: Following on from the last commit, the stop/disconnect packet should NOT be sent when the user logs out. This eliminates the annoying "crash on log out" bug, and allows the client to commit important information at the last moment (attachment data!) --- OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index d9aecd8..d708055 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -926,7 +926,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (m_scene.TryGetClient(udpClient.AgentID, out client)) { client.IsLoggingOut = true; - client.Close(); + client.Close(false); } } -- cgit v1.1 From eb5a95d26bca4840f5a082156c0a37afed166fb1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 18 May 2010 03:02:36 +0200 Subject: Prevent an "index out of range" error on login --- OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index 5339dee..30eb9b8 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -454,9 +454,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends private void StatusNotifyMass(List friendList, UUID userID, bool online) { - string[] friendIDs = new string[friendList.Count]; + int fct = friendList.Count; + string[] friendIDs = new string[fct]; int notlocal = 0; - for (int x = 0; x < friendList.Count; x++) + for (int x = 0 ; x < fct ; x++) { UUID friendID = UUID.Zero; if (UUID.TryParse(friendList[x].Friend, out friendID)) @@ -472,6 +473,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends for (int x = 0; x < friendSessions.GetLength(0); x++) { + if (friendIDs.Length <= x) + continue; PresenceInfo friendSession = friendSessions[x]; if (friendSession != null) { -- cgit v1.1 From 91b1d17e5bd3ff6ed006744bc529b53a67af1a64 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 18 May 2010 01:09:47 -0700 Subject: Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 4 + .../Sirikata/ClientStack/SirikataClientView.cs | 4 + .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 4 + OpenSim/Framework/IClientAPI.cs | 1 + .../Region/ClientStack/LindenUDP/LLClientView.cs | 37 +++++++- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 4 + OpenSim/Region/Framework/Scenes/ScenePresence.cs | 102 +++++++++++---------- .../Server/IRCClientView.cs | 4 + .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 + OpenSim/Tests/Common/Mock/TestClient.cs | 4 + 10 files changed, 114 insertions(+), 54 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 12989f5..39923cb 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -819,6 +819,10 @@ namespace OpenSim.Client.MXP.ClientStack //throw new System.NotImplementedException(); } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { //throw new System.NotImplementedException(); diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index c4b5c87..7c8a979 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -439,6 +439,10 @@ namespace OpenSim.Client.Sirikata.ClientStack throw new System.NotImplementedException(); } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { throw new System.NotImplementedException(); diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 39a16bc..5ad1643 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -445,6 +445,10 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { throw new System.NotImplementedException(); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index c597d62..ae2a80c 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1112,6 +1112,7 @@ namespace OpenSim.Framework void SetDebugPacketLevel(int newDebug); void InPacket(object NewPack); + void ProcessPendingPackets(); void ProcessInPacket(Packet NewPack); void Close(); void Close(bool sendStop); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 5670a78..df6a767 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -376,6 +376,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private AgentUpdateArgs lastarg; private bool m_IsActive = true; private bool m_IsLoggingOut = false; + private bool m_IsPresenceReady = false; protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers @@ -399,6 +400,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Timer m_propertiesPacketTimer; private List m_propertiesBlocks = new List(); + private List m_pendingPackets; #endregion Class Members @@ -439,6 +441,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP get { return m_IsActive; } set { m_IsActive = value; } } + public bool IsLoggingOut { get { return m_IsLoggingOut; } @@ -11196,18 +11199,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// + /// This processes packets which have accumulated while the presence was still in the process of initialising. + /// + public void ProcessPendingPackets() + { + m_IsPresenceReady = true; + foreach (Packet p in m_pendingPackets) + { + ProcessInPacket(p); + } + m_pendingPackets.Clear(); + } + + /// /// Entryway from the client to the simulator. All UDP packets from the client will end up here /// /// OpenMetaverse.packet public void ProcessInPacket(Packet Pack) { - if (m_debugPacketLevel >= 255) - m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); + if (!m_IsPresenceReady) + { + if (m_pendingPackets == null) + { + m_pendingPackets = new List(); + } + m_pendingPackets.Add(Pack); + } + else + { + if (m_debugPacketLevel >= 255) + m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); - if (!ProcessPacketMethod(Pack)) - m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); + if (!ProcessPacketMethod(Pack)) + m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); - PacketPool.Instance.ReturnPacket(Pack); + PacketPool.Instance.ReturnPacket(Pack); + } } private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 84385ad..c454d1f 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -825,6 +825,10 @@ namespace OpenSim.Region.Examples.SimpleModule { } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d76f029..0b644b9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -129,7 +129,7 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; + private Vector3 m_lastPosition; private Vector3 m_lastWorldPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; @@ -715,8 +715,11 @@ namespace OpenSim.Region.Framework.Scenes // Request info about all the (root) agents in this region // Note: This won't send data *to* other clients in that region (children don't send) SendInitialFullUpdateToAllClients(); - RegisterToEvents(); + if (m_controllingClient != null) + { + m_controllingClient.ProcessPendingPackets(); + } SetDirectionVectors(); } @@ -858,7 +861,6 @@ namespace OpenSim.Region.Framework.Scenes m_grouptitle = gm.GetGroupTitle(m_uuid); m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; - m_scene.SetRootAgentScene(m_uuid); // Moved this from SendInitialData to ensure that m_appearance is initialized @@ -875,22 +877,22 @@ namespace OpenSim.Region.Framework.Scenes { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); pos.Y = crossedBorder.BorderLine.Z - 1; - } - - //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. - //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, - //they'll bypass the landing point. But I can't think of any decent way of fixing this. - if (KnownChildRegionHandles.Count == 0) - { - ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (land != null) - { - //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) - { - pos = land.LandData.UserLocation; - } - } + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } } if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) @@ -1027,8 +1029,8 @@ namespace OpenSim.Region.Framework.Scenes bool isFlying = false; if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - + isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -1039,7 +1041,7 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_appearance.AvatarHeight); } - SendTerseUpdateToAllClients(); + SendTerseUpdateToAllClients(); } @@ -1173,7 +1175,6 @@ namespace OpenSim.Region.Framework.Scenes pos.Z = ground + 1.5f; AbsolutePosition = pos; } - m_isChildAgent = false; bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, m_flying); @@ -1745,14 +1746,14 @@ namespace OpenSim.Region.Framework.Scenes // else // { // single or child prim -// } - if (part == null) //CW: Part may be gone. llDie() for example. - { - partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - partRot = part.GetWorldRotation(); +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); } Quaternion partIRot = Quaternion.Inverse(partRot); @@ -1760,22 +1761,22 @@ namespace OpenSim.Region.Framework.Scenes Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av - - if (m_physicsActor == null) - { - AddToPhysicalScene(false); + + if (m_physicsActor == null) + { + AddToPhysicalScene(false); + } + //CW: If the part isn't null then we can set the current position + if (part != null) + { + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. + part.IsOccupied = false; } - //CW: If the part isn't null then we can set the current position - if (part != null) - { - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! - AbsolutePosition = avWorldStandUp; //KF: Fix stand up. - part.IsOccupied = false; - } - else - { - //CW: Since the part doesn't exist, a coarse standup position isn't an issue - AbsolutePosition = m_lastWorldPosition; + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; } m_parentPosition = Vector3.Zero; @@ -1930,7 +1931,7 @@ namespace OpenSim.Region.Framework.Scenes // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) { - autopilot = false; // close enough + autopilot = false; // close enough m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. Not using the part's position because returning the AV to the last known standing position is likely to be more friendly, isn't it? */ @@ -1939,7 +1940,7 @@ namespace OpenSim.Region.Framework.Scenes } // else the autopilot will get us close } else - { // its a scripted sit + { // its a scripted sit m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. I *am* using the part's position this time because we have no real idea how far away the avatar is from the sit target. */ @@ -3744,7 +3745,10 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); m_scene = scene; RegisterToEvents(); - + if (m_controllingClient != null) + { + m_controllingClient.ProcessPendingPackets(); + } /* AbsolutePosition = client.StartPos; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 7c0fe4c..cab640b 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -878,6 +878,10 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 4323c94..b828357 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -839,6 +839,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 05a8ff0..815816a 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -882,6 +882,10 @@ namespace OpenSim.Tests.Common.Mock { } + public void ProcessPendingPackets() + { + } + public void ProcessInPacket(Packet NewPack) { } -- cgit v1.1 From ed1cfb52454410e5d03b11966fdff54d9950a28c Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 18 May 2010 02:33:41 -0700 Subject: Missed a nullref in the previous commit --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index df6a767..5b1aa86 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -11204,6 +11204,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void ProcessPendingPackets() { m_IsPresenceReady = true; + if (m_pendingPackets == null) + return; foreach (Packet p in m_pendingPackets) { ProcessInPacket(p); -- cgit v1.1 From 1c040d8c1ed5ee1ba1e80aa1d248a9b06d1790a5 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 18 May 2010 03:24:43 -0700 Subject: Fix to the scenario where we send an agent to a neighbouring sim (via teleport), then tell our neighbours to close the agents.. thereby disconnecting the user. Added a new CloseChildAgent method in lieu of CloseAgent. This has been a long standing problem - with any luck this will cure it. --- .../Simulation/LocalSimulationConnector.cs | 17 ++++++++++++++++ .../Simulation/RemoteSimulationConnector.cs | 15 ++++++++++++++ .../Framework/Interfaces/IInterregionComms.cs | 8 ++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 23 +++++++++++++++++----- .../Framework/Scenes/SceneCommunicationService.cs | 2 +- .../Server/Handlers/Simulation/AgentHandlers.cs | 23 ++++++++++++++++++++++ .../Simulation/SimulationServiceConnector.cs | 14 ++++++++++++- OpenSim/Services/Interfaces/ISimulationService.cs | 8 ++++++++ 8 files changed, 103 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index e32dbb3..329a259 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -290,6 +290,23 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } + public bool CloseChildAgent(GridRegion destination, UUID id) + { + if (destination == null) + return false; + + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionID == destination.RegionID) + { + //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); + return s.IncomingCloseChildAgent(id); + } + } + //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); + return false; + } + /** * Object-related communications */ diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 9e8454f..377c868 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -253,6 +253,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } + public bool CloseChildAgent(GridRegion destination, UUID id) + { + if (destination == null) + return false; + + // Try local first + if (m_localBackend.CloseChildAgent(destination, id)) + return true; + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(destination.RegionHandle)) + return m_remoteConnector.CloseChildAgent(destination, id); + + return false; + } public bool CloseAgent(GridRegion destination, UUID id) { diff --git a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs index 2d6287f..67a500f 100644 --- a/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs +++ b/OpenSim/Region/Framework/Interfaces/IInterregionComms.cs @@ -68,6 +68,14 @@ namespace OpenSim.Region.Framework.Interfaces bool SendReleaseAgent(ulong regionHandle, UUID id, string uri); /// + /// Close chid agent. + /// + /// + /// + /// + bool SendCloseChildAgent(ulong regionHandle, UUID id); + + /// /// Close agent. /// /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 1b08c50..f331984 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3914,12 +3914,22 @@ namespace OpenSim.Region.Framework.Scenes return false; } + public bool IncomingCloseAgent(UUID agentID) + { + return IncomingCloseAgent(agentID, false); + } + + public bool IncomingCloseChildAgent(UUID agentID) + { + return IncomingCloseAgent(agentID, true); + } + /// /// Tell a single agent to disconnect from the region. /// - /// /// - public bool IncomingCloseAgent(UUID agentID) + /// + public bool IncomingCloseAgent(UUID agentID, bool childOnly) { //m_log.DebugFormat("[SCENE]: Processing incoming close agent for {0}", agentID); @@ -3931,7 +3941,7 @@ namespace OpenSim.Region.Framework.Scenes { m_sceneGraph.removeUserCount(false); } - else + else if (!childOnly) { m_sceneGraph.removeUserCount(true); } @@ -3947,9 +3957,12 @@ namespace OpenSim.Region.Framework.Scenes } else presence.ControllingClient.SendShutdownConnectionNotice(); + presence.ControllingClient.Close(); + } + else if (!childOnly) + { + presence.ControllingClient.Close(); } - - presence.ControllingClient.Close(); return true; } diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 9d0e6f4..6309cd9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -281,7 +281,7 @@ namespace OpenSim.Region.Framework.Scenes uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); GridRegion destination = m_scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); - m_scene.SimulationService.CloseAgent(destination, agentID); + m_scene.SimulationService.CloseChildAgent(destination, agentID); } private void SendCloseChildAgentCompleted(IAsyncResult iar) diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index ab3250d..b648e12 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -108,6 +108,11 @@ namespace OpenSim.Server.Handlers.Simulation DoAgentDelete(request, responsedata, agentID, action, regionID); return responsedata; } + else if (method.Equals("DELETECHILD")) + { + DoChildAgentDelete(request, responsedata, agentID, action, regionID); + return responsedata; + } else { m_log.InfoFormat("[AGENT HANDLER]: method {0} not supported in agent message", method); @@ -320,6 +325,24 @@ namespace OpenSim.Server.Handlers.Simulation } } + protected void DoChildAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID) + { + m_log.Debug(" >>> DoChildAgentDelete action:" + action + "; RegionID:" + regionID); + + GridRegion destination = new GridRegion(); + destination.RegionID = regionID; + + if (action.Equals("release")) + ReleaseAgent(regionID, id); + else + m_SimulationService.CloseChildAgent(destination, id); + + responsedata["int_response_code"] = HttpStatusCode.OK; + responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); + + m_log.Debug("[AGENT HANDLER]: Child Agent Released/Deleted."); + } + protected void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, UUID regionID) { m_log.Debug(" >>> DoDelete action:" + action + "; RegionID:" + regionID); diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index ff0dd7e..8e0063b 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -442,7 +442,7 @@ namespace OpenSim.Services.Connectors.Simulation return true; } - public bool CloseAgent(GridRegion destination, UUID id) + private bool CloseAgent(GridRegion destination, UUID id, bool ChildOnly) { string uri = string.Empty; try @@ -459,6 +459,8 @@ namespace OpenSim.Services.Connectors.Simulation WebRequest request = WebRequest.Create(uri); request.Method = "DELETE"; + if (ChildOnly) + request.Method += "CHILD"; request.Timeout = 10000; StreamReader sr = null; @@ -491,6 +493,16 @@ namespace OpenSim.Services.Connectors.Simulation return true; } + public bool CloseChildAgent(GridRegion destination, UUID id) + { + return CloseAgent(destination, id, true); + } + + public bool CloseAgent(GridRegion destination, UUID id) + { + return CloseAgent(destination, id, false); + } + #endregion Agents #region Objects diff --git a/OpenSim/Services/Interfaces/ISimulationService.cs b/OpenSim/Services/Interfaces/ISimulationService.cs index 67d7cbe..33d6fde 100644 --- a/OpenSim/Services/Interfaces/ISimulationService.cs +++ b/OpenSim/Services/Interfaces/ISimulationService.cs @@ -71,6 +71,14 @@ namespace OpenSim.Services.Interfaces bool ReleaseAgent(UUID originRegion, UUID id, string uri); /// + /// Close child agent. + /// + /// + /// + /// + bool CloseChildAgent(GridRegion destination, UUID id); + + /// /// Close agent. /// /// -- cgit v1.1 From bb0806c61e545b6509843ed0258475e47d4bb273 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 18 May 2010 03:44:09 -0700 Subject: Don't send kill packets to child agents as we close them --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f331984..377abe3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3957,11 +3957,11 @@ namespace OpenSim.Region.Framework.Scenes } else presence.ControllingClient.SendShutdownConnectionNotice(); - presence.ControllingClient.Close(); + presence.ControllingClient.Close(false); } else if (!childOnly) { - presence.ControllingClient.Close(); + presence.ControllingClient.Close(true); } return true; } -- cgit v1.1 From 55f124745ffe743a2d93c2ef93cb5c2f4fe06178 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 18 May 2010 19:25:40 +0200 Subject: Allow remote admin to be used on a different port from the main region port --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index d7904a6..ed43363 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -63,7 +63,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController private static Object SOLock = new Object(); private OpenSimBase m_app; - private BaseHttpServer m_httpd; + private IHttpServer m_httpd; private IConfig m_config; private IConfigSource m_configSource; private string m_requiredPassword = String.Empty; @@ -113,9 +113,10 @@ namespace OpenSim.ApplicationPlugins.RemoteController m_config = m_configSource.Configs["RemoteAdmin"]; m_log.Info("[RADMIN]: Remote Admin Plugin Enabled"); m_requiredPassword = m_config.GetString("access_password", String.Empty); + int port = m_config.GetInt("port", 0); m_app = openSim; - m_httpd = openSim.HttpServer; + m_httpd = MainServer.GetHttpServer((uint)port); Dictionary availableMethods = new Dictionary(); availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; -- cgit v1.1 From ba36c62caad0fb88f89863c9e0afdefc4f2897cc Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 19 May 2010 00:20:51 -0700 Subject: Fix a null reference issue in cmGetAvatarList() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 07cba60..3e62c1a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -121,7 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_List result = new LSL_List(); World.ForEachScenePresence(delegate (ScenePresence avatar) { - if (avatar.UUID != m_host.OwnerID) + if (avatar != null && avatar.UUID != m_host.OwnerID) { if (avatar.IsChildAgent == false) { -- cgit v1.1 From fc76b5f58950b747cfabec19a4349216a48c9c13 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 19 May 2010 00:24:54 -0700 Subject: Fix a null reference issue in cmGetAvatarList() --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 9f829da..4f1e9f7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -94,7 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_List result = new LSL_List(); foreach (ScenePresence avatar in World.GetAvatars()) { - if (avatar.UUID != m_host.OwnerID) + if (avatar != null && avatar.UUID != m_host.OwnerID) { if (avatar.IsChildAgent == false) { -- cgit v1.1 From f77f9ecd8f3f94ccc6d69c7625fd1eacfa9250d7 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 19 May 2010 13:44:59 -0700 Subject: Fix a nullref issue in SitAltitudeCallback --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 103 ++++++++++++----------- 1 file changed, 53 insertions(+), 50 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 565438d..68acabe 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -128,7 +128,7 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; + private Vector3 m_lastPosition; private Vector3 m_lastWorldPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; @@ -857,22 +857,22 @@ namespace OpenSim.Region.Framework.Scenes { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); pos.Y = crossedBorder.BorderLine.Z - 1; - } - - //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. - //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, - //they'll bypass the landing point. But I can't think of any decent way of fixing this. - if (KnownChildRegionHandles.Count == 0) - { - ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (land != null) - { - //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) - { - pos = land.LandData.UserLocation; - } - } + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } } if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) @@ -1036,8 +1036,8 @@ namespace OpenSim.Region.Framework.Scenes bool isFlying = false; if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - + isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -1048,7 +1048,7 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_appearance.AvatarHeight); } - SendTerseUpdateToAllClients(); + SendTerseUpdateToAllClients(); } @@ -1736,14 +1736,14 @@ namespace OpenSim.Region.Framework.Scenes // else // { // single or child prim -// } - if (part == null) //CW: Part may be gone. llDie() for example. - { - partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - partRot = part.GetWorldRotation(); +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); } Quaternion partIRot = Quaternion.Inverse(partRot); @@ -1751,22 +1751,22 @@ namespace OpenSim.Region.Framework.Scenes Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av - - if (m_physicsActor == null) - { - AddToPhysicalScene(false); + + if (m_physicsActor == null) + { + AddToPhysicalScene(false); } - //CW: If the part isn't null then we can set the current position - if (part != null) - { - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! - AbsolutePosition = avWorldStandUp; //KF: Fix stand up. - part.IsOccupied = false; - } - else - { - //CW: Since the part doesn't exist, a coarse standup position isn't an issue - AbsolutePosition = m_lastWorldPosition; + //CW: If the part isn't null then we can set the current position + if (part != null) + { + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. + part.IsOccupied = false; + } + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; } m_parentPosition = Vector3.Zero; @@ -1920,7 +1920,7 @@ namespace OpenSim.Region.Framework.Scenes // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) { - autopilot = false; // close enough + autopilot = false; // close enough m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. Not using the part's position because returning the AV to the last known standing position is likely to be more friendly, isn't it? */ @@ -1929,7 +1929,7 @@ namespace OpenSim.Region.Framework.Scenes } // else the autopilot will get us close } else - { // its a scripted sit + { // its a scripted sit m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. I *am* using the part's position this time because we have no real idea how far away the avatar is from the sit target. */ @@ -2357,11 +2357,14 @@ namespace OpenSim.Region.Framework.Scenes // { // single or child prim partIRot = Quaternion.Inverse(part.GetWorldRotation()); // } - float offZ = collisionPoint.Z - m_initialSitTarget.Z; - Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction -//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); - m_pos += offset; -// ControllingClient.SendClearFollowCamProperties(part.UUID); + if (m_initialSitTarget != null) + { + float offZ = collisionPoint.Z - m_initialSitTarget.Z; + Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction + //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); + m_pos += offset; + // ControllingClient.SendClearFollowCamProperties(part.UUID); + } } } // End SitAltitudeCallback KF. -- cgit v1.1 From 6933b48a7e94511f1de969b28a61d834888fd2f5 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 19 May 2010 13:49:34 -0700 Subject: Fix a nullref issue in SitAltitudeCallback --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0b644b9..b6081de 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2368,12 +2368,15 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); // else // { // single or child prim partIRot = Quaternion.Inverse(part.GetWorldRotation()); -// } - float offZ = collisionPoint.Z - m_initialSitTarget.Z; - Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction -//Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); - m_pos += offset; -// ControllingClient.SendClearFollowCamProperties(part.UUID); +// } + if (m_initialSitTarget != null) + { + float offZ = collisionPoint.Z - m_initialSitTarget.Z; + Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction + //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); + m_pos += offset; + // ControllingClient.SendClearFollowCamProperties(part.UUID); + } } } // End SitAltitudeCallback KF. -- cgit v1.1 From 5532341bf9e477a007e81bdbcc6477923703e2a2 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 19 May 2010 14:04:44 -0700 Subject: Initialise m_initialSitTarget to ZERO_VACTOR for safety's sake as per convo with kitto --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b6081de..c89f656 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -213,7 +213,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_autopilotMoving; private Vector3 m_autoPilotTarget; private bool m_sitAtAutoTarget; - private Vector3 m_initialSitTarget; //KF: First estimate of where to sit + private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit private string m_nextSitAnimation = String.Empty; -- cgit v1.1 From 147c2d6f80c6b911839e890cb42cb63020269afc Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 21 May 2010 02:31:14 +0100 Subject: Change the way the object perms are propagated to attempt to salvage some older content --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 44 +++++++++++----------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e031ebc..ba70ae5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -437,29 +437,31 @@ namespace OpenSim.Region.Framework.Scenes itemCopy.InvType = item.InvType; itemCopy.Folder = recipientFolderId; - if (Permissions.PropagatePermissions()) + if (Permissions.PropagatePermissions() && recipient != senderId) { + // First, make sore base is limited to the next perms + itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions; + // By default, current equals base + itemCopy.CurrentPermissions = itemCopy.BasePermissions; + + // If this is an object, replace current perms + // with folded perms if (item.InvType == (int)InventoryType.Object) { - itemCopy.BasePermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); - itemCopy.BasePermissions |= (item.CurrentPermissions & 7) << 13; - } - else - { - itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions; + itemCopy.CurrentPermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); + itemCopy.CurrentPermissions |= (item.CurrentPermissions & 7) << 13; } - itemCopy.CurrentPermissions = itemCopy.BasePermissions; - if ((item.CurrentPermissions & 8) != 0) // Propagate slam bit - { - itemCopy.BasePermissions &= item.NextPermissions; - itemCopy.CurrentPermissions = itemCopy.BasePermissions; - itemCopy.CurrentPermissions |= 8; - } + // Ensure there is no escalation + itemCopy.CurrentPermissions &= item.NextPermissions; + + // Need slam bit on xfer + itemCopy.CurrentPermissions |= 8; itemCopy.NextPermissions = item.NextPermissions; - itemCopy.EveryOnePermissions = item.EveryOnePermissions & item.NextPermissions; - itemCopy.GroupPermissions = item.GroupPermissions & item.NextPermissions; + + itemCopy.EveryOnePermissions = 0; + itemCopy.GroupPermissions = 0; } else { @@ -913,12 +915,12 @@ namespace OpenSim.Region.Framework.Scenes if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions()) { + agentItem.BasePermissions = taskItem.BasePermissions & taskItem.NextPermissions; if (taskItem.InvType == (int)InventoryType.Object) - agentItem.BasePermissions = taskItem.BasePermissions & ((taskItem.CurrentPermissions & 7) << 13); - else - agentItem.BasePermissions = taskItem.BasePermissions; - agentItem.BasePermissions &= taskItem.NextPermissions; - agentItem.CurrentPermissions = agentItem.BasePermissions | 8; + agentItem.CurrentPermissions = agentItem.BasePermissions & ((taskItem.CurrentPermissions & 7) << 13); + agentItem.CurrentPermissions = agentItem.BasePermissions ; + + agentItem.CurrentPermissions |= 8; agentItem.NextPermissions = taskItem.NextPermissions; agentItem.EveryOnePermissions = taskItem.EveryonePermissions & taskItem.NextPermissions; agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions; -- cgit v1.1 From d28da5e5ce4e36c7a0b052fb5d2f04105d95176b Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 21 May 2010 03:41:32 +0100 Subject: Refactor scene presence list for lockless iteration. Lock contention will now only be for simultaneous add/removes of scene presences from the scene. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 131 ++++++++++---------------- 1 file changed, 49 insertions(+), 82 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index c16ba12..3c2203c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -68,11 +68,9 @@ namespace OpenSim.Region.Framework.Scenes #region Fields - protected Dictionary m_scenePresences = new Dictionary(); - protected ScenePresence[] m_scenePresenceArray = new ScenePresence[0]; - protected List m_scenePresenceList = new List(); - protected OpenMetaverse.ReaderWriterLockSlim m_scenePresencesLock = new OpenMetaverse.ReaderWriterLockSlim(); + protected Dictionary m_scenePresenceMap = new Dictionary(); + protected List m_scenePresenceArray = new List(); // SceneObjects is not currently populated or used. //public Dictionary SceneObjects; @@ -138,9 +136,10 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresencesLock.EnterWriteLock(); try { - m_scenePresences.Clear(); - m_scenePresenceArray = new ScenePresence[0]; - m_scenePresenceList = new List(); + Dictionary newmap = new Dictionary(); + List newlist = new List(); + m_scenePresenceMap = newmap; + m_scenePresenceArray = newlist; } finally { @@ -554,34 +553,27 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresencesLock.EnterWriteLock(); try { - if (!m_scenePresences.ContainsKey(presence.UUID)) + Dictionary newmap = new Dictionary(m_scenePresenceMap); + List newlist = new List(m_scenePresenceArray); + + if (!newmap.ContainsKey(presence.UUID)) { - m_scenePresences.Add(presence.UUID, presence); - - // Create a new array of ScenePresence references - int oldLength = m_scenePresenceArray.Length; - ScenePresence[] newArray = new ScenePresence[oldLength + 1]; - Array.Copy(m_scenePresenceArray, newArray, oldLength); - newArray[oldLength] = presence; - m_scenePresenceArray = newArray; - m_scenePresenceList = new List(m_scenePresenceArray); + newmap.Add(presence.UUID, presence); + newlist.Add(presence); } else { - m_scenePresences[presence.UUID] = presence; - - // Do a linear search through the array of ScenePresence references - // and update the modified entry - for (int i = 0; i < m_scenePresenceArray.Length; i++) - { - if (m_scenePresenceArray[i].UUID == presence.UUID) - { - m_scenePresenceArray[i] = presence; - break; - } - } - m_scenePresenceList = new List(m_scenePresenceArray); + // Remember the old presene reference from the dictionary + ScenePresence oldref = newmap[presence.UUID]; + // Replace the presence reference in the dictionary with the new value + newmap[presence.UUID] = presence; + // Find the index in the list where the old ref was stored and update the reference + newlist[newlist.IndexOf(oldref)] = presence; } + + // Swap out the dictionary and list with new references + m_scenePresenceMap = newmap; + m_scenePresenceArray = newlist; } finally { @@ -604,24 +596,19 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresencesLock.EnterWriteLock(); try { - if (m_scenePresences.Remove(agentID)) + Dictionary newmap = new Dictionary(m_scenePresenceMap); + List newlist = new List(m_scenePresenceArray); + + // Remember the old presene reference from the dictionary + ScenePresence oldref = newmap[agentID]; + // Remove the presence reference from the dictionary + if (newmap.Remove(agentID)) { - // Copy all of the elements from the previous array - // into the new array except the removed element - int oldLength = m_scenePresenceArray.Length; - ScenePresence[] newArray = new ScenePresence[oldLength - 1]; - int j = 0; - for (int i = 0; i < m_scenePresenceArray.Length; i++) - { - ScenePresence presence = m_scenePresenceArray[i]; - if (presence.UUID != agentID) - { - newArray[j] = presence; - ++j; - } - } - m_scenePresenceArray = newArray; - m_scenePresenceList = new List(m_scenePresenceArray); + // Find the index in the list where the old ref was stored and remove the reference + newlist.RemoveAt(newlist.IndexOf(oldref)); + // Swap out the dictionary and list with new references + m_scenePresenceMap = newmap; + m_scenePresenceArray = newlist; } else { @@ -744,7 +731,7 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Request a copy of m_scenePresences in this World + /// Get a reference to the scene presence list. Changes to the list will be done in a copy /// There is no guarantee that presences will remain in the scene after the list is returned. /// This list should remain private to SceneGraph. Callers wishing to iterate should instead /// pass a delegate to ForEachScenePresence. @@ -752,15 +739,7 @@ namespace OpenSim.Region.Framework.Scenes /// private List GetScenePresences() { - m_scenePresencesLock.EnterReadLock(); - try - { - return m_scenePresenceList; - } - finally - { - m_scenePresencesLock.ExitReadLock(); - } + return m_scenePresenceArray; } /// @@ -770,17 +749,10 @@ namespace OpenSim.Region.Framework.Scenes /// null if the presence was not found protected internal ScenePresence GetScenePresence(UUID agentID) { - ScenePresence sp; - m_scenePresencesLock.EnterReadLock(); - try - { - m_scenePresences.TryGetValue(agentID, out sp); - } - finally - { - m_scenePresencesLock.ExitReadLock(); - } - return sp; + Dictionary presences = m_scenePresenceMap; + ScenePresence presence; + presences.TryGetValue(agentID, out presence); + return presence; } /// @@ -791,7 +763,8 @@ namespace OpenSim.Region.Framework.Scenes /// null if the presence was not found protected internal ScenePresence GetScenePresence(string firstName, string lastName) { - foreach (ScenePresence presence in GetScenePresences()) + List presences = GetScenePresences(); + foreach (ScenePresence presence in presences) { if (presence.Firstname == firstName && presence.Lastname == lastName) return presence; @@ -806,7 +779,8 @@ namespace OpenSim.Region.Framework.Scenes /// null if the presence was not found protected internal ScenePresence GetScenePresence(uint localID) { - foreach (ScenePresence presence in GetScenePresences()) + List presences = GetScenePresences(); + foreach (ScenePresence presence in presences) if (presence.LocalId == localID) return presence; return null; @@ -814,15 +788,8 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool TryGetScenePresence(UUID agentID, out ScenePresence avatar) { - m_scenePresencesLock.EnterReadLock(); - try - { - m_scenePresences.TryGetValue(agentID, out avatar); - } - finally - { - m_scenePresencesLock.ExitReadLock(); - } + Dictionary presences = m_scenePresenceMap; + presences.TryGetValue(agentID, out avatar); return (avatar != null); } @@ -1099,9 +1066,9 @@ namespace OpenSim.Region.Framework.Scenes }); Parallel.ForEach(GetScenePresences(), protectedAction); */ - // For now, perform actiona serially - - foreach (ScenePresence sp in GetScenePresences()) + // For now, perform actions serially + List presences = GetScenePresences(); + foreach (ScenePresence sp in presences) { try { -- cgit v1.1 From af5eeab7cf86ec5b8a90aa435d7068ef954dc504 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 21 May 2010 07:37:55 +0200 Subject: Ensure that the first update sent out for any given prim is a full update --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index e29ae2a..cddc7b2 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -325,6 +325,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_cachedTextureSerial; private PriorityQueue m_entityUpdates; + private Dictionary m_seenPrims = new Dictionary(); /// /// List used in construction of data blocks for an object update packet. This is to stop us having to @@ -3495,7 +3496,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Compressed object updates only make sense for LL primitives if (!(update.Entity is SceneObjectPart)) + { canUseCompressed = false; + } + else + { + if (!m_seenPrims.ContainsKey(((SceneObjectPart)update.Entity).LocalId)) + { + updateFlags = PrimUpdateFlags.FullUpdate; + m_seenPrims[((SceneObjectPart)update.Entity).LocalId] = true; + } + } if (updateFlags.HasFlag(PrimUpdateFlags.FullUpdate)) { -- cgit v1.1 From 72b96e81213c0dd3d586f552bd2cbd9221c5341d Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 23 May 2010 06:12:11 +0100 Subject: Add the SitGround flag back in --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 49a7766..d7660fd 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -140,6 +140,7 @@ namespace OpenSim.Region.Framework.Scenes private Vector3? m_forceToApply; private uint m_requestedSitTargetID; private UUID m_requestedSitTargetUUID; + public bool SitGround = false; private SendCourseLocationsMethod m_sendCourseLocationsMethod; @@ -1643,7 +1644,7 @@ namespace OpenSim.Region.Framework.Scenes } } - if (update_movementflag) + if (update_movementflag && !SitGround) Animator.UpdateMovementAnimations(); m_scene.EventManager.TriggerOnClientMovement(this); @@ -1754,6 +1755,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void StandUp() { + SitGround = false; + if (m_parentID != 0) { SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); -- cgit v1.1 From f90d81a864c8ae1cf8125839bc883dc0ace7f214 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 26 May 2010 19:26:30 +0200 Subject: Just because there is an agent update handler, that doesn't mean there is a pre agent update handler. Null check these separately. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 173c9e5..51cc763 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4922,14 +4922,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP arg.SessionID = x.SessionID; arg.State = x.State; UpdateAgent handlerAgentUpdate = OnAgentUpdate; + UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; lastarg = arg; // save this set of arguments for nexttime - if (handlerAgentUpdate != null) - { + if (handlerPreAgentUpdate != null) OnPreAgentUpdate(this, arg); + if (handlerAgentUpdate != null) OnAgentUpdate(this, arg); - } handlerAgentUpdate = null; + handlerPreAgentUpdate = null; } } -- cgit v1.1 From ac5373427f99d259a55147e097a8a76050a60db6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 27 May 2010 20:08:12 +0200 Subject: Comment noisy "CONNECTION DEBUGGING" messages, because they push more important stuff off screen too fast. Clean this time --- OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs | 14 +++++++------- OpenSim/Server/Handlers/Simulation/AgentHandlers.cs | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs index 17d7850..e50481a 100644 --- a/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs +++ b/OpenSim/Server/Handlers/Hypergrid/HomeAgentHandlers.cs @@ -61,13 +61,13 @@ namespace OpenSim.Server.Handlers.Hypergrid public Hashtable Handler(Hashtable request) { - m_log.Debug("[CONNECTION DEBUGGING]: HomeAgentHandler Called"); - - m_log.Debug("---------------------------"); - m_log.Debug(" >> uri=" + request["uri"]); - m_log.Debug(" >> content-type=" + request["content-type"]); - m_log.Debug(" >> http-method=" + request["http-method"]); - m_log.Debug("---------------------------\n"); +// m_log.Debug("[CONNECTION DEBUGGING]: HomeAgentHandler Called"); +// +// m_log.Debug("---------------------------"); +// m_log.Debug(" >> uri=" + request["uri"]); +// m_log.Debug(" >> content-type=" + request["content-type"]); +// m_log.Debug(" >> http-method=" + request["http-method"]); +// m_log.Debug("---------------------------\n"); Hashtable responsedata = new Hashtable(); responsedata["content_type"] = "text/html"; diff --git a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs index b648e12..c4117f5 100644 --- a/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/AgentHandlers.cs @@ -61,13 +61,13 @@ namespace OpenSim.Server.Handlers.Simulation public Hashtable Handler(Hashtable request) { - m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); - - m_log.Debug("---------------------------"); - m_log.Debug(" >> uri=" + request["uri"]); - m_log.Debug(" >> content-type=" + request["content-type"]); - m_log.Debug(" >> http-method=" + request["http-method"]); - m_log.Debug("---------------------------\n"); +// m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); +// +// m_log.Debug("---------------------------"); +// m_log.Debug(" >> uri=" + request["uri"]); +// m_log.Debug(" >> content-type=" + request["content-type"]); +// m_log.Debug(" >> http-method=" + request["http-method"]); +// m_log.Debug("---------------------------\n"); Hashtable responsedata = new Hashtable(); responsedata["content_type"] = "text/html"; -- cgit v1.1 From ba49319c077bc5e7b998674aaac62497e757706c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 27 May 2010 20:08:48 +0200 Subject: Prevent a null ref --- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 4ba4fab..2fc98e5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -84,6 +84,9 @@ namespace OpenSim.Region.Framework.Scenes while (m_pendingObjects != null && m_pendingObjects.Count > 0) { SceneObjectGroup g = m_pendingObjects.Dequeue(); + // Yes, this can really happen + if (g == null) + continue; // This is where we should check for draw distance // do culling and stuff. Problem with that is that until -- cgit v1.1 From 7d6680b38a1220d6709cb189c0a2c430731f58cf Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Thu, 27 May 2010 21:28:47 -0400 Subject: fix hanging output throttle arithmetic had multiply overflow and subtract wrap-around errors --- .../Region/ClientStack/LindenUDP/TokenBucket.cs | 66 +++++++++------------- 1 file changed, 27 insertions(+), 39 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs index bdbd284..91e3d20 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/TokenBucket.cs @@ -133,7 +133,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP this.parent = parent; MaxBurst = maxBurst; DripRate = dripRate; - lastDrip = Environment.TickCount & Int32.MaxValue; + lastDrip = Environment.TickCount; } /// @@ -144,40 +144,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// the bucket, otherwise false public bool RemoveTokens(int amount) { - bool dummy; - return RemoveTokens(amount, out dummy); - } - - /// - /// Remove a given number of tokens from the bucket - /// - /// Number of tokens to remove from the bucket - /// True if tokens were added to the bucket - /// during this call, otherwise false - /// True if the requested number of tokens were removed from - /// the bucket, otherwise false - public bool RemoveTokens(int amount, out bool dripSucceeded) - { if (maxBurst == 0) { - dripSucceeded = true; return true; } - dripSucceeded = Drip(); - - if (content - amount >= 0) + if (amount > maxBurst) { - if (parent != null && !parent.RemoveTokens(amount)) - return false; + throw new Exception("amount " + amount + " exceeds maxBurst " + maxBurst); + } - content -= amount; - return true; + Drip(); + + if (content < amount) + { + return false; } - else + + if (parent != null && !parent.RemoveTokens(amount)) { return false; } + + content -= amount; + return true; } /// @@ -193,25 +183,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP content = maxBurst; return true; } - else - { - int now = Environment.TickCount & Int32.MaxValue; - int deltaMS = now - lastDrip; - if (deltaMS <= 0) - { - if (deltaMS < 0) - lastDrip = now; - return false; - } + int now = Environment.TickCount; + int deltaMS = now - lastDrip; + lastDrip = now; - int dripAmount = deltaMS * tokensPerMS; - - content = Math.Min(content + dripAmount, maxBurst); - lastDrip = now; + if (deltaMS <= 0) + { + return false; + } - return true; + long dripAmount = (long)deltaMS * (long)tokensPerMS + (long)content; + if (dripAmount > maxBurst) + { + dripAmount = maxBurst; } + content = (int)dripAmount; + return true; } } } -- cgit v1.1 From e7bf6afd3afa5fc4760b417e0c0e079f23d20f59 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 29 May 2010 05:14:18 +0200 Subject: Get the user's DOB back from the server response properly. --- OpenSim/Services/Interfaces/IUserAccountService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Interfaces/IUserAccountService.cs b/OpenSim/Services/Interfaces/IUserAccountService.cs index e316731..09d1d87 100644 --- a/OpenSim/Services/Interfaces/IUserAccountService.cs +++ b/OpenSim/Services/Interfaces/IUserAccountService.cs @@ -91,7 +91,7 @@ namespace OpenSim.Services.Interfaces UserTitle = kvp["UserTitle"].ToString(); if (kvp.ContainsKey("Created")) - Convert.ToInt32(kvp["Created"].ToString()); + Created = Convert.ToInt32(kvp["Created"].ToString()); if (kvp.ContainsKey("ServiceURLs") && kvp["ServiceURLs"] != null) { ServiceURLs = new Dictionary(); -- cgit v1.1 From 2f409116db570be77fc75df188a4044250dce226 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 29 May 2010 01:03:59 -0700 Subject: Stop IGridService from throwing a fatal exception when an IPEndPoint cannot be resolved, and add some handlers to deal with this cleanly; a condition was observed on OSGrid where a neighbouring region with an invalid (unresolveable) hostname would prevent a region from starting. This is bad. --- .../EntityTransfer/EntityTransferModule.cs | 31 ++++++++++++++-------- .../Hypergrid/GatekeeperServiceConnector.cs | 14 ++++++++-- .../Connectors/Land/LandServiceConnector.cs | 2 ++ .../Neighbour/NeighbourServiceConnector.cs | 4 ++- .../SimianGrid/SimianGridServiceConnector.cs | 4 ++- .../Simulation/SimulationServiceConnector.cs | 8 ++++-- OpenSim/Services/Interfaces/IGridService.cs | 8 ++++-- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 1 + 8 files changed, 53 insertions(+), 19 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ef37f63..dc1025d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -261,7 +261,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, // it's actually doing a lot of work. IPEndPoint endPoint = finalDestination.ExternalEndPoint; - if (endPoint.Address != null) + if (endPoint != null && endPoint.Address != null) { // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions @@ -825,15 +825,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); IEventQueue eq = agent.Scene.RequestModuleInterface(); - if (eq != null) - { - eq.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); - } - else + IPEndPoint neighbourExternal = neighbourRegion.ExternalEndPoint; + if (neighbourExternal != null) { - agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); + if (eq != null) + { + eq.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourExternal, + capsPath, agent.UUID, agent.ControllingClient.SessionId); + } + else + { + agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourExternal, + capsPath); + } } if (!WaitForCallback(agent.UUID)) @@ -906,10 +910,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.child = true; agent.Appearance = sp.Appearance; - InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; - d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, + IPEndPoint external = region.ExternalEndPoint; + if (external != null) + { + InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; + d.BeginInvoke(sp, agent, region, external, true, InformClientOfNeighbourCompleted, d); + } } #endregion @@ -1038,6 +1046,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; try { + //neighbour.ExternalEndPoint may return null, which will be caught d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, InformClientOfNeighbourCompleted, d); diff --git a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs index c426bba..6f159a0 100644 --- a/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs +++ b/OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs @@ -87,7 +87,12 @@ namespace OpenSim.Services.Connectors.Hypergrid paramList.Add(hash); XmlRpcRequest request = new XmlRpcRequest("link_region", paramList); - string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/"; + IPEndPoint ext = info.ExternalEndPoint; + string uri = ""; + if (ext != null) + { + uri = "http://" + ext.Address + ":" + info.HttpPort + "/"; + } //m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: Linking to " + uri); XmlRpcResponse response = null; try @@ -189,7 +194,12 @@ namespace OpenSim.Services.Connectors.Hypergrid paramList.Add(hash); XmlRpcRequest request = new XmlRpcRequest("get_region", paramList); - string uri = "http://" + gatekeeper.ExternalEndPoint.Address + ":" + gatekeeper.HttpPort + "/"; + IPEndPoint ext = gatekeeper.ExternalEndPoint; + string uri = ""; + if (ext != null) + { + uri = "http://" + ext.Address + ":" + gatekeeper.HttpPort + "/"; + } m_log.Debug("[GATEKEEPER SERVICE CONNECTOR]: contacting " + uri); XmlRpcResponse response = null; try diff --git a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs index 06bc11c..0223a77 100644 --- a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs +++ b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs @@ -83,6 +83,8 @@ namespace OpenSim.Services.Connectors if (info != null) // just to be sure { XmlRpcRequest request = new XmlRpcRequest("land_data", paramList); + + //Possible nullref from info.externalendpoint will be caught here string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/"; XmlRpcResponse response = request.Send(uri, 10000); if (response.IsFault) diff --git a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs index 0a982f8..daf0439 100644 --- a/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs +++ b/OpenSim/Services/Connectors/Neighbour/NeighbourServiceConnector.cs @@ -87,7 +87,9 @@ namespace OpenSim.Services.Connectors public bool DoHelloNeighbourCall(GridRegion region, RegionInfo thisRegion) { - string uri = "http://" + region.ExternalEndPoint.Address + ":" + region.HttpPort + "/region/" + thisRegion.RegionID + "/"; + IPEndPoint ext = region.ExternalEndPoint; + if (ext == null) return false; + string uri = "http://" + ext.Address + ":" + region.HttpPort + "/region/" + thisRegion.RegionID + "/"; //m_log.Debug(" >>> DoHelloNeighbourCall <<< " + uri); WebRequest HelloNeighbourRequest = WebRequest.Create(uri); diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 3a61226..57924b7 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -104,6 +104,8 @@ namespace OpenSim.Services.Connectors.SimianGrid public string RegisterRegion(UUID scopeID, GridRegion regionInfo) { + IPEndPoint ext = regionInfo.ExternalEndPoint; + if (ext == null) return "Region registration for " + regionInfo.RegionName + " failed: Could not resolve EndPoint"; Vector3d minPosition = new Vector3d(regionInfo.RegionLocX, regionInfo.RegionLocY, 0.0); Vector3d maxPosition = minPosition + new Vector3d(Constants.RegionSize, Constants.RegionSize, 4096.0); @@ -114,7 +116,7 @@ namespace OpenSim.Services.Connectors.SimianGrid { "ServerURI", OSD.FromString(regionInfo.ServerURI) }, { "InternalAddress", OSD.FromString(regionInfo.InternalEndPoint.Address.ToString()) }, { "InternalPort", OSD.FromInteger(regionInfo.InternalEndPoint.Port) }, - { "ExternalAddress", OSD.FromString(regionInfo.ExternalEndPoint.Address.ToString()) }, + { "ExternalAddress", OSD.FromString(ext.Address.ToString()) }, { "ExternalPort", OSD.FromInteger(regionInfo.ExternalEndPoint.Port) }, { "MapTexture", OSD.FromUUID(regionInfo.TerrainImage) }, { "Access", OSD.FromInteger(regionInfo.Access) }, diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 8e0063b..748faef 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -348,9 +348,11 @@ namespace OpenSim.Services.Connectors.Simulation public bool RetrieveAgent(GridRegion destination, UUID id, out IAgentData agent) { + IPEndPoint ext = destination.ExternalEndPoint; agent = null; + if (ext == null) return false; // Eventually, we want to use a caps url instead of the agentID - string uri = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; + string uri = "http://" + ext.Address + ":" + destination.HttpPort + AgentPath() + id + "/" + destination.RegionID.ToString() + "/"; //Console.WriteLine(" >>> DoRetrieveRootAgentCall <<< " + uri); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri); @@ -514,8 +516,10 @@ namespace OpenSim.Services.Connectors.Simulation public bool CreateObject(GridRegion destination, ISceneObject sog, bool isLocalCall) { + IPEndPoint ext = destination.ExternalEndPoint; + if (ext == null) return false; string uri - = "http://" + destination.ExternalEndPoint.Address + ":" + destination.HttpPort + ObjectPath() + sog.UUID + "/"; + = "http://" + ext.Address + ":" + destination.HttpPort + ObjectPath() + sog.UUID + "/"; //m_log.Debug(" >>> DoCreateObjectCall <<< " + uri); WebRequest ObjectCreateRequest = WebRequest.Create(uri); diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index e55b633..94cee57 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -259,9 +259,13 @@ namespace OpenSim.Services.Interfaces } catch (SocketException e) { - throw new Exception( + /*throw new Exception( "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + - e + "' attached to this exception", e); + e + "' attached to this exception", e);*/ + // Don't throw a fatal exception here, instead, return Null and handle it in the caller. + // Reason is, on systems such as OSgrid it has occured that known hostnames stop + // resolving and thus make surrounding regions crash out with this exception. + return null; } return new IPEndPoint(ia, m_internalEndPoint.Port); diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index edf41bc..6a2cbeb 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -327,6 +327,7 @@ namespace OpenSim.Services.LLLoginService private void FillOutRegionData(GridRegion destination) { IPEndPoint endPoint = destination.ExternalEndPoint; + if (endPoint == null) return; SimAddress = endPoint.Address.ToString(); SimPort = (uint)endPoint.Port; RegionX = (uint)destination.RegionLocX; -- cgit v1.1 From e3dac1292ef000daadda3e264354d8df0fc77c22 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 29 May 2010 02:10:34 -0700 Subject: Implement suspended updates - When an operation is occurring on lots of prims in a single group, don't schedule any updates until the operation has completed. This makes things like llSetAlpha(LINK_SET,0.0,ALL_SIDES); a *lot* faster, more efficient and less buggy, and also makes unlinking a lot better. Linking is still treacherous.. this needs to be analysed. --- OpenSim/Region/Framework/ModuleLoader.cs | 3 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 47 ++++++-- .../Region/Framework/Scenes/SceneObjectGroup.cs | 17 +++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 +- .../Shared/Api/Implementation/LSL_Api.cs | 132 +++++++++++++++++---- 5 files changed, 168 insertions(+), 39 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/ModuleLoader.cs b/OpenSim/Region/Framework/ModuleLoader.cs index 23be9c2..69ba2042 100644 --- a/OpenSim/Region/Framework/ModuleLoader.cs +++ b/OpenSim/Region/Framework/ModuleLoader.cs @@ -226,7 +226,8 @@ namespace OpenSim.Region.Framework "[MODULES]: Could not load types for [{0}]. Exception {1}", pluginAssembly.FullName, e); // justincc: Right now this is fatal to really get the user's attention - throw e; + // TomMeta: WTF? No, how about we /don't/ throw a fatal exception when there's no need to? + //throw e; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index d4658ec..445c2c8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1499,10 +1499,13 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void LinkObjects(SceneObjectPart root, List children) { + SceneObjectGroup parentGroup = root.ParentGroup; + if (parentGroup == null) return; Monitor.Enter(m_updateLock); + try { - SceneObjectGroup parentGroup = root.ParentGroup; + parentGroup.areUpdatesSuspended = true; List childGroups = new List(); if (parentGroup != null) @@ -1541,12 +1544,12 @@ namespace OpenSim.Region.Framework.Scenes // occur on link to invoke this elsewhere (such as object selection) parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); parentGroup.TriggerScriptChangedEvent(Changed.LINK); - parentGroup.HasGroupChanged = true; - parentGroup.ScheduleGroupForFullUpdate(); - } finally { + parentGroup.areUpdatesSuspended = false; + parentGroup.HasGroupChanged = true; + parentGroup.ScheduleGroupForFullUpdate(); Monitor.Exit(m_updateLock); } } @@ -1583,11 +1586,22 @@ namespace OpenSim.Region.Framework.Scenes } } - foreach (SceneObjectPart child in childParts) + if (childParts.Count > 0) { - // Unlink all child parts from their groups - // - child.ParentGroup.DelinkFromGroup(child, true); + try + { + childParts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart child in childParts) + { + // Unlink all child parts from their groups + // + child.ParentGroup.DelinkFromGroup(child, true); + } + } + finally + { + childParts[0].ParentGroup.areUpdatesSuspended = false; + } } foreach (SceneObjectPart root in rootParts) @@ -1611,10 +1625,21 @@ namespace OpenSim.Region.Framework.Scenes if (numChildren > 1) sendEventsToRemainder = false; - foreach (SceneObjectPart p in newSet) + if (newSet.Count > 0) { - if (p != group.RootPart) - group.DelinkFromGroup(p, sendEventsToRemainder); + try + { + newSet[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart p in newSet) + { + if (p != group.RootPart) + group.DelinkFromGroup(p, sendEventsToRemainder); + } + } + finally + { + newSet[0].ParentGroup.areUpdatesSuspended = false; + } } // If there is more than one prim remaining, we diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index cee2be3..9ebb168 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -109,9 +109,26 @@ namespace OpenSim.Region.Framework.Scenes private long m_maxPersistTime = 0; private long m_minPersistTime = 0; private Random m_rand; + private bool m_suspendUpdates; private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); + public bool areUpdatesSuspended + { + get + { + return m_suspendUpdates; + } + set + { + m_suspendUpdates = value; + if (!value) + { + QueueForUpdateCheck(); + } + } + } + public void lockPartsForRead(bool locked) { if (locked) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c84596b..6e73b65 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2724,7 +2724,10 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentGroup != null) { - m_parentGroup.QueueForUpdateCheck(); + if (!m_parentGroup.areUpdatesSuspended) + { + m_parentGroup.QueueForUpdateCheck(); + } } int timeNow = Util.UnixTimeSinceEpoch(); @@ -4450,8 +4453,9 @@ namespace OpenSim.Region.Framework.Scenes { m_shape.TextureEntry = textureEntry; TriggerScriptChangedEvent(Changed.TEXTURE); - + m_updateFlag = 1; ParentGroup.HasGroupChanged = true; + //This is madness.. //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 68f6e7b..bb02fa3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1649,9 +1649,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - SetAlpha(part, alpha, face); + if (parts.Count > 0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + SetAlpha(part, alpha, face); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } } protected void SetAlpha(SceneObjectPart part, double alpha, int face) @@ -1816,10 +1826,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - SetTexture(part, texture, face); - + if (parts.Count > 0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + SetTexture(part, texture, face); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } ScriptSleep(200); } @@ -3661,9 +3680,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetLinkColor(int linknumber, LSL_Vector color, int face) { List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); + if (parts.Count > 0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } } public void llCreateLink(string target, int parent) @@ -3776,10 +3805,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // Restructuring Multiple Prims. List parts = new List(parentPrim.Children.Values); parts.Remove(parentPrim.RootPart); - foreach (SceneObjectPart part in parts) + if (parts.Count > 0) { - parentPrim.DelinkFromGroup(part.LocalId, true); + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + { + parentPrim.DelinkFromGroup(part.LocalId, true); + } + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } } + parentPrim.HasGroupChanged = true; parentPrim.ScheduleGroupForFullUpdate(); parentPrim.TriggerScriptChangedEvent(Changed.LINK); @@ -3788,11 +3829,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { SceneObjectPart newRoot = parts[0]; parts.Remove(newRoot); - foreach (SceneObjectPart part in parts) + + try { - part.UpdateFlag = 0; - newRoot.ParentGroup.LinkToGroup(part.ParentGroup); + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + { + part.UpdateFlag = 0; + newRoot.ParentGroup.LinkToGroup(part.ParentGroup); + } } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + + newRoot.ParentGroup.HasGroupChanged = true; newRoot.ParentGroup.ScheduleGroupForFullUpdate(); } @@ -3818,11 +3870,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api List parts = new List(parentPrim.Children.Values); parts.Remove(parentPrim.RootPart); - - foreach (SceneObjectPart part in parts) + if (parts.Count > 0) { - parentPrim.DelinkFromGroup(part.LocalId, true); - parentPrim.TriggerScriptChangedEvent(Changed.LINK); + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + { + parentPrim.DelinkFromGroup(part.LocalId, true); + parentPrim.TriggerScriptChangedEvent(Changed.LINK); + } + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } } parentPrim.HasGroupChanged = true; parentPrim.ScheduleGroupForFullUpdate(); @@ -5664,10 +5726,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (var part in parts) + if (parts.Count > 0) { - SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (var part in parts) + { + SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); + } + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } } } @@ -7068,9 +7140,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); - - foreach (SceneObjectPart part in parts) - SetPrimParams(part, rules); + if (parts.Count>0) + { + try + { + parts[0].ParentGroup.areUpdatesSuspended = true; + foreach (SceneObjectPart part in parts) + SetPrimParams(part, rules); + } + finally + { + parts[0].ParentGroup.areUpdatesSuspended = false; + } + } } public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) -- cgit v1.1 From 31439293ccdb5df914dc13287a8f178529fccb6b Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 29 May 2010 03:56:34 -0700 Subject: Meta7 Communities : Authorization service added, skeleton, not yet functional --- .../Services/Meta7Communities/Meta7Communities.cs | 59 ++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 OpenSim/Services/Meta7Communities/Meta7Communities.cs (limited to 'OpenSim') diff --git a/OpenSim/Services/Meta7Communities/Meta7Communities.cs b/OpenSim/Services/Meta7Communities/Meta7Communities.cs new file mode 100644 index 0000000..32f5c32 --- /dev/null +++ b/OpenSim/Services/Meta7Communities/Meta7Communities.cs @@ -0,0 +1,59 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using Nini.Config; +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Data; +using OpenSim.Services.Interfaces; +using OpenSim.Services.AuthorizationService; +using OpenMetaverse; + +namespace OpenSim.Services.Meta7Communities +{ + public class Meta7Communities : AuthorizationServiceBase, IAuthorizationService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + public Meta7Communities(IConfigSource config) + : base(config) + { + m_log.Info("[Communities]: Local Authorization service enabled"); + } + + public bool IsAuthorizedForRegion(string userID, string regionID, out string message) + { + message = "NO GOATS"; + return false; + } + } +} -- cgit v1.1 From 84e30bee6dce30853cf4438382b39e65ec3fa622 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 29 May 2010 12:34:02 +0200 Subject: Revert "Meta7 Communities : Authorization service added, skeleton, not yet functional" This reverts commit 31439293ccdb5df914dc13287a8f178529fccb6b. --- .../Services/Meta7Communities/Meta7Communities.cs | 59 ---------------------- 1 file changed, 59 deletions(-) delete mode 100644 OpenSim/Services/Meta7Communities/Meta7Communities.cs (limited to 'OpenSim') diff --git a/OpenSim/Services/Meta7Communities/Meta7Communities.cs b/OpenSim/Services/Meta7Communities/Meta7Communities.cs deleted file mode 100644 index 32f5c32..0000000 --- a/OpenSim/Services/Meta7Communities/Meta7Communities.cs +++ /dev/null @@ -1,59 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Reflection; -using Nini.Config; -using log4net; -using OpenSim.Framework; -using OpenSim.Framework.Console; -using OpenSim.Data; -using OpenSim.Services.Interfaces; -using OpenSim.Services.AuthorizationService; -using OpenMetaverse; - -namespace OpenSim.Services.Meta7Communities -{ - public class Meta7Communities : AuthorizationServiceBase, IAuthorizationService - { - private static readonly ILog m_log = - LogManager.GetLogger( - MethodBase.GetCurrentMethod().DeclaringType); - - public Meta7Communities(IConfigSource config) - : base(config) - { - m_log.Info("[Communities]: Local Authorization service enabled"); - } - - public bool IsAuthorizedForRegion(string userID, string regionID, out string message) - { - message = "NO GOATS"; - return false; - } - } -} -- cgit v1.1 From 59a536743354ffaa12b23378f559d2d59d7d5304 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 30 May 2010 13:46:05 +0200 Subject: Changes OSSL Api permissions for the case of UUID list. In 0.6.9, the UUIDs would be the IDs of the prim owners in whose prims these functions would run. This changes it so the UUID is the SCRIPT CREATOR instead. Further, osfunctions limited by uuid will not run if the creator and owner differ and the owner has mod rights on the script. There is still a danger in passing moodifiable scripts to others, as they can insert a harmful function, then remove the mod rights to make it runnable. As before, care needs to be taken, but where it was modable prims that were the risk before, modable scripts are the weak spot now. In cases where prim owner == script creator == script owner, nothing will change. --- .../Shared/Api/Implementation/OSSL_Api.cs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 942e4ef..8cfa833 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -278,10 +278,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (!m_FunctionPerms[function].Contains(UUID.Zero)) { - if (!m_FunctionPerms[function].Contains(m_host.OwnerID)) + TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID); + if (ti == null) + { + OSSLError( + String.Format("{0} permission error. Can't find script in prim inventory.", + function)); + } + if (!m_FunctionPerms[function].Contains(ti.CreatorID)) OSSLError( - String.Format("{0} permission denied. Prim owner is not in the list of users allowed to execute this function.", + String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function.", function)); + if (ti.CreatorID != ti.OwnerID) + { + if ((ti.CurrentPermissions & (uint)PermissionMask.Modify) != 0) + OSSLError( + String.Format("{0} permission denied. Script permissions error.", + function)); + + } } } } @@ -2141,4 +2156,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } -} \ No newline at end of file +} -- cgit v1.1 From 890f3cc54cc57883a110b372530bf2a7d5b37fff Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 30 May 2010 15:46:54 +0200 Subject: Changes osFunction permissions again. Allow_ with a list of UUIDs now again refers to prim OWNERS. A new option set, Creators_, is added to allow selection by script creator. For existing installs, this means no functional change. The warning from my prior commit doesn't apply anymore. --- .../Shared/Api/Implementation/OSSL_Api.cs | 67 ++++++++++++++++------ 1 file changed, 51 insertions(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 8cfa833..2e0456e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -105,6 +105,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // modification of user data, or allows the compromise of // sensitive data by design. + class FunctionPerms + { + public List AllowedCreators; + public List AllowedOwners; + + public FunctionPerms() + { + AllowedCreators = new List(); + AllowedOwners = new List(); + } + } + [Serializable] public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi { @@ -117,7 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; internal float m_ScriptDelayFactor = 1.0f; internal float m_ScriptDistanceFactor = 1.0f; - internal Dictionary > m_FunctionPerms = new Dictionary >(); + internal Dictionary m_FunctionPerms = new Dictionary(); public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) { @@ -217,31 +229,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (!m_FunctionPerms.ContainsKey(function)) { - string perm = m_ScriptEngine.Config.GetString("Allow_" + function, ""); - if (perm == "") + FunctionPerms perms = new FunctionPerms(); + m_FunctionPerms[function] = perms; + + string ownerPerm = m_ScriptEngine.Config.GetString("Allow_" + function, ""); + string creatorPerm = m_ScriptEngine.Config.GetString("Creators_" + function, ""); + if (ownerPerm == "" && creatorPerm == "") { - m_FunctionPerms[function] = null; // a null value is default + // Default behavior + perms.AllowedOwners = null; + perms.AllowedCreators = null; } else { bool allowed; - if (bool.TryParse(perm, out allowed)) + if (bool.TryParse(ownerPerm, out allowed)) { // Boolean given if (allowed) { - m_FunctionPerms[function] = new List(); - m_FunctionPerms[function].Add(UUID.Zero); + // Allow globally + perms.AllowedOwners.Add(UUID.Zero); } - else - m_FunctionPerms[function] = new List(); // Empty list = none } else { - m_FunctionPerms[function] = new List(); + string[] ids = ownerPerm.Split(new char[] {','}); + foreach (string id in ids) + { + string current = id.Trim(); + UUID uuid; + + if (UUID.TryParse(current, out uuid)) + { + if (uuid != UUID.Zero) + perms.AllowedOwners.Add(uuid); + } + } - string[] ids = perm.Split(new char[] {','}); + ids = creatorPerm.Split(new char[] {','}); foreach (string id in ids) { string current = id.Trim(); @@ -250,7 +277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (UUID.TryParse(current, out uuid)) { if (uuid != UUID.Zero) - m_FunctionPerms[function].Add(uuid); + perms.AllowedCreators.Add(uuid); } } } @@ -266,8 +293,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // // To allow use by anyone, the list contains UUID.Zero // - if (m_FunctionPerms[function] == null) // No list = true + if (m_FunctionPerms[function].AllowedOwners == null) { + // Allow / disallow by threat level if (level > m_MaxThreatLevel) OSSLError( String.Format( @@ -276,8 +304,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - if (!m_FunctionPerms[function].Contains(UUID.Zero)) + if (!m_FunctionPerms[function].AllowedOwners.Contains(UUID.Zero)) { + // Not anyone. Do detailed checks + if (m_FunctionPerms[function].AllowedOwners.Contains(m_host.OwnerID)) + { + // prim owner is in the list of allowed owners + return; + } + TaskInventoryItem ti = m_host.Inventory.GetInventoryItem(m_itemID); if (ti == null) { @@ -285,9 +320,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api String.Format("{0} permission error. Can't find script in prim inventory.", function)); } - if (!m_FunctionPerms[function].Contains(ti.CreatorID)) + if (!m_FunctionPerms[function].AllowedCreators.Contains(ti.CreatorID)) OSSLError( - String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function.", + String.Format("{0} permission denied. Script creator is not in the list of users allowed to execute this function and prim owner also has no permission.", function)); if (ti.CreatorID != ti.OwnerID) { -- cgit v1.1 From bbb4d6e4c934cd25615c98f2ee4500a5d28fa701 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 31 May 2010 01:02:04 +0200 Subject: Fix a nullref in EventManager caused by RegionReady not setting the scene --- .../OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs index c653e98..672109b 100644 --- a/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/RegionReadyModule/RegionReadyModule.cs @@ -146,6 +146,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.RegionReady c.Position = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 30); c.Sender = null; c.SenderUUID = UUID.Zero; + c.Scene = m_scene; m_log.InfoFormat("[RegionReady]: Region \"{0}\" is ready: \"{1}\" on channel {2}", m_scene.RegionInfo.RegionName, c.Message, m_channelNotify); -- cgit v1.1 From 6c1665bf46f691f83e93561cfbcdcd4d3f3bd954 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 31 May 2010 08:38:41 -0700 Subject: Fix casting in llParcelMediaCommandList so that it actually, you know, works --- .../Shared/Api/Implementation/LSL_Api.cs | 32 +++++++++++----------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bb02fa3..d0f245b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9046,17 +9046,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int width = 0; int height = 0; - ParcelMediaCommandEnum? commandToSend = null; + uint commandToSend = 0; float time = 0.0f; // default is from start ScenePresence presence = null; for (int i = 0; i < commandList.Data.Length; i++) { - ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; + uint command = (uint)(commandList.GetLSLIntegerItem(i)); switch (command) { - case ParcelMediaCommandEnum.Agent: + case (uint)ParcelMediaCommandEnum.Agent: // we send only to one agent if ((i + 1) < commandList.Length) { @@ -9073,25 +9073,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.Loop: + case (uint)ParcelMediaCommandEnum.Loop: loop = 1; commandToSend = command; update = true; //need to send the media update packet to set looping break; - case ParcelMediaCommandEnum.Play: + case (uint)ParcelMediaCommandEnum.Play: loop = 0; commandToSend = command; update = true; //need to send the media update packet to make sure it doesn't loop break; - case ParcelMediaCommandEnum.Pause: - case ParcelMediaCommandEnum.Stop: - case ParcelMediaCommandEnum.Unload: + case (uint)ParcelMediaCommandEnum.Pause: + case (uint)ParcelMediaCommandEnum.Stop: + case (uint)ParcelMediaCommandEnum.Unload: commandToSend = command; break; - case ParcelMediaCommandEnum.Url: + case (uint)ParcelMediaCommandEnum.Url: if ((i + 1) < commandList.Length) { if (commandList.Data[i + 1] is LSL_String) @@ -9104,7 +9104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.Texture: + case (uint)ParcelMediaCommandEnum.Texture: if ((i + 1) < commandList.Length) { if (commandList.Data[i + 1] is LSL_String) @@ -9117,7 +9117,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.Time: + case (uint)ParcelMediaCommandEnum.Time: if ((i + 1) < commandList.Length) { if (commandList.Data[i + 1] is LSL_Float) @@ -9129,7 +9129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.AutoAlign: + case (uint)ParcelMediaCommandEnum.AutoAlign: if ((i + 1) < commandList.Length) { if (commandList.Data[i + 1] is LSL_Integer) @@ -9143,7 +9143,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.Type: + case (uint)ParcelMediaCommandEnum.Type: if ((i + 1) < commandList.Length) { if (commandList.Data[i + 1] is LSL_String) @@ -9156,7 +9156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.Desc: + case (uint)ParcelMediaCommandEnum.Desc: if ((i + 1) < commandList.Length) { if (commandList.Data[i + 1] is LSL_String) @@ -9169,7 +9169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } break; - case ParcelMediaCommandEnum.Size: + case (uint)ParcelMediaCommandEnum.Size: if ((i + 2) < commandList.Length) { if (commandList.Data[i + 1] is LSL_Integer) @@ -9239,7 +9239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - if (commandToSend != null) + if (commandToSend != 0) { // the commandList contained a start/stop/... command, too if (presence == null) -- cgit v1.1 From d4b4cbf5a5fead727b5e2e48f69d2016eb942cff Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 31 May 2010 19:00:02 +0200 Subject: Fix create selection getting overwritten by multiple updates for the same prim. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 4 ++-- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 ++++++++- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 5 files changed, 13 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 51cc763..fe8475a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4561,11 +4561,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (recipientID == data.OwnerID) { - if ((data.Flags & PrimFlags.CreateSelected) != 0) + if (data.CreateSelected) { // Only send this flag once, then unset it flags |= PrimFlags.CreateSelected; - data.Flags &= ~PrimFlags.CreateSelected; + data.CreateSelected = false; } } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 445c2c8..5fbc658 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1542,7 +1542,7 @@ namespace OpenSim.Region.Framework.Scenes // We need to explicitly resend the newly link prim's object properties since no other actions // occur on link to invoke this elsewhere (such as object selection) - parentGroup.RootPart.AddFlag(PrimFlags.CreateSelected); + parentGroup.RootPart.CreateSelected = true; parentGroup.TriggerScriptChangedEvent(Changed.LINK); } finally diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9ebb168..509ec01 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2486,7 +2486,7 @@ namespace OpenSim.Region.Framework.Scenes linkPart.LinkNum = 2; linkPart.SetParent(this); - linkPart.AddFlag(PrimFlags.CreateSelected); + linkPart.CreateSelected = true; //if (linkPart.PhysActor != null) //{ diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 6e73b65..2f4191d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -388,7 +388,6 @@ namespace OpenSim.Region.Framework.Scenes // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log _flags = 0; - _flags |= PrimFlags.CreateSelected; TrimPermissions(); //m_undo = new UndoStack(ParentGroup.GetSceneMaxUndo()); @@ -418,6 +417,7 @@ namespace OpenSim.Region.Framework.Scenes private PrimFlags _flags = 0; private DateTime m_expires; private DateTime m_rezzed; + private bool m_createSelected = true; public UUID CreatorID { @@ -978,6 +978,13 @@ namespace OpenSim.Region.Framework.Scenes set { m_updateFlag = value; } } + [XmlIgnore] + public bool CreateSelected + { + get { return m_createSelected; } + set { m_createSelected = value; } + } + #endregion //--------------- diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bb02fa3..228ab6d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3742,7 +3742,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } parentPrim.TriggerScriptChangedEvent(Changed.LINK); - parentPrim.RootPart.AddFlag(PrimFlags.CreateSelected); + parentPrim.RootPart.CreateSelected = true; parentPrim.HasGroupChanged = true; parentPrim.ScheduleGroupForFullUpdate(); -- cgit v1.1 From 70f779041334e7cf3642c334e9800362afde7895 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 01:07:46 +0200 Subject: Split GetAxisAlignedBoundingBox into two methods to allow calculation of combined bounding boxes and offsets --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 509ec01..4203ba9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -794,9 +794,15 @@ namespace OpenSim.Region.Framework.Scenes /// offsetHeight is the offset in the Z axis from the centre of the bounding box to the centre of the root prim /// /// - public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) + public void GetAxisAlignedBoundingBoxRaw(out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) { - float maxX = -256f, maxY = -256f, maxZ = -256f, minX = 256f, minY = 256f, minZ = 256f; + maxX = -256f; + maxY = -256f; + maxZ = -256f; + minX = 256f; + minY = 256f; + minZ = 256f; + lockPartsForRead(true); { foreach (SceneObjectPart part in m_parts.Values) @@ -1034,7 +1040,18 @@ namespace OpenSim.Region.Framework.Scenes } } lockPartsForRead(false); + } + + public Vector3 GetAxisAlignedBoundingBox(out float offsetHeight) + { + float minX; + float maxX; + float minY; + float maxY; + float minZ; + float maxZ; + GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ); Vector3 boundingBox = new Vector3(maxX - minX, maxY - minY, maxZ - minZ); offsetHeight = 0; -- cgit v1.1 From f57f2370f1737e997e8871d5b05a426e9ac19ba7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 01:25:24 +0200 Subject: Add a method to get the bounding box and root prim offsets within it for a group of prims. --- OpenSim/Region/Framework/Scenes/Scene.cs | 44 ++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 933999e..22248af 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5236,5 +5236,49 @@ namespace OpenSim.Region.Framework.Scenes ReloadEstateData(); } } + + public Vector3[] GetCombinedBoundingBox(List objects, out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ) + { + minX = 256; + maxX = -256; + minY = 256; + maxY = -256; + minZ = 8192; + maxZ = -256; + + List offsets = new List(); + + foreach (SceneObjectGroup g in objects) + { + float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; + + g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); + + if (minX > ominX) + minX = ominX; + if (minY > ominY) + minY = ominY; + if (minZ > ominZ) + minZ = ominZ; + if (maxX < omaxX) + maxX = omaxX; + if (maxY < omaxY) + maxY = omaxY; + if (maxZ < omaxZ) + maxZ = omaxZ; + } + + foreach (SceneObjectGroup g in objects) + { + Vector3 vec = g.AbsolutePosition; + vec.X -= minX; + vec.Y -= minY; + vec.Z -= minZ; + + offsets.Add(vec); + } + + return offsets.ToArray(); + } } } -- cgit v1.1 From bf233ea0dc564dbae3896d8b5ac355fb2f247a00 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 02:27:30 +0200 Subject: Continuing refactor. Refactor DeRezObject to deal with multiple objects --- .../InventoryAccess/HGInventoryAccessModule.cs | 17 ++- .../InventoryAccess/InventoryAccessModule.cs | 14 +++ .../Framework/Interfaces/IInventoryAccessModule.cs | 2 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 18 ++- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 138 ++++++++++++--------- 5 files changed, 118 insertions(+), 71 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 93aeb94..2ab46aa 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -119,9 +119,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// DeleteToInventory /// - public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) + public override UUID DeleteToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient) { - UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient); + UUID ret = UUID.Zero; + + // HACK: Only works for lists of length one. + // Intermediate version, just to make things compile + foreach (SceneObjectGroup g in objectGroups) + ret = DeleteToInventory(action, folderID, g, remoteClient); + + return ret; + } + + public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, + SceneObjectGroup objectGroup, IClientAPI remoteClient) + { + UUID assetID = base.DeleteToInventory(action, folderID, new List() {objectGroup}, remoteClient); if (!assetID.Equals(UUID.Zero)) { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 901dcba..3035d88 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -189,6 +189,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, + List objectGroups, IClientAPI remoteClient) + { + // HACK: This is only working for lists containing a single item! + // It's just a hack to make this WIP compile and run. Nothing + // currently calls this with multiple items. + UUID ret = UUID.Zero; + + foreach (SceneObjectGroup g in objectGroups) + ret = DeleteToInventory(action, folderID, g, remoteClient); + + return ret; + } + + public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) { UUID assetID = UUID.Zero; diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index 8185258..97f4188 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces public interface IInventoryAccessModule { UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data); - UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient); + UUID DeleteToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient); SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment); diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index c08b961..241cac0 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Scenes { public DeRezAction action; public IClientAPI remoteClient; - public SceneObjectGroup objectGroup; + public List objectGroups; public UUID folderID; public bool permissionToDelete; } @@ -75,7 +75,7 @@ namespace OpenSim.Region.Framework.Scenes /// Delete the given object from the scene /// public void DeleteToInventory(DeRezAction action, UUID folderID, - SceneObjectGroup objectGroup, IClientAPI remoteClient, + List objectGroups, IClientAPI remoteClient, bool permissionToDelete) { if (Enabled) @@ -87,7 +87,7 @@ namespace OpenSim.Region.Framework.Scenes DeleteToInventoryHolder dtis = new DeleteToInventoryHolder(); dtis.action = action; dtis.folderID = folderID; - dtis.objectGroup = objectGroup; + dtis.objectGroups = objectGroups; dtis.remoteClient = remoteClient; dtis.permissionToDelete = permissionToDelete; @@ -103,7 +103,10 @@ namespace OpenSim.Region.Framework.Scenes // This is not ideal since the object will still be available for manipulation when it should be, but it's // better than losing the object for now. if (permissionToDelete) - objectGroup.DeleteGroup(false); + { + foreach (SceneObjectGroup g in objectGroups) + g.DeleteGroup(false); + } } private void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e) @@ -140,9 +143,12 @@ namespace OpenSim.Region.Framework.Scenes { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) - invAccess.DeleteToInventory(x.action, x.folderID, x.objectGroup, x.remoteClient); + invAccess.DeleteToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); if (x.permissionToDelete) - m_scene.DeleteSceneObject(x.objectGroup, false); + { + foreach (SceneObjectGroup g in x.objectGroups) + m_scene.DeleteSceneObject(g, false); + } } catch (Exception e) { diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index cbe3456..e1128a6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1550,79 +1550,98 @@ namespace OpenSim.Region.Framework.Scenes public virtual void DeRezObject(IClientAPI remoteClient, uint localID, UUID groupID, DeRezAction action, UUID destinationID) { - SceneObjectPart part = GetSceneObjectPart(localID); - if (part == null) - return; + DeRezObjects(remoteClient, new List() { localID} , groupID, action, destinationID); + } - if (part.ParentGroup == null || part.ParentGroup.IsDeleted) - return; + public virtual void DeRezObjects(IClientAPI remoteClient, List localIDs, + UUID groupID, DeRezAction action, UUID destinationID) + { + // First, see of we can perform the requested action and + // build a list of eligible objects + List deleteIDs = new List(); + List deleteGroups = new List(); - // Can't delete child prims - if (part != part.ParentGroup.RootPart) - return; + // Start with true for both, then remove the flags if objects + // that we can't derez are part of the selection + bool permissionToTake = true; + bool permissionToTakeCopy = true; + bool permissionToDelete = true; - SceneObjectGroup grp = part.ParentGroup; + foreach (uint localID in localIDs) + { + // Invalid id + SceneObjectPart part = GetSceneObjectPart(localID); + if (part == null) + continue; - //force a database backup/update on this SceneObjectGroup - //So that we know the database is upto date, for when deleting the object from it - ForceSceneObjectBackup(grp); + // Already deleted by someone else + if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + continue; - bool permissionToTake = false; - bool permissionToDelete = false; + // Can't delete child prims + if (part != part.ParentGroup.RootPart) + continue; - if (action == DeRezAction.SaveToExistingUserInventoryItem) - { - if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero) - { - permissionToTake = true; + SceneObjectGroup grp = part.ParentGroup; + + deleteIDs.Add(localID); + deleteGroups.Add(grp); + + // Force a database backup/update on this SceneObjectGroup + // So that we know the database is upto date, + // for when deleting the object from it + ForceSceneObjectBackup(grp); + + if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) + permissionToTakeCopy = false; + if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) + permissionToTake = false; + + if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) permissionToDelete = false; - } + } - else if (action == DeRezAction.TakeCopy) + + // Handle god perms + if (Permissions.IsGod(remoteClient.AgentId)) { - permissionToTake = - Permissions.CanTakeCopyObject( - grp.UUID, - remoteClient.AgentId); + permissionToTake = true; + permissionToTakeCopy = true; + permissionToDelete = true; } - else if (action == DeRezAction.GodTakeCopy) - { - permissionToTake = - Permissions.IsGod( - remoteClient.AgentId); - } - else if (action == DeRezAction.Take) - { - permissionToTake = - Permissions.CanTakeObject( - grp.UUID, - remoteClient.AgentId); - //If they can take, they can delete! - permissionToDelete = permissionToTake; - } - else if (action == DeRezAction.Delete) + // If we're re-saving, we don't even want to delete + if (action == DeRezAction.SaveToExistingUserInventoryItem) + permissionToDelete = false; + + // if we want to take a copy,, we also don't want to delete + // Note: after this point, the permissionToTakeCopy flag + // becomes irrelevant. It already includes the permissionToTake + // permission and after excluding no copy items here, we can + // just use that. + if (action == DeRezAction.TakeCopy) { - permissionToTake = - Permissions.CanDeleteObject( - grp.UUID, - remoteClient.AgentId); - permissionToDelete = permissionToTake; + // If we don't have permission, stop right here + if (!permissionToTakeCopy) + return; + + // Don't delete + permissionToDelete = false; } - else if (action == DeRezAction.Return) + + if (action == DeRezAction.Return) { if (remoteClient != null) { - permissionToTake = - Permissions.CanReturnObjects( + if (Permissions.CanReturnObjects( null, remoteClient.AgentId, - new List() {grp}); - permissionToDelete = permissionToTake; - - if (permissionToDelete) + deleteGroups)) + foreach (SceneObjectGroup g in deleteGroups) { - AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); + AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); + DeleteSceneObject(g, false); + return; } } else // Auto return passes through here with null agent @@ -1631,22 +1650,17 @@ namespace OpenSim.Region.Framework.Scenes permissionToDelete = true; } } - else - { - m_log.DebugFormat( - "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name); - return; - } if (permissionToTake) { m_asyncSceneObjectDeleter.DeleteToInventory( - action, destinationID, grp, remoteClient, + action, destinationID, deleteGroups, remoteClient, permissionToDelete); } else if (permissionToDelete) { - DeleteSceneObject(grp, false); + foreach (SceneObjectGroup g in deleteGroups) + DeleteSceneObject(g, false); } } -- cgit v1.1 From eca15cfbf25134ddc8bb752abbe3a6ba01bf07a9 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 02:45:14 +0200 Subject: Change the handling of CreateSelected. Only send it on real creation, not for each prim coming into view. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 2f4191d..e4a36ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -388,6 +388,7 @@ namespace OpenSim.Region.Framework.Scenes // the prim into an agent inventory (Linden client reports that the "Object not found for drop" in its log _flags = 0; + CreateSelected = true; TrimPermissions(); //m_undo = new UndoStack(ParentGroup.GetSceneMaxUndo()); @@ -417,7 +418,7 @@ namespace OpenSim.Region.Framework.Scenes private PrimFlags _flags = 0; private DateTime m_expires; private DateTime m_rezzed; - private bool m_createSelected = true; + private bool m_createSelected = false; public UUID CreatorID { -- cgit v1.1 From 16d8602d3cad613a830a4903bb0d2beb1fa6b7e2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 03:04:49 +0200 Subject: Fix prim returns I broke earlier --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 11 +++++++---- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e1128a6..e111867 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1637,11 +1637,14 @@ namespace OpenSim.Region.Framework.Scenes null, remoteClient.AgentId, deleteGroups)) - foreach (SceneObjectGroup g in deleteGroups) { - AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); - DeleteSceneObject(g, false); - return; + permissionToTake = true; + permissionToDelete = true; + + foreach (SceneObjectGroup g in deleteGroups) + { + AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); + } } } else // Auto return passes through here with null agent diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 4203ba9..7e73f91 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -801,7 +801,7 @@ namespace OpenSim.Region.Framework.Scenes maxZ = -256f; minX = 256f; minY = 256f; - minZ = 256f; + minZ = 8192f; lockPartsForRead(true); { -- cgit v1.1 From c900134f911b7f11c4fa25c67d55c112b1f56033 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 16:03:53 +0200 Subject: Lock the object queue when dequeueing --- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 159 +++++++++++++------------ 1 file changed, 81 insertions(+), 78 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 2fc98e5..5cbd8d9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -67,105 +67,108 @@ namespace OpenSim.Region.Framework.Scenes public void SendPrimUpdates() { - if (m_pendingObjects == null) + lock(m_pendingObjects) { - if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) + if (m_pendingObjects == null) { - m_pendingObjects = new Queue(); - - foreach (EntityBase e in m_presence.Scene.Entities) + if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) { - if (e != null && e is SceneObjectGroup) - m_pendingObjects.Enqueue((SceneObjectGroup)e); + m_pendingObjects = new Queue(); + + foreach (EntityBase e in m_presence.Scene.Entities) + { + if (e != null && e is SceneObjectGroup) + m_pendingObjects.Enqueue((SceneObjectGroup)e); + } } } - } - - while (m_pendingObjects != null && m_pendingObjects.Count > 0) - { - SceneObjectGroup g = m_pendingObjects.Dequeue(); - // Yes, this can really happen - if (g == null) - continue; - - // This is where we should check for draw distance - // do culling and stuff. Problem with that is that until - // we recheck in movement, that won't work right. - // So it's not implemented now. - // - - // Don't even queue if we have sent this one - // - if (!m_updateTimes.ContainsKey(g.UUID)) - g.ScheduleFullUpdateToAvatar(m_presence); - } - while (m_partsUpdateQueue.Count > 0) - { - SceneObjectPart part = m_partsUpdateQueue.Dequeue(); - - if (part.ParentGroup == null || part.ParentGroup.IsDeleted) - continue; - - if (m_updateTimes.ContainsKey(part.UUID)) + while (m_pendingObjects != null && m_pendingObjects.Count > 0) { - ScenePartUpdate update = m_updateTimes[part.UUID]; + SceneObjectGroup g = m_pendingObjects.Dequeue(); + // Yes, this can really happen + if (g == null) + continue; - // We deal with the possibility that two updates occur at - // the same unix time at the update point itself. + // This is where we should check for draw distance + // do culling and stuff. Problem with that is that until + // we recheck in movement, that won't work right. + // So it's not implemented now. + // + + // Don't even queue if we have sent this one + // + if (!m_updateTimes.ContainsKey(g.UUID)) + g.ScheduleFullUpdateToAvatar(m_presence); + } - if ((update.LastFullUpdateTime < part.TimeStampFull) || - part.IsAttachment) + while (m_partsUpdateQueue.Count > 0) + { + SceneObjectPart part = m_partsUpdateQueue.Dequeue(); + + if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + continue; + + if (m_updateTimes.ContainsKey(part.UUID)) { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", -// part.Name, part.UUID, part.TimeStampFull); + ScenePartUpdate update = m_updateTimes[part.UUID]; - part.SendFullUpdate(m_presence.ControllingClient, - m_presence.GenerateClientFlags(part.UUID)); + // We deal with the possibility that two updates occur at + // the same unix time at the update point itself. - // We'll update to the part's timestamp rather than - // the current time to avoid the race condition - // whereby the next tick occurs while we are doing - // this update. If this happened, then subsequent - // updates which occurred on the same tick or the - // next tick of the last update would be ignored. + if ((update.LastFullUpdateTime < part.TimeStampFull) || + part.IsAttachment) + { + // m_log.DebugFormat( + // "[SCENE PRESENCE]: Fully updating prim {0}, {1} - part timestamp {2}", + // part.Name, part.UUID, part.TimeStampFull); - update.LastFullUpdateTime = part.TimeStampFull; + part.SendFullUpdate(m_presence.ControllingClient, + m_presence.GenerateClientFlags(part.UUID)); - } - else if (update.LastTerseUpdateTime <= part.TimeStampTerse) - { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", -// part.Name, part.UUID, part.TimeStampTerse); + // We'll update to the part's timestamp rather than + // the current time to avoid the race condition + // whereby the next tick occurs while we are doing + // this update. If this happened, then subsequent + // updates which occurred on the same tick or the + // next tick of the last update would be ignored. - part.SendTerseUpdateToClient(m_presence.ControllingClient); + update.LastFullUpdateTime = part.TimeStampFull; - update.LastTerseUpdateTime = part.TimeStampTerse; - } - } - else - { - //never been sent to client before so do full update - ScenePartUpdate update = new ScenePartUpdate(); - update.FullID = part.UUID; - update.LastFullUpdateTime = part.TimeStampFull; - m_updateTimes.Add(part.UUID, update); + } + else if (update.LastTerseUpdateTime <= part.TimeStampTerse) + { + // m_log.DebugFormat( + // "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", + // part.Name, part.UUID, part.TimeStampTerse); - // Attachment handling - // - if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) + part.SendTerseUpdateToClient(m_presence.ControllingClient); + + update.LastTerseUpdateTime = part.TimeStampTerse; + } + } + else { - if (part != part.ParentGroup.RootPart) + //never been sent to client before so do full update + ScenePartUpdate update = new ScenePartUpdate(); + update.FullID = part.UUID; + update.LastFullUpdateTime = part.TimeStampFull; + m_updateTimes.Add(part.UUID, update); + + // Attachment handling + // + if (part.ParentGroup.RootPart.Shape.PCode == 9 && part.ParentGroup.RootPart.Shape.State != 0) + { + if (part != part.ParentGroup.RootPart) + continue; + + part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); continue; + } - part.ParentGroup.SendFullUpdateToClient(m_presence.ControllingClient); - continue; + part.SendFullUpdate(m_presence.ControllingClient, + m_presence.GenerateClientFlags(part.UUID)); } - - part.SendFullUpdate(m_presence.ControllingClient, - m_presence.GenerateClientFlags(part.UUID)); } } } -- cgit v1.1 From 6668c789d34bf9b068df5821973fdb75cf129b75 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 1 Jun 2010 19:01:21 +0200 Subject: One should not lock null objects. --- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index 5cbd8d9..f478a4a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -67,14 +67,14 @@ namespace OpenSim.Region.Framework.Scenes public void SendPrimUpdates() { - lock(m_pendingObjects) + if (m_pendingObjects == null) { - if (m_pendingObjects == null) + if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) { - if (!m_presence.IsChildAgent || (m_presence.Scene.m_seeIntoRegionFromNeighbor)) - { - m_pendingObjects = new Queue(); + m_pendingObjects = new Queue(); + lock(m_pendingObjects) + { foreach (EntityBase e in m_presence.Scene.Entities) { if (e != null && e is SceneObjectGroup) @@ -82,7 +82,10 @@ namespace OpenSim.Region.Framework.Scenes } } } + } + lock(m_pendingObjects) + { while (m_pendingObjects != null && m_pendingObjects.Count > 0) { SceneObjectGroup g = m_pendingObjects.Dequeue(); -- cgit v1.1 From 90c814a7cace3bac3df451a8b184c32f462c4da2 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 1 Jun 2010 13:29:12 -0700 Subject: Fix nullref in cmGetAvatarList() (ported from 0.69) --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 3e62c1a..4fb5c95 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -125,9 +125,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (avatar.IsChildAgent == false) { - result.Add(avatar.UUID); - result.Add(avatar.PhysicsActor.Position); - result.Add(avatar.Name); + if (avatar.PhysicsActor != null && avatar.PhysicsActor.Position != null) + { + result.Add(avatar.UUID); + result.Add(avatar.PhysicsActor.Position); + result.Add(avatar.Name); + } } } }); -- cgit v1.1 From d8962ef4151043babe8d5c33c332bf49b020b119 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 2 Jun 2010 01:01:56 +0200 Subject: Add two new osFunctions: list osGetPrimititveParams(key prim, list rules); osSetPrimitiveParams(key prim, list rules); --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 18 ++++++++++++++++++ .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 16 ++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 3 +++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 4 ++++ .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 9 +++++++++ 5 files changed, 50 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8cc5e25..481a3e6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10261,6 +10261,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(100); return tid.ToString(); } + + public void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules) + { + SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); + if (obj == null) + return; + + SetPrimParams(obj, rules); + } + + public LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules) + { + SceneObjectPart obj = World.GetSceneObjectPart(new UUID(prim)); + if (obj == null) + return new LSL_List(); + + return GetLinkPrimitiveParams(obj, rules); + } } public class NotecardCache diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 2e0456e..f2a2f32 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2190,5 +2190,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } + + public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) + { + CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams"); + m_host.AddScriptLPS(1); + + return m_LSL_Api.GetLinkPrimitiveParamsEx(prim, rules); + } + + public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) + { + CheckThreatLevel(ThreatLevel.High, "osGetPrimitiveParams"); + m_host.AddScriptLPS(1); + + m_LSL_Api.SetPrimitiveParamsEx(prim, rules); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 7ab04a3..cba46a3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -395,5 +395,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Vector llWind(LSL_Vector offset); LSL_String llXorBase64Strings(string str1, string str2); LSL_String llXorBase64StringsCorrect(string str1, string str2); + + void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); + LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 9dbd369..1ab7f10 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -35,6 +35,7 @@ using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces { @@ -173,5 +174,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osSetSpeed(string UUID, float SpeedModifier); void osCauseHealing(string avatar, double healing); void osCauseDamage(string avatar, double damage); + LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); + void osSetPrimitiveParams(LSL_Key prim, LSL_List rules); + } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index fd9309a..7af5d43 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -41,6 +41,7 @@ using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; @@ -678,5 +679,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osCauseHealing(avatar, healing); } + public LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules) + { + return m_OSSL_Functions.osGetPrimitiveParams(prim, rules); + } + public void osSetPrimitiveParams(LSL_Key prim, LSL_List rules) + { + m_OSSL_Functions.osSetPrimitiveParams(prim, rules); + } } } -- cgit v1.1 From 70aa965c2678f91e45986f50a89588339a904f04 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 2 Jun 2010 01:04:17 +0200 Subject: Add a forgotten security check. Make the new functions only work on prims owned by the host prim owner. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 481a3e6..3c2ef34 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10268,6 +10268,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (obj == null) return; + if (obj.OwnerID != m_host.OwnerID) + return; + SetPrimParams(obj, rules); } @@ -10277,6 +10280,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (obj == null) return new LSL_List(); + if (obj.OwnerID != m_host.OwnerID) + return new LSL_List(); + return GetLinkPrimitiveParams(obj, rules); } } -- cgit v1.1 From 293f775fa56c8bcb3986373e004f54e549168be6 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 2 Jun 2010 07:59:18 -0700 Subject: Always provide at least 2 packets of a texture (if the texture is larger than 1 packet). This fixes compatibility with the newer (broken) SnowGlobe and Emerald viewer(s), but also matches the behaviour of SL. --- OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 9869a99..5c17b0e 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -202,6 +202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_stopPacket = TexturePacketCount(); } + //Give them at least two packets, to play nice with some broken viewers (SL also behaves this way) + if (m_stopPacket == 1 && Layers[0].End > FIRST_PACKET_SIZE) m_stopPacket++; + m_currentPacket = StartPacket; } } -- cgit v1.1 From dda7185b437fbbbd8ec7871b910a04990069a829 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 3 Jun 2010 17:55:50 -0700 Subject: Change the admin kick message to something more generic, "OpenSim Manager" is not really accurate --- OpenSim/Region/Application/OpenSim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index a09b903..75561a7 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -427,7 +427,7 @@ namespace OpenSim if (alert != null) presence.ControllingClient.Kick(alert); else - presence.ControllingClient.Kick("\nThe OpenSim manager kicked you out.\n"); + presence.ControllingClient.Kick("\nYou have been logged out by an administrator.\n"); // ...and close on our side presence.Scene.IncomingCloseAgent(presence.UUID); -- cgit v1.1 From e962c44749ca63dec9df7de1c74b03d9b59c3f20 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Fri, 4 Jun 2010 19:36:31 -0700 Subject: Fix support for PRIM_SCULPT_FLAG_INVERT and PRIM_SCULPT_FLAG_MIRROR in the llSetPrimitiveParams series of functions. This makes it possible to mirror a sculpt by script. --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3c2ef34..0a4544c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7112,13 +7112,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api shapeBlock.PathScaleX = 100; shapeBlock.PathScaleY = 150; - if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && - type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && - type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && - type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) + if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 && + (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 && + (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 && + (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0) { // default - type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; + type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; } // retain pathcurve -- cgit v1.1 From fad5158ab4ab01a179eac80c92df301157fb8319 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 7 Jun 2010 00:09:22 +0200 Subject: Add a call to SOG.ResumeScripts() after region crossing / teleport --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 22248af..19329a8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2495,6 +2495,8 @@ namespace OpenSim.Region.Framework.Scenes newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1); + newObject.ResumeScripts(); + // Do this as late as possible so that listeners have full access to the incoming object EventManager.TriggerOnIncomingSceneObject(newObject); -- cgit v1.1 From 4921d5ac2dc1f439b7820a22c89fd8239ff33bbc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 8 Jun 2010 22:03:08 +0200 Subject: Make the text mode remote console really work. It can now be used to send multi-word commands with proper quoting, handles arguments with spaces and allows interactive use, e.g. user creation. --- OpenSim/ConsoleClient/ConsoleClient.cs | 38 +++++++++++++++++++++++------- OpenSim/Framework/Console/RemoteConsole.cs | 36 +++++++++++++++++----------- OpenSim/Server/Base/ServicesServerBase.cs | 5 ++++ 3 files changed, 57 insertions(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/ConsoleClient/ConsoleClient.cs b/OpenSim/ConsoleClient/ConsoleClient.cs index 8c616e0..f4605da 100644 --- a/OpenSim/ConsoleClient/ConsoleClient.cs +++ b/OpenSim/ConsoleClient/ConsoleClient.cs @@ -29,6 +29,7 @@ using Nini.Config; using log4net; using System.Reflection; using System; +using System.IO; using System.Xml; using System.Collections.Generic; using OpenSim.Server.Base; @@ -73,9 +74,18 @@ namespace OpenSim.ConsoleClient Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/StartSession/", String.Format("USER={0}&PASS={1}", m_User, m_Pass), LoginReply); - int res = m_Server.Run(); + string pidFile = serverConfig.GetString("PIDFile", String.Empty); - Environment.Exit(res); + while (m_Server.Running) + { + System.Threading.Thread.Sleep(500); + // MainConsole.Instance.Prompt(); + } + + if (pidFile != String.Empty) + File.Delete(pidFile); + + Environment.Exit(0); return 0; } @@ -83,13 +93,14 @@ namespace OpenSim.ConsoleClient private static void SendCommand(string module, string[] cmd) { string sendCmd = ""; + string[] cmdlist = new string[cmd.Length - 1]; + + sendCmd = cmd[0]; + if (cmd.Length > 1) { - sendCmd = cmd[0]; - - Array.Copy(cmd, 1, cmd, 0, cmd.Length-1); - Array.Resize(ref cmd, cmd.Length-1); - sendCmd += "\"" + String.Join("\" \"", cmd) + "\""; + Array.Copy(cmd, 1, cmdlist, 0, cmd.Length - 1); + sendCmd += " \"" + String.Join("\" \"", cmdlist) + "\""; } Requester.MakeRequest("http://"+m_Host+":"+m_Port.ToString()+"/SessionCommand/", String.Format("ID={0}&COMMAND={1}", m_SessionID, sendCmd), CommandReply); @@ -183,16 +194,27 @@ namespace OpenSim.ConsoleClient while (lines.Count > 100) lines.RemoveAt(0); + string prompt = String.Empty; + foreach (string l in lines) { string[] parts = l.Split(new char[] {':'}, 3); if (parts.Length != 3) continue; - MainConsole.Instance.Output(parts[2].Trim(), parts[1]); + if (parts[2].StartsWith("+++") || parts[2].StartsWith("-++")) + prompt = parts[2]; + else + MainConsole.Instance.Output(parts[2].Trim(), parts[1]); } + Requester.MakeRequest(requestUrl, requestData, ReadResponses); + + if (prompt.StartsWith("+++")) + MainConsole.Instance.ReadLine(prompt.Substring(3), true, true); + else if (prompt.StartsWith("-++")) + SendCommand(String.Empty, new string[] { MainConsole.Instance.ReadLine(prompt.Substring(3), false, true) }); } public static void CommandReply(string requestUrl, string requestData, string replyData) diff --git a/OpenSim/Framework/Console/RemoteConsole.cs b/OpenSim/Framework/Console/RemoteConsole.cs index 6f8348d..a46a6cb 100644 --- a/OpenSim/Framework/Console/RemoteConsole.cs +++ b/OpenSim/Framework/Console/RemoteConsole.cs @@ -106,8 +106,15 @@ namespace OpenSim.Framework.Console public override string ReadLine(string p, bool isCommand, bool e) { + if (isCommand) + Output("+++"+p); + else + Output("-++"+p); + m_DataEvent.WaitOne(); + string cmdinput; + lock (m_InputData) { if (m_InputData.Count == 0) @@ -116,29 +123,30 @@ namespace OpenSim.Framework.Console return ""; } - string cmdinput = m_InputData[0]; + cmdinput = m_InputData[0]; m_InputData.RemoveAt(0); if (m_InputData.Count == 0) m_DataEvent.Reset(); - if (isCommand) + } + + if (isCommand) + { + string[] cmd = Commands.Resolve(Parser.Parse(cmdinput)); + + if (cmd.Length != 0) { - string[] cmd = Commands.Resolve(Parser.Parse(cmdinput)); + int i; - if (cmd.Length != 0) + for (i=0 ; i < cmd.Length ; i++) { - int i; - - for (i=0 ; i < cmd.Length ; i++) - { - if (cmd[i].Contains(" ")) - cmd[i] = "\"" + cmd[i] + "\""; - } - return String.Empty; + if (cmd[i].Contains(" ")) + cmd[i] = "\"" + cmd[i] + "\""; } + return String.Empty; } - return cmdinput; } + return cmdinput; } private void DoExpire() @@ -308,7 +316,7 @@ namespace OpenSim.Framework.Console return reply; } - if (post["COMMAND"] == null || post["COMMAND"].ToString() == String.Empty) + if (post["COMMAND"] == null) return reply; lock (m_InputData) diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 63ba673..a5bebb8 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -236,6 +236,11 @@ namespace OpenSim.Server.Base Initialise(); } + public bool Running + { + get { return m_Running; } + } + public virtual int Run() { while (m_Running) -- cgit v1.1 From 6e2cc98eacf48a24ae19433a3f6c2ba9693c5b9e Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 8 Jun 2010 16:15:16 -0400 Subject: Fixed llMoveToTarget() and Rotation Lock/Enable (ChODE/ODEPrim only) --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 230 ++++++++++++++++++++------ 1 file changed, 179 insertions(+), 51 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index fbe52c8..7ce01dc 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -64,11 +64,16 @@ namespace OpenSim.Region.Physics.OdePlugin private Vector3 m_taintVelocity; private Vector3 m_taintTorque; private Quaternion m_taintrot; - private Vector3 m_angularEnable = Vector3.One; // Current setting - private Vector3 m_taintAngularLock = Vector3.One; // Request from LSL - - + private Vector3 m_rotateEnable = Vector3.One; // Current setting + private Vector3 m_rotateEnableRequest = Vector3.One; // Request from LSL + private bool m_rotateEnableUpdate = false; + private Vector3 m_lockX; + private Vector3 m_lockY; + private Vector3 m_lockZ; private IntPtr Amotor = IntPtr.Zero; + private IntPtr AmotorX = IntPtr.Zero; + private IntPtr AmotorY = IntPtr.Zero; + private IntPtr AmotorZ = IntPtr.Zero; private Vector3 m_PIDTarget; private float m_PIDTau; @@ -729,7 +734,12 @@ namespace OpenSim.Region.Physics.OdePlugin public override float Buoyancy { get { return m_buoyancy; } - set { m_buoyancy = value; } +// set { m_buoyancy = value; } + set { + m_buoyancy = value; + + Console.WriteLine("m_buoyancy={0}", m_buoyancy); + } } public override void link(PhysicsActor obj) @@ -744,14 +754,18 @@ namespace OpenSim.Region.Physics.OdePlugin public override void LockAngularMotion(Vector3 axis) { - // reverse the zero/non zero values for ODE. + // This is actually ROTATION ENABLE, not a lock. + // default is <1,1,1> which is all enabled. + // The lock value is updated inside Move(), no point in using the taint system. + // OS 'm_taintAngularLock' etc change to m_rotateEnable. if (axis.IsFinite()) { axis.X = (axis.X > 0) ? 1f : 0f; axis.Y = (axis.Y > 0) ? 1f : 0f; axis.Z = (axis.Z > 0) ? 1f : 0f; m_log.DebugFormat("[axislock]: <{0},{1},{2}>", axis.X, axis.Y, axis.Z); - m_taintAngularLock = axis; + m_rotateEnableRequest = axis; + m_rotateEnableUpdate = true; } else { @@ -1391,10 +1405,10 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_taintCollidesWater != m_collidesWater) changefloatonwater(timestep); - - if (!m_angularEnable.ApproxEquals(m_taintAngularLock,0f)) +/* obsolete + if (!m_angularLock.ApproxEquals(m_taintAngularLock,0f)) changeAngularLock(timestep); - + */ } else { @@ -1402,15 +1416,16 @@ namespace OpenSim.Region.Physics.OdePlugin } } - +/* obsolete private void changeAngularLock(float timestep) { if (_parent == null) { - m_angularEnable = m_taintAngularLock; + m_angularLock = m_taintAngularLock; + m_angularLockSet = true; } } - + */ private void changelink(float timestep) { // If the newly set parent is not null @@ -2991,7 +3006,7 @@ Console.WriteLine(" JointCreateFixed"); if (fence == 1) border_limit = 0.5f; // bounce point frcount++; // used to limit debug comment output - if (frcount > 10) + if (frcount > 50) frcount = 0; if(revcount > 0) revcount--; @@ -3200,8 +3215,91 @@ Console.WriteLine(" JointCreateFixed"); } m_lastposition = l_position; - /// End UpdatePositionAndVelocity insert - + /// End UpdatePositionAndVelocity insert + + + // Rotation lock ===================================== + if(m_rotateEnableUpdate) + { + // Snapshot current angles, set up Amotor(s) + m_rotateEnableUpdate = false; + m_rotateEnable = m_rotateEnableRequest; +Console.WriteLine("RotEnable {0} = {1}",m_primName, m_rotateEnable); + + if (Amotor != IntPtr.Zero) + { + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; +Console.WriteLine("Old Amotor Destroyed"); + } + + if (!m_rotateEnable.ApproxEquals(Vector3.One, 0.003f)) + { // not all are enabled + d.Quaternion r = d.BodyGetQuaternion(Body); + Quaternion locrot = new Quaternion(r.X, r.Y, r.Z, r.W); + // extract the axes vectors + Vector3 vX = new Vector3(1f,0f,0f); + Vector3 vY = new Vector3(0f,1f,0f); + Vector3 vZ = new Vector3(0f,0f,1f); + vX = vX * locrot; + vY = vY * locrot; + vZ = vZ * locrot; + // snapshot the current angle vectors + m_lockX = vX; + m_lockY = vY; + m_lockZ = vZ; + // m_lockRot = locrot; + Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); + d.JointAttach(Amotor, Body, IntPtr.Zero); + d.JointSetAMotorMode(Amotor, 0); // User mode?? +Console.WriteLine("New Amotor Created for {0}", m_primName); + + float axisnum = 3; // how many to lock + axisnum = (axisnum - (m_rotateEnable.X + m_rotateEnable.Y + m_rotateEnable.Z)); + d.JointSetAMotorNumAxes(Amotor,(int)axisnum); +Console.WriteLine("AxisNum={0}",(int)axisnum); + + int i = 0; + + if (m_rotateEnable.X == 0) + { + d.JointSetAMotorAxis(Amotor, i, 0, m_lockX.X, m_lockX.Y, m_lockX.Z); +Console.WriteLine("AxisX {0} set to {1}", i, m_lockX); + i++; + } + + if (m_rotateEnable.Y == 0) + { + d.JointSetAMotorAxis(Amotor, i, 0, m_lockY.X, m_lockY.Y, m_lockY.Z); +Console.WriteLine("AxisY {0} set to {1}", i, m_lockY); + i++; + } + + if (m_rotateEnable.Z == 0) + { + d.JointSetAMotorAxis(Amotor, i, 0, m_lockZ.X, m_lockZ.Y, m_lockZ.Z); +Console.WriteLine("AxisZ {0} set to {1}", i, m_lockZ); + i++; + } + + // These lowstops and high stops are effectively (no wiggle room) + d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0f); + d.JointSetAMotorParam(Amotor, (int) dParam.Vel, 0f); + d.JointSetAMotorParam(Amotor, (int) dParam.Vel3, 0f); + d.JointSetAMotorParam(Amotor, (int) dParam.Vel2, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM3, 0f); + d.JointSetAMotorParam(Amotor, (int)dParam.StopCFM2, 0f); + } // else none are locked + } // end Rotation Update + + + // VEHICLE processing ========================================== if (m_type != Vehicle.TYPE_NONE) { // get body attitude @@ -3420,7 +3518,7 @@ Console.WriteLine(" JointCreateFixed"); //if(frcount == 0) Console.WriteLine("V3 = {0}", angObjectVel); - // Rotation Axis Disables: + /* // Rotation Axis Disables: if (!m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) { if (m_angularEnable.X == 0) @@ -3430,7 +3528,7 @@ Console.WriteLine(" JointCreateFixed"); if (m_angularEnable.Z == 0) angObjectVel.Z = 0f; } - + */ angObjectVel = angObjectVel * rotq; // ================ Converts to WORLD rotation // Vertical attractor section @@ -3500,35 +3598,58 @@ Console.WriteLine(" JointCreateFixed"); } // end VEHICLES else { + // Dyamics (NON-'VEHICLES') are dealt with here ================================================================ + if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009 - // NON-'VEHICLES' are dealt with here - /// Dynamics Angular Lock ======================================================================== - if (d.BodyIsEnabled(Body) && !m_angularEnable.ApproxEquals(Vector3.One, 0.003f)) - { - d.Vector3 avel2 = d.BodyGetAngularVel(Body); - if (m_angularEnable.X == 0) - avel2.X = 0; - if (m_angularEnable.Y == 0) - avel2.Y = 0; - if (m_angularEnable.Z == 0) - avel2.Z = 0; - d.BodySetAngularVel(Body, avel2.X, avel2.Y, avel2.Z); - } - - - /// Dynamics Buoyancy =============================================================================== + + /// Dynamics Buoyancy //KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle. // m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up // NB Prims in ODE are no subject to global gravity + // This should only affect gravity operations + float m_mass = CalculateMass(); + // calculate z-force due togravity on object. fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass - if (m_usePID) + if ((m_usePID) && (m_PIDTau > 0.0f)) // Dynamics llMoveToTarget. { -//if(frcount == 0) Console.WriteLine("PID " + m_primName); - // KF - this is for object MoveToTarget. - - //if (!d.BodyIsEnabled(Body)) + fz = 0; // llMoveToTarget ignores gravity. + // it also ignores mass of object, and any physical resting on it. + // Vector3 m_PIDTarget is where we are going + // float m_PIDTau is time to get there + fx = 0; + fy = 0; + d.Vector3 pos = d.BodyGetPosition(Body); + Vector3 error = new Vector3( + (m_PIDTarget.X - pos.X), + (m_PIDTarget.Y - pos.Y), + (m_PIDTarget.Z - pos.Z)); + if (error.ApproxEquals(Vector3.Zero,0.01f)) + { // Very close, Jump there and quit move + d.BodySetPosition(Body, m_PIDTarget.X, m_PIDTarget.Y, m_PIDTarget.Z); + _target_velocity = Vector3.Zero; + d.BodySetLinearVel(Body, _target_velocity.X, _target_velocity.Y, _target_velocity.Z); + } + else + { + float scale = 50.0f * timestep / m_PIDTau; + if ((error.ApproxEquals(Vector3.Zero,0.5f)) && (_target_velocity != Vector3.Zero)) + { + // Nearby, quit update of velocity + } + else + { // Far, calc damped velocity + _target_velocity = error * scale; + } + d.BodySetLinearVel(Body, _target_velocity.X, _target_velocity.Y, _target_velocity.Z); + } + } // end PID MoveToTarget + + /* Original OS implementation: Does not work correctly as another phys object resting on THIS object purturbs its position. + This is incorrect behavior. llMoveToTarget must move the Body no matter what phys object is resting on it. + + //if (!d.BodyIsEnabled(Body)) //d.BodySetForce(Body, 0f, 0f, 0f); // no lock; for now it's only called from within Simulate() @@ -3559,6 +3680,7 @@ Console.WriteLine(" JointCreateFixed"); (m_PIDTarget.Z - pos.Z) * ((PID_G - m_PIDTau) * timestep) ); +if(frcount == 0) Console.WriteLine("PID {0} b={1} fz={2} vel={3}", m_primName, m_buoyancy, fz, _target_velocity); // if velocity is zero, use position control; otherwise, velocity control if (_target_velocity.ApproxEquals(Vector3.Zero,0.1f)) @@ -3591,9 +3713,11 @@ Console.WriteLine(" JointCreateFixed"); fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass); } } // end if (m_usePID) - + End of old PID system */ + + /// Dynamics Hover =================================================================================== - // Hover PID Controller needs to be mutually exlusive to MoveTo PID controller + // Hover PID Controller can only run if the PIDcontroller is not in use. if (m_useHoverPID && !m_usePID) { //Console.WriteLine("Hover " + m_primName); @@ -3709,14 +3833,14 @@ Console.WriteLine(" JointCreateFixed"); // d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z); RLAservo = timestep / m_APIDStrength * scaler; rotforce = rotforce * RLAservo * diff_angle ; - + /* if (m_angularEnable.X == 0) rotforce.X = 0; if (m_angularEnable.Y == 0) rotforce.Y = 0; if (m_angularEnable.Z == 0) rotforce.Z = 0; - + */ d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z); //Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo); } @@ -3763,11 +3887,12 @@ Console.WriteLine(" JointCreateFixed"); fy = nmin; d.BodyAddForce(Body, fx, fy, fz); //Console.WriteLine("AddForce " + fx + "," + fy + "," + fz); - } - } - } - else - { // is not physical, or is not a body or is selected + } // end apply forces + } // end Dynamics + +/* obsolete? + else + { // is not physical, or is not a body or is selected // from old UpdatePositionAndVelocity, ... Not a body.. so Make sure the client isn't interpolating _velocity.X = 0; _velocity.Y = 0; @@ -3781,8 +3906,11 @@ Console.WriteLine(" JointCreateFixed"); m_rotationalVelocity.Y = 0; m_rotationalVelocity.Z = 0; _zeroFlag = true; - return; - } - } // end Move() + return; + } + */ + } // end root prims + + } // end Move() } // end class } -- cgit v1.1 From 30d3ea3d4be1bed3001e2bda5890cce183c4f388 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 9 Jun 2010 17:00:24 +0100 Subject: Give attachments the same priority as other avatars in BestAvatarResponsiveness policy --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 4780cdd..7b7677b 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -210,7 +210,10 @@ namespace OpenSim.Region.Framework.Scenes { PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; if (physActor == null || !physActor.IsPhysical) - priority+=100; + priority += 100; + + if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) + priority = 1.0; } return priority; } -- cgit v1.1 From b3cf5ccf6d7fcfa2cb4a1405962b8fba73ae0119 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 11 Jun 2010 17:04:54 +0200 Subject: Clone cmGetAvatarList into osGetAvatarList for more generic use. --- .../Shared/Api/Implementation/OSSL_Api.cs | 27 ++++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs | 1 + .../ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs | 5 ++++ 3 files changed, 33 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index f2a2f32..0e86c86 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2206,5 +2206,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_LSL_Api.SetPrimitiveParamsEx(prim, rules); } + + /// + /// Like osGetAgents but returns enough info for a radar + /// + /// Strided list of the UUID, position and name of each avatar in the region + public LSL_List osGetAvatarList() + { + CheckThreatLevel(ThreatLevel.None, "osGetAvatarList"); + + LSL_List result = new LSL_List(); + World.ForEachScenePresence(delegate (ScenePresence avatar) + { + if (avatar != null && avatar.UUID != m_host.OwnerID) + { + if (avatar.IsChildAgent == false) + { + if (avatar.PhysicsActor != null && avatar.PhysicsActor.Position != null) + { + result.Add(avatar.UUID); + result.Add(avatar.PhysicsActor.Position); + result.Add(avatar.Name); + } + } + } + }); + return result; + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs index 1ab7f10..c8f3623 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs @@ -176,6 +176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces void osCauseDamage(string avatar, double damage); LSL_List osGetPrimitiveParams(LSL_Key prim, LSL_List rules); void osSetPrimitiveParams(LSL_Key prim, LSL_List rules); + LSL_List osGetAvatarList(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs index 7af5d43..6cc5f51 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs @@ -687,5 +687,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { m_OSSL_Functions.osSetPrimitiveParams(prim, rules); } + + public LSL_List osGetAvatarList() + { + return m_OSSL_Functions.osGetAvatarList(); + } } } -- cgit v1.1 From 8d5cec5e0d8edb9fafce4df3235c05dbc46b9240 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 11 Jun 2010 17:08:18 +0200 Subject: Remove cmGetAvatarList() --- .../Shared/Api/Implementation/CM_Api.cs | 25 ---------------------- .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 1 - .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 4 ---- 3 files changed, 30 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 4fb5c95..880ca1b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -113,31 +113,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } /// - /// Like osGetAgents but returns enough info for a radar - /// - /// Strided list of the UUID, position and name of each avatar in the region - public LSL_List cmGetAvatarList() - { - LSL_List result = new LSL_List(); - World.ForEachScenePresence(delegate (ScenePresence avatar) - { - if (avatar != null && avatar.UUID != m_host.OwnerID) - { - if (avatar.IsChildAgent == false) - { - if (avatar.PhysicsActor != null && avatar.PhysicsActor.Position != null) - { - result.Add(avatar.UUID); - result.Add(avatar.PhysicsActor.Position); - result.Add(avatar.Name); - } - } - } - }); - return result; - } - - /// /// Get the current Windlight scene /// /// List of windlight parameters diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs index fba27f9..f13b6e5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs @@ -44,6 +44,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_List cmGetWindlightScene(LSL_List rules); int cmSetWindlightScene(LSL_List rules); int cmSetWindlightSceneTargeted(LSL_List rules, key target); - LSL_List cmGetAvatarList(); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs index aaffbe4..c0edaae 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs @@ -72,9 +72,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target); } - public LSL_List cmGetAvatarList() - { - return m_CM_Functions.cmGetAvatarList(); - } } } -- cgit v1.1 From 97d83c87ec27f355844016281ce1be156fe7cd3f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 11 Jun 2010 17:23:06 +0200 Subject: Rename cm* function set to ls* (for LightShare) --- .../Shared/Api/Implementation/CM_Api.cs | 18 +++++++++--------- .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 6 +++--- .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 21 ++++++++++++++++++--- 3 files changed, 30 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 880ca1b..9a99f5e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -70,7 +70,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_localID = localID; m_itemID = itemID; - if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) + if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) m_CMFunctionsEnabled = true; m_comms = m_ScriptEngine.World.RequestModuleInterface(); @@ -116,11 +116,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// Get the current Windlight scene /// /// List of windlight parameters - public LSL_List cmGetWindlightScene(LSL_List rules) + public LSL_List lsGetWindlightScene(LSL_List rules) { if (!m_CMFunctionsEnabled) { - CMShoutError("Careminster functions are not enabled."); + CMShoutError("LightShare functions are not enabled."); return new LSL_List(); } m_host.AddScriptLPS(1); @@ -440,16 +440,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// /// success: true or false - public int cmSetWindlightScene(LSL_List rules) + public int lsSetWindlightScene(LSL_List rules) { if (!m_CMFunctionsEnabled) { - CMShoutError("Careminster functions are not enabled."); + CMShoutError("LightShare functions are not enabled."); return 0; } if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) { - CMShoutError("cmSetWindlightScene can only be used by estate managers or owners."); + CMShoutError("lsSetWindlightScene can only be used by estate managers or owners."); return 0; } int success = 0; @@ -472,16 +472,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// /// /// success: true or false - public int cmSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) + public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) { if (!m_CMFunctionsEnabled) { - CMShoutError("Careminster functions are not enabled."); + CMShoutError("LightShare functions are not enabled."); return 0; } if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) { - CMShoutError("cmSetWindlightSceneTargeted can only be used by estate managers or owners."); + CMShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); return 0; } int success = 0; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs index f13b6e5..f47ae7d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs @@ -41,8 +41,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces public interface ICM_Api { // Windlight Functions - LSL_List cmGetWindlightScene(LSL_List rules); - int cmSetWindlightScene(LSL_List rules); - int cmSetWindlightSceneTargeted(LSL_List rules, key target); + LSL_List lsGetWindlightScene(LSL_List rules); + int lsSetWindlightScene(LSL_List rules); + int lsSetWindlightSceneTargeted(LSL_List rules, key target); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs index c0edaae..92c3d98 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs @@ -58,19 +58,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_CM_Functions = (ICM_Api)api; } + public LSL_List lsGetWindlightScene(LSL_List rules) + { + return m_CM_Functions.lsGetWindlightScene(rules); + } + + public int lsSetWindlightScene(LSL_List rules) + { + return m_CM_Functions.lsSetWindlightScene(rules); + } + + public int lsSetWindlightSceneTargeted(LSL_List rules, key target) + { + return m_CM_Functions.lsSetWindlightSceneTargeted(rules, target); + } + public LSL_List cmGetWindlightScene(LSL_List rules) { - return m_CM_Functions.cmGetWindlightScene(rules); + return m_CM_Functions.lsGetWindlightScene(rules); } public int cmSetWindlightScene(LSL_List rules) { - return m_CM_Functions.cmSetWindlightScene(rules); + return m_CM_Functions.lsSetWindlightScene(rules); } public int cmSetWindlightSceneTargeted(LSL_List rules, key target) { - return m_CM_Functions.cmSetWindlightSceneTargeted(rules, target); + return m_CM_Functions.lsSetWindlightSceneTargeted(rules, target); } } } -- cgit v1.1 From 10ef80cf153a9fd3d841a47a5033bb3c1344c39d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 11 Jun 2010 17:42:16 +0200 Subject: Rename CM files to LS --- .../Shared/Api/Implementation/CM_Api.cs | 504 --------------------- .../Shared/Api/Implementation/LS_Api.cs | 504 +++++++++++++++++++++ .../ScriptEngine/Shared/Api/Interface/ICM_Api.cs | 48 -- .../ScriptEngine/Shared/Api/Interface/ILS_Api.cs | 48 ++ .../ScriptEngine/Shared/Api/Runtime/CM_Stub.cs | 91 ---- .../ScriptEngine/Shared/Api/Runtime/LS_Stub.cs | 91 ++++ 6 files changed, 643 insertions(+), 643 deletions(-) delete mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs delete mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs delete mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs create mode 100644 OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs deleted file mode 100644 index 9a99f5e..0000000 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ /dev/null @@ -1,504 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.Remoting.Lifetime; -using OpenMetaverse; -using Nini.Config; -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.World.LightShare; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.ScriptEngine.Shared; -using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; -using OpenSim.Region.ScriptEngine.Shared.ScriptBase; -using OpenSim.Region.ScriptEngine.Interfaces; -using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; - -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; - -namespace OpenSim.Region.ScriptEngine.Shared.Api -{ - [Serializable] - public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi - { - internal IScriptEngine m_ScriptEngine; - internal SceneObjectPart m_host; - internal uint m_localID; - internal UUID m_itemID; - internal bool m_CMFunctionsEnabled = false; - internal IScriptModuleComms m_comms = null; - - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) - { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_localID = localID; - m_itemID = itemID; - - if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) - m_CMFunctionsEnabled = true; - - m_comms = m_ScriptEngine.World.RequestModuleInterface(); - if (m_comms == null) - m_CMFunctionsEnabled = false; - } - - public override Object InitializeLifetimeService() - { - ILease lease = (ILease)base.InitializeLifetimeService(); - - if (lease.CurrentState == LeaseState.Initial) - { - lease.InitialLeaseTime = TimeSpan.FromMinutes(0); - // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); - // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); - } - return lease; - } - - public Scene World - { - get { return m_ScriptEngine.World; } - } - - // - //Dumps an error message on the debug console. - // - - internal void CMShoutError(string message) - { - if (message.Length > 1023) - message = message.Substring(0, 1023); - - World.SimChat(Utils.StringToBytes(message), - ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); - - IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); - wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); - } - - /// - /// Get the current Windlight scene - /// - /// List of windlight parameters - public LSL_List lsGetWindlightScene(LSL_List rules) - { - if (!m_CMFunctionsEnabled) - { - CMShoutError("LightShare functions are not enabled."); - return new LSL_List(); - } - m_host.AddScriptLPS(1); - RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_List toadd = new LSL_List(); - - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - toadd.Add(new LSL_Float(wl.blurMultiplier)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - toadd.Add(new LSL_Float(wl.cloudCoverage)); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - toadd.Add(new LSL_Float(wl.cloudScale)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - toadd.Add(new LSL_Float(wl.cloudScrollX)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - toadd.Add(new LSL_Float(wl.cloudScrollY)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - toadd.Add(new LSL_Float(wl.densityMultiplier)); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - toadd.Add(new LSL_Float(wl.distanceMultiplier)); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - toadd.Add(new LSL_Float(wl.eastAngle)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - toadd.Add(new LSL_Float(wl.fresnelOffset)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - toadd.Add(new LSL_Float(wl.fresnelScale)); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - toadd.Add(new LSL_Float(wl.hazeDensity)); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - toadd.Add(new LSL_Float(wl.hazeHorizon)); - break; - case (int)ScriptBaseClass.WL_HORIZON: - toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - toadd.Add(new LSL_Integer(wl.maxAltitude)); - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - toadd.Add(new LSL_Float(wl.refractScaleAbove)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - toadd.Add(new LSL_Float(wl.refractScaleBelow)); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - toadd.Add(new LSL_Float(wl.sceneGamma)); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - toadd.Add(new LSL_Float(wl.starBrightness)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - toadd.Add(new LSL_Float(wl.sunGlowFocus)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - toadd.Add(new LSL_Float(wl.sunGlowSize)); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - toadd.Add(new LSL_Float(wl.underwaterFogModifier)); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); - break; - } - - if (toadd.Length > 0) - { - values.Add(rule); - values.Add(toadd.Data[0]); - } - idx++; - } - - - return values; - - } - - private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) - { - RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_Types.Quaternion iQ; - LSL_Types.Vector3 iV; - switch (rule) - { - case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: - idx++; - wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_AMBIENT: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - idx++; - wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - idx++; - wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - idx++; - wl.cloudScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - idx++; - wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - idx++; - wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - idx++; - wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - idx++; - wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - idx++; - wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - idx++; - wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - idx++; - wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - idx++; - wl.eastAngle = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - idx++; - wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - idx++; - wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - idx++; - wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - idx++; - wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HORIZON: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - idx++; - wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - idx++; - wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - idx++; - iV = rules.GetVector3Item(idx); - wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - idx++; - wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - idx++; - wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - idx++; - wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - idx++; - wl.starBrightness = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - idx++; - wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - idx++; - wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - idx++; - wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - idx++; - iV = rules.GetVector3Item(idx); - wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - idx++; - wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); - break; - } - idx++; - } - return wl; - } - /// - /// Set the current Windlight scene - /// - /// - /// success: true or false - public int lsSetWindlightScene(LSL_List rules) - { - if (!m_CMFunctionsEnabled) - { - CMShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - CMShoutError("lsSetWindlightScene can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; - } - else - { - CMShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - /// - /// Set the current Windlight scene to a target avatar - /// - /// - /// success: true or false - public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) - { - if (!m_CMFunctionsEnabled) - { - CMShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - CMShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); - success = 1; - } - else - { - CMShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - - } -} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs new file mode 100644 index 0000000..fe71ed5 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -0,0 +1,504 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Lifetime; +using OpenMetaverse; +using Nini.Config; +using OpenSim; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.World.LightShare; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Shared.Api +{ + [Serializable] + public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi + { + internal IScriptEngine m_ScriptEngine; + internal SceneObjectPart m_host; + internal uint m_localID; + internal UUID m_itemID; + internal bool m_LSFunctionsEnabled = false; + internal IScriptModuleComms m_comms = null; + + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + { + m_ScriptEngine = ScriptEngine; + m_host = host; + m_localID = localID; + m_itemID = itemID; + + if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) + m_LSFunctionsEnabled = true; + + m_comms = m_ScriptEngine.World.RequestModuleInterface(); + if (m_comms == null) + m_LSFunctionsEnabled = false; + } + + public override Object InitializeLifetimeService() + { + ILease lease = (ILease)base.InitializeLifetimeService(); + + if (lease.CurrentState == LeaseState.Initial) + { + lease.InitialLeaseTime = TimeSpan.FromMinutes(0); + // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); + // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); + } + return lease; + } + + public Scene World + { + get { return m_ScriptEngine.World; } + } + + // + //Dumps an error message on the debug console. + // + + internal void LSShoutError(string message) + { + if (message.Length > 1023) + message = message.Substring(0, 1023); + + World.SimChat(Utils.StringToBytes(message), + ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); + + IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); + wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); + } + + /// + /// Get the current Windlight scene + /// + /// List of windlight parameters + public LSL_List lsGetWindlightScene(LSL_List rules) + { + if (!m_LSFunctionsEnabled) + { + LSShoutError("LightShare functions are not enabled."); + return new LSL_List(); + } + m_host.AddScriptLPS(1); + RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_List toadd = new LSL_List(); + + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + toadd.Add(new LSL_Float(wl.blurMultiplier)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + toadd.Add(new LSL_Float(wl.cloudCoverage)); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + toadd.Add(new LSL_Float(wl.cloudScale)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + toadd.Add(new LSL_Float(wl.cloudScrollX)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + toadd.Add(new LSL_Float(wl.cloudScrollY)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + toadd.Add(new LSL_Float(wl.densityMultiplier)); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + toadd.Add(new LSL_Float(wl.distanceMultiplier)); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + toadd.Add(new LSL_Float(wl.eastAngle)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + toadd.Add(new LSL_Float(wl.fresnelOffset)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + toadd.Add(new LSL_Float(wl.fresnelScale)); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + toadd.Add(new LSL_Float(wl.hazeDensity)); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + toadd.Add(new LSL_Float(wl.hazeHorizon)); + break; + case (int)ScriptBaseClass.WL_HORIZON: + toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + toadd.Add(new LSL_Integer(wl.maxAltitude)); + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + toadd.Add(new LSL_Float(wl.refractScaleAbove)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + toadd.Add(new LSL_Float(wl.refractScaleBelow)); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + toadd.Add(new LSL_Float(wl.sceneGamma)); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + toadd.Add(new LSL_Float(wl.starBrightness)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + toadd.Add(new LSL_Float(wl.sunGlowFocus)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + toadd.Add(new LSL_Float(wl.sunGlowSize)); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + toadd.Add(new LSL_Float(wl.underwaterFogModifier)); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); + break; + } + + if (toadd.Length > 0) + { + values.Add(rule); + values.Add(toadd.Data[0]); + } + idx++; + } + + + return values; + + } + + private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) + { + RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); + + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_Types.Quaternion iQ; + LSL_Types.Vector3 iV; + switch (rule) + { + case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: + idx++; + wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_AMBIENT: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + idx++; + wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + idx++; + wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + idx++; + wl.cloudScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + idx++; + wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + idx++; + wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + idx++; + wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + idx++; + wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + idx++; + wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + idx++; + wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + idx++; + wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + idx++; + wl.eastAngle = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + idx++; + wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + idx++; + wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + idx++; + wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + idx++; + wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HORIZON: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + idx++; + wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + idx++; + wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + idx++; + iV = rules.GetVector3Item(idx); + wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + idx++; + wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + idx++; + wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + idx++; + wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + idx++; + wl.starBrightness = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + idx++; + wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + idx++; + wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + idx++; + wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + idx++; + iV = rules.GetVector3Item(idx); + wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + idx++; + wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); + break; + } + idx++; + } + return wl; + } + /// + /// Set the current Windlight scene + /// + /// + /// success: true or false + public int lsSetWindlightScene(LSL_List rules) + { + if (!m_LSFunctionsEnabled) + { + LSShoutError("LightShare functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (LightShareModule.EnableWindlight) + { + RegionLightShareData wl = getWindlightProfileFromRules(rules); + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + success = 1; + } + else + { + LSShoutError("Windlight module is disabled"); + return 0; + } + return success; + } + /// + /// Set the current Windlight scene to a target avatar + /// + /// + /// success: true or false + public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) + { + if (!m_LSFunctionsEnabled) + { + LSShoutError("LightShare functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (LightShareModule.EnableWindlight) + { + RegionLightShareData wl = getWindlightProfileFromRules(rules); + World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); + success = 1; + } + else + { + LSShoutError("Windlight module is disabled"); + return 0; + } + return success; + } + + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs deleted file mode 100644 index f47ae7d..0000000 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs +++ /dev/null @@ -1,48 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System.Collections; -using OpenSim.Region.ScriptEngine.Interfaces; - -using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; - -namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces -{ - public interface ICM_Api - { - // Windlight Functions - LSL_List lsGetWindlightScene(LSL_List rules); - int lsSetWindlightScene(LSL_List rules); - int lsSetWindlightSceneTargeted(LSL_List rules, key target); - } -} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs new file mode 100644 index 0000000..9aa437b --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILS_Api.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System.Collections; +using OpenSim.Region.ScriptEngine.Interfaces; + +using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; + +namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces +{ + public interface ILS_Api + { + // Windlight Functions + LSL_List lsGetWindlightScene(LSL_List rules); + int lsSetWindlightScene(LSL_List rules); + int lsSetWindlightSceneTargeted(LSL_List rules, key target); + } +} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs deleted file mode 100644 index 92c3d98..0000000 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs +++ /dev/null @@ -1,91 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Runtime.Remoting.Lifetime; -using System.Threading; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.ScriptEngine.Interfaces; -using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; -using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; -using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; - -namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase -{ - public partial class ScriptBaseClass : MarshalByRefObject - { - public ICM_Api m_CM_Functions; - - public void ApiTypeCM(IScriptApi api) - { - if (!(api is ICM_Api)) - return; - - m_CM_Functions = (ICM_Api)api; - } - - public LSL_List lsGetWindlightScene(LSL_List rules) - { - return m_CM_Functions.lsGetWindlightScene(rules); - } - - public int lsSetWindlightScene(LSL_List rules) - { - return m_CM_Functions.lsSetWindlightScene(rules); - } - - public int lsSetWindlightSceneTargeted(LSL_List rules, key target) - { - return m_CM_Functions.lsSetWindlightSceneTargeted(rules, target); - } - - public LSL_List cmGetWindlightScene(LSL_List rules) - { - return m_CM_Functions.lsGetWindlightScene(rules); - } - - public int cmSetWindlightScene(LSL_List rules) - { - return m_CM_Functions.lsSetWindlightScene(rules); - } - - public int cmSetWindlightSceneTargeted(LSL_List rules, key target) - { - return m_CM_Functions.lsSetWindlightSceneTargeted(rules, target); - } - } -} diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs new file mode 100644 index 0000000..8280ca5 --- /dev/null +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs @@ -0,0 +1,91 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Runtime.Remoting.Lifetime; +using System.Threading; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; +using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; +using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; + +namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase +{ + public partial class ScriptBaseClass : MarshalByRefObject + { + public ILS_Api m_LS_Functions; + + public void ApiTypeLS(IScriptApi api) + { + if (!(api is ILS_Api)) + return; + + m_LS_Functions = (ILS_Api)api; + } + + public LSL_List lsGetWindlightScene(LSL_List rules) + { + return m_LS_Functions.lsGetWindlightScene(rules); + } + + public int lsSetWindlightScene(LSL_List rules) + { + return m_LS_Functions.lsSetWindlightScene(rules); + } + + public int lsSetWindlightSceneTargeted(LSL_List rules, key target) + { + return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); + } + + public LSL_List cmGetWindlightScene(LSL_List rules) + { + return m_LS_Functions.lsGetWindlightScene(rules); + } + + public int cmSetWindlightScene(LSL_List rules) + { + return m_LS_Functions.lsSetWindlightScene(rules); + } + + public int cmSetWindlightSceneTargeted(LSL_List rules, key target) + { + return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); + } + } +} -- cgit v1.1 From ef93ac44528f5e3294e1674e33f100b19dee61f0 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 11 Jun 2010 17:48:33 +0200 Subject: Remove the cm* function namespace --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs | 15 --------------- .../OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs index 8280ca5..f8dbe03 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs @@ -72,20 +72,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); } - - public LSL_List cmGetWindlightScene(LSL_List rules) - { - return m_LS_Functions.lsGetWindlightScene(rules); - } - - public int cmSetWindlightScene(LSL_List rules) - { - return m_LS_Functions.lsSetWindlightScene(rules); - } - - public int cmSetWindlightSceneTargeted(LSL_List rules, key target) - { - return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); - } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp index 23138ef..f02d2d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp @@ -18,10 +18,10 @@ - + -- cgit v1.1 From be71a2e5bc321d82b373cd070681b5a6ffddc492 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 11 Jun 2010 17:52:19 +0200 Subject: Revert "Remove the cm* function namespace" This reverts commit ef93ac44528f5e3294e1674e33f100b19dee61f0. --- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs | 15 +++++++++++++++ .../OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs index f8dbe03..8280ca5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs @@ -72,5 +72,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); } + + public LSL_List cmGetWindlightScene(LSL_List rules) + { + return m_LS_Functions.lsGetWindlightScene(rules); + } + + public int cmSetWindlightScene(LSL_List rules) + { + return m_LS_Functions.lsSetWindlightScene(rules); + } + + public int cmSetWindlightSceneTargeted(LSL_List rules, key target) + { + return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp index f02d2d9..23138ef 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp @@ -18,10 +18,10 @@ + - -- cgit v1.1 From 57a60282f5746a3aa73c0cac34059fbdbd319c0c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 12 Jun 2010 06:57:10 +0100 Subject: Don't filre CHANGED_INVENTORY if a prim comes in from storage --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index c4cff12..c3cdca8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -681,7 +681,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (TaskInventoryItem item in items) { m_items.Add(item.ItemID, item); - m_part.TriggerScriptChangedEvent(Changed.INVENTORY); +// m_part.TriggerScriptChangedEvent(Changed.INVENTORY); } m_items.LockItemsForWrite(false); -- cgit v1.1 From e337c9130f8e25f81d9d9c9d98da8dee89f38aeb Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 12 Jun 2010 07:34:22 +0200 Subject: Make local teleports send CHANGED_TELEPORT --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 3 +++ .../Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 266621f..5e2c04c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -180,6 +180,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Teleport(position); + + foreach (SceneObjectGroup grp in sp.Attachments) + sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } else // Another region possibly in another simulator { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp index 23138ef..f02d2d9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OpenSim.Region.ScriptEngine.Shared.Api.Runtime.mdp @@ -18,10 +18,10 @@ - + -- cgit v1.1 From 03a48f87e418e79ca780b29a696e5e878213e7ef Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 12 Jun 2010 08:29:20 +0200 Subject: Preserving the link numbers is a serializer's highest duty. Prevent region crossings from screwing up complex attachments by preserving link numbers. --- .../Framework/Scenes/Serialization/SceneObjectSerializer.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index f7544ac..5bdaa17 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -221,7 +221,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization sr = new StringReader(parts[i].OuterXml); reader = new XmlTextReader(sr); SceneObjectPart part = SceneObjectPart.FromXml(reader); + + int originalLinkNum = part.LinkNum; + sceneObject.AddPart(part); + + // SceneObjectGroup.AddPart() tries to be smart and automatically set the LinkNum. + // We override that here + if (originalLinkNum != 0) + part.LinkNum = originalLinkNum; + part.StoreUndoState(); reader.Close(); sr.Close(); -- cgit v1.1 From 3ea11fe2e6593fe0455a7c5bf842deca307f373e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 12 Jun 2010 04:35:51 -0700 Subject: Get rid of spamming SOG debug message --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 66ad14f..c7d21bb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2230,8 +2230,8 @@ namespace OpenSim.Region.Framework.Scenes /// public void ScheduleGroupForFullUpdate() { - if (IsAttachment) - m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); + //if (IsAttachment) + // m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId); checkAtTargets(); RootPart.ScheduleFullUpdate(); -- cgit v1.1 From f59e272643a92b20e7f7eb97f54a30c8b045725d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 13 Jun 2010 22:21:05 +0200 Subject: Introduce SOP.UpdateSitters() to update sitting avatars' chat position if needed --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 9 +++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 ++++++++ 2 files changed, 17 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c7d21bb..6f68029 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2174,6 +2174,7 @@ namespace OpenSim.Region.Framework.Scenes { m_rootPart.UpdateFlag = 1; lastPhysGroupPos = AbsolutePosition; + UpdateSitters(); } if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) @@ -3832,6 +3833,14 @@ namespace OpenSim.Region.Framework.Scenes } } + private void UpdateSitters() + { + foreach (SceneObjectPart part in Children.Values) + { + part.UpdateSitter(); + } + } + public override string ToString() { return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e4a36ef..705e0a3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4720,5 +4720,13 @@ namespace OpenSim.Region.Framework.Scenes Inventory.UpdateInventoryItem(item); } } + + public void UpdateSitter() + { + if (m_sitTargetAvatar != UUID.Zero) + return; + + // Update sitting avatar chat position + } } } -- cgit v1.1 From 3d319d6c3ff2bded0f4b6c730f227a490dd2fb2e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 13 Jun 2010 22:23:07 +0200 Subject: Actually update the SP. EXPERIMENTAL --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 705e0a3..a83119e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4726,7 +4726,13 @@ namespace OpenSim.Region.Framework.Scenes if (m_sitTargetAvatar != UUID.Zero) return; + ScenePresence p = m_parentGroup.Scene.GetScenePresence(m_sitTargetAvatar); + if (p == null) + return; + // Update sitting avatar chat position + + p.AbsolutePosition = AbsolutePosition; } } } -- cgit v1.1 From 520b0e131c43e97d4a08c8ed93a32228ab61a99e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 13 Jun 2010 22:37:11 +0200 Subject: Try to make prims stop moving. Reset velocity, etc, unconditionally. Although the phys actor may be new, the prim fields could still be set and the slimupdates system would continue sending that data out. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index a83119e..be2bbc5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1738,7 +1738,7 @@ namespace OpenSim.Region.Framework.Scenes // which stops client-side interpolation of deactivated joint proxy objects. } - if (!UsePhysics && !isNew) + if (!UsePhysics) { // reset velocity to 0 on physics switch-off. Without that, the client thinks the // prim still has velocity and continues to interpolate its position along the old -- cgit v1.1 From 305876180690e5c236d6bda60a6173a16ad5edc8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 13 Jun 2010 22:43:14 +0200 Subject: D.U.H. un-reverse a reversed condition --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index be2bbc5..c3e87b7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4723,7 +4723,7 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateSitter() { - if (m_sitTargetAvatar != UUID.Zero) + if (m_sitTargetAvatar == UUID.Zero) return; ScenePresence p = m_parentGroup.Scene.GetScenePresence(m_sitTargetAvatar); -- cgit v1.1 From d520360cb83bb3f7733228ff74cf083b0855b261 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 13 Jun 2010 23:01:15 +0200 Subject: Try it witht he root prim --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c3e87b7..68681c9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4732,7 +4732,7 @@ namespace OpenSim.Region.Framework.Scenes // Update sitting avatar chat position - p.AbsolutePosition = AbsolutePosition; + p.AbsolutePosition = GroupPosition; } } } -- cgit v1.1 From 62763cc0fb80caae199ea03d2cb8d031924c111e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 14 Jun 2010 00:02:17 +0200 Subject: Report current position instead of position at the time we sat down --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 68681c9..91b7d35 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4732,7 +4732,7 @@ namespace OpenSim.Region.Framework.Scenes // Update sitting avatar chat position - p.AbsolutePosition = GroupPosition; + p.AbsolutePosition = GroupPosition + OffsetPosition + m_sitTargetPosition; } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b6f67f7..7a7816a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -466,6 +466,13 @@ namespace OpenSim.Region.Framework.Scenes if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! m_pos = actor.Position; + // If we're sitting, we need to update our position + if (m_parentID == 0) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); + m_parentPosition = part.AbsolutePosition; + } + return m_parentPosition + m_pos; } set -- cgit v1.1 From 093cc047cd42f4cc3d59f365aa70cc196855e83f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 14 Jun 2010 00:03:43 +0200 Subject: Revert "Try it witht he root prim" This reverts commit d520360cb83bb3f7733228ff74cf083b0855b261. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 91b7d35..c3e87b7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4732,7 +4732,7 @@ namespace OpenSim.Region.Framework.Scenes // Update sitting avatar chat position - p.AbsolutePosition = GroupPosition + OffsetPosition + m_sitTargetPosition; + p.AbsolutePosition = AbsolutePosition; } } } -- cgit v1.1 From 5fda89fdb5ca6569239412b7b2d38163b8b3b5ab Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 14 Jun 2010 00:04:02 +0200 Subject: Revert "D.U.H." This reverts commit 305876180690e5c236d6bda60a6173a16ad5edc8. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index c3e87b7..be2bbc5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4723,7 +4723,7 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateSitter() { - if (m_sitTargetAvatar == UUID.Zero) + if (m_sitTargetAvatar != UUID.Zero) return; ScenePresence p = m_parentGroup.Scene.GetScenePresence(m_sitTargetAvatar); -- cgit v1.1 From f9b4f5f594caf609d255c585c4224f0455403908 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 14 Jun 2010 00:05:01 +0200 Subject: Revert "Introduce SOP.UpdateSitters() to update sitting avatars' chat position if" This reverts commit f59e272643a92b20e7f7eb97f54a30c8b045725d. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 9 --------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 14 -------------- 2 files changed, 23 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 6f68029..c7d21bb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -2174,7 +2174,6 @@ namespace OpenSim.Region.Framework.Scenes { m_rootPart.UpdateFlag = 1; lastPhysGroupPos = AbsolutePosition; - UpdateSitters(); } if (UsePhysics && !GroupRotation.ApproxEquals(lastPhysGroupRot, 0.1f)) @@ -3833,14 +3832,6 @@ namespace OpenSim.Region.Framework.Scenes } } - private void UpdateSitters() - { - foreach (SceneObjectPart part in Children.Values) - { - part.UpdateSitter(); - } - } - public override string ToString() { return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index be2bbc5..b80a557 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4720,19 +4720,5 @@ namespace OpenSim.Region.Framework.Scenes Inventory.UpdateInventoryItem(item); } } - - public void UpdateSitter() - { - if (m_sitTargetAvatar != UUID.Zero) - return; - - ScenePresence p = m_parentGroup.Scene.GetScenePresence(m_sitTargetAvatar); - if (p == null) - return; - - // Update sitting avatar chat position - - p.AbsolutePosition = AbsolutePosition; - } } } -- cgit v1.1 From 1532dbca0ae54ee6427153d7beec95b8cb52e1e3 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 14 Jun 2010 00:12:39 +0200 Subject: Guard against a potential nullref --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 7a7816a..9c507c2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -470,7 +470,8 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentID == 0) { SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); - m_parentPosition = part.AbsolutePosition; + if (part != null) + m_parentPosition = part.AbsolutePosition; } return m_parentPosition + m_pos; -- cgit v1.1 From 9b30f446729e16c165551ecf0756dedb85d8b269 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 14 Jun 2010 02:28:31 +0200 Subject: D.U.H. #2. Inverted test. Again. Argh! --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9c507c2..6d2cd88 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -467,7 +467,7 @@ namespace OpenSim.Region.Framework.Scenes m_pos = actor.Position; // If we're sitting, we need to update our position - if (m_parentID == 0) + if (m_parentID != 0) { SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); if (part != null) -- cgit v1.1 From 704da8c8238835c63e8ca560fc7778603e9f6795 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 14 Jun 2010 04:03:54 -0700 Subject: osGetAvatarList: Use AbsolutePosition instead of the position of the physics actor, or the avatar disappears when they sit down. --- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 0e86c86..db43902 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2222,12 +2222,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (avatar.IsChildAgent == false) { - if (avatar.PhysicsActor != null && avatar.PhysicsActor.Position != null) - { - result.Add(avatar.UUID); - result.Add(avatar.PhysicsActor.Position); - result.Add(avatar.Name); - } + result.Add(avatar.UUID); + result.Add(avatar.AbsolutePosition); + result.Add(avatar.Name); } } }); -- cgit v1.1 From ef1496ca2d22ad3d24bc9b53830a49f5a9c550d8 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 14 Jun 2010 04:28:38 -0700 Subject: Add "alert dialog" for sending dialogs to users from the console --- OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index b5c3176..4e36c5d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -55,6 +55,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog m_scene.AddCommand( this, "alert general", "alert general ", "Send an alert to everyone", HandleAlertConsoleCommand); + + m_scene.AddCommand( + this, "alert dialog", "alert dialog ", "Send a dialog alert to everyone", HandleAlertConsoleCommand); + + } public void PostInitialise() {} @@ -181,6 +186,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog "[DIALOG]: Sending general alert in region {0} with message {1}", m_scene.RegionInfo.RegionName, message); SendGeneralAlert(message); } + else if (cmdparams[1] == "dialog") + { + string message = CombineParams(cmdparams, 2); + + m_log.InfoFormat( + "[DIALOG]: Sending dialog alert in region {0} with message {1}", m_scene.RegionInfo.RegionName, message); + SendNotificationToUsersInRegion(UUID.Zero, "System", message); + } else { string firstName = cmdparams[1]; -- cgit v1.1 From 117fd629d68ef8ab373b70fd5e9e6a643e8eaa65 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 16 Jun 2010 08:32:47 -0700 Subject: Allow llMapDestination to be used in any event if the host is an attachment. This fixes Mantis 0000098. --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9f3e354..c332fd8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9470,8 +9470,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); - if (detectedParams == null) return; // only works on the first detected avatar - + if (detectedParams == null) + { + if (m_host.IsAttachment == true) + { + detectedParams = new DetectParams(); + detectedParams.Key = m_host.OwnerID; + } + else + { + return; + } + } + ScenePresence avatar = World.GetScenePresence(detectedParams.Key); if (avatar != null) { @@ -9479,6 +9490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); } + ScriptSleep(1000); } -- cgit v1.1 From b9c40320f108a84d7841cdc9e98009cf650f930e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Wed, 16 Jun 2010 09:20:20 -0700 Subject: Fix llAttachToAvatar. This addresses mantis 128 . --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c332fd8..877c3cb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3065,9 +3065,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (m_host.ParentGroup.RootPart.AttachmentPoint == 0) - return; - TaskInventoryItem item; m_host.TaskInventory.LockItemsForRead(true); @@ -3093,11 +3090,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(m_host.OwnerID); + /* IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; if (attachmentsModule != null) + { attachmentsModule.AttachObject( - presence.ControllingClient, grp.LocalId, + presence.ControllingClient, grp.LocalId, (uint)attachment, Quaternion.Identity, Vector3.Zero, false); + } + */ + grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false); } } -- cgit v1.1 From d1c8b083b8d44417d67fb401646eaa7215ff0851 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 17 Jun 2010 04:15:07 -0700 Subject: Fix llRot2Euler with a mathematically sound implementation. The only difference between this an SL is that SL resolves a figure of negative PI into PI, and does the equivalent in the reverse (llEuler2Rot, -1.0 becomes 1.0); --- .../Shared/Api/Implementation/LSL_Api.cs | 46 +++++++++++++--------- 1 file changed, 27 insertions(+), 19 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 877c3cb..fe8c70e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -502,25 +502,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return remainder; } - // Old implementation of llRot2Euler, now normalized - - public LSL_Vector llRot2Euler(LSL_Rotation r) - { - m_host.AddScriptLPS(1); - //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke - LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); - double m = (t.x + t.y + t.z + t.s); - if (m == 0) return new LSL_Vector(); - double n = 2 * (r.y * r.s + r.x * r.z); - double p = m * m - n * n; - if (p > 0) - return new LSL_Vector(NormalizeAngle(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s))), - NormalizeAngle(Math.Atan2(n, Math.Sqrt(p))), - NormalizeAngle(Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s)))); - else if (n > 0) - return new LSL_Vector(0.0, Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); - else - return new LSL_Vector(0.0, -Math.PI * 0.5, NormalizeAngle(Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z))); + public LSL_Vector llRot2Euler(LSL_Rotation q1) + { + m_host.AddScriptLPS(1); + LSL_Vector eul = new LSL_Vector(); + + double sqw = q1.s*q1.s; + double sqx = q1.x*q1.x; + double sqy = q1.z*q1.z; + double sqz = q1.y*q1.y; + double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor + double test = q1.x*q1.z + q1.y*q1.s; + if (test > 0.4999*unit) { // singularity at north pole + eul.z = 2 * Math.Atan2(q1.x,q1.s); + eul.y = Math.PI/2; + eul.x = 0; + return eul; + } + if (test < -0.4999*unit) { // singularity at south pole + eul.z = -2 * Math.Atan2(q1.x,q1.s); + eul.y = -Math.PI/2; + eul.x = 0; + return eul; + } + eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw); + eul.y = Math.Asin(2*test/unit); + eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw); + return eul; } /* From wiki: -- cgit v1.1 From 958c6c6fde45e41433452f44bf8e2e925153a24d Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 17 Jun 2010 13:04:18 -0400 Subject: Add rez on water surface. --- OpenSim/Region/Framework/Scenes/Scene.cs | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b58bfb8..a88b87f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1967,14 +1967,24 @@ namespace OpenSim.Region.Framework.Scenes /// public Vector3 GetNewRezLocation(Vector3 RayStart, Vector3 RayEnd, UUID RayTargetID, Quaternion rot, byte bypassRayCast, byte RayEndIsIntersection, bool frontFacesOnly, Vector3 scale, bool FaceCenter) { + + float wheight = (float)RegionInfo.RegionSettings.WaterHeight; + Vector3 wpos = Vector3.Zero; + // Check for water surface intersection from above + if ( (RayStart.Z > wheight) && (RayEnd.Z < wheight) ) + { + float ratio = (RayStart.Z - wheight) / (RayStart.Z - RayEnd.Z); + wpos.X = RayStart.X - (ratio * (RayStart.X - RayEnd.X)); + wpos.Y = RayStart.Y - (ratio * (RayStart.Y - RayEnd.Y)); + wpos.Z = wheight; + } + Vector3 pos = Vector3.Zero; if (RayEndIsIntersection == (byte)1) { pos = RayEnd; - return pos; } - - if (RayTargetID != UUID.Zero) + else if (RayTargetID != UUID.Zero) { SceneObjectPart target = GetSceneObjectPart(RayTargetID); @@ -1996,7 +2006,7 @@ namespace OpenSim.Region.Framework.Scenes EntityIntersection ei = target.TestIntersectionOBB(NewRay, Quaternion.Identity, frontFacesOnly, FaceCenter); // Un-comment out the following line to Get Raytrace results printed to the console. - // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); + // m_log.Info("[RAYTRACERESULTS]: Hit:" + ei.HitTF.ToString() + " Point: " + ei.ipoint.ToString() + " Normal: " + ei.normal.ToString()); float ScaleOffset = 0.5f; // If we hit something @@ -2019,13 +2029,10 @@ namespace OpenSim.Region.Framework.Scenes //pos.Z -= 0.25F; } - - return pos; } else { // We don't have a target here, so we're going to raytrace all the objects in the scene. - EntityIntersection ei = m_sceneGraph.GetClosestIntersectingPrim(new Ray(AXOrigin, AXdirection), true, false); // Un-comment the following line to print the raytrace results to the console. @@ -2034,13 +2041,12 @@ namespace OpenSim.Region.Framework.Scenes if (ei.HitTF) { pos = new Vector3(ei.ipoint.X, ei.ipoint.Y, ei.ipoint.Z); - } else + } + else { // fall back to our stupid functionality pos = RayEnd; } - - return pos; } } else @@ -2051,8 +2057,12 @@ namespace OpenSim.Region.Framework.Scenes //increase height so its above the ground. //should be getting the normal of the ground at the rez point and using that? pos.Z += scale.Z / 2f; - return pos; +// return pos; } + + // check against posible water intercept + if (wpos.Z > pos.Z) pos = wpos; + return pos; } -- cgit v1.1 From 6d8da699b275cf9a52214de3b22256533b7bb784 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 19 Jun 2010 07:00:01 -0700 Subject: Add "AvatarHeight/2" to the Home Position when set to avoid having the avatar fall through the ground when they TP home. --- OpenSim/Region/Framework/Scenes/Scene.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 97de147..dc58d84 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3235,6 +3235,16 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void SetHomeRezPoint(IClientAPI remoteClient, ulong regionHandle, Vector3 position, Vector3 lookAt, uint flags) { + //Add half the avatar's height so that the user doesn't fall through prims + ScenePresence presence; + if (TryGetScenePresence(remoteClient.AgentId, out presence)) + { + if (presence.Appearance != null) + { + position.Z = position.Z + (presence.Appearance.AvatarHeight / 2); + } + } + if (GridUserService != null && GridUserService.SetHome(remoteClient.AgentId.ToString(), RegionInfo.RegionID, position, lookAt)) // FUBAR ALERT: this needs to be "Home position set." so the viewer saves a home-screenshot. m_dialogModule.SendAlertToUser(remoteClient, "Home position set."); -- cgit v1.1 From 49d7d8534ccd037f4690c5ac6aecd66a460960df Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 19 Jun 2010 10:06:09 -0700 Subject: Allow moving an avatar as part of a linkset using llSetLinkPrimitiveParams. This unlocks an awful lot of poseball-free content, and is a step towards resolving mantis #59. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 56 ++++++++++++- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 39 ++++++++- .../Shared/Api/Implementation/LSL_Api.cs | 97 ++++++++++++++++++++++ 3 files changed, 188 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c7d21bb..3e92954 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -110,8 +110,8 @@ namespace OpenSim.Region.Framework.Scenes private long m_minPersistTime = 0; private Random m_rand; private bool m_suspendUpdates; - - private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); + private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); + private List m_linkedAvatars = new List(); public bool areUpdatesSuspended { @@ -1116,6 +1116,47 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Add the avatar to this linkset (avatar is sat). + /// + /// + public void AddAvatar(UUID agentID) + { + ScenePresence presence; + if (m_scene.TryGetScenePresence(agentID, out presence)) + { + if (!m_linkedAvatars.Contains(presence)) + { + m_linkedAvatars.Add(presence); + } + } + } + + /// + /// Delete the avatar from this linkset (avatar is unsat). + /// + /// + public void DeleteAvatar(UUID agentID) + { + ScenePresence presence; + if (m_scene.TryGetScenePresence(agentID, out presence)) + { + if (m_linkedAvatars.Contains(presence)) + { + m_linkedAvatars.Remove(presence); + } + } + } + + /// + /// Returns the list of linked presences (avatars sat on this group) + /// + /// + public List GetLinkedAvatars() + { + return m_linkedAvatars; + } + + /// /// Attach this scene object to the given avatar. /// /// @@ -2974,6 +3015,17 @@ namespace OpenSim.Region.Framework.Scenes } } + + + /// + /// Gets the number of parts + /// + /// + public int GetPartCount() + { + return Children.Count; + } + /// /// Get the parts of this scene object /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d4fc6cd..76267ab 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -219,6 +219,7 @@ namespace OpenSim.Region.Framework.Scenes //PauPaw:Proper PID Controler for autopilot************ private bool m_moveToPositionInProgress; private Vector3 m_moveToPositionTarget; + private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); private bool m_followCamAuto; @@ -537,10 +538,39 @@ namespace OpenSim.Region.Framework.Scenes } } + public Quaternion OffsetRotation + { + get { return m_offsetRotation; } + set { m_offsetRotation = value; } + } + public Quaternion Rotation { - get { return m_bodyRot; } - set { m_bodyRot = value; } + get { + if (m_parentID != 0) + { + if (m_offsetRotation != null) + { + return m_offsetRotation; + } + else + { + return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + + } + else + { + return m_bodyRot; + } + } + set { + m_bodyRot = value; + if (m_parentID != 0) + { + m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + } } public Quaternion PreviousRotation @@ -1795,6 +1825,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! AbsolutePosition = avWorldStandUp; //KF: Fix stand up. part.IsOccupied = false; + part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); } else { @@ -1804,6 +1835,7 @@ namespace OpenSim.Region.Framework.Scenes m_parentPosition = Vector3.Zero; m_parentID = 0; + m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); SendFullUpdateToAllClients(); m_requestedSitTargetID = 0; @@ -1904,6 +1936,7 @@ namespace OpenSim.Region.Framework.Scenes part.SetAvatarOnSitTarget(UUID); // set that Av will be on it offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one sitOrientation = avSitOrientation; // Change rotatione to the scripted one + OffsetRotation = avSitOrientation; autopilot = false; // Jump direct to scripted llSitPos() } else @@ -2311,6 +2344,7 @@ namespace OpenSim.Region.Framework.Scenes m_bodyRot = sitTargetOrient; m_parentPosition = part.AbsolutePosition; part.IsOccupied = true; + part.ParentGroup.AddAvatar(agentID); Console.WriteLine("Scripted Sit ofset {0}", m_pos); } else @@ -2341,6 +2375,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); m_parentPosition = part.AbsolutePosition; part.IsOccupied = true; + part.ParentGroup.AddAvatar(agentID); m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fe8c70e..61c5add 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -219,6 +219,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } + public List GetLinkAvatars(int linkType) + { + List ret = new List(); + if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted) + return ret; + + List avs = m_host.ParentGroup.GetLinkedAvatars(); + + switch (linkType) + { + case ScriptBaseClass.LINK_SET: + return avs; + + case ScriptBaseClass.LINK_ROOT: + return ret; + + case ScriptBaseClass.LINK_ALL_OTHERS: + return avs; + + case ScriptBaseClass.LINK_ALL_CHILDREN: + return avs; + + case ScriptBaseClass.LINK_THIS: + return ret; + + default: + if (linkType < 0) + return ret; + + int partCount = m_host.ParentGroup.GetPartCount(); + + if (linkType <= partCount) + { + return ret; + } + else + { + linkType = linkType - partCount; + if (linkType > avs.Count) + { + return ret; + } + else + { + ret.Add(avs[linkType-1]); + return ret; + } + } + } + } + public List GetLinkParts(int linkType) { List ret = new List(); @@ -7152,6 +7203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); List parts = GetLinkParts(linknumber); + List avatars = GetLinkAvatars(linknumber); if (parts.Count>0) { try @@ -7165,6 +7217,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api parts[0].ParentGroup.areUpdatesSuspended = false; } } + if (avatars.Count > 0) + { + foreach (ScenePresence avatar in avatars) + SetPrimParams(avatar, rules); + } } public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) @@ -7172,6 +7229,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api llSetLinkPrimitiveParams(linknumber, rules); } + protected void SetPrimParams(ScenePresence av, LSL_List rules) + { + //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset. + //We only support PRIM_POSITION and PRIM_ROTATION + + int idx = 0; + + while (idx < rules.Length) + { + int code = rules.GetLSLIntegerItem(idx++); + + int remain = rules.Length - idx; + + + + switch (code) + { + case (int)ScriptBaseClass.PRIM_POSITION: + if (remain < 1) + return; + LSL_Vector v; + v = rules.GetVector3Item(idx++); + av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); + av.SendFullUpdateToAllClients(); + + break; + + case (int)ScriptBaseClass.PRIM_ROTATION: + if (remain < 1) + return; + LSL_Rotation r; + r = rules.GetQuaternionItem(idx++); + av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); + av.SendFullUpdateToAllClients(); + break; + } + } + + } + protected void SetPrimParams(SceneObjectPart part, LSL_List rules) { if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) -- cgit v1.1 From 76b59b8df776121708b7ff93312c25c341b19ea6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 20 Jun 2010 06:23:08 +0200 Subject: Make dataserver() return a 0 when agent id offline, instead of a timeout --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 61c5add..5c6d382 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4232,22 +4232,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID uuid = (UUID)id; UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); + if (account == null) + return UUID.Zero.ToString(); + PresenceInfo pinfo = null; PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); if (pinfos != null && pinfos.Length > 0) pinfo = pinfos[0]; - if (pinfo == null) - return UUID.Zero.ToString(); - string reply = String.Empty; switch (data) { case 1: // DATA_ONLINE (0|1) - // TODO: implement fetching of this information - if (pinfo != null) + if (pinfo != null && pinfo.RegionID != UUID.Zero) reply = "1"; else reply = "0"; -- cgit v1.1 From 95c763201f6f777557bc1c88e4bcbfbfd0aeebda Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 20 Jun 2010 06:36:46 +0200 Subject: Set the offline flag in inventory offers --- .../CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 2f1e9dd..0d04491 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -241,6 +241,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer im.imSessionID = itemID.Guid; } + im.offline = 1; // Remember these + // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. -- cgit v1.1 From 797767da57be98da24bd91b61eb5b35fc242bb3c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 20 Jun 2010 07:16:19 +0200 Subject: Insert a space after the comma on the ToString methos of lsl vectors and rotations to match SL. --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 1ea52c5..212dbe3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared public override string ToString() { - string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); + string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z); return s; } public static explicit operator LSLString(Vector3 vec) { - string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); + string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z); return new LSLString(s); } public static explicit operator string(Vector3 vec) { - string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); + string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z); return s; } @@ -337,19 +337,19 @@ namespace OpenSim.Region.ScriptEngine.Shared public override string ToString() { - string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); + string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s); return st; } public static explicit operator string(Quaternion r) { - string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); + string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s); return s; } public static explicit operator LSLString(Quaternion r) { - string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); + string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s); return new LSLString(s); } -- cgit v1.1 From 13a0b65a804349e41b8e692727068ac6580c0d35 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 20 Jun 2010 21:38:06 +0200 Subject: Modify avatar responsiveness policy to send roots before children --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 7b7677b..b95b5f2 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -208,12 +208,19 @@ namespace OpenSim.Region.Framework.Scenes if (entity is SceneObjectPart) { - PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; - if (physActor == null || !physActor.IsPhysical) - priority += 100; - if (((SceneObjectPart)entity).ParentGroup.RootPart.IsAttachment) + { priority = 1.0; + } + else + { + PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor; + if (physActor == null || !physActor.IsPhysical) + priority += 100; + } + + if (((SceneObjectPart)entity).ParentGroup.RootPart != (SceneObjectPart)entity) + priority +=1; } return priority; } -- cgit v1.1 From a1416612a9f9e0d5cbe1c1f02d313e9be020226d Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 20 Jun 2010 14:45:04 -0700 Subject: Update all clients sitting on a linkset if a child prim is moved. This prevents avatars being "lost in the void" until they stand up when a child prim is moved that they're sitting on. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b80a557..78faa01 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -711,6 +711,12 @@ namespace OpenSim.Region.Framework.Scenes // Tell the physics engines that this prim changed. m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); } + + List avs = ParentGroup.GetLinkedAvatars(); + foreach (ScenePresence av in avs) + { + av.SendFullUpdateToAllClients(); + } } } } -- cgit v1.1 From fc715a092c9b48ddfbf75eb35e1a052885aecbff Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 20 Jun 2010 15:38:48 -0700 Subject: Fix the sit code to ensure that we use the root prim of a linkset as a reference in the case of an avatar sitting on a child prim. This fixes various camera issues and fixes mantis #0000059. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 76267ab..472c389 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1766,7 +1766,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentID != 0) { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); if (part != null) { part.TaskInventory.LockItemsForRead(true); @@ -2028,7 +2028,9 @@ namespace OpenSim.Region.Framework.Scenes //Console.WriteLine("Camera At ={0}", cameraAtOffset); //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); - ControllingClient.SendSitResponse(part.UUID, offsetr, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child + ControllingClient.SendSitResponse(part.ParentGroup.UUID, offsetr + part.OffsetPosition, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target // This calls HandleAgentSit twice, once from here, and the client calls // HandleAgentSit itself after it gets to the location @@ -2398,7 +2400,17 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); return; } } - m_parentID = m_requestedSitTargetID; + + //We want our offsets to reference the root prim, not the child we may have sat on + if (!part.IsRoot) + { + m_parentID = part.ParentGroup.RootPart.LocalId; + m_pos += part.OffsetPosition; + } + else + { + m_parentID = m_requestedSitTargetID; + } Velocity = Vector3.Zero; RemoveFromPhysicalScene(); -- cgit v1.1 From 9d251b1dc518522979b73fdadc0329067b669149 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 20 Jun 2010 15:57:01 -0700 Subject: Fix the StandUp position to calculate as if we're still using the child prim id. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 472c389..a376ab1 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1822,7 +1822,7 @@ namespace OpenSim.Region.Framework.Scenes //CW: If the part isn't null then we can set the current position if (part != null) { - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! AbsolutePosition = avWorldStandUp; //KF: Fix stand up. part.IsOccupied = false; part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); -- cgit v1.1 From 973537f819c361344273009364b53e73c05e0739 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 21 Jun 2010 17:06:05 +0200 Subject: Ensure no UUID.Zero region ID is ever written to presence. Add a Migration to add a LastSeen field of type "Timestamp" to Presence for MySQL --- OpenSim/Data/MySQL/MySQLPresenceData.cs | 4 +++- OpenSim/Data/MySQL/Resources/Presence.migrations | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index 71caa1a..7b0016b 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -78,6 +78,9 @@ namespace OpenSim.Data.MySQL if (pd.Length == 0) return false; + if (regionID == UUID.Zero) + return; + MySqlCommand cmd = new MySqlCommand(); cmd.CommandText = String.Format("update {0} set RegionID=?RegionID where `SessionID`=?SessionID", m_Realm); @@ -90,6 +93,5 @@ namespace OpenSim.Data.MySQL return true; } - } } diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations index 91f7de5..1075a15 100644 --- a/OpenSim/Data/MySQL/Resources/Presence.migrations +++ b/OpenSim/Data/MySQL/Resources/Presence.migrations @@ -13,3 +13,11 @@ CREATE UNIQUE INDEX SessionID ON Presence(SessionID); CREATE INDEX UserID ON Presence(UserID); COMMIT; + +:VERSION 1 # -------------------------- + +BEGIN; + +ALTER TABLE `Presence` ADD COLUMN LastSeen timestamp; + +COMMIT; -- cgit v1.1 From ab023c6a292cbd014ab5d45b50d481b524c05df3 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 21 Jun 2010 18:06:46 +0200 Subject: Fix build break --- OpenSim/Data/MySQL/MySQLPresenceData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index 7b0016b..9ef880c 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -79,7 +79,7 @@ namespace OpenSim.Data.MySQL return false; if (regionID == UUID.Zero) - return; + return false; MySqlCommand cmd = new MySqlCommand(); -- cgit v1.1 From 53905cf919bc0365ba2f77d1cf0c06d0239c0418 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 21 Jun 2010 22:15:33 +0200 Subject: Bump the migration version, ot it would never happen --- OpenSim/Data/MySQL/Resources/Presence.migrations | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/Resources/Presence.migrations b/OpenSim/Data/MySQL/Resources/Presence.migrations index 1075a15..be4030e 100644 --- a/OpenSim/Data/MySQL/Resources/Presence.migrations +++ b/OpenSim/Data/MySQL/Resources/Presence.migrations @@ -14,7 +14,7 @@ CREATE INDEX UserID ON Presence(UserID); COMMIT; -:VERSION 1 # -------------------------- +:VERSION 2 # -------------------------- BEGIN; -- cgit v1.1 From 3ea4e5ccbe123c2ba6d8c47b7e870bfd90754f20 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 21 Jun 2010 23:26:27 +0200 Subject: Correctly update the LastSeen field --- OpenSim/Data/MySQL/MySQLPresenceData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLPresenceData.cs b/OpenSim/Data/MySQL/MySQLPresenceData.cs index 9ef880c..2390feb 100644 --- a/OpenSim/Data/MySQL/MySQLPresenceData.cs +++ b/OpenSim/Data/MySQL/MySQLPresenceData.cs @@ -83,7 +83,7 @@ namespace OpenSim.Data.MySQL MySqlCommand cmd = new MySqlCommand(); - cmd.CommandText = String.Format("update {0} set RegionID=?RegionID where `SessionID`=?SessionID", m_Realm); + cmd.CommandText = String.Format("update {0} set RegionID=?RegionID, LastSeen=NOW() where `SessionID`=?SessionID", m_Realm); cmd.Parameters.AddWithValue("?SessionID", sessionID.ToString()); cmd.Parameters.AddWithValue("?RegionID", regionID.ToString()); -- cgit v1.1 From 3428196631bb13f04d04208af9fd28a432805ccf Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 22 Jun 2010 02:33:20 +0200 Subject: Guard prioritizer agains null values as those produced by a bullet dying before it can be updated --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index b95b5f2..8cd0160 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -52,6 +52,9 @@ namespace OpenSim.Region.Framework.Scenes public double GetUpdatePriority(IClientAPI client, ISceneEntity entity) { double priority = 0; + + if (entity == null) + return 100000; switch (m_scene.UpdatePrioritizationScheme) { -- cgit v1.1 From 962dade15596d0aeff3baba0b0b85c17524766c6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 22 Jun 2010 04:04:59 +0200 Subject: Cause collisions with the avatar to be sent to attachments. Currently ignores collision filter. Physics collisions are still dodgy, so we don't get the events we should be getting. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 140 +++++++++++++++++++++++ 1 file changed, 140 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a376ab1..654e9ce 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -228,6 +228,7 @@ namespace OpenSim.Region.Framework.Scenes private int m_updateCount = 0; //KF: Update Anims for a while private static readonly int UPDATE_COUNT = 10; // how many frames to update for private const int NumMovementsBetweenRayCast = 5; + private List m_lastColliders = new List(); private bool CameraConstraintActive; //private int m_moveToPositionStateStatus; @@ -3595,6 +3596,145 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); } } + List thisHitColliders = new List(); + List endedColliders = new List(); + List startedColliders = new List(); + + foreach (uint localid in coldata.Keys) + { + thisHitColliders.Add(localid); + if (!m_lastColliders.Contains(localid)) + { + startedColliders.Add(localid); + } + //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); + } + + // calculate things that ended colliding + foreach (uint localID in m_lastColliders) + { + if (!thisHitColliders.Contains(localID)) + { + endedColliders.Add(localID); + } + } + //add the items that started colliding this time to the last colliders list. + foreach (uint localID in startedColliders) + { + m_lastColliders.Add(localID); + } + // remove things that ended colliding from the last colliders list + foreach (uint localID in endedColliders) + { + m_lastColliders.Remove(localID); + } + + // do event notification + if (startedColliders.Count > 0) + { + ColliderArgs StartCollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in startedColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + StartCollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); + } + } + + if (endedColliders.Count > 0) + { + ColliderArgs EndCollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in endedColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + EndCollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); + } + } + + if (thisHitColliders.Count > 0) + { + ColliderArgs CollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in thisHitColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + CollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); + } + } + if (m_invulnerable) return; -- cgit v1.1 From 5c02fb435db171daf6d1ef360340137b3b0fd467 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 22 Jun 2010 17:35:00 +0200 Subject: Security fix: Allow only textures to be fetched using HTTP texture cap --- OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs index f8e3d59..75efb79 100644 --- a/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Assets/GetTextureModule.cs @@ -131,6 +131,12 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps if (texture != null) { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + httpResponse.Send(); + return null; + } SendTexture(httpRequest, httpResponse, texture); } else @@ -147,6 +153,12 @@ namespace OpenSim.Region.CoreModules.Avatar.ObjectCaps if (texture != null) { + if (texture.Type != (sbyte)AssetType.Texture) + { + httpResponse.StatusCode = (int)System.Net.HttpStatusCode.NotFound; + httpResponse.Send(); + return null; + } SendTexture(httpRequest, httpResponse, texture); } else -- cgit v1.1 From e94cf3d9b71206384d33b4cc02fb252dfc93aed7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 24 Jun 2010 03:35:42 +0100 Subject: And another conflict --- .../Region/Framework/Scenes/SceneObjectPartInventory.cs | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 5be71df..2cde8f3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -310,7 +310,6 @@ namespace OpenSim.Region.Framework.Scenes } else { -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs if (m_part.ParentGroup.m_savedScriptState != null) RestoreSavedScriptState(item.OldItemID, item.ItemID); @@ -327,22 +326,6 @@ namespace OpenSim.Region.Framework.Scenes StoreScriptErrors(item.ItemID, null); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); -======= - lock (m_items) - { - if (m_part.ParentGroup.m_savedScriptState != null) - RestoreSavedScriptState(item.OldItemID, item.ItemID); - - m_items[item.ItemID].PermsMask = 0; - m_items[item.ItemID].PermsGranter = UUID.Zero; - - string script = Utils.BytesToString(asset.Data); - m_part.ParentGroup.Scene.EventManager.TriggerRezScript( - m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); - m_part.ParentGroup.AddActiveScriptCount(1); - m_part.ScheduleFullUpdate(); - } ->>>>>>> master:OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs } } } -- cgit v1.1 From 9d03271265684f7724d9a242340ca6942bab3592 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 24 Jun 2010 03:43:50 +0200 Subject: And another --- OpenSim/Region/Application/OpenSimBase.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index ae942f9..27cb137 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -408,8 +408,6 @@ namespace OpenSim scene.SnmpService.BootInfo("ScriptEngine started", scene); } -======= ->>>>>>> master:OpenSim/Region/Application/OpenSimBase.cs m_sceneManager.Add(scene); if (m_autoCreateClientStack) -- cgit v1.1 From 6c37a02c0fee5147437f1b133b3fb7d1c44f89ad Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 24 Jun 2010 06:02:44 +0200 Subject: bug fix. 0,0 is a vlid sim coordinate --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 9d6c9a9..ac8c291 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -656,7 +656,7 @@ namespace OpenSim.Region.CoreModules.World.Land int x; int y; - if (x_float > Constants.RegionSize || x_float <= 0 || y_float > Constants.RegionSize || y_float <= 0) + if (x_float > Constants.RegionSize || x_float < 0 || y_float > Constants.RegionSize || y_float < 0) return null; try -- cgit v1.1 From b012e963d7fac1b877cf1a4738967538f20332b2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 24 Jun 2010 18:48:40 +0200 Subject: New viewers don't set the "save offline IM" flag anymore. Set it serverside so messages get saved --- .../CoreModules/Avatar/InstantMessage/InstantMessageModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index ab141eb..2dc7384 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -156,6 +156,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return; } + if (dialog == (byte)InstantMessageDialog.MessageFromAgent || + dialog == (byte)InstantMessageDialog.MessageFromObject) + { + im.offline = 1; + } + if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, -- cgit v1.1 From 2cc1f14b0c938cff51b7bbf3f13a51b306f87e1b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 24 Jun 2010 19:37:02 +0200 Subject: Replace the imSessionID, which is useless out of context, with the scope id in saved IMs --- .../CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 9412735..5f9f518 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -204,6 +204,13 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if ((im.offline != 0) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { + // It's not delivered. Make sure the scope id is saved + // We don't need the imSessionID here anymore, overwrite it + Scene scene = FindScene(new UUID(im.fromAgentID)); + if (scene == null) + scene = m_SceneList[0]; + im.imSessionID = new Guid(scene.RegionInfo.ScopeID.ToString()); + bool success = SynchronousRestObjectPoster.BeginPostObject( "POST", m_RestURL+"/SaveMessage/", im); -- cgit v1.1 From cbca58401ab67035c8c9aa20a0cf4bccd8cc8bef Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 24 Jun 2010 20:46:24 +0200 Subject: Add the object owner UUID into the binary bucket of object to user IM --- .../Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 2 ++ OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index 5f9f518..a2dc91f 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -201,6 +201,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private void UndeliveredMessage(GridInstantMessage im) { + if (im.dialog == 19) + im.offline = 1; // We want them pushed out to the server if ((im.offline != 0) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7d7320d..0abc828 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3272,7 +3272,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api msg.ParentEstateID = 0; //ParentEstateID; msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; - msg.binaryBucket = new byte[0];// binaryBucket; + msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString()); if (m_TransferModule != null) { -- cgit v1.1 From f186882c0fbe9675a000417e27354e323315de1a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 24 Jun 2010 20:51:04 +0200 Subject: Also make prims send the proper position. I hate it when people comment out things just because they're "not yet used". Grrrr. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0abc828..fb191e6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3266,12 +3266,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api msg.message = message.Substring(0, 1024); else msg.message = message; - msg.dialog = (byte)19; // messgage from script ??? // dialog; + msg.dialog = (byte)19; // MessageFromObject msg.fromGroup = false;// fromGroup; msg.offline = (byte)0; //offline; - msg.ParentEstateID = 0; //ParentEstateID; - msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); - msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; + msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID; + msg.Position = new Vector3(m_host.AbsolutePosition); + msg.RegionID = World.RegionInfo.RegionID.Guid; msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString()); if (m_TransferModule != null) -- cgit v1.1 From 8a0ec60c8f518a4c3bf3e91d02ad75a07ab40b76 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 25 Jun 2010 01:41:00 +0200 Subject: Unhook the dwell request from the land module (and therefore local storage) --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index ac8c291..91c8130 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -168,7 +168,7 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelGodForceOwner += ClientOnParcelGodForceOwner; client.OnParcelReclaim += ClientOnParcelReclaim; client.OnParcelInfoRequest += ClientOnParcelInfoRequest; - client.OnParcelDwellRequest += ClientOnParcelDwellRequest; +// client.OnParcelDwellRequest += ClientOnParcelDwellRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; client.OnPreAgentUpdate += ClientOnPreAgentUpdate; -- cgit v1.1 From afff74a8351586e0e7ecd7dd1cdfde1964830a6b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 25 Jun 2010 01:44:17 +0200 Subject: Add DwellModule interface --- .../Region/Framework/Interfaces/IDwellModule.cs | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 OpenSim/Region/Framework/Interfaces/IDwellModule.cs (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IDwellModule.cs b/OpenSim/Region/Framework/Interfaces/IDwellModule.cs new file mode 100644 index 0000000..db50439 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IDwellModule.cs @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using OpenMetaverse; +using OpenSim.Framework; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IDwellModule + { + int GetDwell(UUID parcelID); + } +} -- cgit v1.1 From 3101d530647cdf401b6078dacf6d7ceb063b049d Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Fri, 25 Jun 2010 05:25:41 -0700 Subject: Make "Allow other residents to edit terrain" default to FALSE --- OpenSim/Framework/LandData.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index 060e886..ef07438 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -62,7 +62,7 @@ namespace OpenSim.Framework private uint _flags = (uint) ParcelFlags.AllowFly | (uint) ParcelFlags.AllowLandmark | (uint) ParcelFlags.AllowAPrimitiveEntry | - (uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.AllowTerraform | + (uint) ParcelFlags.AllowDeedToGroup | (uint) ParcelFlags.CreateObjects | (uint) ParcelFlags.AllowOtherScripts | (uint) ParcelFlags.SoundLocal; -- cgit v1.1 From 96e649189f24b6261d0bcdd6aa7f5a078b8d3f7f Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Fri, 25 Jun 2010 14:25:39 -0700 Subject: Add two events: OnAttachToBackup and OnDetachFromBackup. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 26 ++++++++++++++++++++++ .../Region/Framework/Scenes/SceneObjectGroup.cs | 4 ++++ 2 files changed, 30 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 80f9114..904e38a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -43,6 +43,10 @@ namespace OpenSim.Region.Framework.Scenes public delegate void ObjectDuplicateDelegate(EntityBase original, EntityBase clone); + public delegate void AttachToBackupDelegate(SceneObjectGroup sog); + + public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); + public delegate void ObjectCreateDelegate(EntityBase obj); public delegate void ObjectDeleteDelegate(EntityBase obj); @@ -61,6 +65,8 @@ namespace OpenSim.Region.Framework.Scenes private PhysicsCrash handlerPhysicsCrash = null; public event ObjectDuplicateDelegate OnObjectDuplicate; + public event AttachToBackupDelegate OnAttachToBackup; + public event DetachFromBackupDelegate OnDetachFromBackup; public event ObjectCreateDelegate OnObjectCreate; public event ObjectDeleteDelegate OnObjectRemove; @@ -388,10 +394,14 @@ namespace OpenSim.Region.Framework.Scenes m_numPrim += sceneObject.Children.Count; if (attachToBackup) + { sceneObject.AttachToBackup(); + } if (OnObjectCreate != null) + { OnObjectCreate(sceneObject); + } lock (m_dictionary_lock) { @@ -458,6 +468,22 @@ namespace OpenSim.Region.Framework.Scenes } } + public void FireAttachToBackup(SceneObjectGroup obj) + { + if (OnAttachToBackup != null) + { + OnAttachToBackup(obj); + } + } + + public void FireDetachFromBackup(SceneObjectGroup obj) + { + if (OnDetachFromBackup != null) + { + OnDetachFromBackup(obj); + } + } + /// /// Process all pending updates /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3e92954..e18dfd2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -658,6 +658,8 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void AttachToBackup() { + m_scene.SceneGraph.FireAttachToBackup(this); + if (InSceneBackup) { //m_log.DebugFormat( @@ -2703,6 +2705,8 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void DetachFromBackup() { + m_scene.SceneGraph.FireDetachFromBackup(this); + if (m_isBackedUp) m_scene.EventManager.OnBackup -= ProcessBackup; -- cgit v1.1 From f64d1cb3967b5352921b296348f618a62fdfa622 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Fri, 25 Jun 2010 14:39:15 -0700 Subject: Add new event: OnChangedBackup --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 11 +++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 4 ++++ 2 files changed, 15 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index ce7b0eb..81ef54f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -47,6 +47,8 @@ namespace OpenSim.Region.Framework.Scenes public delegate void DetachFromBackupDelegate(SceneObjectGroup sog); + public delegate void ChangedBackupDelegate(SceneObjectGroup sog); + public delegate void ObjectCreateDelegate(EntityBase obj); public delegate void ObjectDeleteDelegate(EntityBase obj); @@ -67,6 +69,7 @@ namespace OpenSim.Region.Framework.Scenes public event ObjectDuplicateDelegate OnObjectDuplicate; public event AttachToBackupDelegate OnAttachToBackup; public event DetachFromBackupDelegate OnDetachFromBackup; + public event ChangedBackupDelegate OnChangeBackup; public event ObjectCreateDelegate OnObjectCreate; public event ObjectDeleteDelegate OnObjectRemove; @@ -484,6 +487,14 @@ namespace OpenSim.Region.Framework.Scenes } } + public void FireChangeBackup(SceneObjectGroup obj) + { + if (OnChangeBackup != null) + { + OnChangeBackup(obj); + } + } + /// /// Process all pending updates /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index e18dfd2..7081ced 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -200,6 +200,10 @@ namespace OpenSim.Region.Framework.Scenes { if (value) { + if (m_isBackedUp) + { + m_scene.SceneGraph.FireChangeBackup(this); + } timeLastChanged = DateTime.Now.Ticks; if (!m_hasGroupChanged) timeFirstChanged = DateTime.Now.Ticks; -- cgit v1.1 From 6274317e63e18785a2c3d96514ca371e0a04cf71 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 26 Jun 2010 06:16:24 +0200 Subject: Fix loading of attachments on login --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 654e9ce..4a4cac9 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4151,7 +4151,14 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); { m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); stateData = attServ.Get(ControllingClient.AgentId.ToString()); - doc.LoadXml(stateData); + if (stateData != String.Empty) + { + try + { + doc.LoadXml(stateData); + } + catch { } + } } Dictionary itemData = new Dictionary(); -- cgit v1.1 From 70d3b9aecaf5bf2447b43a1359c631eb60ca66aa Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 11:14:58 -0700 Subject: Add a DeleteAllSceneObjects(bool exceptNoCopy) method to allow NoCopy objects to be retained when the scene is cleared. --- OpenSim/Region/Framework/Scenes/Scene.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index dc58d84..c596baa 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2183,6 +2183,14 @@ namespace OpenSim.Region.Framework.Scenes /// public void DeleteAllSceneObjects() { + DeleteAllSceneObjects(false); + } + + /// + /// Delete every object from the scene. This does not include attachments worn by avatars. + /// + public void DeleteAllSceneObjects(bool exceptNoCopy) + { lock (Entities) { ICollection entities = new List(Entities); @@ -2192,8 +2200,13 @@ namespace OpenSim.Region.Framework.Scenes if (e is SceneObjectGroup) { SceneObjectGroup sog = (SceneObjectGroup)e; - if (!sog.IsAttachment) - DeleteSceneObject((SceneObjectGroup)e, false); + if (sog != null && !sog.IsAttachment) + { + if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0)) + { + DeleteSceneObject((SceneObjectGroup)e, false); + } + } } } } -- cgit v1.1 From acab2a159d150072aa9952100aa6722cbd51c1ea Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 11:24:36 -0700 Subject: Return objects which are NoCopy instead of just leaving them when cleaning the scene, if exceptNoCopy = true. --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c596baa..abc7377 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2206,6 +2206,10 @@ namespace OpenSim.Region.Framework.Scenes { DeleteSceneObject((SceneObjectGroup)e, false); } + else + { + DeRezObject(null, sog.RootPart.LocalId, sog.RootPart.GroupID, DeRezAction.Return, UUID.Zero); + } } } } -- cgit v1.1 From bd19cf739a03e255b0bf46021d3fab6ea0148afb Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 12:38:08 -0700 Subject: Fix a bug with DeRezObjects (check for a null remoteClient) --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 5e1798b..83fd349 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1591,15 +1591,17 @@ namespace OpenSim.Region.Framework.Scenes // So that we know the database is upto date, // for when deleting the object from it ForceSceneObjectBackup(grp); + if (remoteClient != null) + { + if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) + permissionToTakeCopy = false; + if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) + permissionToTake = false; - if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) - permissionToTakeCopy = false; - if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) - permissionToTake = false; - - if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) - permissionToDelete = false; + if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) + permissionToDelete = false; + } } // Handle god perms -- cgit v1.1 From ed5dac7e82adfe639a2057ed5d531418277869d7 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 13:06:47 -0700 Subject: Fix another nullref issue in DeRezSceneObject --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 83fd349..0380199 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1605,7 +1605,7 @@ namespace OpenSim.Region.Framework.Scenes } // Handle god perms - if (Permissions.IsGod(remoteClient.AgentId)) + if (remoteClient != null && Permissions.IsGod(remoteClient.AgentId)) { permissionToTake = true; permissionToTakeCopy = true; -- cgit v1.1 From d188ed8ed86661a79b68f5c43ce0a94dc51308f0 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 13:07:17 -0700 Subject: Return everything at once, it's more efficient that way --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index abc7377..bbac919 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2191,6 +2191,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void DeleteAllSceneObjects(bool exceptNoCopy) { + List toReturn = new List(); lock (Entities) { ICollection entities = new List(Entities); @@ -2208,12 +2209,16 @@ namespace OpenSim.Region.Framework.Scenes } else { - DeRezObject(null, sog.RootPart.LocalId, sog.RootPart.GroupID, DeRezAction.Return, UUID.Zero); + toReturn.Add((SceneObjectGroup)e); } } } } } + if (toReturn.Count > 0) + { + returnObjects(toReturn.ToArray(), UUID.Zero); + } } /// -- cgit v1.1 From 8f0adfbfb264532d55c0f0bab5bc508d36ad365e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 15:15:19 -0700 Subject: Trigger the RegionLightShareData OnSave event properly when the profile is saved --- OpenSim/Region/Framework/Scenes/Scene.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index bbac919..c5fb198 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1770,6 +1770,7 @@ namespace OpenSim.Region.Framework.Scenes public void StoreWindlightProfile(RegionLightShareData wl) { m_regInfo.WindlightSettings = wl; + wl.Save(); m_storageManager.DataStore.StoreRegionWindlightSettings(wl); m_eventManager.TriggerOnSaveNewWindlightProfile(); } -- cgit v1.1 From 49272657d7085471b85a4735968495bda31f599f Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 15:30:47 -0700 Subject: Make RegionLightShareData serializable --- OpenSim/Framework/RegionInfo.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index afc4060..2a74e79 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs @@ -40,6 +40,7 @@ using OpenSim.Framework.Console; namespace OpenSim.Framework { + [Serializable] public class RegionLightShareData : ICloneable { public UUID regionID = UUID.Zero; -- cgit v1.1 From c3e806a2eac31c4dde67586f0404c796628ba9ce Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 17:25:45 -0700 Subject: Add a new accessor for the TerainModule : "HasChanged" --- OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 1e7ea7b..5bf1f9c 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -93,6 +93,14 @@ namespace OpenSim.Region.CoreModules.World.Terrain get { return m_commander; } } + public bool HasChanged + { + get + { + return m_tainted; + } + } + #endregion #region INonSharedRegionModule Members -- cgit v1.1 From 3bcee57e3efbd63f392067bff1a01ae51be98d13 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 17:34:19 -0700 Subject: add HasChanged to ITerrainModule --- OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | 7 ++----- OpenSim/Region/Framework/Interfaces/ITerrainModule.cs | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 5bf1f9c..ffd86a4 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -93,12 +93,9 @@ namespace OpenSim.Region.CoreModules.World.Terrain get { return m_commander; } } - public bool HasChanged + public bool HasChanged() { - get - { - return m_tainted; - } + return m_tainted; } #endregion diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs index 5947afb..98996e2 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs @@ -42,7 +42,8 @@ namespace OpenSim.Region.Framework.Interfaces /// Use this if you change terrain data outside of the terrain module (e.g. in osTerrainSetHeight) /// void TaintTerrain(); - + + bool HasChanged(); /// /// Load a terrain from a stream. /// -- cgit v1.1 From c97e9f86219cd79e6fee7266174e78825c405476 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 18:43:01 -0700 Subject: Reverting the ITerrainModule changes. Turns out this was useless. --- OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs | 5 ----- OpenSim/Region/Framework/Interfaces/ITerrainModule.cs | 3 +-- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index ffd86a4..1e7ea7b 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -93,11 +93,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain get { return m_commander; } } - public bool HasChanged() - { - return m_tainted; - } - #endregion #region INonSharedRegionModule Members diff --git a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs index 98996e2..5947afb 100644 --- a/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ITerrainModule.cs @@ -42,8 +42,7 @@ namespace OpenSim.Region.Framework.Interfaces /// Use this if you change terrain data outside of the terrain module (e.g. in osTerrainSetHeight) /// void TaintTerrain(); - - bool HasChanged(); + /// /// Load a terrain from a stream. /// -- cgit v1.1 From 592ff1288dd1fccc1d2efde90e94ca0ab4a57652 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 18:51:19 -0700 Subject: Add a new global event : OnTerrainUpdate --- .../CoreModules/World/Terrain/TerrainModule.cs | 2 ++ OpenSim/Region/Framework/Scenes/EventManager.cs | 24 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs index 1e7ea7b..0c20393 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/TerrainModule.cs @@ -544,6 +544,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain m_scene.PhysicsScene.SetTerrain(m_channel.GetFloatsSerialised()); m_scene.SaveTerrain(); + m_scene.EventManager.TriggerTerrainUpdate(); + // Clients who look at the map will never see changes after they looked at the map, so i've commented this out. //m_scene.CreateTerrainTexture(true); } diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index ef125cd..0c9759d 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -55,8 +55,12 @@ namespace OpenSim.Region.Framework.Scenes public delegate void OnTerrainTickDelegate(); + public delegate void OnTerrainUpdateDelegate(); + public event OnTerrainTickDelegate OnTerrainTick; + public event OnTerrainUpdateDelegate OnTerrainUpdate; + public delegate void OnBackupDelegate(IRegionDataStore datastore, bool forceBackup); public event OnBackupDelegate OnBackup; @@ -716,6 +720,26 @@ namespace OpenSim.Region.Framework.Scenes } } } + public void TriggerTerrainUpdate() + { + OnTerrainUpdateDelegate handlerTerrainUpdate = OnTerrainUpdate; + if (handlerTerrainUpdate != null) + { + foreach (OnTerrainUpdateDelegate d in handlerTerrainUpdate.GetInvocationList()) + { + try + { + d(); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerTerrainUpdate failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } public void TriggerTerrainTick() { -- cgit v1.1 From 9f00f141fe679b13e93240589f7d8b7f519e012b Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 18:54:55 -0700 Subject: Restore "AllowCareminsterFunctions" as an alias to the new "AllowLightshareFunctions". --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index fe71ed5..1fa8c30 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -73,6 +73,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) m_LSFunctionsEnabled = true; + if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) + m_LSFunctionsEnabled = true; + m_comms = m_ScriptEngine.World.RequestModuleInterface(); if (m_comms == null) m_LSFunctionsEnabled = false; -- cgit v1.1 From ef0ac7c4032ebb369479c18a4f2cc432b613234f Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 26 Jun 2010 23:20:28 -0700 Subject: Deal with incoming land objects properly so they don't just stack up --- .../CoreModules/World/Land/LandManagementModule.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 91c8130..cfee1b0 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1303,18 +1303,31 @@ namespace OpenSim.Region.CoreModules.World.Land public void EventManagerOnIncomingLandDataFromStorage(List data) { - for (int i = 0; i < data.Count; i++) + lock (m_landList) { - IncomingLandObjectFromStorage(data[i]); + //Remove all the land objects in the sim and then process our new data + foreach (int n in m_landList.Keys) + { + m_scene.EventManager.TriggerLandObjectRemoved(m_landList[n].LandData.GlobalID); + } + m_landIDList.Initialize(); + m_landList.Clear(); + + for (int i = 0; i < data.Count; i++) + { + IncomingLandObjectFromStorage(data[i]); + } } } public void IncomingLandObjectFromStorage(LandData data) { + ILandObject new_land = new LandObject(data.OwnerID, data.IsGroupOwned, m_scene); new_land.LandData = data.Copy(); new_land.SetLandBitmapFromByteArray(); AddLandObject(new_land); + new_land.SendLandUpdateToAvatarsOverMe(); } public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) -- cgit v1.1 From 19f18c8a1b6377fec44ebd358bb4d810d36bd586 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 27 Jun 2010 21:04:30 +0200 Subject: Make drag copy and copy-on-ray handle friends list perms properly --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 81ef54f..dfcbc4c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1851,6 +1851,28 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup copy = original.Copy(AgentID, GroupID, true); copy.AbsolutePosition = copy.AbsolutePosition + offset; + if (copy.OwnerID != AgentID) + { + copy.SetOwnerId(AgentID); + copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); + + List partList = + new List(copy.Children.Values); + + if (m_parentScene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart child in partList) + { + child.Inventory.ChangeInventoryOwner(AgentID); + child.TriggerScriptChangedEvent(Changed.OWNER); + child.ApplyNextOwnerPermissions(); + } + } + + copy.RootPart.ObjectSaleType = 0; + copy.RootPart.SalePrice = 10; + } + Entities.Add(copy); // Since we copy from a source group that is in selected -- cgit v1.1 From 9c553cd254b5b27f3ddcffddee9684aeb4a6298b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 27 Jun 2010 20:20:08 +0100 Subject: Fix more perms weirdness. Preserve "Locked" status across gives and rez/take. Preserve "Anyone can move" flag in most cases. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 55c1575..6532537 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -402,7 +402,7 @@ namespace OpenSim.Region.Framework.Scenes // First, make sore base is limited to the next perms itemCopy.BasePermissions = item.BasePermissions & (item.NextPermissions | (uint)PermissionMask.Move); // By default, current equals base - itemCopy.CurrentPermissions = itemCopy.BasePermissions; + itemCopy.CurrentPermissions = itemCopy.BasePermissions & item.CurrentPermissions; // If this is an object, replace current perms // with folded perms @@ -413,7 +413,7 @@ namespace OpenSim.Region.Framework.Scenes } // Ensure there is no escalation - itemCopy.CurrentPermissions &= item.NextPermissions; + itemCopy.CurrentPermissions &= (item.NextPermissions | (uint)PermissionMask.Move); // Need slam bit on xfer itemCopy.CurrentPermissions |= 8; @@ -918,12 +918,13 @@ namespace OpenSim.Region.Framework.Scenes { agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); if (taskItem.InvType == (int)InventoryType.Object) - agentItem.CurrentPermissions = agentItem.BasePermissions & ((taskItem.CurrentPermissions & 7) << 13); - agentItem.CurrentPermissions = agentItem.BasePermissions ; + agentItem.CurrentPermissions = agentItem.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move)); + else + agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions; agentItem.CurrentPermissions |= 8; agentItem.NextPermissions = taskItem.NextPermissions; - agentItem.EveryOnePermissions = taskItem.EveryonePermissions & taskItem.NextPermissions; + agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions; } else @@ -1105,11 +1106,11 @@ namespace OpenSim.Region.Framework.Scenes if (Permissions.PropagatePermissions()) { destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions & - srcTaskItem.NextPermissions; + (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions & - srcTaskItem.NextPermissions; + (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions & - srcTaskItem.NextPermissions; + (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.BasePermissions = srcTaskItem.BasePermissions & (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.CurrentPermissions |= 8; // Slam! -- cgit v1.1 From d570cffa39e9ca6417ebd1c05cbdfea1d3beabd2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 28 Jun 2010 01:29:30 +0200 Subject: Fix Copy on Ray, Drag Copy and other little things. Removed the wrong and nonworking ownership assignment in SOG, which messed things up before. No longer trust the client to send the ID of the person something is copied as, since it allows to run a script with someone else's permissions. Properly adjust inventory ownership and perms. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 6 +++--- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 18 ++---------------- 3 files changed, 6 insertions(+), 20 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index f071841..cf1dda9 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -6307,8 +6307,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerObjectDuplicate != null) { handlerObjectDuplicate(dupe.ObjectData[i].ObjectLocalID, dupe.SharedData.Offset, - dupe.SharedData.DuplicateFlags, AgentandGroupData.AgentID, - AgentandGroupData.GroupID); + dupe.SharedData.DuplicateFlags, AgentId, + m_activeGroupID); } } @@ -6898,7 +6898,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (handlerObjectDuplicateOnRay != null) { handlerObjectDuplicateOnRay(dupeOnRay.ObjectData[i].ObjectLocalID, dupeOnRay.AgentData.DuplicateFlags, - dupeOnRay.AgentData.AgentID, dupeOnRay.AgentData.GroupID, dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd, + AgentId, m_activeGroupID, dupeOnRay.AgentData.RayTargetID, dupeOnRay.AgentData.RayEnd, dupeOnRay.AgentData.RayStart, dupeOnRay.AgentData.BypassRaycast, dupeOnRay.AgentData.RayEndIsIntersection, dupeOnRay.AgentData.CopyCenters, dupeOnRay.AgentData.CopyRotates); } diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index dfcbc4c..69a909b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1851,7 +1851,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup copy = original.Copy(AgentID, GroupID, true); copy.AbsolutePosition = copy.AbsolutePosition + offset; - if (copy.OwnerID != AgentID) + if (original.OwnerID != AgentID) { copy.SetOwnerId(AgentID); copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7081ced..241295f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1781,7 +1781,9 @@ namespace OpenSim.Region.Framework.Scenes dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); if (!userExposed) + { dupe.RootPart.IsAttachment = previousAttachmentStatus; + } dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; @@ -1806,16 +1808,6 @@ namespace OpenSim.Region.Framework.Scenes dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); } - // Now we've made a copy that replaces this one, we need to - // switch the owner to the person who did the copying - // Second Life copies an object and duplicates the first one in it's place - // So, we have to make a copy of this one, set it in it's place then set the owner on this one - if (userExposed) - { - SetRootPartOwner(m_rootPart, cAgentID, cGroupID); - m_rootPart.ScheduleFullUpdate(); - } - List partList; lockPartsForRead(true); @@ -1837,12 +1829,6 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); newPart.LinkNum = part.LinkNum; - - if (userExposed) - { - SetPartOwner(newPart, cAgentID, cGroupID); - newPart.ScheduleFullUpdate(); - } } } -- cgit v1.1 From a817f6b48c27fe5e950846d687edcd4d375a3c6c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 28 Jun 2010 01:48:24 +0200 Subject: Remove AgentID and GroupOD from the signature of SOG.Copy(). They were never used, but made for a very mispleading read of the code in the callers. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 6 +++--- .../ContentManagementSystem/ContentManagementEntity.cs | 2 +- .../Region/OptionalModules/ContentManagementSystem/MetaEntity.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 69a909b..a36800b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1848,7 +1848,7 @@ namespace OpenSim.Region.Framework.Scenes { if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) { - SceneObjectGroup copy = original.Copy(AgentID, GroupID, true); + SceneObjectGroup copy = original.Copy(true); copy.AbsolutePosition = copy.AbsolutePosition + offset; if (original.OwnerID != AgentID) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 241295f..c48ce3b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1700,7 +1700,7 @@ namespace OpenSim.Region.Framework.Scenes "[SCENE]: Storing {0}, {1} in {2}", Name, UUID, m_scene.RegionInfo.RegionName); - SceneObjectGroup backup_group = Copy(OwnerID, GroupID, false); + SceneObjectGroup backup_group = Copy(false); backup_group.RootPart.Velocity = RootPart.Velocity; backup_group.RootPart.Acceleration = RootPart.Acceleration; backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; @@ -1758,7 +1758,7 @@ namespace OpenSim.Region.Framework.Scenes /// Duplicates this object, including operations such as physics set up and attaching to the backup event. /// /// - public SceneObjectGroup Copy(UUID cAgentID, UUID cGroupID, bool userExposed) + public SceneObjectGroup Copy(bool userExposed) { SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); dupe.m_isBackedUp = false; @@ -3897,7 +3897,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual ISceneObject CloneForNewScene() { - SceneObjectGroup sog = Copy(this.OwnerID, this.GroupID, false); + SceneObjectGroup sog = Copy(false); sog.m_isDeleted = false; return sog; } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs index c277034..ada6701 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/ContentManagementEntity.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement public ContentManagementEntity(SceneObjectGroup Unchanged, bool physics) : base(Unchanged, false) { - m_UnchangedEntity = Unchanged.Copy(Unchanged.RootPart.OwnerID, Unchanged.RootPart.GroupID, false); + m_UnchangedEntity = Unchanged.Copy(false); } public ContentManagementEntity(string objectXML, Scene scene, bool physics) diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index 1a72971..841ee00 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs @@ -80,7 +80,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement /// public MetaEntity(SceneObjectGroup orig, bool physics) { - m_Entity = orig.Copy(orig.RootPart.OwnerID, orig.RootPart.GroupID, false); + m_Entity = orig.Copy(false); Initialize(physics); } -- cgit v1.1 From 4fa1d4896c89d9907fe49f3ad718444b63c03ec9 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 28 Jun 2010 02:30:36 +0200 Subject: Change the way IRegionModule us referenced by IEmailModule to allow later conversion to new style --- OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs | 2 +- OpenSim/Region/Framework/Interfaces/IEmailModule.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs index 83f004d..c0975ea 100644 --- a/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/EMailModules/EmailModule.cs @@ -40,7 +40,7 @@ using OpenSim.Region.Framework.Scenes; namespace OpenSim.Region.CoreModules.Scripting.EmailModules { - public class EmailModule : IEmailModule + public class EmailModule : IRegionModule, IEmailModule { // // Log diff --git a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs index 3a2c423..4f1b91a 100644 --- a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs @@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces public int numLeft; } - public interface IEmailModule : IRegionModule + public interface IEmailModule { void SendEmail(UUID objectID, string address, string subject, string body); Email GetNextEmail(UUID objectID, string sender, string subject); -- cgit v1.1 From 827d9be48f8177b5975df68208a8cf7c730b58f0 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 27 Jun 2010 22:23:01 -0700 Subject: Fix the sound issue. It was caused by missing assets; once the client has made one request, it continued to wait for asset before requesting any new ones, until the TransferRequest timed out. Fixed by adding a TransferAbortPacket if the asset cannot be retrieved. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index f071841..5b5dc1e 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2208,6 +2208,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(sound, ThrottleOutPacketType.Task); } + public void SendTransferAbort(TransferRequestPacket transferRequest) + { + TransferAbortPacket abort = (TransferAbortPacket)PacketPool.Instance.GetPacket(PacketType.TransferAbort); + abort.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID; + abort.TransferInfo.ChannelType = transferRequest.TransferInfo.ChannelType; + m_log.Debug("[Assets] Aborting transfer; asset request failed"); + OutPacket(abort, ThrottleOutPacketType.Task); + } + public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain) { SoundTriggerPacket sound = (SoundTriggerPacket)PacketPool.Instance.GetPacket(PacketType.SoundTrigger); @@ -11502,7 +11511,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); - m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); + if (!m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived)) + { + //We need to send a TransferAbort here, so the client doesn't wait forever for the asset, + //which causes it to not request any more for a while. Which is bad. + SendTransferAbort(transferRequest); + } } /// -- cgit v1.1 From 3e908023b2f7e9edb77687089f2363a77b13d1fc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 28 Jun 2010 08:58:51 +0200 Subject: Force IM timestamps to current server time to prevent "Saved on" headers while the sender is online --- .../Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index 2dc7384..a7aa4ea 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -156,6 +156,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return; } + // Force timestamp to server time to avoid "Saved on" headers + // being generated for online users + im.timestamp = (uint)Util.UnixTimeSinceEpoch(); + if (dialog == (byte)InstantMessageDialog.MessageFromAgent || dialog == (byte)InstantMessageDialog.MessageFromObject) { -- cgit v1.1 From a5a1df68c29b2d78279bcff60ce66fe97772d0c6 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 28 Jun 2010 04:02:33 -0700 Subject: Provide the interface for StoreAsset to report success or failure --- OpenSim/Data/AssetDataBase.cs | 2 +- OpenSim/Data/IAssetData.cs | 2 +- OpenSim/Data/MSSQL/MSSQLAssetData.cs | 4 +++- OpenSim/Data/MySQL/MySQLAssetData.cs | 4 +++- OpenSim/Data/SQLite/SQLiteAssetData.cs | 4 +++- OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs | 4 +++- OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs | 3 ++- 7 files changed, 16 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/AssetDataBase.cs b/OpenSim/Data/AssetDataBase.cs index e1a810c..b4ae913 100644 --- a/OpenSim/Data/AssetDataBase.cs +++ b/OpenSim/Data/AssetDataBase.cs @@ -38,7 +38,7 @@ namespace OpenSim.Data { public abstract AssetBase GetAsset(UUID uuid); - public abstract void StoreAsset(AssetBase asset); + public abstract bool StoreAsset(AssetBase asset); public abstract bool ExistsAsset(UUID uuid); public abstract List FetchAssetMetadataSet(int start, int count); diff --git a/OpenSim/Data/IAssetData.cs b/OpenSim/Data/IAssetData.cs index 90d5eeb..065d3a5 100644 --- a/OpenSim/Data/IAssetData.cs +++ b/OpenSim/Data/IAssetData.cs @@ -34,7 +34,7 @@ namespace OpenSim.Data public interface IAssetDataPlugin : IPlugin { AssetBase GetAsset(UUID uuid); - void StoreAsset(AssetBase asset); + bool StoreAsset(AssetBase asset); bool ExistsAsset(UUID uuid); List FetchAssetMetadataSet(int start, int count); void Initialise(string connect); diff --git a/OpenSim/Data/MSSQL/MSSQLAssetData.cs b/OpenSim/Data/MSSQL/MSSQLAssetData.cs index c7488d8..c882555 100644 --- a/OpenSim/Data/MSSQL/MSSQLAssetData.cs +++ b/OpenSim/Data/MSSQL/MSSQLAssetData.cs @@ -143,7 +143,7 @@ namespace OpenSim.Data.MSSQL /// Create asset in m_database /// /// the asset - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { string sql = @@ -192,10 +192,12 @@ namespace OpenSim.Data.MSSQL try { command.ExecuteNonQuery(); + return true; } catch(Exception e) { m_log.Error("[ASSET DB]: Error storing item :" + e.Message); + return false; } } } diff --git a/OpenSim/Data/MySQL/MySQLAssetData.cs b/OpenSim/Data/MySQL/MySQLAssetData.cs index fe5152a..f9ce3d9 100644 --- a/OpenSim/Data/MySQL/MySQLAssetData.cs +++ b/OpenSim/Data/MySQL/MySQLAssetData.cs @@ -153,7 +153,7 @@ namespace OpenSim.Data.MySQL /// /// Asset UUID to create /// On failure : Throw an exception and attempt to reconnect to database - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { lock (m_dbLock) { @@ -201,12 +201,14 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("?data", asset.Data); cmd.ExecuteNonQuery(); cmd.Dispose(); + return true; } } catch (Exception e) { m_log.ErrorFormat("[ASSET DB]: MySQL failure creating asset {0} with name \"{1}\". Error: {2}", asset.FullID, asset.Name, e.Message); + return false; } } } diff --git a/OpenSim/Data/SQLite/SQLiteAssetData.cs b/OpenSim/Data/SQLite/SQLiteAssetData.cs index 16e560c..75e51a3 100644 --- a/OpenSim/Data/SQLite/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLite/SQLiteAssetData.cs @@ -119,7 +119,7 @@ namespace OpenSim.Data.SQLite /// Create an asset /// /// Asset Base - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString()); if (ExistsAsset(asset.FullID)) @@ -141,6 +141,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.ExecuteNonQuery(); + return true; } } } @@ -161,6 +162,7 @@ namespace OpenSim.Data.SQLite cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.ExecuteNonQuery(); + return true; } } } diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs index df50902..3da298b 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteAssetData.cs @@ -119,7 +119,7 @@ namespace OpenSim.Data.SQLiteLegacy /// Create an asset /// /// Asset Base - override public void StoreAsset(AssetBase asset) + override public bool StoreAsset(AssetBase asset) { //m_log.Info("[ASSET DB]: Creating Asset " + asset.FullID.ToString()); if (ExistsAsset(asset.FullID)) @@ -139,6 +139,7 @@ namespace OpenSim.Data.SQLiteLegacy cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.ExecuteNonQuery(); + return true; } } } @@ -157,6 +158,7 @@ namespace OpenSim.Data.SQLiteLegacy cmd.Parameters.Add(new SqliteParameter(":Data", asset.Data)); cmd.ExecuteNonQuery(); + return true; } } } diff --git a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs index 4a15cf2..5bab62c 100644 --- a/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs +++ b/OpenSim/Tests/Common/Mock/MockAssetDataPlugin.cs @@ -54,9 +54,10 @@ namespace OpenSim.Tests.Common.Mock return assets.Find(x=>x.FullID == uuid); } - public void StoreAsset(AssetBase asset) + public bool StoreAsset(AssetBase asset) { assets.Add(asset); + return true; } public List FetchAssetMetadataSet(int start, int count) { return new List(count); } -- cgit v1.1 From 06fa0388750b939ede9e3d7783e41a574e101397 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 28 Jun 2010 07:09:05 -0700 Subject: Return a UUID.Zero if the asset fails to upload --- OpenSim/Services/AssetService/AssetService.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/AssetService/AssetService.cs b/OpenSim/Services/AssetService/AssetService.cs index 470a4dd..3122382 100644 --- a/OpenSim/Services/AssetService/AssetService.cs +++ b/OpenSim/Services/AssetService/AssetService.cs @@ -144,7 +144,10 @@ namespace OpenSim.Services.AssetService public string Store(AssetBase asset) { //m_log.DebugFormat("[ASSET SERVICE]: Store asset {0} {1}", asset.Name, asset.ID); - m_Database.StoreAsset(asset); + if (!m_Database.StoreAsset(asset)) + { + return UUID.Zero.ToString(); + } return asset.ID; } -- cgit v1.1 From 6f4d4543b94f28160d697489e591da6614f0c8fc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 29 Jun 2010 03:51:16 +0200 Subject: Make newly created prims be named "Object" and make newly created scripts have a default touch handler. Compatibility patch --- OpenSim/Framework/PrimitiveBaseShape.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs index 4d1de22..990c859 100644 --- a/OpenSim/Framework/PrimitiveBaseShape.cs +++ b/OpenSim/Framework/PrimitiveBaseShape.cs @@ -1196,7 +1196,7 @@ namespace OpenSim.Framework prim.Textures = this.Textures; prim.Properties = new Primitive.ObjectProperties(); - prim.Properties.Name = "Primitive"; + prim.Properties.Name = "Object"; prim.Properties.Description = ""; prim.Properties.CreatorID = UUID.Zero; prim.Properties.GroupID = UUID.Zero; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6532537..a2a8882 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1378,7 +1378,7 @@ namespace OpenSim.Region.Framework.Scenes return; AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, - Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), + Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n\n touch_start(integer num)\n {\n }\n}"), remoteClient.AgentId); AssetService.Store(asset); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 09c945b..5b007e6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -358,7 +358,7 @@ namespace OpenSim.Region.Framework.Scenes UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, Quaternion rotationOffset, Vector3 offsetPosition) { - m_name = "Primitive"; + m_name = "Object"; Rezzed = DateTime.UtcNow; _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed); @@ -1625,7 +1625,7 @@ namespace OpenSim.Region.Framework.Scenes PrimitiveBaseShape shape = PrimitiveBaseShape.Create(); part.Shape = shape; - part.Name = "Primitive"; + part.Name = "Object"; part._ownerID = UUID.Random(); return part; -- cgit v1.1 From 3cd717d929d641b8e34d2212165af8d32fc8978e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 29 Jun 2010 04:09:14 +0200 Subject: Comment the "Notecard saved" notification that pops up when a notecard is saved into a prim. Sl doesn't have it, and for good reason: It also happens on scripts in our version. Which is wrong. Better no message than a wrong one. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a2a8882..e61132e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1285,7 +1285,7 @@ namespace OpenSim.Region.Framework.Scenes } if (part.Inventory.UpdateInventoryItem(itemInfo)) { - remoteClient.SendAgentAlertMessage("Notecard saved", false); + // remoteClient.SendAgentAlertMessage("Notecard saved", false); part.GetProperties(remoteClient); } } -- cgit v1.1 From 8dc7c0849eecaea09ce3571bab28b44c17bb3743 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 29 Jun 2010 23:18:48 -0700 Subject: The other half of the asset fix. Implement an exponentially incrementing retry timer for asset upload failures. Total queue time in the ballpark of 24 hours, which should be a reasonable time for any grid admin to get their asset service back online. This should stop lost assets. --- OpenSim/Framework/AssetBase.cs | 8 ++ .../Connectors/Asset/AssetServiceConnector.cs | 99 +++++++++++++++++++--- 2 files changed, 96 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/AssetBase.cs b/OpenSim/Framework/AssetBase.cs index 53d28be..98fa846 100644 --- a/OpenSim/Framework/AssetBase.cs +++ b/OpenSim/Framework/AssetBase.cs @@ -60,6 +60,8 @@ namespace OpenSim.Framework /// private AssetMetadata m_metadata; + private int m_uploadAttempts; + // This is needed for .NET serialization!!! // Do NOT "Optimize" away! public AssetBase() @@ -197,6 +199,12 @@ namespace OpenSim.Framework set { m_metadata.Type = value; } } + public int UploadAttempts + { + get { return m_uploadAttempts; } + set { m_uploadAttempts = value; } + } + /// /// Is this a region only asset, or does this exist on the asset server also /// diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index 65b3537..ae600bb 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -30,6 +30,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Timers; using Nini.Config; using OpenSim.Framework; using OpenSim.Framework.Console; @@ -48,7 +49,9 @@ namespace OpenSim.Services.Connectors private string m_ServerURI = String.Empty; private IImprovedAssetCache m_Cache = null; - + private int m_retryCounter; + private Dictionary> m_retryQueue = new Dictionary>(); + private Timer m_retryTimer; public AssetServicesConnector() { } @@ -85,6 +88,55 @@ namespace OpenSim.Services.Connectors MainConsole.Instance.Commands.AddCommand("asset", false, "dump asset", "dump asset ", "dump one cached asset", HandleDumpAsset); + + m_retryTimer = new Timer(); + m_retryTimer.Elapsed += new ElapsedEventHandler(retryCheck); + m_retryTimer.Interval = 60000; + } + + protected void retryCheck(object source, ElapsedEventArgs e) + { + m_retryCounter++; + if (m_retryCounter > 60) m_retryCounter -= 60; + List keys = new List(); + foreach (int a in m_retryQueue.Keys) + { + keys.Add(a); + } + foreach (int a in keys) + { + //We exponentially fall back on frequency until we reach one attempt per hour + //The net result is that we end up in the queue for roughly 24 hours.. + //24 hours worth of assets could be a lot, so the hope is that the region admin + //will have gotten the asset connector back online quickly! + + int timefactor = a ^ 2; + if (timefactor > 60) + { + timefactor = 60; + } + + //First, find out if we care about this timefactor + if (timefactor % a == 0) + { + //Yes, we do! + List retrylist = m_retryQueue[a]; + m_retryQueue.Remove(a); + + foreach(AssetBase ass in retrylist) + { + Store(ass); //Store my ass. This function will put it back in the dictionary if it fails + } + } + } + + if (m_retryQueue.Count == 0) + { + //It might only be one tick per minute, but I have + //repented and abandoned my wasteful ways + m_retryCounter = 0; + m_retryTimer.Stop(); + } } protected void SetCache(IImprovedAssetCache cache) @@ -222,20 +274,45 @@ namespace OpenSim.Services.Connectors } catch (Exception e) { - m_log.WarnFormat("[ASSET CONNECTOR]: Unable to send asset {0} to asset server. Reason: {1}", asset.ID, e.Message); + newID = UUID.Zero.ToString(); } - if (newID != String.Empty) + if (newID == UUID.Zero.ToString()) { - // Placing this here, so that this work with old asset servers that don't send any reply back - // SynchronousRestObjectRequester returns somethins that is not an empty string - if (newID != null) - asset.ID = newID; - - if (m_Cache != null) - m_Cache.Cache(asset); + //The asset upload failed, put it in a queue for later + asset.UploadAttempts++; + if (asset.UploadAttempts > 30) + { + //By this stage we've been in the queue for a good few hours; + //We're going to drop the asset. + m_log.ErrorFormat("[Assets] Dropping asset {0} - Upload has been in the queue for too long.", asset.ID.ToString()); + } + else + { + if (!m_retryQueue.ContainsKey(asset.UploadAttempts)) + { + m_retryQueue.Add(asset.UploadAttempts, new List()); + } + List m_queue = m_retryQueue[asset.UploadAttempts]; + m_queue.Add(asset); + m_log.WarnFormat("[Assets] Upload failed: {0} - Requeuing asset for another run.", asset.ID.ToString()); + m_retryTimer.Start(); + } + } + else + { + if (newID != String.Empty) + { + // Placing this here, so that this work with old asset servers that don't send any reply back + // SynchronousRestObjectRequester returns somethins that is not an empty string + if (newID != null) + asset.ID = newID; + + if (m_Cache != null) + m_Cache.Cache(asset); + } } - return newID; + return asset.ID; } public bool UpdateContent(string id, byte[] data) -- cgit v1.1 From 3940a4dbc7ffb4eab319ea9c2f1f787ddeee65e8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 1 Jul 2010 16:11:10 +0200 Subject: Avoid a spurious error message when taking a friend's no copy item --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 9 ++++- .../Shared/Api/Implementation/LSL_Api.cs | 40 ++++++++++++++++------ 2 files changed, 38 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 0ac427f..167e166 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1604,8 +1604,15 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) + if (action == DeRezAction.TakeCopy) + { + if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) + permissionToTakeCopy = false; + } + else + { permissionToTakeCopy = false; + } if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) permissionToTake = false; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fb191e6..d49bbb2 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9829,19 +9829,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llXorBase64StringsCorrect(string str1, string str2) { m_host.AddScriptLPS(1); - string ret = String.Empty; - string src1 = llBase64ToString(str1); - string src2 = llBase64ToString(str2); - int c = 0; - for (int i = 0; i < src1.Length; i++) + + if (str1 == String.Empty) + return String.Empty; + if (str2 == String.Empty) + return str1; + + byte[] data1 = Convert.FromBase64String(str1); + byte[] data2 = Convert.FromBase64String(str2); + + byte[] d2 = new Byte[data1.Length]; + int pos = 0; + + if (data1.Length <= data2.Length) { - ret += (char) (src1[i] ^ src2[c]); + Array.Copy(data2, 0, d2, 0, data1.Length); + } + else + { + while (pos < data1.Length) + { + int len = data1.Length - pos; + if (len > data2.Length) + len = data2.Length; - c++; - if (c >= src2.Length) - c = 0; + Array.Copy(data2, 0, d2, pos, len); + pos += len; + } } - return llStringToBase64(ret); + + for (pos = 0 ; pos < data1.Length ; pos++ ) + data1[pos] ^= d2[pos]; + + return Convert.ToBase64String(data1); } public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) -- cgit v1.1 From d5cbe4cb75a40a5b98d92d7fac504943edf428a1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 1 Jul 2010 16:40:26 +0200 Subject: Remove trailing slash from HTTP URLs to be compatible with SL --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 9b565ed..ab27da9 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -155,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_UrlMap[url] = urlData; - string uri = "/lslhttp/" + urlcode.ToString() + "/"; + string uri = "/lslhttp/" + urlcode.ToString(); m_HttpServer.AddPollServiceHTTPHandler(uri,HandleHttpPoll, new PollServiceEventArgs(HttpRequestHandler,HasEvents, GetEvents, NoEvents, -- cgit v1.1 From 3d5d44279b99e58cb4f2db3532df522ad3b5cccf Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 1 Jul 2010 17:06:29 +0200 Subject: ANother stab at LSL compatibility --- OpenSim/Framework/ParcelMediaCommandEnum.cs | 2 +- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/ParcelMediaCommandEnum.cs b/OpenSim/Framework/ParcelMediaCommandEnum.cs index 93c41ec..e714382 100644 --- a/OpenSim/Framework/ParcelMediaCommandEnum.cs +++ b/OpenSim/Framework/ParcelMediaCommandEnum.cs @@ -27,7 +27,7 @@ namespace OpenSim.Framework { - public enum ParcelMediaCommandEnum + public enum ParcelMediaCommandEnum : int { Stop = 0, Pause = 1, diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index ab27da9..f8cb414 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; } - string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; + string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString(); UrlData urlData = new UrlData(); urlData.hostID = host.UUID; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d49bbb2..e226682 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9394,7 +9394,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (aList.Data[i] != null) { - switch ((ParcelMediaCommandEnum) aList.Data[i]) + switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString())) { case ParcelMediaCommandEnum.Url: list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); -- cgit v1.1 From 1cb7695fb0bcdcbdbb6f2a410fd9f337438afef7 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 1 Jul 2010 08:48:02 -0700 Subject: Catch newid == null which is what happens if the asset service is offline (seems a connection failure does not throw an exception) --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index ae600bb..bc56963 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -271,6 +271,10 @@ namespace OpenSim.Services.Connectors { newID = SynchronousRestObjectRequester. MakeRequest("POST", uri, asset); + if (newID == null) + { + newID = UUID.Zero.ToString(); + } } catch (Exception e) { -- cgit v1.1 From 38384cc79c04fe9b97070104283be02511c4e12c Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 1 Jul 2010 08:52:30 -0700 Subject: Report asset upload success if it has previously failed --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index bc56963..bbccef9 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -305,6 +305,10 @@ namespace OpenSim.Services.Connectors } else { + if (asset.UploadAttempts > 0) + { + m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), asset.UploadAttempts.ToString())); + } if (newID != String.Empty) { // Placing this here, so that this work with old asset servers that don't send any reply back -- cgit v1.1 From b38a22506b31041e29a1271db32046efcb14af4e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 1 Jul 2010 08:55:52 -0700 Subject: Fix build break --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index bbccef9..94acd6c 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -307,7 +307,7 @@ namespace OpenSim.Services.Connectors { if (asset.UploadAttempts > 0) { - m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), asset.UploadAttempts.ToString())); + m_log.InfoFormat("[Assets] Upload of {0} succeeded after {1} failed attempts", asset.ID.ToString(), asset.UploadAttempts.ToString()); } if (newID != String.Empty) { -- cgit v1.1 From 071d601dcbd812bf2e3b163a53323ab5e00a315e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Thu, 1 Jul 2010 09:46:57 -0700 Subject: Cache all assets on upload so that the client can still retrieve the asset if it enters a retry queue --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index 94acd6c..e63dd50 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -256,11 +256,10 @@ namespace OpenSim.Services.Connectors public string Store(AssetBase asset) { + if (m_Cache != null) + m_Cache.Cache(asset); if (asset.Temporary || asset.Local) { - if (m_Cache != null) - m_Cache.Cache(asset); - return asset.ID; } -- cgit v1.1 From 60c15d7c283a7ded6d7e7b6c40b77b2a6b7218f2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 2 Jul 2010 03:05:40 +0200 Subject: Fix a dumb little sign error that makes a LSL wiki example fail --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index 212dbe3..5927973 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -663,13 +663,13 @@ namespace OpenSim.Region.ScriptEngine.Shared Object[] ret; if (start < 0) - start=m_data.Length-start; + start=m_data.Length+start; if (start < 0) start=0; if (end < 0) - end=m_data.Length-end; + end=m_data.Length+end; if (end < 0) end=0; -- cgit v1.1 From a7c4cb95aade11c302c9d1113f720467233b8600 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 2 Jul 2010 04:26:55 +0200 Subject: Fox another scripting nasty. Stuff no system.string objects into lists --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e226682..11d7c2b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5247,7 +5247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api case ',': if (parens == 0) { - result.Add(src.Substring(start,length).Trim()); + result.Add(new LSL_String(src.Substring(start,length).Trim())); start += length+1; length = 0; } -- cgit v1.1 From beb5259cd1ae11464e2affaa19788361979fbd0e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 2 Jul 2010 04:51:31 +0200 Subject: Remove GetEconomyData and the economy data structure (unused) --- OpenSim/Framework/IMoneyModule.cs | 21 --------------------- .../World/MoneyModule/SampleMoneyModule.cs | 21 --------------------- 2 files changed, 42 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs index 3480960..17e74a0 100644 --- a/OpenSim/Framework/IMoneyModule.cs +++ b/OpenSim/Framework/IMoneyModule.cs @@ -43,27 +43,6 @@ namespace OpenSim.Framework bool AmountCovered(IClientAPI client, int amount); void ApplyCharge(UUID agentID, int amount, string text); - EconomyData GetEconomyData(); - event ObjectPaid OnObjectPaid; } - - public struct EconomyData - { - public int ObjectCapacity; - public int ObjectCount; - public int PriceEnergyUnit; - public int PriceGroupCreate; - public int PriceObjectClaim; - public float PriceObjectRent; - public float PriceObjectScaleFactor; - public int PriceParcelClaim; - public float PriceParcelClaimFactor; - public int PriceParcelRent; - public int PricePublicObjectDecay; - public int PricePublicObjectDelete; - public int PriceRentLight; - public int PriceUpload; - public int TeleportMinPrice; - } } diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index b9a75cc..e070077 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -268,27 +268,6 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule } - public EconomyData GetEconomyData() - { - EconomyData edata = new EconomyData(); - edata.ObjectCapacity = ObjectCapacity; - edata.ObjectCount = ObjectCount; - edata.PriceEnergyUnit = PriceEnergyUnit; - edata.PriceGroupCreate = PriceGroupCreate; - edata.PriceObjectClaim = PriceObjectClaim; - edata.PriceObjectRent = PriceObjectRent; - edata.PriceObjectScaleFactor = PriceObjectScaleFactor; - edata.PriceParcelClaim = PriceParcelClaim; - edata.PriceParcelClaimFactor = PriceParcelClaimFactor; - edata.PriceParcelRent = PriceParcelRent; - edata.PricePublicObjectDecay = PricePublicObjectDecay; - edata.PricePublicObjectDelete = PricePublicObjectDelete; - edata.PriceRentLight = PriceRentLight; - edata.PriceUpload = PriceUpload; - edata.TeleportMinPrice = TeleportMinPrice; - return edata; - } - private void GetClientFunds(IClientAPI client) { CheckExistAndRefreshFunds(client.AgentId); -- cgit v1.1 From c87e6a289c5ab93025bf03f486629fd5aa00aaaa Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 2 Jul 2010 06:20:36 +0200 Subject: Clean up IMoneyModule and adjust the other modules to the changes --- OpenSim/Framework/Capabilities/Caps.cs | 2 +- OpenSim/Framework/IMoneyModule.cs | 11 ++++---- .../AssetTransaction/AssetTransactionModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- .../Avatar/XmlRpcGroups/GroupsModule.cs | 4 +-- .../World/MoneyModule/SampleMoneyModule.cs | 31 +++++++++++----------- 6 files changed, 26 insertions(+), 26 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 62a1e17..da953bb 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -814,7 +814,7 @@ namespace OpenSim.Framework.Capabilities if (mm != null) { - if (!mm.UploadCovered(client)) + if (!mm.UploadCovered(client, mm.UploadCharge)) { if (client != null) client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); diff --git a/OpenSim/Framework/IMoneyModule.cs b/OpenSim/Framework/IMoneyModule.cs index 17e74a0..3d4873d 100644 --- a/OpenSim/Framework/IMoneyModule.cs +++ b/OpenSim/Framework/IMoneyModule.cs @@ -35,13 +35,14 @@ namespace OpenSim.Framework bool ObjectGiveMoney(UUID objectID, UUID fromID, UUID toID, int amount); - int GetBalance(IClientAPI client); - void ApplyUploadCharge(UUID agentID); - bool UploadCovered(IClientAPI client); - void ApplyGroupCreationCharge(UUID agentID); - bool GroupCreationCovered(IClientAPI client); + int GetBalance(UUID agentID); + bool UploadCovered(IClientAPI client, int amount); bool AmountCovered(IClientAPI client, int amount); void ApplyCharge(UUID agentID, int amount, string text); + void ApplyUploadCharge(UUID agentID, int amount, string text); + + int UploadCharge { get; } + int GroupCreationCharge { get; } event ObjectPaid OnObjectPaid; } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 7e08ecf..ae31050 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -243,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction if (mm != null) { - if (!mm.UploadCovered(remoteClient)) + if (!mm.UploadCovered(remoteClient, mm.UploadCharge)) { remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); return; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 167e166..489b8ca 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes IMoneyModule money=RequestModuleInterface(); if (money != null) { - money.ApplyUploadCharge(agentID); + money.ApplyUploadCharge(agentID, money.UploadCharge, "Asset upload"); } AddInventoryItem(agentID, item); diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 56c0d98..3f15b69 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -722,11 +722,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups if (money != null) { // do the transaction, that is if the agent has got sufficient funds - if (!money.GroupCreationCovered(remoteClient)) { + if (!money.AmountCovered(remoteClient, money.GroupCreationCharge)) { remoteClient.SendCreateGroupReply(UUID.Zero, false, "You have got issuficient funds to create a group."); return UUID.Zero; } - money.ApplyGroupCreationCharge(GetRequestingAgentID(remoteClient)); + money.ApplyCharge(GetRequestingAgentID(remoteClient), money.GroupCreationCharge, "Group Creation"); } UUID groupID = m_groupData.CreateGroup(GetRequestingAgentID(remoteClient), name, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, GetRequestingAgentID(remoteClient)); diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index e070077..6f5ef9e 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -108,6 +108,16 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule public event ObjectPaid OnObjectPaid; + public int UploadCharge + { + get { return 0; } + } + + public int GroupCreationCharge + { + get { return 0; } + } + /// /// Startup /// @@ -188,15 +198,10 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule // Please do not refactor these to be just one method // Existing implementations need the distinction // - public void ApplyUploadCharge(UUID agentID) - { - } - - public void ApplyGroupCreationCharge(UUID agentID) + public void ApplyCharge(UUID agentID, int amount, string text) { } - - public void ApplyCharge(UUID agentID, int amount, string text) + public void ApplyUploadCharge(UUID agentID, int amount, string text) { } @@ -769,7 +774,7 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); } - public int GetBalance(IClientAPI client) + public int GetBalance(UUID agentID) { return 0; } @@ -777,16 +782,10 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule // Please do not refactor these to be just one method // Existing implementations need the distinction // - public bool UploadCovered(IClientAPI client) - { - return AmountCovered(client, PriceUpload); - } - - public bool GroupCreationCovered(IClientAPI client) + public bool UploadCovered(IClientAPI client, int amount) { - return AmountCovered(client, PriceGroupCreate); + return true; } - public bool AmountCovered(IClientAPI client, int amount) { return true; -- cgit v1.1 From 233c872d24c8cc9d0b883ff8f816f67e57638042 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 2 Jul 2010 09:40:58 +0200 Subject: Call client.Start() sunchronously. Calling thos async avoids some stuttering when people log in, but fatally screws up money. --- OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index cda461c..f2bcc0b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -900,7 +900,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Start the IClientAPI // Spin it off so that it doesn't clog up the LLUDPServer - Util.FireAndForget(delegate(object o) { client.Start(); }); + //Util.FireAndForget(delegate(object o) { client.Start(); }); + + // NOTE: DO NOT CALL THIS ASYNCHRONOUSLY!!!!! + // This method will ultimately cause the modules to hook + // client events in OnNewClient. If they can't do this + // before further packets are processed, packets WILL BE LOST. + // This includes the all-important EconomyDataRequest! + // So using FireAndForget here WILL screw up money. Badly. + // You have been warned! + client.Start(); } else { -- cgit v1.1 From 721d8a72987cea267ce9d32dfb91a288019107b2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 3 Jul 2010 07:09:27 +0200 Subject: Re-add the slashes at the end of the URL. Too much depends on them --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index f8cb414..9b565ed 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; } - string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString(); + string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; UrlData urlData = new UrlData(); urlData.hostID = host.UUID; @@ -155,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp m_UrlMap[url] = urlData; - string uri = "/lslhttp/" + urlcode.ToString(); + string uri = "/lslhttp/" + urlcode.ToString() + "/"; m_HttpServer.AddPollServiceHTTPHandler(uri,HandleHttpPoll, new PollServiceEventArgs(HttpRequestHandler,HasEvents, GetEvents, NoEvents, -- cgit v1.1 From 86a82e6ecb564c4b3126d3472482d713213aaf31 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 3 Jul 2010 08:33:08 +0200 Subject: Now, fix the slash issue the right way. Our URLs now work like SL's --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index 9b565ed..1fd1f47 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp engine.PostScriptEvent(itemID, "http_request", new Object[] { urlcode.ToString(), "URL_REQUEST_DENIED", "" }); return urlcode; } - string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString() + "/"; + string url = "http://" + m_ExternalHostNameForLSL + ":" + m_HttpServer.Port.ToString() + "/lslhttp/" + urlcode.ToString(); UrlData urlData = new UrlData(); urlData.hostID = host.UUID; @@ -152,10 +152,9 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp urlData.urlcode = urlcode; urlData.requests = new Dictionary(); - m_UrlMap[url] = urlData; - string uri = "/lslhttp/" + urlcode.ToString() + "/"; + string uri = "/lslhttp/" + urlcode.ToString(); m_HttpServer.AddPollServiceHTTPHandler(uri,HandleHttpPoll, new PollServiceEventArgs(HttpRequestHandler,HasEvents, GetEvents, NoEvents, @@ -386,6 +385,7 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp return response; } + public void HttpRequestHandler(UUID requestID, Hashtable request) { lock (request) @@ -400,8 +400,8 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp int pos1 = uri.IndexOf("/");// /lslhttp int pos2 = uri.IndexOf("/", pos1 + 1);// /lslhttp/ - int pos3 = uri.IndexOf("/", pos2 + 1);// /lslhttp// - string uri_tmp = uri.Substring(0, pos3 + 1); + int pos3 = pos2 + 37; // /lslhttp/urlcode + string uri_tmp = uri.Substring(0, pos3); //HTTP server code doesn't provide us with QueryStrings string pathInfo; string queryString; -- cgit v1.1 From 3d495b709ec897970b24ce48d6a8495d520864d4 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 3 Jul 2010 06:08:18 -0700 Subject: Implement a timeout value in the SynchronousRestObjectRequester. Default is 100 seconds. --- .../HttpServer/SynchronousRestObjectRequester.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs index eab463c..bb3b8b1 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs @@ -57,6 +57,21 @@ namespace OpenSim.Framework.Servers.HttpServer /// the request. You'll want to make sure you deal with this as they're not uncommon public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj) { + return MakeRequest(verb, requestUrl, obj, 100); + } + /// + /// Perform a synchronous REST request. + /// + /// + /// + /// + /// + /// + /// + /// Thrown if we encounter a network issue while posting + /// the request. You'll want to make sure you deal with this as they're not uncommon + public static TResponse MakeRequest(string verb, string requestUrl, TRequest obj, int pTimeout) + { Type type = typeof (TRequest); TResponse deserial = default(TResponse); @@ -81,7 +96,7 @@ namespace OpenSim.Framework.Servers.HttpServer int length = (int) buffer.Length; request.ContentLength = length; - + request.Timeout = pTimeout * 1000; Stream requestStream = null; try { -- cgit v1.1 From 2b49cb922799aadcdb93225d74735fcf7da94bbd Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 3 Jul 2010 06:09:20 -0700 Subject: Make sure the AssetServiceConnector times out within 30 seconds. If it doesn't, the client will get bored and give an upload error, instead of granting success and entering the asset into our retry queue. --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index e63dd50..1f40312 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -269,8 +269,8 @@ namespace OpenSim.Services.Connectors try { newID = SynchronousRestObjectRequester. - MakeRequest("POST", uri, asset); - if (newID == null) + MakeRequest("POST", uri, asset, 25); + if (newID == null || newID == "") { newID = UUID.Zero.ToString(); } -- cgit v1.1 From 39ae1def85fcaf56761c88ad0a000e659941162c Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 3 Jul 2010 06:10:02 -0700 Subject: Re-implement the Undo stack as a List; the old implementation was buggy --- OpenSim/Framework/UndoStack.cs | 51 +++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/UndoStack.cs b/OpenSim/Framework/UndoStack.cs index 4d800ae..3799180 100644 --- a/OpenSim/Framework/UndoStack.cs +++ b/OpenSim/Framework/UndoStack.cs @@ -26,6 +26,7 @@ */ using System; +using System.Collections.Generic; namespace OpenSim.Framework { @@ -36,33 +37,30 @@ namespace OpenSim.Framework [Serializable] public class UndoStack { - private int m_new = 1; - private int m_old = 0; - private T[] m_Undos; + private List m_undolist; + private int m_max; public UndoStack(int capacity) { - m_Undos = new T[capacity + 1]; + m_undolist = new List(); + m_max = capacity; } public bool IsFull { - get { return m_new == m_old; } + get { return m_undolist.Count >= m_max; } } public int Capacity { - get { return m_Undos.Length - 1; } + get { return m_max; } } public int Count { get { - int count = m_new - m_old - 1; - if (count < 0) - count += m_Undos.Length; - return count; + return m_undolist.Count; } } @@ -70,45 +68,32 @@ namespace OpenSim.Framework { if (IsFull) { - m_old++; - if (m_old >= m_Undos.Length) - m_old -= m_Undos.Length; + m_undolist.RemoveAt(0); } - if (++m_new >= m_Undos.Length) - m_new -= m_Undos.Length; - m_Undos[m_new] = item; + m_undolist.Add(item); } public T Pop() { - if (Count > 0) + if (m_undolist.Count > 0) { - T deleted = m_Undos[m_new]; - m_Undos[m_new--] = default(T); - if (m_new < 0) - m_new += m_Undos.Length; - return deleted; + int ind = m_undolist.Count - 1; + T item = m_undolist[ind]; + m_undolist.RemoveAt(ind); + return item; } else - throw new InvalidOperationException("Cannot pop from emtpy stack"); + throw new InvalidOperationException("Cannot pop from empty stack"); } public T Peek() { - return m_Undos[m_new]; + return m_undolist[m_undolist.Count - 1]; } public void Clear() { - if (Count > 0) - { - for (int i = 0; i < m_Undos.Length; i++) - { - m_Undos[i] = default(T); - } - m_new = 1; - m_old = 0; - } + m_undolist.Clear(); } } } -- cgit v1.1 From fe2b044d38f3bd3aa669334d34567fd991a67b3e Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 3 Jul 2010 06:10:55 -0700 Subject: Fix Undo! Made a lot of changes to Undo state saving; it now considers that groups of objects can be moved and not just individual prims.. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 39 ++++++++++----- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 ++++++- OpenSim/Region/Framework/Scenes/UndoState.cs | 55 ++++++++++++++++++---- 3 files changed, 87 insertions(+), 23 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c48ce3b..da664da 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -349,7 +349,21 @@ namespace OpenSim.Region.Framework.Scenes public virtual Quaternion Rotation { get { return m_rotation; } - set { m_rotation = value; } + set { + lockPartsForRead(true); + try + { + foreach(SceneObjectPart p in m_parts.Values) + { + p.StoreUndoState(true); + } + } + finally + { + lockPartsForRead(false); + } + m_rotation = value; + } } public Quaternion GroupRotation @@ -421,6 +435,7 @@ namespace OpenSim.Region.Framework.Scenes get { return m_rootPart.GroupPosition; } set { + Vector3 val = value; if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) @@ -431,7 +446,10 @@ namespace OpenSim.Region.Framework.Scenes } lockPartsForRead(true); - + foreach (SceneObjectPart part in m_parts.Values) + { + part.IgnoreUndoUpdate = true; + } if (RootPart.GetStatusSandbox()) { if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) @@ -443,12 +461,12 @@ namespace OpenSim.Region.Framework.Scenes return; } } - foreach (SceneObjectPart part in m_parts.Values) { + part.IgnoreUndoUpdate = false; + part.StoreUndoState(true); part.GroupPosition = val; } - lockPartsForRead(false); //if (m_rootPart.PhysActor != null) @@ -724,7 +742,6 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart part in m_parts.Values) { - Vector3 partscale = part.Scale; Vector3 partoffset = part.OffsetPosition; @@ -3132,7 +3149,6 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetChildPart(localID); if (part != null) { - part.IgnoreUndoUpdate = true; if (scale.X > m_scene.m_maxNonphys) scale.X = m_scene.m_maxNonphys; if (scale.Y > m_scene.m_maxNonphys) @@ -3218,8 +3234,7 @@ namespace OpenSim.Region.Framework.Scenes y *= a; z *= a; } - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); + } } } @@ -3229,13 +3244,17 @@ namespace OpenSim.Region.Framework.Scenes Vector3 prevScale = part.Scale; prevScale.X *= x; prevScale.Y *= y; - prevScale.Z *= z; + prevScale.Z *= z;; + part.IgnoreUndoUpdate = true; part.Resize(prevScale); + part.IgnoreUndoUpdate = false; lockPartsForRead(true); { foreach (SceneObjectPart obPart in m_parts.Values) { + obPart.IgnoreUndoUpdate = false; + obPart.StoreUndoState(true); obPart.IgnoreUndoUpdate = true; if (obPart.UUID != m_rootPart.UUID) { @@ -3251,7 +3270,6 @@ namespace OpenSim.Region.Framework.Scenes obPart.UpdateOffSet(currentpos); } obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(); } } lockPartsForRead(false); @@ -3263,7 +3281,6 @@ namespace OpenSim.Region.Framework.Scenes } part.IgnoreUndoUpdate = false; - part.StoreUndoState(); HasGroupChanged = true; ScheduleGroupForTerseUpdate(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5b007e6..72ad281 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3504,9 +3504,12 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.ScheduleGroupForTerseUpdate(); //m_parentGroup.ScheduleGroupForFullUpdate(); } - public void StoreUndoState() { + StoreUndoState(false); + } + public void StoreUndoState(bool group) + { if (!Undoing) { if (!IgnoreUndoUpdate) @@ -3528,7 +3531,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_parentGroup.GetSceneMaxUndo() > 0) { UndoState nUndo = new UndoState(this); - + nUndo.GroupChange = group; m_undo.Push(nUndo); } @@ -4010,6 +4013,15 @@ namespace OpenSim.Region.Framework.Scenes nUndo = new UndoState(this); } UndoState goback = m_undo.Pop(); + m_log.Debug("Got goback"); + if (goback == null) + { + m_log.Debug("it's null"); + } + else + { + m_log.Debug(goback.GroupPosition.ToString()); + } if (goback != null) { goback.PlaybackState(this); diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 55e407e..77381ab 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -35,6 +35,10 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; public Quaternion Rotation = Quaternion.Identity; + public bool GroupChange = false; + public Vector3 GroupPosition = Vector3.Zero; + public Quaternion GroupRotation = Quaternion.Identity; + public Vector3 GroupScale = Vector3.Zero; public UndoState(SceneObjectPart part) { @@ -42,12 +46,24 @@ namespace OpenSim.Region.Framework.Scenes { if (part.ParentID == 0) { - Position = part.ParentGroup.AbsolutePosition; + GroupScale = part.Shape.Scale; + + //FUBAR WARNING: Do NOT get the group's absoluteposition here + //or you'll experience a loop and/or a stack issue + GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; + GroupRotation = part.ParentGroup.Rotation; + Position = part.ParentGroup.RootPart.AbsolutePosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; } else { + GroupScale = part.Shape.Scale; + + //FUBAR WARNING: Do NOT get the group's absoluteposition here + //or you'll experience a loop and/or a stack issue + GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; + GroupRotation = part.ParentGroup.Rotation; Position = part.OffsetPosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; @@ -61,14 +77,14 @@ namespace OpenSim.Region.Framework.Scenes { if (part.ParentID == 0) { - if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation) + if (Position == part.ParentGroup.RootPart.AbsolutePosition && Rotation == part.ParentGroup.Rotation && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) return true; else return false; } else { - if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale) + if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale) return true; else return false; @@ -84,10 +100,10 @@ namespace OpenSim.Region.Framework.Scenes { part.Undoing = true; - if (part.ParentID == 0) + if (part.ParentID == 0 && GroupChange == false) { if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; + part.ParentGroup.AbsolutePosition = Position; part.RotationOffset = Rotation; if (Scale != Vector3.Zero) part.Resize(Scale); @@ -95,11 +111,30 @@ namespace OpenSim.Region.Framework.Scenes } else { - if (Position != Vector3.Zero) - part.OffsetPosition = Position; - part.UpdateRotation(Rotation); - if (Scale != Vector3.Zero) - part.Resize(Scale); part.ScheduleTerseUpdate(); + if (GroupChange) + { + if (Position != Vector3.Zero) + { + //Calculate the scale... + Vector3 gs = part.Shape.Scale; + float scale = GroupScale.Z / gs.Z; + + //Scale first since it can affect our position + part.ParentGroup.GroupResize(gs * scale, part.LocalId); + part.ParentGroup.AbsolutePosition = GroupPosition; + part.ParentGroup.Rotation = GroupRotation; + + } + } + else + { + if (Position != Vector3.Zero) //We can use this for all the updates since all are set + { + part.OffsetPosition = Position; + part.UpdateRotation(Rotation); + part.Resize(Scale); part.ScheduleTerseUpdate(); + } + } } part.Undoing = false; -- cgit v1.1 From 4cd5e642319b31e1da838ca6fda97ae2992b2c79 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 3 Jul 2010 09:22:58 -0700 Subject: Use SendTransferAbort in a more sensible place --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 14b716b..4dfd5d1 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -11511,12 +11511,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP // m_log.DebugFormat("[CLIENT]: {0} requesting asset {1}", Name, requestID); - if (!m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived)) - { - //We need to send a TransferAbort here, so the client doesn't wait forever for the asset, - //which causes it to not request any more for a while. Which is bad. - SendTransferAbort(transferRequest); - } + + //Note, the bool returned from the below function is useless since it is always false. + m_assetService.Get(requestID.ToString(), transferRequest, AssetReceived); + } /// @@ -11565,8 +11563,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP } //m_log.DebugFormat("[ASSET CACHE]: Asset transfer request for asset which is {0} already known to be missing. Dropping", requestID); - - // FIXME: We never tell the client about assets which do not exist when requested by this transfer mechanism, which can't be right. + + //We need to send a TransferAbort here, so the client doesn't wait forever for the asset, + //which causes it to not request any more for a while. Which is bad. + SendTransferAbort(transferRequest); return; } -- cgit v1.1 From edcfaf60c99b7cde324621c2ffcfbb16e4eb4c5e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 3 Jul 2010 20:27:00 +0200 Subject: Fix IMs the right way. This sets it up so that timestamps are actually in PST (to match viewer time), does correct storage and retrieval of IMs, corrects the session ID and makes sure IMs don't get marked "saved" if they're live. Removes the group IM save option, which our group IM module never had in the first place, as saving group chatter makes no sense at all. --- .../Avatar/InstantMessage/InstantMessageModule.cs | 27 +++++++-- .../Avatar/InstantMessage/OfflineMessageModule.cs | 65 +++++++++++++--------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 7 ++- .../Shared/Api/Implementation/LSL_Api.cs | 22 +++++++- 4 files changed, 86 insertions(+), 35 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index a7aa4ea..ffdac58 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -156,16 +156,31 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage return; } - // Force timestamp to server time to avoid "Saved on" headers - // being generated for online users - im.timestamp = (uint)Util.UnixTimeSinceEpoch(); + DateTime dt = DateTime.UtcNow; - if (dialog == (byte)InstantMessageDialog.MessageFromAgent || - dialog == (byte)InstantMessageDialog.MessageFromObject) + // Ticks from UtcNow, but make it look like local. Evil, huh? + dt = DateTime.SpecifyKind(dt, DateTimeKind.Local); + + try + { + // Convert that to the PST timezone + TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles"); + dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo); + } + catch { - im.offline = 1; + m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp."); } + // And make it look local again to fool the unix time util + dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc); + + im.timestamp = (uint)Util.ToUnixTime(dt); + + // If client is null, this message comes from storage and IS offline + if (client != null) + im.offline = 0; + if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index a2dc91f..feeb9e6 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -192,6 +192,17 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Needed for proper state management for stored group // invitations // + + im.offline = 1; + + // Reconstruct imSessionID + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + { + UUID fromAgentID = new UUID(im.fromAgentID); + UUID sessionID = fromAgentID ^ client.AgentId; + im.imSessionID = new Guid(sessionID.ToString()); + } + Scene s = FindScene(client.AgentId); if (s != null) s.EventManager.TriggerIncomingInstantMessage(im); @@ -201,35 +212,37 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private void UndeliveredMessage(GridInstantMessage im) { - if (im.dialog == 19) - im.offline = 1; // We want them pushed out to the server - if ((im.offline != 0) - && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) + if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && + im.dialog != (byte)InstantMessageDialog.MessageFromAgent && + im.dialog != (byte)InstantMessageDialog.GroupNotice && + im.dialog != (byte)InstantMessageDialog.InventoryOffered) { - // It's not delivered. Make sure the scope id is saved - // We don't need the imSessionID here anymore, overwrite it - Scene scene = FindScene(new UUID(im.fromAgentID)); - if (scene == null) - scene = m_SceneList[0]; - im.imSessionID = new Guid(scene.RegionInfo.ScopeID.ToString()); + return; + } - bool success = SynchronousRestObjectPoster.BeginPostObject( - "POST", m_RestURL+"/SaveMessage/", im); + // It's not delivered. Make sure the scope id is saved + // We don't need the imSessionID here anymore, overwrite it + Scene scene = FindScene(new UUID(im.fromAgentID)); + if (scene == null) + scene = m_SceneList[0]; + im.imSessionID = new Guid(scene.RegionInfo.ScopeID.ToString()); - if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) - { - IClientAPI client = FindClient(new UUID(im.fromAgentID)); - if (client == null) - return; - - client.SendInstantMessage(new GridInstantMessage( - null, new UUID(im.toAgentID), - "System", new UUID(im.fromAgentID), - (byte)InstantMessageDialog.MessageFromAgent, - "User is not logged in. "+ - (success ? "Message saved." : "Message not saved"), - false, new Vector3())); - } + bool success = SynchronousRestObjectPoster.BeginPostObject( + "POST", m_RestURL+"/SaveMessage/", im); + + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + { + IClientAPI client = FindClient(new UUID(im.fromAgentID)); + if (client == null) + return; + + client.SendInstantMessage(new GridInstantMessage( + null, new UUID(im.toAgentID), + "System", new UUID(im.fromAgentID), + (byte)InstantMessageDialog.MessageFromAgent, + "User is not logged in. "+ + (success ? "Message saved." : "Message not saved"), + false, new Vector3())); } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4a4cac9..e51d9ee 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3730,8 +3730,11 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); { CollidingMessage.Colliders = colliding; - foreach (SceneObjectGroup att in Attachments) - Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); + lock (m_attachments) + { + foreach (SceneObjectGroup att in m_attachments) + Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); + } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 11d7c2b..f153504 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3252,7 +3252,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here // m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); // m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); - msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; + DateTime dt = DateTime.UtcNow; + + // Ticks from UtcNow, but make it look like local. Evil, huh? + dt = DateTime.SpecifyKind(dt, DateTimeKind.Local); + + try + { + // Convert that to the PST timezone + TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles"); + dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo); + } + catch + { + // No logging here, as it could be VERY spammy + } + + // And make it look local again to fool the unix time util + dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc); + + msg.timestamp = (uint)Util.ToUnixTime(dt); + //if (client != null) //{ msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; -- cgit v1.1 From 3368e3853ae931e8e7137dc10a410265b4afbd5a Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 06:45:04 -0700 Subject: Check cached asset to make sure it contains data, and if not, re-request --- OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs index 1f40312..ad18a23 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServiceConnector.cs @@ -151,8 +151,8 @@ namespace OpenSim.Services.Connectors AssetBase asset = null; if (m_Cache != null) asset = m_Cache.Get(id); - - if (asset == null) + + if (asset == null || asset.Data == null || asset.Data.Length == 0) { asset = SynchronousRestObjectRequester. MakeRequest("GET", uri, 0); @@ -229,7 +229,7 @@ namespace OpenSim.Services.Connectors if (m_Cache != null) asset = m_Cache.Get(id); - if (asset == null) + if (asset == null || asset.Data == null || asset.Data.Length == 0) { bool result = false; -- cgit v1.1 From 7665013ad8c7ac876955dc803619405dfa2af71d Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 19:25:54 -0700 Subject: Correct positioning of timeout modifier in the SynchronousRestObjectRequester --- OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs index bb3b8b1..f07f7ab 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs @@ -77,6 +77,7 @@ namespace OpenSim.Framework.Servers.HttpServer WebRequest request = WebRequest.Create(requestUrl); request.Method = verb; + request.Timeout = pTimeout * 1000; if ((verb == "POST") || (verb == "PUT")) { @@ -96,7 +97,6 @@ namespace OpenSim.Framework.Servers.HttpServer int length = (int) buffer.Length; request.ContentLength = length; - request.Timeout = pTimeout * 1000; Stream requestStream = null; try { -- cgit v1.1 From 5b68343361cbd000a2f024b37797ec235abb7207 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 19:28:39 -0700 Subject: The majority of the Undo fix. There is still an issue with Rotation which i'll address next; however position undo and scale undo should be working just fine now. Also removed some residual debug logging. --- OpenSim/Framework/UndoStack.cs | 9 ++- .../Region/Framework/Scenes/SceneObjectGroup.cs | 38 +++++----- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 61 ++++++++--------- .../Scenes/Serialization/SceneObjectSerializer.cs | 4 +- OpenSim/Region/Framework/Scenes/UndoState.cs | 80 ++++++++++++++++++++-- 5 files changed, 135 insertions(+), 57 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/UndoStack.cs b/OpenSim/Framework/UndoStack.cs index 3799180..4cd779a 100644 --- a/OpenSim/Framework/UndoStack.cs +++ b/OpenSim/Framework/UndoStack.cs @@ -88,7 +88,14 @@ namespace OpenSim.Framework public T Peek() { - return m_undolist[m_undolist.Count - 1]; + if (m_undolist.Count > 0) + { + return m_undolist[m_undolist.Count - 1]; + } + else + { + return default(T); + } } public void Clear() diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index da664da..34712b8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -355,7 +355,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach(SceneObjectPart p in m_parts.Values) { - p.StoreUndoState(true); + p.StoreUndoState(UndoType.STATE_GROUP_ROTATION); } } finally @@ -435,7 +435,6 @@ namespace OpenSim.Region.Framework.Scenes get { return m_rootPart.GroupPosition; } set { - Vector3 val = value; if ((m_scene.TestBorderCross(val - Vector3.UnitX, Cardinals.E) || m_scene.TestBorderCross(val + Vector3.UnitX, Cardinals.W) @@ -464,7 +463,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in m_parts.Values) { part.IgnoreUndoUpdate = false; - part.StoreUndoState(true); + part.StoreUndoState(UndoType.STATE_GROUP_POSITION); part.GroupPosition = val; } lockPartsForRead(false); @@ -1488,7 +1487,7 @@ namespace OpenSim.Region.Framework.Scenes public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) { - part.StoreUndoState(); + part.StoreUndoState(UndoType.STATE_PRIM_ALL); part.OnGrab(offsetPos, remoteClient); } @@ -3245,6 +3244,9 @@ namespace OpenSim.Region.Framework.Scenes prevScale.X *= x; prevScale.Y *= y; prevScale.Z *= z;; + + part.IgnoreUndoUpdate = false; + part.StoreUndoState(UndoType.STATE_GROUP_SCALE); part.IgnoreUndoUpdate = true; part.Resize(prevScale); part.IgnoreUndoUpdate = false; @@ -3253,11 +3255,12 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart obPart in m_parts.Values) { - obPart.IgnoreUndoUpdate = false; - obPart.StoreUndoState(true); - obPart.IgnoreUndoUpdate = true; if (obPart.UUID != m_rootPart.UUID) { + obPart.IgnoreUndoUpdate = false; + obPart.StoreUndoState(UndoType.STATE_GROUP_SCALE); + obPart.IgnoreUndoUpdate = true; + Vector3 currentpos = new Vector3(obPart.OffsetPosition); currentpos.X *= x; currentpos.Y *= y; @@ -3296,14 +3299,11 @@ namespace OpenSim.Region.Framework.Scenes /// public void UpdateGroupPosition(Vector3 pos) { - foreach (SceneObjectPart part in Children.Values) - { - part.StoreUndoState(); - } if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) { if (IsAttachment) { + m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION); m_rootPart.AttachedPos = pos; } if (RootPart.GetStatusSandbox()) @@ -3336,7 +3336,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetChildPart(localID); foreach (SceneObjectPart parts in Children.Values) { - parts.StoreUndoState(); + parts.StoreUndoState(UndoType.STATE_PRIM_POSITION); } if (part != null) { @@ -3361,7 +3361,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart part in Children.Values) { - part.StoreUndoState(); + part.StoreUndoState(UndoType.STATE_PRIM_POSITION); } Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); Vector3 oldPos = @@ -3409,7 +3409,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart parts in Children.Values) { - parts.StoreUndoState(); + parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION); } m_rootPart.UpdateRotation(rot); @@ -3433,7 +3433,7 @@ namespace OpenSim.Region.Framework.Scenes { foreach (SceneObjectPart parts in Children.Values) { - parts.StoreUndoState(); + parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION); } m_rootPart.UpdateRotation(rot); @@ -3460,7 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart part = GetChildPart(localID); foreach (SceneObjectPart parts in Children.Values) { - parts.StoreUndoState(); + parts.StoreUndoState(UndoType.STATE_PRIM_ROTATION); } if (part != null) { @@ -3496,7 +3496,7 @@ namespace OpenSim.Region.Framework.Scenes part.UpdateRotation(rot); part.OffsetPosition = pos; part.IgnoreUndoUpdate = false; - part.StoreUndoState(); + part.StoreUndoState(UndoType.STATE_PRIM_ROTATION); } } } @@ -3510,7 +3510,7 @@ namespace OpenSim.Region.Framework.Scenes Quaternion axRot = rot; Quaternion oldParentRot = m_rootPart.RotationOffset; - m_rootPart.StoreUndoState(); + m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION); m_rootPart.UpdateRotation(rot); if (m_rootPart.PhysActor != null) { @@ -3542,7 +3542,7 @@ namespace OpenSim.Region.Framework.Scenes if (childpart != m_rootPart) { childpart.IgnoreUndoUpdate = false; - childpart.StoreUndoState(); + childpart.StoreUndoState(UndoType.STATE_PRIM_ROTATION); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 72ad281..93a23ca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -697,7 +697,7 @@ namespace OpenSim.Region.Framework.Scenes get { return m_offsetPosition; } set { - StoreUndoState(); + StoreUndoState(UndoType.STATE_PRIM_POSITION); m_offsetPosition = value; if (ParentGroup != null && !ParentGroup.IsDeleted) @@ -759,7 +759,7 @@ namespace OpenSim.Region.Framework.Scenes set { - StoreUndoState(); + StoreUndoState(UndoType.STATE_PRIM_ROTATION); m_rotationOffset = value; PhysicsActor actor = PhysActor; @@ -958,7 +958,7 @@ namespace OpenSim.Region.Framework.Scenes get { return m_shape.Scale; } set { - StoreUndoState(); + StoreUndoState(UndoType.STATE_PRIM_SCALE); if (m_shape != null) { m_shape.Scale = value; @@ -1522,7 +1522,7 @@ namespace OpenSim.Region.Framework.Scenes { m_redo.Clear(); } - StoreUndoState(); + StoreUndoState(UndoType.STATE_ALL); } public byte ConvertScriptUintToByte(uint indata) @@ -2721,7 +2721,7 @@ namespace OpenSim.Region.Framework.Scenes /// public void Resize(Vector3 scale) { - StoreUndoState(); + StoreUndoState(UndoType.STATE_PRIM_SCALE); m_shape.Scale = scale; ParentGroup.HasGroupChanged = true; @@ -3504,13 +3504,11 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.ScheduleGroupForTerseUpdate(); //m_parentGroup.ScheduleGroupForFullUpdate(); } - public void StoreUndoState() + public void StoreUndoState(UndoType type) { - StoreUndoState(false); - } - public void StoreUndoState(bool group) - { - if (!Undoing) + + + if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing)) { if (!IgnoreUndoUpdate) { @@ -3521,17 +3519,25 @@ namespace OpenSim.Region.Framework.Scenes if (m_undo.Count > 0) { UndoState last = m_undo.Peek(); - if (last != null) - { - if (last.Compare(this)) - return; - } + } if (m_parentGroup.GetSceneMaxUndo() > 0) { - UndoState nUndo = new UndoState(this); - nUndo.GroupChange = group; + UndoState lastUndo = m_undo.Peek(); + + UndoState nUndo = new UndoState(this, type); + + if (lastUndo != null) + { + TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated); + if (ts.TotalMilliseconds < 500) + { + //Delete the last entry since it was less than 500 milliseconds ago + nUndo.Merge(lastUndo); + m_undo.Pop(); + } + } m_undo.Push(nUndo); } @@ -4008,20 +4014,13 @@ namespace OpenSim.Region.Framework.Scenes if (m_undo.Count > 0) { UndoState nUndo = null; - if (m_parentGroup.GetSceneMaxUndo() > 0) - { - nUndo = new UndoState(this); - } UndoState goback = m_undo.Pop(); - m_log.Debug("Got goback"); - if (goback == null) - { - m_log.Debug("it's null"); - } - else + if (m_parentGroup.GetSceneMaxUndo() > 0) { - m_log.Debug(goback.GroupPosition.ToString()); + nUndo = new UndoState(this, goback.Type); } + + if (goback != null) { goback.PlaybackState(this); @@ -4036,13 +4035,13 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_redo) { + UndoState gofwd = m_redo.Pop(); if (m_parentGroup.GetSceneMaxUndo() > 0) { - UndoState nUndo = new UndoState(this); + UndoState nUndo = new UndoState(this, gofwd.Type); m_undo.Push(nUndo); } - UndoState gofwd = m_redo.Pop(); if (gofwd != null) gofwd.PlayfwdState(this); } diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 5bdaa17..77e477f 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -105,7 +105,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization sceneObject.AddPart(part); part.LinkNum = linkNum; part.TrimPermissions(); - part.StoreUndoState(); + part.StoreUndoState(UndoType.STATE_ALL); reader.Close(); sr.Close(); } @@ -231,7 +231,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization if (originalLinkNum != 0) part.LinkNum = originalLinkNum; - part.StoreUndoState(); + part.StoreUndoState(UndoType.STATE_ALL); reader.Close(); sr.Close(); } diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 77381ab..ad05351 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -27,26 +27,43 @@ using OpenMetaverse; using OpenSim.Region.Framework.Interfaces; +using System; namespace OpenSim.Region.Framework.Scenes { + [Flags] + public enum UndoType + { + STATE_PRIM_POSITION = 1, + STATE_PRIM_ROTATION = 2, + STATE_PRIM_SCALE = 4, + STATE_PRIM_ALL = 7, + STATE_GROUP_POSITION = 8, + STATE_GROUP_ROTATION = 16, + STATE_GROUP_SCALE = 32, + STATE_GROUP_ALL = 56, + STATE_ALL = 63 + } + public class UndoState { public Vector3 Position = Vector3.Zero; public Vector3 Scale = Vector3.Zero; public Quaternion Rotation = Quaternion.Identity; - public bool GroupChange = false; public Vector3 GroupPosition = Vector3.Zero; public Quaternion GroupRotation = Quaternion.Identity; public Vector3 GroupScale = Vector3.Zero; + public DateTime LastUpdated = DateTime.Now; + public UndoType Type; - public UndoState(SceneObjectPart part) + public UndoState(SceneObjectPart part, UndoType type) { + Type = type; if (part != null) { if (part.ParentID == 0) { - GroupScale = part.Shape.Scale; + GroupScale = part.ParentGroup.RootPart.Shape.Scale; //FUBAR WARNING: Do NOT get the group's absoluteposition here //or you'll experience a loop and/or a stack issue @@ -55,6 +72,7 @@ namespace OpenSim.Region.Framework.Scenes Position = part.ParentGroup.RootPart.AbsolutePosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; + LastUpdated = DateTime.Now; } else { @@ -67,10 +85,54 @@ namespace OpenSim.Region.Framework.Scenes Position = part.OffsetPosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; + LastUpdated = DateTime.Now; } } } - + public void Merge(UndoState last) + { + if ((Type & UndoType.STATE_GROUP_POSITION) == 0 || ((last.Type & UndoType.STATE_GROUP_POSITION) >= (Type & UndoType.STATE_GROUP_POSITION))) + { + GroupPosition = last.GroupPosition; + Position = last.Position; + } + if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE))) + { + Console.WriteLine("Setting groupscale to " + last.GroupScale.ToString()); + GroupScale = last.GroupScale; + Scale = last.Scale; + } + if ((Type & UndoType.STATE_GROUP_ROTATION) == 0 || ((last.Type & UndoType.STATE_GROUP_ROTATION) >= (Type & UndoType.STATE_GROUP_ROTATION))) + { + GroupRotation = last.GroupRotation; + Rotation = last.Rotation; + } + if ((Type & UndoType.STATE_PRIM_POSITION) == 0 || ((last.Type & UndoType.STATE_PRIM_POSITION) >= (Type & UndoType.STATE_PRIM_POSITION))) + { + Position = last.Position; + } + if ((Type & UndoType.STATE_PRIM_SCALE) == 0 || ((last.Type & UndoType.STATE_PRIM_SCALE) >= (Type & UndoType.STATE_PRIM_SCALE))) + { + Scale = last.Scale; + } + if ((Type & UndoType.STATE_PRIM_ROTATION) == 0 || ((last.Type & UndoType.STATE_PRIM_ROTATION) >= (Type & UndoType.STATE_PRIM_ROTATION))) + { + Rotation = last.Rotation; + } + Type = Type | last.Type; + } + public bool Compare(UndoState undo) + { + if (undo == null || Position == null) return false; + if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation) + { + return true; + } + else + { + return false; + } + } public bool Compare(SceneObjectPart part) { if (part != null) @@ -96,6 +158,14 @@ namespace OpenSim.Region.Framework.Scenes public void PlaybackState(SceneObjectPart part) { + bool GroupChange = false; + if ((Type & UndoType.STATE_GROUP_POSITION) != 0 + || (Type & UndoType.STATE_GROUP_ROTATION) != 0 + || (Type & UndoType.STATE_GROUP_SCALE) != 0) + { + GroupChange = true; + } + if (part != null) { part.Undoing = true; @@ -113,6 +183,7 @@ namespace OpenSim.Region.Framework.Scenes { if (GroupChange) { + part.ParentGroup.RootPart.Undoing = true; if (Position != Vector3.Zero) { //Calculate the scale... @@ -125,6 +196,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentGroup.Rotation = GroupRotation; } + part.ParentGroup.RootPart.Undoing = false; } else { -- cgit v1.1 From c616335019dc9419460407930af4e40e84663efa Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 19:58:52 -0700 Subject: Rotation undo fix and remove a debug chatter i missed. Still not working: Individual child prim rotational undo and special cases where the root prim was moved or rotated (all the children then need to restore their offsets). Coming shortly. --- OpenSim/Region/Framework/Scenes/UndoState.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index ad05351..f9601e6 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.Framework.Scenes //FUBAR WARNING: Do NOT get the group's absoluteposition here //or you'll experience a loop and/or a stack issue GroupPosition = part.ParentGroup.RootPart.AbsolutePosition; - GroupRotation = part.ParentGroup.Rotation; + GroupRotation = part.ParentGroup.GroupRotation; Position = part.ParentGroup.RootPart.AbsolutePosition; Rotation = part.RotationOffset; Scale = part.Shape.Scale; @@ -98,7 +98,6 @@ namespace OpenSim.Region.Framework.Scenes } if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE))) { - Console.WriteLine("Setting groupscale to " + last.GroupScale.ToString()); GroupScale = last.GroupScale; Scale = last.Scale; } @@ -184,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes if (GroupChange) { part.ParentGroup.RootPart.Undoing = true; - if (Position != Vector3.Zero) + if (GroupPosition != Vector3.Zero) { //Calculate the scale... Vector3 gs = part.Shape.Scale; @@ -193,7 +192,7 @@ namespace OpenSim.Region.Framework.Scenes //Scale first since it can affect our position part.ParentGroup.GroupResize(gs * scale, part.LocalId); part.ParentGroup.AbsolutePosition = GroupPosition; - part.ParentGroup.Rotation = GroupRotation; + part.ParentGroup.UpdateGroupRotationR(GroupRotation); } part.ParentGroup.RootPart.Undoing = false; -- cgit v1.1 From 8849b9af8bd3260152dede0ccf61fd98137ef6c5 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 4 Jul 2010 20:45:11 -0700 Subject: Fix single prim rotation undo. All UNDO functions are now working correctly except for when the root prim is moved or rotated as a single prim (coming soon). --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 34712b8..7492601 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3492,11 +3492,11 @@ namespace OpenSim.Region.Framework.Scenes } else { + part.StoreUndoState(UndoType.STATE_PRIM_ROTATION); part.IgnoreUndoUpdate = true; part.UpdateRotation(rot); part.OffsetPosition = pos; part.IgnoreUndoUpdate = false; - part.StoreUndoState(UndoType.STATE_PRIM_ROTATION); } } } -- cgit v1.1 From be5dd04150bae69745de3cf5efde3d5be288dd71 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 5 Jul 2010 03:58:18 -0700 Subject: Bring "Redo" up to date with "Undo" so it works too --- OpenSim/Region/Framework/Scenes/UndoState.cs | 41 +++++++--------------------- 1 file changed, 10 insertions(+), 31 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index f9601e6..2af3316 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -123,7 +123,7 @@ namespace OpenSim.Region.Framework.Scenes public bool Compare(UndoState undo) { if (undo == null || Position == null) return false; - if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation) + if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation) { return true; } @@ -155,7 +155,7 @@ namespace OpenSim.Region.Framework.Scenes return false; } - public void PlaybackState(SceneObjectPart part) + private void RestoreState(SceneObjectPart part) { bool GroupChange = false; if ((Type & UndoType.STATE_GROUP_POSITION) != 0 @@ -172,7 +172,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0 && GroupChange == false) { if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; + part.ParentGroup.AbsolutePosition = Position; part.RotationOffset = Rotation; if (Scale != Vector3.Zero) part.Resize(Scale); @@ -193,7 +193,7 @@ namespace OpenSim.Region.Framework.Scenes part.ParentGroup.GroupResize(gs * scale, part.LocalId); part.ParentGroup.AbsolutePosition = GroupPosition; part.ParentGroup.UpdateGroupRotationR(GroupRotation); - + } part.ParentGroup.RootPart.Undoing = false; } @@ -211,35 +211,13 @@ namespace OpenSim.Region.Framework.Scenes } } + public void PlaybackState(SceneObjectPart part) + { + RestoreState(part); + } public void PlayfwdState(SceneObjectPart part) { - if (part != null) - { - part.Undoing = true; - - if (part.ParentID == 0) - { - if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; - if (Rotation != Quaternion.Identity) - part.UpdateRotation(Rotation); - if (Scale != Vector3.Zero) - part.Resize(Scale); - part.ParentGroup.ScheduleGroupForTerseUpdate(); - } - else - { - if (Position != Vector3.Zero) - part.OffsetPosition = Position; - if (Rotation != Quaternion.Identity) - part.UpdateRotation(Rotation); - if (Scale != Vector3.Zero) - part.Resize(Scale); - part.ScheduleTerseUpdate(); - } - part.Undoing = false; - - } + RestoreState(part); } } public class LandUndoState @@ -267,3 +245,4 @@ namespace OpenSim.Region.Framework.Scenes } } } + -- cgit v1.1 From e947d04038f7b42929368d9f7b6d440be139e675 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 5 Jul 2010 05:44:35 -0700 Subject: Undo fix is now complete. This commit repairs the special case of the root prim moving or rotating independently of the rest of the group. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 49 +++++++++++++++++----- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 - OpenSim/Region/Framework/Scenes/UndoState.cs | 5 ++- 3 files changed, 41 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7492601..f85d3d9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -3386,10 +3386,27 @@ namespace OpenSim.Region.Framework.Scenes } lockPartsForRead(false); - AbsolutePosition = newPos; + //We have to set undoing here because otherwise an undo state will be saved + if (!m_rootPart.Undoing) + { + m_rootPart.Undoing = true; + AbsolutePosition = newPos; + m_rootPart.Undoing = false; + } + else + { + AbsolutePosition = newPos; + } HasGroupChanged = true; - ScheduleGroupForTerseUpdate(); + if (m_rootPart.Undoing) + { + ScheduleGroupForFullUpdate(); + } + else + { + ScheduleGroupForTerseUpdate(); + } } public void OffsetForNewRegion(Vector3 offset) @@ -3488,7 +3505,16 @@ namespace OpenSim.Region.Framework.Scenes if (part.UUID == m_rootPart.UUID) { UpdateRootRotation(rot); - AbsolutePosition = pos; + if (!m_rootPart.Undoing) + { + m_rootPart.Undoing = true; + AbsolutePosition = pos; + m_rootPart.Undoing = false; + } + else + { + AbsolutePosition = pos; + } } else { @@ -3511,6 +3537,12 @@ namespace OpenSim.Region.Framework.Scenes Quaternion oldParentRot = m_rootPart.RotationOffset; m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION); + bool cancelUndo = false; + if (!m_rootPart.Undoing) + { + m_rootPart.Undoing = true; + cancelUndo = true; + } m_rootPart.UpdateRotation(rot); if (m_rootPart.PhysActor != null) { @@ -3534,18 +3566,13 @@ namespace OpenSim.Region.Framework.Scenes newRot *= Quaternion.Inverse(axRot); prim.RotationOffset = newRot; prim.ScheduleTerseUpdate(); + prim.IgnoreUndoUpdate = false; } } - - foreach (SceneObjectPart childpart in Children.Values) + if (cancelUndo == true) { - if (childpart != m_rootPart) - { - childpart.IgnoreUndoUpdate = false; - childpart.StoreUndoState(UndoType.STATE_PRIM_ROTATION); - } + m_rootPart.Undoing = false; } - lockPartsForRead(false); m_rootPart.ScheduleTerseUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 93a23ca..3327b1e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3506,8 +3506,6 @@ namespace OpenSim.Region.Framework.Scenes } public void StoreUndoState(UndoType type) { - - if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing)) { if (!IgnoreUndoUpdate) diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs index 2af3316..f71b507 100644 --- a/OpenSim/Region/Framework/Scenes/UndoState.cs +++ b/OpenSim/Region/Framework/Scenes/UndoState.cs @@ -172,8 +172,9 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentID == 0 && GroupChange == false) { if (Position != Vector3.Zero) - part.ParentGroup.AbsolutePosition = Position; - part.RotationOffset = Rotation; + + part.ParentGroup.UpdateSinglePosition(Position, part.LocalId); + part.ParentGroup.UpdateSingleRotation(Rotation, part.LocalId); if (Scale != Vector3.Zero) part.Resize(Scale); part.ParentGroup.ScheduleGroupForTerseUpdate(); -- cgit v1.1 From 90c5555d6d542a0c8605759c0036af1c83601ddf Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Tue, 6 Jul 2010 02:22:47 +0000 Subject: rewrote hanging llParseStringKeepNulls() --- .../Shared/Api/Implementation/LSL_Api.cs | 315 ++++++++++----------- 1 file changed, 145 insertions(+), 170 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fb191e6..1459778 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -562,23 +562,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api double sqx = q1.x*q1.x; double sqy = q1.z*q1.z; double sqz = q1.y*q1.y; - double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor - double test = q1.x*q1.z + q1.y*q1.s; - if (test > 0.4999*unit) { // singularity at north pole - eul.z = 2 * Math.Atan2(q1.x,q1.s); - eul.y = Math.PI/2; - eul.x = 0; - return eul; - } - if (test < -0.4999*unit) { // singularity at south pole - eul.z = -2 * Math.Atan2(q1.x,q1.s); - eul.y = -Math.PI/2; - eul.x = 0; - return eul; - } + double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor + double test = q1.x*q1.z + q1.y*q1.s; + if (test > 0.4999*unit) { // singularity at north pole + eul.z = 2 * Math.Atan2(q1.x,q1.s); + eul.y = Math.PI/2; + eul.x = 0; + return eul; + } + if (test < -0.4999*unit) { // singularity at south pole + eul.z = -2 * Math.Atan2(q1.x,q1.s); + eul.y = -Math.PI/2; + eul.x = 0; + return eul; + } eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw); - eul.y = Math.Asin(2*test/unit); - eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw); + eul.y = Math.Asin(2*test/unit); + eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw); return eul; } @@ -804,53 +804,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // This method mimics the 180 errors found in SL // See www.euclideanspace.com... angleBetween - LSL_Vector vec_a = a; - LSL_Vector vec_b = b; - - // Eliminate zero length - LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a); - LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b); - if (vec_a_mag < 0.00001 || - vec_b_mag < 0.00001) - { - return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); - } - - // Normalize - vec_a = llVecNorm(vec_a); - vec_b = llVecNorm(vec_b); - - // Calculate axis and rotation angle - LSL_Vector axis = vec_a % vec_b; - LSL_Float cos_theta = vec_a * vec_b; - - // Check if parallel - if (cos_theta > 0.99999) - { - return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); - } - - // Check if anti-parallel - else if (cos_theta < -0.99999) - { - LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a); - if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0); - return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0); - } - else // other rotation - { - LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f; - axis = llVecNorm(axis); - double x, y, z, s, t; - s = Math.Cos(theta); - t = Math.Sin(theta); - x = axis.x * t; - y = axis.y * t; - z = axis.z * t; - return new LSL_Rotation(x,y,z,s); - } - } - + LSL_Vector vec_a = a; + LSL_Vector vec_b = b; + + // Eliminate zero length + LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a); + LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b); + if (vec_a_mag < 0.00001 || + vec_b_mag < 0.00001) + { + return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); + } + + // Normalize + vec_a = llVecNorm(vec_a); + vec_b = llVecNorm(vec_b); + + // Calculate axis and rotation angle + LSL_Vector axis = vec_a % vec_b; + LSL_Float cos_theta = vec_a * vec_b; + + // Check if parallel + if (cos_theta > 0.99999) + { + return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); + } + + // Check if anti-parallel + else if (cos_theta < -0.99999) + { + LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a); + if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0); + return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0); + } + else // other rotation + { + LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f; + axis = llVecNorm(axis); + double x, y, z, s, t; + s = Math.Cos(theta); + t = Math.Sin(theta); + x = axis.x * t; + y = axis.y * t; + z = axis.z * t; + return new LSL_Rotation(x,y,z,s); + } + } + public void llWhisper(int channelID, string text) { m_host.AddScriptLPS(1); @@ -8627,130 +8627,105 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) { - int beginning = 0; - int srclen = src.Length; - int seplen = separators.Length; - object[] separray = separators.Data; - int spclen = spacers.Length; - object[] spcarray = spacers.Data; - int mlen = seplen+spclen; + int srclen = src.Length; + int seplen = separators.Length; + object[] separray = separators.Data; + int spclen = spacers.Length; + object[] spcarray = spacers.Data; - int[] offset = new int[mlen+1]; - bool[] active = new bool[mlen]; + int outlen = 0; + LSL_String[] outarray = new LSL_String[srclen*2+1]; - int best; - int j; - - // Initial capacity reduces resize cost - - LSL_List tokens = new LSL_List(); + int i, j, lastUsed; m_host.AddScriptLPS(1); - // All entries are initially valid - - for (int i = 0; i < mlen; i++) - active[i] = true; - - offset[mlen] = srclen; - - while (beginning < srclen) - { - - best = mlen; // as bad as it gets + /* + * Point to beginning of current non-delimeter string. + */ + lastUsed = 0; - // Scan for separators + /* + * Scan through source string from beginning to end. + */ + for (i = 0; i < srclen;) { - for (j = 0; j < seplen; j++) - { - if (active[j]) - { - // scan all of the markers - if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) - { - // not present at all - active[j] = false; - } - else - { - // present and correct - if (offset[j] < offset[best]) - { - // closest so far - best = j; - if (offset[best] == beginning) - break; - } - } + /* + * See if rest of string (starting at i) matches any separator. + */ + string rest = src.Substring(i); + for (j = 0; j < seplen; j ++) { + string sep = separray[j].ToString(); + if ((sep.Length > 0) && rest.StartsWith(sep)) { + + /* + * Separator matched, output string from end of last delimeter to beginning of this one. + */ + outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed)); + + /* + * Remove separator from input string. + */ + i += sep.Length; + + /* + * Next non-delimeter starts where this separator left off. + */ + lastUsed = i; + goto nextsrc; } } - // Scan for spacers - - if (offset[best] != beginning) - { - for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) - { - if (active[j]) - { - // scan all of the markers - if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) - { - // not present at all - active[j] = false; - } - else - { - // present and correct - if (offset[j] < offset[best]) - { - // closest so far - best = j; - } - } - } + /* + * See if rest of string (starting at i) matches any spacer. + */ + for (j = 0; j < spclen; j ++) { + string spc = spcarray[j].ToString(); + if ((spc.Length > 0) && rest.StartsWith(spc)) { + + /* + * Spacer matched, output string from end of last delimeter to beginning of this one. + * Then output the spacer itself. + */ + outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed)); + outarray[outlen++] = new LSL_String(spc); + + /* + * Remove spacer from input string. + */ + i += spc.Length; + + /* + * Next non-delimeter starts where this spacer left off. + */ + lastUsed = i; + goto nextsrc; } } - // This is the normal exit from the scanning loop - - if (best == mlen) - { - // no markers were found on this pass - // so we're pretty much done - tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); - break; - } - - // Otherwise we just add the newly delimited token - // and recalculate where the search should continue. - - tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); - - if (best < seplen) - { - beginning = offset[best] + (separray[best].ToString()).Length; - } - else - { - beginning = offset[best] + (spcarray[best - seplen].ToString()).Length; - tokens.Add(new LSL_String(spcarray[best - seplen].ToString())); - } + /* + * Didn't match any separator or spacer, skip over it and it + * becomes part of the non-delimeter string starting with + * lastUsed. + */ + i ++; + nextsrc:; } - // This an awkward an not very intuitive boundary case. If the - // last substring is a tokenizer, then there is an implied trailing - // null list entry. Hopefully the single comparison will not be too - // arduous. Alternatively the 'break' could be replced with a return - // but that's shabby programming. + /* + * Output last non-delimeter (including a possible null string if + * delimeter ran to end of source string). + */ + outarray[outlen++] = new LSL_String(src.Substring(lastUsed)); - if (beginning == srclen) - { - if (srclen != 0) - tokens.Add(new LSL_String("")); + /* + * Make up an exact-sized output array suitable for an LSL_List object. + */ + object[] outlist = new object[outlen]; + for (i = 0; i < outlen; i ++) { + outlist[i] = outarray[i]; } - - return tokens; + return new LSL_List(outlist); } public LSL_Integer llGetObjectPermMask(int mask) -- cgit v1.1 From faaef1b498a09d9f12a77c46391f2379af8ec7ac Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Tue, 6 Jul 2010 23:59:06 +0000 Subject: minimizes temp garbage for llParseStringKeepNulls() and uses common routine for llParseStringKeepNulls()/llParseString2List() --- .../Shared/Api/Implementation/LSL_Api.cs | 201 +++++++-------------- 1 file changed, 67 insertions(+), 134 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b9b3318..b335ae6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5877,74 +5877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) { - m_host.AddScriptLPS(1); - LSL_List ret = new LSL_List(); - LSL_List spacers = new LSL_List(); - if (in_spacers.Length > 0 && separators.Length > 0) - { - for (int i = 0; i < in_spacers.Length; i++) - { - object s = in_spacers.Data[i]; - for (int j = 0; j < separators.Length; j++) - { - if (separators.Data[j].ToString() == s.ToString()) - { - s = null; - break; - } - } - if (s != null) - { - spacers.Add(s); - } - } - } - object[] delimiters = new object[separators.Length + spacers.Length]; - separators.Data.CopyTo(delimiters, 0); - spacers.Data.CopyTo(delimiters, separators.Length); - bool dfound = false; - do - { - dfound = false; - int cindex = -1; - string cdeli = ""; - for (int i = 0; i < delimiters.Length; i++) - { - int index = str.IndexOf(delimiters[i].ToString()); - bool found = index != -1; - if (found && String.Empty != delimiters[i].ToString()) - { - if ((cindex > index) || (cindex == -1)) - { - cindex = index; - cdeli = delimiters[i].ToString(); - } - dfound = dfound || found; - } - } - if (cindex != -1) - { - if (cindex > 0) - { - ret.Add(new LSL_String(str.Substring(0, cindex))); - } - // Cannot use spacers.Contains() because spacers may be either type String or LSLString - for (int j = 0; j < spacers.Length; j++) - { - if (spacers.Data[j].ToString() == cdeli) - { - ret.Add(new LSL_String(cdeli)); - break; - } - } - str = str.Substring(cindex + cdeli.Length); - } - } while (dfound); - if (str != "") - { - ret.Add(new LSL_String(str)); - } - return ret; + return ParseString2List(str, separators, in_spacers, false); } public LSL_Integer llOverMyLand(string id) @@ -8616,8 +8549,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // The function returns an ordered list // representing the tokens found in the supplied // sources string. If two successive tokenizers - // are encountered, then a NULL entry is added - // to the list. + // are encountered, then a null-string entry is + // added to the list. // // It is a precondition that the source and // toekizer lisst are non-null. If they are null, @@ -8625,7 +8558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // while their lengths are being determined. // // A small amount of working memoryis required - // of approximately 8*#tokenizers. + // of approximately 8*#tokenizers + 8*srcstrlen. // // There are many ways in which this function // can be implemented, this implementation is @@ -8641,109 +8574,109 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // and eliminates redundant tokenizers as soon // as is possible. // - // The implementation tries to avoid any copying - // of arrays or other objects. + // The implementation tries to minimize temporary + // garbage generation. // public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) { + return ParseString2List(src, separators, spacers, true); + } + + private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls) + { int srclen = src.Length; int seplen = separators.Length; object[] separray = separators.Data; int spclen = spacers.Length; object[] spcarray = spacers.Data; + int dellen = 0; + string[] delarray = new string[seplen+spclen]; int outlen = 0; - LSL_String[] outarray = new LSL_String[srclen*2+1]; + string[] outarray = new string[srclen*2+1]; - int i, j, lastUsed; + int i, j; + string d; m_host.AddScriptLPS(1); /* - * Point to beginning of current non-delimeter string. + * Convert separator and spacer lists to C# strings. + * Also filter out null strings so we don't hang. */ - lastUsed = 0; + for (i = 0; i < seplen; i ++) { + d = separray[i].ToString(); + if (d.Length > 0) { + delarray[dellen++] = d; + } + } + seplen = dellen; + + for (i = 0; i < spclen; i ++) { + d = spcarray[i].ToString(); + if (d.Length > 0) { + delarray[dellen++] = d; + } + } /* * Scan through source string from beginning to end. */ - for (i = 0; i < srclen;) { + for (i = 0;;) { /* - * See if rest of string (starting at i) matches any separator. + * Find earliest delimeter in src starting at i (if any). */ - string rest = src.Substring(i); - for (j = 0; j < seplen; j ++) { - string sep = separray[j].ToString(); - if ((sep.Length > 0) && rest.StartsWith(sep)) { - - /* - * Separator matched, output string from end of last delimeter to beginning of this one. - */ - outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed)); - - /* - * Remove separator from input string. - */ - i += sep.Length; - - /* - * Next non-delimeter starts where this separator left off. - */ - lastUsed = i; - goto nextsrc; + int earliestDel = -1; + int earliestSrc = srclen; + string earliestStr = null; + for (j = 0; j < dellen; j ++) { + d = delarray[j]; + if (d != null) { + int index = src.IndexOf(d, i); + if (index < 0) { + delarray[j] = null; // delim nowhere in src, don't check it anymore + } else if (index < earliestSrc) { + earliestSrc = index; // where delimeter starts in source string + earliestDel = j; // where delimeter is in delarray[] + earliestStr = d; // the delimeter string from delarray[] + if (index == i) break; // can't do any better than found at beg of string + } } } /* - * See if rest of string (starting at i) matches any spacer. + * Output source string starting at i through start of earliest delimeter. */ - for (j = 0; j < spclen; j ++) { - string spc = spcarray[j].ToString(); - if ((spc.Length > 0) && rest.StartsWith(spc)) { - - /* - * Spacer matched, output string from end of last delimeter to beginning of this one. - * Then output the spacer itself. - */ - outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed)); - outarray[outlen++] = new LSL_String(spc); - - /* - * Remove spacer from input string. - */ - i += spc.Length; - - /* - * Next non-delimeter starts where this spacer left off. - */ - lastUsed = i; - goto nextsrc; - } + if (keepNulls || (earliestSrc > i)) { + outarray[outlen++] = src.Substring(i, earliestSrc - i); } /* - * Didn't match any separator or spacer, skip over it and it - * becomes part of the non-delimeter string starting with - * lastUsed. + * If no delimeter found at or after i, we're done scanning. */ - i ++; - nextsrc:; - } + if (earliestDel < 0) break; - /* - * Output last non-delimeter (including a possible null string if - * delimeter ran to end of source string). - */ - outarray[outlen++] = new LSL_String(src.Substring(lastUsed)); + /* + * If delimeter was a spacer, output the spacer. + */ + if (earliestDel >= seplen) { + outarray[outlen++] = earliestStr; + } + + /* + * Look at rest of src string following delimeter. + */ + i = earliestSrc + earliestStr.Length; + } /* * Make up an exact-sized output array suitable for an LSL_List object. */ object[] outlist = new object[outlen]; for (i = 0; i < outlen; i ++) { - outlist[i] = outarray[i]; + outlist[i] = new LSL_String(outarray[i]); } return new LSL_List(outlist); } -- cgit v1.1 From 05b35eb57ce7cc9fa068f34b5798a6c7c3fc09a8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 8 Jul 2010 18:17:02 +0100 Subject: Correct a merge artefact --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 27 ---------------------- 1 file changed, 27 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 9f29420..ecfc68f 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -11496,33 +11496,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP //m_log.Debug("asset request " + requestID); } - if (null == asset) - { - if ((m_hyperAssets != null) && (transferRequest.TransferInfo.SourceType < 2000)) - { - // Try the user's inventory, but only if it's different from the regions' - string userAssets = m_hyperAssets.GetUserAssetServer(AgentId); - if ((userAssets != string.Empty) && (userAssets != m_hyperAssets.GetSimAssetServer())) - { - m_log.DebugFormat("[CLIENT]: asset {0} not found in local asset storage. Trying user's storage.", id); - if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset) - transferRequest.TransferInfo.SourceType = 2222; // marker - else if (transferRequest.TransferInfo.SourceType == (int)SourceType.SimInventoryItem) - transferRequest.TransferInfo.SourceType = 3333; // marker - - m_assetService.Get(userAssets + "/" + id, transferRequest, AssetReceived); - return; - } - } - - //m_log.DebugFormat("[ASSET CACHE]: Asset transfer request for asset which is {0} already known to be missing. Dropping", requestID); - - //We need to send a TransferAbort here, so the client doesn't wait forever for the asset, - //which causes it to not request any more for a while. Which is bad. - SendTransferAbort(transferRequest); - return; - } - // Scripts cannot be retrieved by direct request if (transferRequest.TransferInfo.SourceType == (int)SourceType.Asset && asset.Type == 10) return; -- cgit v1.1 From 8aa5f30082f667fc23ccfdb839e04ba8b72f872c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 10 Jul 2010 10:51:49 +0200 Subject: Make taken items go back to the folder they came from --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 14 ++++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 +++ 2 files changed, 17 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 90b7b51..2057c65 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -322,6 +322,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } + // Override and put into where it came from, if it came + // from anywhere in inventory + // + if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) + { + if (objectGroup.RootPart.FromFolderID != UUID.Zero) + { + InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID); + folder = m_Scene.InventoryService.GetFolder(f); + } + } + if (folder == null) // None of the above { folder = new InventoryFolderBase(folderID); @@ -485,6 +497,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); + group.RootPart.FromFolderID = item.Folder; + if (!m_Scene.Permissions.CanRezObject( group.Children.Count, remoteClient.AgentId, pos) && !attachment) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 3327b1e..b552cdc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -180,6 +180,9 @@ namespace OpenSim.Region.Framework.Scenes public UUID FromItemID; [XmlIgnore] + public UUID FromFolderID; + + [XmlIgnore] public int STATUS_ROTATE_X; [XmlIgnore] -- cgit v1.1 From cecd660388e0cda34115be44955758e8221a77d1 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 10 Jul 2010 18:48:49 -0700 Subject: Fix an issue where the SynchronousRestObjectRequester will fail if a webserver does not report a content length (-1), but the content is still valid --- OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs index f07f7ab..077a1e8 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestObjectRequester.cs @@ -118,7 +118,7 @@ namespace OpenSim.Framework.Servers.HttpServer { using (WebResponse resp = request.GetResponse()) { - if (resp.ContentLength > 0) + if (resp.ContentLength != 0) { Stream respStream = resp.GetResponseStream(); XmlSerializer deserializer = new XmlSerializer(typeof(TResponse)); -- cgit v1.1 From cea856cfc294fb546332bb86abe9f70d791013d5 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 10 Jul 2010 19:00:12 -0700 Subject: Fix the synchronousrestformsrequester so it will successfully handle a response from a server which does not provide a valid content length header --- OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index b0cf34d..92a6caa 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -99,7 +99,7 @@ namespace OpenSim.Framework.Servers.HttpServer { using (WebResponse resp = request.GetResponse()) { - if (resp.ContentLength > 0) + if (resp.ContentLength != 0) { Stream respStream = null; try -- cgit v1.1 From 7f0f11304f0979355d75538ab7326b687b62e76e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 11 Jul 2010 14:26:57 +0200 Subject: Add scripted controllers into agent intersim messaging --- OpenSim/Framework/ChildAgentDataUpdate.cs | 65 ++++++++++++++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 ++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 33 +++++++++++ 3 files changed, 102 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index a1ac84c..89ee39c 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -265,6 +265,46 @@ namespace OpenSim.Framework } } + public class ControllerData + { + public UUID ItemID; + public uint IgnoreControls; + public uint EventControls; + + public ControllerData(UUID item, uint ignore, uint ev) + { + ItemID = item; + IgnoreControls = ignore; + EventControls = ev; + } + + public ControllerData(OSDMap args) + { + UnpackUpdateMessage(args); + } + + public OSDMap PackUpdateMessage() + { + OSDMap controldata = new OSDMap(); + controldata["item"] = OSD.FromUUID(ItemID); + controldata["ignore"] = OSD.FromInteger(IgnoreControls); + controldata["event"] = OSD.FromInteger(EventControls); + + return controldata; + } + + + public void UnpackUpdateMessage(OSDMap args) + { + if (args["item"] != null) + ItemID = args["item"].AsUUID(); + if (args["ignore"] != null) + IgnoreControls = (uint)args["ignore"].AsInteger(); + if (args["event"] != null) + EventControls = (uint)args["event"].AsInteger(); + } + } + public class AgentData : IAgentData { private UUID m_id; @@ -313,6 +353,9 @@ namespace OpenSim.Framework public UUID[] Wearables; public AttachmentData[] Attachments; + // Scripted + public ControllerData[] Controllers; + public string CallbackURI; public virtual OSDMap Pack() @@ -403,6 +446,14 @@ namespace OpenSim.Framework args["attachments"] = attachs; } + if ((Controllers != null) && (Controllers.Length > 0)) + { + OSDArray controls = new OSDArray(Controllers.Length); + foreach (ControllerData ctl in Controllers) + controls.Add(ctl.PackUpdateMessage()); + args["controllers"] = controls; + } + if ((CallbackURI != null) && (!CallbackURI.Equals(""))) args["callback_uri"] = OSD.FromString(CallbackURI); @@ -559,6 +610,20 @@ namespace OpenSim.Framework } } + if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) + { + OSDArray controls = (OSDArray)(args["controllers"]); + Controllers = new ControllerData[controls.Count]; + int i = 0; + foreach (OSD o in controls) + { + if (o.Type == OSDType.Map) + { + Controllers[i++] = new ControllerData((OSDMap)o); + } + } + } + if (args["callback_uri"] != null) CallbackURI = args["callback_uri"].AsString(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b552cdc..e87766e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4145,6 +4145,10 @@ namespace OpenSim.Region.Framework.Scenes case 16: _nextOwnerMask = ApplyMask(_nextOwnerMask, set, mask) & baseMask; + // Prevent the client from creating no mod, no copy + // objects + if ((_nextOwnerMask & (uint)PermissionMask.Copy) == 0) + _nextOwnerMask |= (uint)PermissionMask.Transfer; break; } SendFullUpdateToAllClients(); diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5ac7755..efe3365 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3365,6 +3365,18 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); cAgent.Attachments = attachs; } + lock (scriptedcontrols) + { + ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; + int i = 0; + + foreach (ScriptControllers c in scriptedcontrols.Values) + { + controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); + } + cAgent.Controllers = controls; + } + // Animations try { @@ -3446,6 +3458,27 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); } catch { } + try + { + lock (scriptedcontrols) + { + if (cAgent.Controllers != null) + { + scriptedcontrols.Clear(); + + foreach (ControllerData c in cAgent.Controllers) + { + ScriptControllers sc = new ScriptControllers(); + sc.itemID = c.ItemID; + sc.ignoreControls = (ScriptControlled)c.IgnoreControls; + sc.eventControls = (ScriptControlled)c.EventControls; + + scriptedcontrols[sc.itemID] = sc; + } + } + } + } + catch { } // Animations try { -- cgit v1.1 From 5f4105d48c9776423a730e6480a2587bd64550a5 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Mon, 12 Jul 2010 13:55:56 -0700 Subject: Removed the CHANGED_COLOR event post from the Color accessor in SOP. This is not the correct usage of this changed event - it's only supposed to be posted when the /textures/ change colour or alpha transparency, not the floating text. This fixes several race conditions in scripts ported from SL. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index e87766e..f8ae321 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -882,7 +882,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_color = value; - TriggerScriptChangedEvent(Changed.COLOR); /* ScheduleFullUpdate() need not be called b/c after * setting the color, the text will be set, so then -- cgit v1.1 From 31cbd6d113c8039c70f874479039cb3eaf689c2a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 13 Jul 2010 18:23:23 +0200 Subject: Add CreateSelected flag onto objects rezzed from inventory --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 2057c65..e5f1e70 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -498,6 +498,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); group.RootPart.FromFolderID = item.Folder; + group.RootPart.CreateSelected = true if (!m_Scene.Permissions.CanRezObject( group.Children.Count, remoteClient.AgentId, pos) -- cgit v1.1 From 89c1c5c35a7665315e66e46276d1b6066f3cf2b8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 13 Jul 2010 20:40:23 +0200 Subject: Revamp the permissions propagation. This MAY mess up. Please test. Change the slam bit from 3 to 4. Assume the old slam bit is always set. The new slam bit is a "changed owner" bit, correcting a bug where an item passed from the creator to another with less than full perms, then back (sale test) would arrive back full perm. Lots of in-code docs. --- OpenSim/Data/Tests/RegionTests.cs | 2 +- .../InventoryAccess/InventoryAccessModule.cs | 54 ++++++--- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 134 +++++++++++++++------ OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 5 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 1 - 6 files changed, 140 insertions(+), 58 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/Tests/RegionTests.cs b/OpenSim/Data/Tests/RegionTests.cs index 1f654d3..2506678 100644 --- a/OpenSim/Data/Tests/RegionTests.cs +++ b/OpenSim/Data/Tests/RegionTests.cs @@ -781,7 +781,7 @@ namespace OpenSim.Data.Tests // Ownership changes when you drop an object into an object // owned by someone else Assert.That(t.OwnerID,Is.EqualTo(sog.RootPart.OwnerID), "Assert.That(t.OwnerID,Is.EqualTo(sog.RootPart.OwnerID))"); - Assert.That(t.CurrentPermissions, Is.EqualTo(curperm | 8), "Assert.That(t.CurrentPermissions, Is.EqualTo(curperm | 8))"); + Assert.That(t.CurrentPermissions, Is.EqualTo(curperm | 16), "Assert.That(t.CurrentPermissions, Is.EqualTo(curperm | 8))"); Assert.That(t.ParentID,Is.EqualTo(sog.RootPart.FolderID), "Assert.That(t.ParentID,Is.EqualTo(sog.RootPart.FolderID))"); Assert.That(t.ParentPartID,Is.EqualTo(sog.RootPart.UUID), "Assert.That(t.ParentPartID,Is.EqualTo(sog.RootPart.UUID))"); } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index e5f1e70..1a7da61 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -381,12 +381,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if ((nextPerms & (uint)PermissionMask.Modify) == 0) perms &= ~(uint)PermissionMask.Modify; + // Make sure all bits but the ones we want are clear + // on take. + // This will be applied to the current perms, so + // it will do what we want. + objectGroup.RootPart.NextOwnerMask &= + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify); + objectGroup.RootPart.NextOwnerMask |= + (uint)PermissionMask.Move; + item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask; item.CurrentPermissions = item.BasePermissions; item.NextPermissions = objectGroup.RootPart.NextOwnerMask; item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask; item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask; - item.CurrentPermissions |= 8; // Slam! + + // Magic number badness. Maybe this deserves an enum. + // bit 4 (16) is the "Slam" bit, it means treat as passed + // and apply next owner perms on rez + item.CurrentPermissions |= 16; // Slam! } else { @@ -396,7 +411,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; item.GroupPermissions = objectGroup.RootPart.GroupMask; - item.CurrentPermissions |= 8; // Slam! + item.CurrentPermissions &= + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify | + (uint)PermissionMask.Move | + 7); // Preserve folded permissions } // TODO: add the new fields (Flags, Sale info, etc) @@ -498,7 +518,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); group.RootPart.FromFolderID = item.Folder; - group.RootPart.CreateSelected = true + + // If it's rezzed in world, select it. Much easier to + // find small items. + // + if (!attachment) + group.RootPart.CreateSelected = true; if (!m_Scene.Permissions.CanRezObject( group.Children.Count, remoteClient.AgentId, pos) @@ -572,7 +597,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess List partList = new List(group.Children.Values); group.SetGroup(remoteClient.ActiveGroupId, remoteClient); - if (rootPart.OwnerID != item.Owner) + if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; @@ -580,14 +605,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (m_Scene.Permissions.PropagatePermissions()) { - if ((item.CurrentPermissions & 8) != 0) + foreach (SceneObjectPart part in partList) { - foreach (SceneObjectPart part in partList) - { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - part.GroupMask = 0; // DO NOT propagate here - } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + part.GroupMask = 0; // DO NOT propagate here } group.ApplyNextOwnerPermissions(); @@ -596,19 +618,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess foreach (SceneObjectPart part in partList) { - if (part.OwnerID != item.Owner) + if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); - } - else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam! - { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - part.GroupMask = 0; // DO NOT propagate here } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 38a5456..5796194 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -280,6 +280,10 @@ namespace OpenSim.Region.Framework.Scenes public void UpdateInventoryItemAsset(IClientAPI remoteClient, UUID transactionID, UUID itemID, InventoryItemBase itemUpd) { + // This one will let people set next perms on items in agent + // inventory. Rut-Roh. Whatever. Make this secure. Yeah. + // + // Passing something to another avatar or a an object will already InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); @@ -289,11 +293,9 @@ namespace OpenSim.Region.Framework.Scenes { item.Name = itemUpd.Name; item.Description = itemUpd.Description; - item.NextPermissions = itemUpd.NextPermissions; - item.CurrentPermissions |= 8; // Slam! - item.EveryOnePermissions = itemUpd.EveryOnePermissions; - item.GroupPermissions = itemUpd.GroupPermissions; - + item.NextPermissions = itemUpd.NextPermissions & item.BasePermissions; + item.EveryOnePermissions = itemUpd.EveryOnePermissions & item.BasePermissions; + item.GroupPermissions = itemUpd.GroupPermissions & item.BasePermissions; item.GroupID = itemUpd.GroupID; item.GroupOwned = itemUpd.GroupOwned; item.CreationDate = itemUpd.CreationDate; @@ -399,28 +401,96 @@ namespace OpenSim.Region.Framework.Scenes if (Permissions.PropagatePermissions() && recipient != senderId) { - // First, make sore base is limited to the next perms - itemCopy.BasePermissions = item.BasePermissions & (item.NextPermissions | (uint)PermissionMask.Move); - // By default, current equals base - itemCopy.CurrentPermissions = itemCopy.BasePermissions & item.CurrentPermissions; - - // If this is an object, replace current perms - // with folded perms + // Trying to do this right this time. This is evil. If + // you believe in Good, go elsewhere. Vampires and other + // evil creatores only beyond this point. You have been + // warned. + + // We're going to mask a lot of things by the next perms + // Tweak the next perms to be nicer to our data + // + // In this mask, all the bits we do NOT want to mess + // with are set. These are: + // + // Transfer + // Copy + // Modufy + uint permsMask = ~ ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify); + + // Now, reduce the next perms to the mask bits + // relevant to the operation + uint nextPerms = permsMask | (item.NextPermissions & + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify)); + + // nextPerms now has all bits set, except for the actual + // next permission bits. + + // This checks for no mod, no copy, no trans. + // This indicates an error or messed up item. Do it like + // SL and assume trans + if (nextPerms == permsMask) + nextPerms |= (uint)PermissionMask.Transfer; + + // Inventory owner perms are the logical AND of the + // folded perms and the root prim perms, however, if + // the root prim is mod, the inventory perms will be + // mod. This happens on "take" and is of little concern + // here, save for preventing escalation + + // This hack ensures that items previously permalocked + // get unlocked when they're passed or rezzed + uint basePerms = item.BasePermissions | + (uint)PermissionMask.Move; + uint ownerPerms = item.CurrentPermissions; + + // Mask the base permissions. This is a conservative + // approach altering only the three main perms + basePerms &= nextPerms; + + // If this is an object, root prim perms may be more + // permissive than folded perms. Use folded perms as + // a mask if (item.InvType == (int)InventoryType.Object) { - itemCopy.CurrentPermissions &= ~(uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer); - itemCopy.CurrentPermissions |= (item.CurrentPermissions & 7) << 13; + // Create a safe mask for the current perms + uint foldedPerms = (item.CurrentPermissions & 7) << 13; + foldedPerms |= permsMask; + + bool isRootMod = (item.CurrentPermissions & + (uint)PermissionMask.Modify) != 0 ? + true : false; + + // Mask the owner perms to the folded perms + ownerPerms &= foldedPerms; + + // If the root was mod, let the mask reflect that + if (isRootMod) + ownerPerms |= (uint)PermissionMask.Modify; } - // Ensure there is no escalation - itemCopy.CurrentPermissions &= (item.NextPermissions | (uint)PermissionMask.Move); + // These will be applied to the root prim at next rez. + // The slam bit (bit 3) and folded permission (bits 0-2) + // are preserved due to the above mangling + ownerPerms &= nextPerms; - // Need slam bit on xfer - itemCopy.CurrentPermissions |= 8; + // Assign to the actual item. Make sure the slam bit is + // set, if it wasn't set before. + itemCopy.BasePermissions = basePerms; + itemCopy.CurrentPermissions = ownerPerms | 16; // Slam itemCopy.NextPermissions = item.NextPermissions; - itemCopy.EveryOnePermissions = 0; + // This preserves "everyone can move" + itemCopy.EveryOnePermissions = item.EveryOnePermissions & + nextPerms; + + // Intentionally killing "share with group" here, as + // the recipient will not have the group this is + // set to itemCopy.GroupPermissions = 0; } else @@ -922,7 +992,7 @@ namespace OpenSim.Region.Framework.Scenes else agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions; - agentItem.CurrentPermissions |= 8; + agentItem.CurrentPermissions |= 16; // Slam agentItem.NextPermissions = taskItem.NextPermissions; agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions; @@ -1113,7 +1183,7 @@ namespace OpenSim.Region.Framework.Scenes (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.BasePermissions = srcTaskItem.BasePermissions & (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); - destTaskItem.CurrentPermissions |= 8; // Slam! + destTaskItem.CurrentPermissions |= 16; // Slam! } } @@ -1497,7 +1567,7 @@ namespace OpenSim.Region.Framework.Scenes srcTaskItem.NextPermissions; destTaskItem.BasePermissions = srcTaskItem.BasePermissions & srcTaskItem.NextPermissions; - destTaskItem.CurrentPermissions |= 8; // Slam! + destTaskItem.CurrentPermissions |= 16; // Slam! } } @@ -1889,17 +1959,14 @@ namespace OpenSim.Region.Framework.Scenes group.SetGroup(sourcePart.GroupID, null); - if (rootPart.OwnerID != item.OwnerID) + if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { if (Permissions.PropagatePermissions()) { - if ((item.CurrentPermissions & 8) != 0) + foreach (SceneObjectPart part in partList) { - foreach (SceneObjectPart part in partList) - { - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; } group.ApplyNextOwnerPermissions(); } @@ -1907,17 +1974,14 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart part in partList) { - if (part.OwnerID != item.OwnerID) + if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.OwnerID; part.Inventory.ChangeInventoryOwner(item.OwnerID); } - else if ((item.CurrentPermissions & 8) != 0) // Slam! - { - part.EveryoneMask = item.EveryonePermissions; - part.NextOwnerMask = item.NextPermissions; - } + part.EveryoneMask = item.EveryonePermissions; + part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c5fb198..d323e19 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4818,7 +4818,7 @@ namespace OpenSim.Region.Framework.Scenes part.NextOwnerMask; item.GroupPermissions = part.GroupMask & part.NextOwnerMask; - item.CurrentPermissions |= 8; // Slam! + item.CurrentPermissions |= 16; // Slam! item.CreationDate = Util.UnixTimeSinceEpoch(); if (InventoryService.AddItem(item)) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 1149a20..70b37fb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -170,13 +170,14 @@ namespace OpenSim.Region.Framework.Scenes taskItem.GroupPermissions = item.GroupPermissions & item.NextPermissions; taskItem.NextPermissions = item.NextPermissions; - taskItem.CurrentPermissions |= 8; + // We're adding this to a prim we don't own. Force + // owner change + taskItem.CurrentPermissions |= 16; // Slam } else { taskItem.BasePermissions = item.BasePermissions; taskItem.CurrentPermissions = item.CurrentPermissions; - taskItem.CurrentPermissions |= 8; taskItem.EveryonePermissions = item.EveryOnePermissions; taskItem.GroupPermissions = item.GroupPermissions; taskItem.NextPermissions = item.NextPermissions; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 2cde8f3..0066158 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1082,7 +1082,6 @@ namespace OpenSim.Region.Framework.Scenes item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) item.CurrentPermissions &= ~(uint)PermissionMask.Modify; - item.CurrentPermissions |= 8; } item.OwnerChanged = true; item.CurrentPermissions &= item.NextPermissions; -- cgit v1.1 From 7ab103c96f3e82cac592f20d61358e1928da8e27 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Tue, 13 Jul 2010 20:37:13 +0000 Subject: Rewrite collision dictionary handling, cleans up deleted obects/avs. Fixes occasional collision event failure. ChOde only. --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 90 +++++++++++++++++----- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 67 +++++++--------- OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 6 ++ 3 files changed, 103 insertions(+), 60 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 38c38b6..61c16b8 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -565,7 +565,29 @@ namespace OpenSim.Region.Physics.OdePlugin CAPSULE_RADIUS = 0.01f; } + + if(Shell != IntPtr.Zero) + { + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); + } + Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); + _parent_scene.geom_name_map[Shell] = m_name; + _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; +//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name); d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); d.GeomSetCollideBits(Shell, (int)m_collisionFlags); @@ -931,10 +953,23 @@ namespace OpenSim.Region.Physics.OdePlugin Body = IntPtr.Zero; } - if (Shell != IntPtr.Zero) + if(Shell != IntPtr.Zero) { - d.GeomDestroy(Shell); - _parent_scene.geom_name_map.Remove(Shell); + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); Shell = IntPtr.Zero; } @@ -1097,11 +1132,24 @@ namespace OpenSim.Region.Physics.OdePlugin Body = IntPtr.Zero; } - - if (Shell != IntPtr.Zero) + + if(Shell != IntPtr.Zero) { - d.GeomDestroy(Shell); - _parent_scene.geom_name_map.Remove(Shell); + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); Shell = IntPtr.Zero; } } @@ -1277,9 +1325,6 @@ namespace OpenSim.Region.Physics.OdePlugin + (Amotor!=IntPtr.Zero ? "Amotor ":"")); } AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); - - _parent_scene.geom_name_map[Shell] = m_name; - _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; _parent_scene.AddCharacter(this); } else @@ -1299,17 +1344,28 @@ namespace OpenSim.Region.Physics.OdePlugin { //kill the body d.BodyDestroy(Body); - Body = IntPtr.Zero; } - if (Shell != IntPtr.Zero) + if(Shell != IntPtr.Zero) { - d.GeomDestroy(Shell); - _parent_scene.geom_name_map.Remove(Shell); + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries +//string tShell; +//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); +//Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); Shell = IntPtr.Zero; } - } m_isPhysical = m_tainted_isPhysical; @@ -1327,13 +1383,9 @@ namespace OpenSim.Region.Physics.OdePlugin CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); d.BodyDestroy(Body); - d.GeomDestroy(Shell); AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); Velocity = Vector3.Zero; - - _parent_scene.geom_name_map[Shell] = m_name; - _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; } else { diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 7ce01dc..6b17ce7 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.Physics.OdePlugin private OdeScene _parent_scene; public IntPtr m_targetSpace = IntPtr.Zero; public IntPtr prim_geom; - public IntPtr prev_geom; +// public IntPtr prev_geom; public IntPtr _triMeshData; private IntPtr _linkJointGroup = IntPtr.Zero; @@ -274,7 +274,7 @@ namespace OpenSim.Region.Physics.OdePlugin prim_geom = IntPtr.Zero; - prev_geom = IntPtr.Zero; +// prev_geom = IntPtr.Zero; if (!pos.IsFinite()) { @@ -776,13 +776,26 @@ namespace OpenSim.Region.Physics.OdePlugin public void SetGeom(IntPtr geom) { - prev_geom = prim_geom; + if(prim_geom != IntPtr.Zero) + { + // Remove any old entries +//string tPA; +//_parent_scene.geom_name_map.TryGetValue(prim_geom, out tPA); +//Console.WriteLine("**** Remove {0}", tPA); + if(_parent_scene.geom_name_map.ContainsKey(prim_geom)) _parent_scene.geom_name_map.Remove(prim_geom); + if(_parent_scene.actor_name_map.ContainsKey(prim_geom)) _parent_scene.actor_name_map.Remove(prim_geom); + d.GeomDestroy(prim_geom); + } + prim_geom = geom; //Console.WriteLine("SetGeom to " + prim_geom + " for " + m_primName); if (prim_geom != IntPtr.Zero) { + _parent_scene.geom_name_map[prim_geom] = this.m_primName; + _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); +//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, this.m_primName); } if (childPrim) @@ -1774,17 +1787,17 @@ namespace OpenSim.Region.Physics.OdePlugin public void CreateGeom(IntPtr m_targetSpace, IMesh _mesh) { //Console.WriteLine("CreateGeom:"); - if (_mesh != null) + if (_mesh != null) // Special - make mesh { setMesh(_parent_scene, _mesh); } - else + else // not a mesh { - if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) + if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) // special profile?? { - if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) + if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) // Equi-size { - if (((_size.X / 2f) > 0f)) + if (((_size.X / 2f) > 0f)) // Has size { _parent_scene.waitForSpaceUnlock(m_targetSpace); try @@ -1815,7 +1828,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } } - else + else // not equi-size { _parent_scene.waitForSpaceUnlock(m_targetSpace); try @@ -1832,7 +1845,7 @@ namespace OpenSim.Region.Physics.OdePlugin } } - else + else // not special profile { _parent_scene.waitForSpaceUnlock(m_targetSpace); try @@ -1894,9 +1907,6 @@ namespace OpenSim.Region.Physics.OdePlugin } } - _parent_scene.geom_name_map[prim_geom] = this.m_primName; - _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this; - changeSelectedStatus(timestep); m_taintadd = false; @@ -2045,22 +2055,7 @@ Console.WriteLine(" JointCreateFixed"); { if (_pbs.SculptEntry && _parent_scene.meshSculptedPrim) { - - - if (prim_geom != IntPtr.Zero) - { - try - { - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; - _mesh = null; - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.Error("[PHYSICS]: PrimGeom dead"); - } - } + _mesh = null; //Console.WriteLine("changePhysicsStatus for " + m_primName ); changeadd(2f); } @@ -2120,8 +2115,6 @@ Console.WriteLine(" JointCreateFixed"); _parent_scene.waitForSpaceUnlock(m_targetSpace); d.SpaceRemove(m_targetSpace, prim_geom); } - d.GeomDestroy(prim_geom); - prim_geom = IntPtr.Zero; // we don't need to do space calculation because the client sends a position update also. // Construction of new prim @@ -2223,16 +2216,8 @@ Console.WriteLine(" JointCreateFixed"); disableBody(); } } - try - { - d.GeomDestroy(prim_geom); - } - catch (System.AccessViolationException) - { - prim_geom = IntPtr.Zero; - m_log.Error("[PHYSICS]: PrimGeom dead"); - } - prim_geom = IntPtr.Zero; + + // we don't need to do space calculation because the client sends a position update also. if (_size.X <= 0) _size.X = 0.01f; if (_size.Y <= 0) _size.Y = 0.01f; diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index 79e2986..ab084fd 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -2206,6 +2206,12 @@ namespace OpenSim.Region.Physics.OdePlugin { if (prim.prim_geom != IntPtr.Zero) { + +//string tPA; +//geom_name_map.TryGetValue(prim.prim_geom, out tPA); +//Console.WriteLine("**** Remove {0}", tPA); + if(geom_name_map.ContainsKey(prim.prim_geom)) geom_name_map.Remove(prim.prim_geom); + if(actor_name_map.ContainsKey(prim.prim_geom)) actor_name_map.Remove(prim.prim_geom); d.GeomDestroy(prim.prim_geom); prim.prim_geom = IntPtr.Zero; } -- cgit v1.1 From 8c26c8bbc6d4ee34b5b9255d3807fb4def88367f Mon Sep 17 00:00:00 2001 From: sacha Date: Tue, 13 Jul 2010 21:10:26 +0000 Subject: adding the 'wearble' case for llGetLocalPos. Still not working cause the offsets are not updated (always <0,0,0>) --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5492266..27034ed 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -74,7 +74,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); +// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected IScriptEngine m_ScriptEngine; protected SceneObjectPart m_host; protected uint m_localID; @@ -2136,6 +2136,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetLocalPos() { m_host.AddScriptLPS(1); + if (m_host.IsAttachment == true) { +//m_log.DebugFormat("[localpos]: {0}) {1} {2}",m_host.OffsetPosition.X,m_host.OffsetPosition.Y,m_host.OffsetPosition.Z); + return new LSL_Vector(m_host.OffsetPosition.X, + m_host.OffsetPosition.Y, + m_host.OffsetPosition.Z); + } + if (m_host.ParentID != 0) { return new LSL_Vector(m_host.OffsetPosition.X, -- cgit v1.1 From 7270cd0ade15ac7175e8394e085e48955ccb280c Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 13 Jul 2010 14:57:50 -0700 Subject: Second part of the fix for llGetLocalPos; get attachment offset in the root prim of an attachment. This function now behaves in line with SL. --- .../Shared/Api/Implementation/LSL_Api.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 27034ed..976a9ff 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2136,12 +2136,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Vector llGetLocalPos() { m_host.AddScriptLPS(1); - if (m_host.IsAttachment == true) { -//m_log.DebugFormat("[localpos]: {0}) {1} {2}",m_host.OffsetPosition.X,m_host.OffsetPosition.Y,m_host.OffsetPosition.Z); - return new LSL_Vector(m_host.OffsetPosition.X, - m_host.OffsetPosition.Y, - m_host.OffsetPosition.Z); - } + if (m_host.IsAttachment == true) { + if (m_host.IsRoot == true) + { + return new LSL_Vector(m_host.AbsolutePosition.X, + m_host.AbsolutePosition.Y, + m_host.AbsolutePosition.Z); + + } + else + { + return new LSL_Vector(m_host.OffsetPosition.X, + m_host.OffsetPosition.Y, + m_host.OffsetPosition.Z); + } + } if (m_host.ParentID != 0) { -- cgit v1.1 From c5891c14c7547dc0cbbf1bd5bf3a0d2923616f25 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Tue, 13 Jul 2010 15:32:35 -0700 Subject: Bail out in AttachToBackup if the group is an attachment --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f85d3d9..7053c02 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -679,6 +679,7 @@ namespace OpenSim.Region.Framework.Scenes /// public virtual void AttachToBackup() { + if (IsAttachment) return; m_scene.SceneGraph.FireAttachToBackup(this); if (InSceneBackup) -- cgit v1.1 From af13c80d6835d7440994e6ad50ff40a8e3aeb99e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 03:59:26 +0200 Subject: Remove getting the object capacity from the money module. It is now set directly from the Region Info (and the region ini file) --- OpenSim/Region/CoreModules/World/Land/LandObject.cs | 4 ++-- OpenSim/Region/Framework/Scenes/Scene.cs | 18 +----------------- .../World/MoneyModule/SampleMoneyModule.cs | 7 +++---- 3 files changed, 6 insertions(+), 23 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 3945142..2a87da2 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.World.Land else { // Normal Calculations - return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.objectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); + return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); } } public int GetSimulatorMaxPrimCount(ILandObject thisObject) @@ -158,7 +158,7 @@ namespace OpenSim.Region.CoreModules.World.Land else { //Normal Calculations - return m_scene.objectCapacity; + return m_scene.RegionInfo.ObjectCapacity; } } #endregion diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d323e19..7c25e87 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -492,8 +492,6 @@ namespace OpenSim.Region.Framework.Scenes set { m_sceneGraph.RestorePresences = value; } } - public int objectCapacity = 45000; - #endregion #region BinaryStats @@ -703,7 +701,7 @@ namespace OpenSim.Region.Framework.Scenes StatsReporter.OnSendStatsResult += SendSimStatsPackets; StatsReporter.OnStatsIncorrect += m_sceneGraph.RecalculateStats; - StatsReporter.SetObjectCapacity(objectCapacity); + StatsReporter.SetObjectCapacity(RegionInfo.ObjectCapacity); // Old /* @@ -4206,20 +4204,6 @@ namespace OpenSim.Region.Framework.Scenes #region Other Methods - public void SetObjectCapacity(int objects) - { - // Region specific config overrides global - // - if (RegionInfo.ObjectCapacity != 0) - objects = RegionInfo.ObjectCapacity; - - if (StatsReporter != null) - { - StatsReporter.SetObjectCapacity(objects); - } - objectCapacity = objects; - } - #endregion public void HandleObjectPermissionsUpdate(IClientAPI controller, UUID agentID, UUID sessionID, byte field, uint localId, uint mask, byte set) diff --git a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs index 6f5ef9e..653f856 100644 --- a/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs +++ b/OpenSim/Region/OptionalModules/World/MoneyModule/SampleMoneyModule.cs @@ -138,8 +138,6 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule public void AddRegion(Scene scene) { // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter. - scene.SetObjectCapacity(ObjectCapacity); - if (m_enabled) { scene.RegisterModuleInterface(this); @@ -252,7 +250,6 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule if (config == "Economy" && startupConfig != null) { - ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000); PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); @@ -701,7 +698,9 @@ namespace OpenSim.Region.OptionalModules.World.MoneyModule if (user != null) { - user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, + Scene s = LocateSceneClientIn(user.AgentId); + + user.SendEconomyData(EnergyEfficiency, s.RegionInfo.ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, TeleportMinPrice, TeleportPriceExponent); -- cgit v1.1 From cbb3a8ab94f8df6963f8045a3ca3795bcbcfe0b5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 16:21:55 +0200 Subject: Fix a permissions issue --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 15 +++++++++++---- .../Framework/Scenes/SceneObjectGroup.Inventory.cs | 18 +++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 5796194..e972382 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -447,10 +447,6 @@ namespace OpenSim.Region.Framework.Scenes (uint)PermissionMask.Move; uint ownerPerms = item.CurrentPermissions; - // Mask the base permissions. This is a conservative - // approach altering only the three main perms - basePerms &= nextPerms; - // If this is an object, root prim perms may be more // permissive than folded perms. Use folded perms as // a mask @@ -466,10 +462,17 @@ namespace OpenSim.Region.Framework.Scenes // Mask the owner perms to the folded perms ownerPerms &= foldedPerms; + basePerms &= foldedPerms; // If the root was mod, let the mask reflect that + // We also need to adjust the base here, because + // we should be able to edit in-inventory perms + // for the root prim, if it's mod. if (isRootMod) + { ownerPerms |= (uint)PermissionMask.Modify; + basePerms |= (uint)PermissionMask.Modify; + } } // These will be applied to the root prim at next rez. @@ -477,6 +480,10 @@ namespace OpenSim.Region.Framework.Scenes // are preserved due to the above mangling ownerPerms &= nextPerms; + // Mask the base permissions. This is a conservative + // approach altering only the three main perms + basePerms &= nextPerms; + // Assign to the actual item. Make sure the slam bit is // set, if it wasn't set before. itemCopy.BasePermissions = basePerms; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 70b37fb..abb4de6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -280,7 +280,7 @@ namespace OpenSim.Region.Framework.Scenes PermissionMask.Move | PermissionMask.Transfer) | 7; - uint ownerMask = 0x7ffffff; + uint ownerMask = 0x7fffffff; foreach (SceneObjectPart part in m_parts.Values) { ownerMask &= part.OwnerMask; @@ -294,12 +294,16 @@ namespace OpenSim.Region.Framework.Scenes if ((ownerMask & (uint)PermissionMask.Transfer) == 0) perms &= ~(uint)PermissionMask.Transfer; - if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0) - perms &= ~((uint)PermissionMask.Modify >> 13); - if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0) - perms &= ~((uint)PermissionMask.Copy >> 13); - if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0) - perms &= ~((uint)PermissionMask.Transfer >> 13); + // If root prim permissions are applied here, this would screw + // with in-inventory manipulation of the next owner perms + // in a major way. So, let's move this to the give itself. + // Yes. I know. Evil. +// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Modify) == 0) +// perms &= ~((uint)PermissionMask.Modify >> 13); +// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Copy) == 0) +// perms &= ~((uint)PermissionMask.Copy >> 13); +// if ((ownerMask & RootPart.NextOwnerMask & (uint)PermissionMask.Transfer) == 0) +// perms &= ~((uint)PermissionMask.Transfer >> 13); return perms; } -- cgit v1.1 From 0c445239a68688311d6fa7405ef13ceb3e773930 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 19:21:01 +0200 Subject: Remove useless quaternion parameter from AttachObject sig --- OpenSim/Framework/IClientAPI.cs | 2 +- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 +- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 8 ++++---- OpenSim/Region/DataSnapshot/ObjectSnapshot.cs | 2 +- OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | 4 ++-- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index d85b101..100c861 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -57,7 +57,7 @@ namespace OpenSim.Framework RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects); public delegate void ObjectAttach( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent); + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); public delegate void ModifyTerrain(UUID user, float height, float seconds, byte size, byte action, float north, float west, float south, float east, diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index ecfc68f..82b9958 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -5744,7 +5744,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (att.ObjectData.Length > 0) { - handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, att.ObjectData[0].Rotation, false); + handlerObjectAttach(this, att.ObjectData[0].ObjectLocalID, att.AgentData.AttachmentPoint, false); } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d3d6f25..08b2315 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -71,7 +71,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments get { return false; } } - public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent) + public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); @@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; // Calls attach with a Zero position - if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) + if (AttachObject(remoteClient, objectLocalID, AttachmentPt, Vector3.Zero, false)) { m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); @@ -109,7 +109,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } public bool AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Vector3 attachPos, bool silent) { SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); if (group != null) @@ -246,7 +246,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments tainted = true; AttachObject( - remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); + remoteClient, objatt.LocalId, AttachmentPt, objatt.AbsolutePosition, false); //objatt.ScheduleGroupForFullUpdate(); if (tainted) diff --git a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs index 6e69902..00f6918 100644 --- a/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/ObjectSnapshot.cs @@ -73,7 +73,7 @@ namespace OpenSim.Region.DataSnapshot.Providers client.OnGrabUpdate += delegate(UUID objectID, Vector3 offset, Vector3 grapPos, IClientAPI remoteClient, List surfaceArgs) { this.Stale = true; }; client.OnObjectAttach += delegate(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, - Quaternion rot, bool silent) { this.Stale = true; }; + bool silent) { this.Stale = true; }; client.OnObjectDuplicate += delegate(uint localID, Vector3 offset, uint dupeFlags, UUID AgentID, UUID GroupID) { this.Stale = true; }; client.OnObjectDuplicateOnRay += delegate(uint localID, uint dupeFlags, UUID AgentID, UUID GroupID, diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 958847b..11887e6 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -45,7 +45,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// void AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, bool silent); + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent); /// /// Attach an object to an avatar. @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// true if the object was successfully attached, false otherwise bool AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent); + IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Vector3 attachPos, bool silent); /// /// Rez an attachment from user inventory and change inventory status to match. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7c25e87..873a11d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2633,7 +2633,7 @@ namespace OpenSim.Region.Framework.Scenes if (AttachmentsModule != null) AttachmentsModule.AttachObject( - sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false); + sp.ControllingClient, grp.LocalId, (uint)0, grp.AbsolutePosition, false); } else -- cgit v1.1 From bebbe407ee166a0aa22f0ec8d14ada780924f9af Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 19:58:23 +0200 Subject: Major attachments cleanup. Remove unused AttachObject ClientView method Clean up use of AttachObject throughout, reduce number of overloads and number of parameters --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 5 - .../Sirikata/ClientStack/SirikataClientView.cs | 5 - .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 5 - OpenSim/Framework/IClientAPI.cs | 1 - .../Region/ClientStack/LindenUDP/LLClientView.cs | 24 ----- .../Avatar/Attachments/AttachmentsModule.cs | 101 ++++++++++----------- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 4 - .../Framework/Interfaces/IAttachmentsModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +- .../Server/IRCClientView.cs | 5 - .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 - .../Shared/Api/Implementation/LSL_Api.cs | 9 -- OpenSim/Tests/Common/Mock/TestClient.cs | 4 - 13 files changed, 49 insertions(+), 123 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 5798a64..ce2e9a1 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -1047,11 +1047,6 @@ namespace OpenSim.Client.MXP.ClientStack // Minimap function, not used. } - public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - // Need to translate to MXP somehow - } - public void SetChildAgentThrottle(byte[] throttle) { // Need to translate to MXP somehow diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index 906947e..2063616 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -602,11 +602,6 @@ namespace OpenSim.Client.Sirikata.ClientStack throw new System.NotImplementedException(); } - public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - throw new System.NotImplementedException(); - } - public void SetChildAgentThrottle(byte[] throttle) { throw new System.NotImplementedException(); diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 13a27f5..841f9a4 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -608,11 +608,6 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - throw new System.NotImplementedException(); - } - public void SetChildAgentThrottle(byte[] throttle) { throw new System.NotImplementedException(); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 100c861..95aec94 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1019,7 +1019,6 @@ namespace OpenSim.Framework void SendCoarseLocationUpdate(List users, List CoarseLocations); - void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID); void SetChildAgentThrottle(byte[] throttle); void SendAvatarDataImmediate(ISceneEntity avatar); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 82b9958..754127d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3687,30 +3687,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Primitive Packet/Data Sending Methods - /// - /// - /// - /// - /// - /// - public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD - return; - - ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach); - // TODO: don't create new blocks if recycling an old packet - attach.AgentData.AgentID = AgentId; - attach.AgentData.SessionID = m_sessionId; - attach.AgentData.AttachmentPoint = attachPoint; - attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1]; - attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock(); - attach.ObjectData[0].ObjectLocalID = localID; - attach.ObjectData[0].Rotation = rotation; - attach.Header.Zerocoded = true; - OutPacket(attach, ThrottleOutPacketType.Task); - } - void HandleQueueEmpty(ThrottleOutPacketTypeFlags categories) { if ((categories & ThrottleOutPacketTypeFlags.Task) != 0) diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 08b2315..902fb88 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -71,6 +71,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments get { return false; } } + // Called by client + // public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { m_log.Debug("[ATTACHMENTS MODULE]: Invoking AttachObject"); @@ -86,7 +88,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return; // Calls attach with a Zero position - if (AttachObject(remoteClient, objectLocalID, AttachmentPt, Vector3.Zero, false)) + if (AttachObject(remoteClient, part.ParentGroup, AttachmentPt, false)) { m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); @@ -108,72 +110,64 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public bool AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Vector3 attachPos, bool silent) + public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) { - SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); - if (group != null) + Vector3 attachPos = group.AbsolutePosition; + + if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { - if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) + // If the attachment point isn't the same as the one previously used + // set it's offset position = 0 so that it appears on the attachment point + // and not in a weird location somewhere unknown. + if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) { - // If the attachment point isn't the same as the one previously used - // set it's offset position = 0 so that it appears on the attachment point - // and not in a weird location somewhere unknown. - if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) - { - attachPos = Vector3.Zero; - } - - // AttachmentPt 0 means the client chose to 'wear' the attachment. - if (AttachmentPt == 0) - { - // Check object for stored attachment point - AttachmentPt = (uint)group.GetAttachmentPoint(); - } - - // if we still didn't find a suitable attachment point....... - if (AttachmentPt == 0) - { - // Stick it on left hand with Zero Offset from the attachment point. - AttachmentPt = (uint)AttachmentPoint.LeftHand; - attachPos = Vector3.Zero; - } + attachPos = Vector3.Zero; + } - group.SetAttachmentPoint((byte)AttachmentPt); - group.AbsolutePosition = attachPos; + // AttachmentPt 0 means the client chose to 'wear' the attachment. + if (AttachmentPt == 0) + { + // Check object for stored attachment point + AttachmentPt = (uint)group.GetAttachmentPoint(); + } - // Saves and gets itemID - UUID itemId; + // if we still didn't find a suitable attachment point....... + if (AttachmentPt == 0) + { + // Stick it on left hand with Zero Offset from the attachment point. + AttachmentPt = (uint)AttachmentPoint.LeftHand; + attachPos = Vector3.Zero; + } - if (group.GetFromItemID() == UUID.Zero) - { - m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); - } - else - { - itemId = group.GetFromItemID(); - } + group.SetAttachmentPoint((byte)AttachmentPt); + group.AbsolutePosition = attachPos; - SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); + // Saves and gets itemID + UUID itemId; - group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); - - // In case it is later dropped again, don't let - // it get cleaned up - group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); - group.HasGroupChanged = false; + if (group.GetFromItemID() == UUID.Zero) + { + m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); } else { - remoteClient.SendAgentAlertMessage( - "You don't have sufficient permissions to attach this object", false); - - return false; + itemId = group.GetFromItemID(); } + + SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); + + group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); + + // In case it is later dropped again, don't let + // it get cleaned up + group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); + group.HasGroupChanged = false; } else { - m_log.DebugFormat("[ATTACHMENTS MODULE]: AttachObject found no such scene object {0}", objectLocalID); + remoteClient.SendAgentAlertMessage( + "You don't have sufficient permissions to attach this object", false); + return false; } @@ -245,8 +239,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; - AttachObject( - remoteClient, objatt.LocalId, AttachmentPt, objatt.AbsolutePosition, false); + AttachObject(remoteClient, objatt, AttachmentPt, false); //objatt.ScheduleGroupForFullUpdate(); if (tainted) diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 8ec5bb5..4db8f9e 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -536,10 +536,6 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - } - public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 11887e6..9fe6d96 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -58,7 +58,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// true if the object was successfully attached, false otherwise bool AttachObject( - IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Vector3 attachPos, bool silent); + IClientAPI remoteClient, SceneObjectGroup grp, uint AttachmentPt, bool silent); /// /// Rez an attachment from user inventory and change inventory status to match. diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 873a11d..daad3d2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2632,8 +2632,7 @@ namespace OpenSim.Region.Framework.Scenes RootPrim.RemFlag(PrimFlags.TemporaryOnRez); if (AttachmentsModule != null) - AttachmentsModule.AttachObject( - sp.ControllingClient, grp.LocalId, (uint)0, grp.AbsolutePosition, false); + AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); } else diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index d72ee6f..c7a9484 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1064,11 +1064,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - - } - public void SendAvatarDataImmediate(ISceneEntity avatar) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index c3edba2..23255fb 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -627,10 +627,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - } - public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 976a9ff..defe633 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3160,15 +3160,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence presence = World.GetScenePresence(m_host.OwnerID); - /* - IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; - if (attachmentsModule != null) - { - attachmentsModule.AttachObject( - presence.ControllingClient, grp.LocalId, - (uint)attachment, Quaternion.Identity, Vector3.Zero, false); - } - */ grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false); } } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index f8304c0..2993b46 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -630,10 +630,6 @@ namespace OpenSim.Tests.Common.Mock { } - public virtual void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID) - { - } - public virtual void SendDialog(string objectname, UUID objectID, string ownerFirstName, string ownerLastName, string msg, UUID textureID, int ch, string[] buttonlabels) { } -- cgit v1.1 From d665f0ae66adc82ada320e3150a580be2fcb928f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 20:46:26 +0200 Subject: Detach attachments displaced by other attachments --- .../Avatar/Attachments/AttachmentsModule.cs | 24 +++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 902fb88..34198d2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -142,19 +142,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments group.SetAttachmentPoint((byte)AttachmentPt); group.AbsolutePosition = attachPos; - // Saves and gets itemID - UUID itemId; + // Remove any previous attachments + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + UUID itemID = UUID.Zero; + if (sp != null) + { + foreach(SceneObjectGroup grp in sp.Attachments) + { + if (grp.GetAttachmentPoint() == (byte)AttachmentPt) + { + itemID = grp.GetFromItemID(); + break; + } + } + if (itemID != UUID.Zero) + DetachSingleAttachmentToInv(itemID, remoteClient); + } if (group.GetFromItemID() == UUID.Zero) { - m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); + m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); } else { - itemId = group.GetFromItemID(); + itemID = group.GetFromItemID(); } - SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemId, group); + SetAttachmentInventoryStatus(remoteClient, AttachmentPt, itemID, group); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); -- cgit v1.1 From ddfff55cc76144607086fbca03c86df57a271ed0 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 14 Jul 2010 21:06:49 +0200 Subject: Preserve attachment data while a prim is in world. Allows attachment editing on the ground without losing attachpoint and position --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 10 ++++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 ++++++++ 2 files changed, 18 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 1a7da61..1bf3a66 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -219,6 +219,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess Vector3 originalPosition = objectGroup.AbsolutePosition; + // Restore attachment data after trip through the sim + if (objectGroup.RootPart.AttachPoint > 0) + inventoryStoredPosition = objectGroup.RootPart.AttachOffset; + objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; + objectGroup.AbsolutePosition = inventoryStoredPosition; string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); @@ -516,6 +521,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); + Vector3 storedPosition = group.AbsolutePosition; group.RootPart.FromFolderID = item.Folder; @@ -635,6 +641,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { + // Save attachment data + group.RootPart.AttachPoint = group.RootPart.Shape.State; + group.RootPart.AttachOffset = storedPosition; + group.ClearPartAttachmentData(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index f8ae321..87b2d74 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -182,6 +182,14 @@ namespace OpenSim.Region.Framework.Scenes [XmlIgnore] public UUID FromFolderID; + // The following two are to hold the attachment data + // while an object is inworld + [XmlIgnore] + public byte AttachPoint = 0; + + [XmlIgnore] + public Vector3 AttachOffset = Vector3.Zero; + [XmlIgnore] public int STATUS_ROTATE_X; -- cgit v1.1 From 8d2b4b7b487f7a35b610d894c03619e638866473 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 15 Jul 2010 20:03:08 +0200 Subject: Fix a few permissions vulnerability. Owners could cause permissions escalation on items contained in prims using a hacked viewer --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 35 ++++++++++++++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++ .../Framework/Scenes/SceneObjectPartInventory.cs | 6 ---- 3 files changed, 35 insertions(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index c77efc7..e1674be 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1359,16 +1359,45 @@ namespace OpenSim.Region.Framework.Scenes { agentTransactions.HandleTaskItemUpdateFromTransaction( remoteClient, part, transactionID, currentItem); - } - if (part.Inventory.UpdateInventoryItem(itemInfo)) - { + if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) remoteClient.SendAgentAlertMessage("Notecard saved", false); else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) remoteClient.SendAgentAlertMessage("Script saved", false); else remoteClient.SendAgentAlertMessage("Item saved", false); + } + // Check if we're allowed to mess with permissions + if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god + { + if (remoteClient.AgentId != part.OwnerID) // Not owner + { + // Friends and group members can't change any perms + itemInfo.BasePermissions = currentItem.BasePermissions; + itemInfo.EveryonePermissions = currentItem.EveryonePermissions; + itemInfo.GroupPermissions = currentItem.GroupPermissions; + itemInfo.NextPermissions = currentItem.NextPermissions; + itemInfo.CurrentPermissions = currentItem.CurrentPermissions; + } + else + { + // Owner can't change base, and can change other + // only up to base + // Base ALWAYS has move + currentItem.BasePermissions |= (uint)PermissionMask.Move; + itemInfo.BasePermissions = currentItem.BasePermissions; + itemInfo.EveryonePermissions &= currentItem.BasePermissions; + itemInfo.GroupPermissions &= currentItem.BasePermissions; + itemInfo.CurrentPermissions &= currentItem.BasePermissions; + itemInfo.NextPermissions &= currentItem.BasePermissions; + // Next ALWAYS has move + itemInfo.NextPermissions |= (uint)PermissionMask.Move; + } + + } + if (part.Inventory.UpdateInventoryItem(itemInfo)) + { part.GetProperties(remoteClient); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 87b2d74..b19c443 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4156,6 +4156,9 @@ namespace OpenSim.Region.Framework.Scenes // objects if ((_nextOwnerMask & (uint)PermissionMask.Copy) == 0) _nextOwnerMask |= (uint)PermissionMask.Transfer; + + _nextOwnerMask |= (uint)PermissionMask.Move; + break; } SendFullUpdateToAllClients(); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 0066158..2a3727a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -762,12 +762,6 @@ namespace OpenSim.Region.Framework.Scenes else if ((InventoryType)item.Type == InventoryType.Notecard) { ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); - - if (presence != null) - { - presence.ControllingClient.SendAgentAlertMessage( - "Notecard saved", false); - } } m_items[item.ItemID] = item; -- cgit v1.1 From 3f91805afbff1b69ebebcee4ed2593671cf12e12 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 15 Jul 2010 20:28:18 +0200 Subject: prevent hacked viewers from being able to delete arbitrary items from any prim. Allow friends with perms and shared group members to move or copy things out of prims --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index e1674be..4575068 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -935,6 +935,9 @@ namespace OpenSim.Region.Framework.Scenes } if (part != null && group != null) { + if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) + return; + TaskInventoryItem item = group.GetInventoryItem(localID, itemID); if (item == null) return; @@ -1074,9 +1077,21 @@ namespace OpenSim.Region.Framework.Scenes return; } - // Only owner can copy - if (remoteClient.AgentId != taskItem.OwnerID) - return; + TaskInventoryItem item = part.Inventory.GetInventoryItem(itemId); + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + { + // If the item to be moved is no copy, we need to be able to + // edit the prim. + if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) + return; + } + else + { + // If the item is copiable, then we just need to have perms + // on it. The delete check is a pure rights check + if (!Permissions.CanDeleteObject(part.UUID, remoteClient.AgentId)) + return; + } MoveTaskInventoryItem(remoteClient, folderId, part, itemId); } -- cgit v1.1 From 2e5f200b3b571575c6fefe58d2a4a37bf0745303 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 16 Jul 2010 20:23:41 +0200 Subject: Fix showing CreateSelected on all parts of a rez --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 1bf3a66..c300250 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -529,7 +529,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // find small items. // if (!attachment) + { group.RootPart.CreateSelected = true; + foreach (SceneObjectPart child in group.Children.Values) + child.CreateSelected = true; + } if (!m_Scene.Permissions.CanRezObject( group.Children.Count, remoteClient.AgentId, pos) -- cgit v1.1 From 236c0f8e8b5f9ef86c8614b53e5f404754c9e8d9 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Fri, 16 Jul 2010 22:17:06 +0000 Subject: Fix llSetForecAndTorque([0]) stops linear motion. Mantis #187 --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 6b17ce7..7e70db9 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -1735,6 +1735,13 @@ namespace OpenSim.Region.Physics.OdePlugin if (m_isphysical) { disableBodySoft(); + + if (Body != IntPtr.Zero) + { + d.BodySetLinearVel(Body, 0f, 0f, 0f); + d.BodySetForce(Body, 0, 0, 0); + enableBodySoft(); + } } } else @@ -1756,6 +1763,7 @@ namespace OpenSim.Region.Physics.OdePlugin d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } +/* Uhhh - stop the motion if the object is _selected_!! if (m_isphysical) { if (Body != IntPtr.Zero) @@ -1765,6 +1773,7 @@ namespace OpenSim.Region.Physics.OdePlugin enableBodySoft(); } } +*/ } resetCollisionAccounting(); -- cgit v1.1 From 9bf6179d24cc7fd63643627914272adc78385f1e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 17 Jul 2010 02:26:09 +0200 Subject: Fix scripted give of items --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index defe633..b196642 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4177,7 +4177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api byte[] bucket = new byte[17]; bucket[0] = (byte)assetType; - byte[] objBytes = objId.GetBytes(); + byte[] objBytes = agentItem.ID.GetBytes(); Array.Copy(objBytes, 0, bucket, 1, 16); Console.WriteLine("Giving inventory"); -- cgit v1.1 From e06b7ee3689bdfd8d71ef3199edb2fb220ec5c21 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 17 Jul 2010 02:38:00 +0200 Subject: Make webloading more robust by addign retries --- .../RegionLoader/Web/RegionLoaderWebServer.cs | 48 ++++++++++------------ 1 file changed, 22 insertions(+), 26 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs index 0ec4af5..dd224cd 100644 --- a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs +++ b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs @@ -48,6 +48,9 @@ namespace OpenSim.Framework.RegionLoader.Web public RegionInfo[] LoadRegions() { + int tries = 3; + int wait = 2000; + if (m_configSource == null) { m_log.Error("[WEBLOADER]: Unable to load configuration source!"); @@ -64,35 +67,28 @@ namespace OpenSim.Framework.RegionLoader.Web } else { - HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); - webRequest.Timeout = 30000; //30 Second Timeout - m_log.Debug("[WEBLOADER]: Sending Download Request..."); - HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse(); - m_log.Debug("[WEBLOADER]: Downloading Region Information From Remote Server..."); - StreamReader reader = new StreamReader(webResponse.GetResponseStream()); - string xmlSource = String.Empty; - string tempStr = reader.ReadLine(); - while (tempStr != null) - { - xmlSource = xmlSource + tempStr; - tempStr = reader.ReadLine(); - } - m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " + - xmlSource.Length); - XmlDocument xmlDoc = new XmlDocument(); - xmlDoc.LoadXml(xmlSource); - if (xmlDoc.FirstChild.Name == "Regions") + while (tries > 0) { - RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count]; - int i; - for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++) + HttpWebRequest webRequest = (HttpWebRequest) WebRequest.Create(url); + webRequest.Timeout = 30000; //30 Second Timeout + m_log.Debug("[WEBLOADER]: Sending Download Request..."); + HttpWebResponse webResponse = (HttpWebResponse) webRequest.GetResponse(); + m_log.Debug("[WEBLOADER]: Downloading Region Information From Remote Server..."); + StreamReader reader = new StreamReader(webResponse.GetResponseStream()); + string xmlSource = String.Empty; + string tempStr = reader.ReadLine(); + while (tempStr != null) { - m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml); - regionInfos[i] = - new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource); + xmlSource = xmlSource + tempStr; + tempStr = reader.ReadLine(); + } + m_log.Debug("[WEBLOADER]: Request yielded no regions."); + tries--; + if (tries > 0) + { + m_log.Debug("[WEBLOADER]: Retrying"); + System.Threading.Thread.Sleep(wait); } - - return regionInfos; } return null; } -- cgit v1.1 From d1040c9ff9b47b143e456d06801bd6be148bb1b9 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 17 Jul 2010 02:46:04 +0200 Subject: Replace the screenful of code i deleted. --- .../RegionLoader/Web/RegionLoaderWebServer.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs index dd224cd..f0ffc2c 100644 --- a/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs +++ b/OpenSim/Framework/RegionLoader/Web/RegionLoaderWebServer.cs @@ -82,6 +82,25 @@ namespace OpenSim.Framework.RegionLoader.Web xmlSource = xmlSource + tempStr; tempStr = reader.ReadLine(); } + m_log.Debug("[WEBLOADER]: Done downloading region information from server. Total Bytes: " + + xmlSource.Length); + XmlDocument xmlDoc = new XmlDocument(); + xmlDoc.LoadXml(xmlSource); + if (xmlDoc.FirstChild.Name == "Regions") + { + RegionInfo[] regionInfos = new RegionInfo[xmlDoc.FirstChild.ChildNodes.Count]; + int i; + for (i = 0; i < xmlDoc.FirstChild.ChildNodes.Count; i++) + { + m_log.Debug(xmlDoc.FirstChild.ChildNodes[i].OuterXml); + regionInfos[i] = + new RegionInfo("REGION CONFIG #" + (i + 1), xmlDoc.FirstChild.ChildNodes[i],false,m_configSource); + } + + if (i > 0) + return regionInfos; + } + m_log.Debug("[WEBLOADER]: Request yielded no regions."); tries--; if (tries > 0) -- cgit v1.1 From c41d418380789255de778499c426d293969760f5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 17 Jul 2010 16:32:55 +0200 Subject: Allow communicating with blue box dialogs across a region border via a child agent --- OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index 4e36c5d..fb0bd1a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -86,14 +86,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { ScenePresence sp = m_scene.GetScenePresence(agentID); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendAgentAlertMessage(message, modal); } public void SendAlertToUser(string firstName, string lastName, string message, bool modal) { ScenePresence presence = m_scene.GetScenePresence(firstName, lastName); - if (presence != null && !presence.IsChildAgent) + if (presence != null) presence.ControllingClient.SendAgentAlertMessage(message, modal); } @@ -101,8 +101,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { m_scene.ForEachScenePresence(delegate(ScenePresence presence) { - if (!presence.IsChildAgent) - presence.ControllingClient.SendAlertMessage(message); + presence.ControllingClient.SendAlertMessage(message); }); } @@ -124,7 +123,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog } ScenePresence sp = m_scene.GetScenePresence(avatarID); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); } @@ -133,7 +132,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog { ScenePresence sp = m_scene.GetScenePresence(avatarID); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); } @@ -154,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog ScenePresence sp = m_scene.GetScenePresence(avatarid); - if (sp != null && !sp.IsChildAgent) + if (sp != null) sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); } @@ -218,4 +217,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Dialog return result; } } -} \ No newline at end of file +} -- cgit v1.1 From d52fb4d2e944db4a31ddafaefcdda3690f1c6bb7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 17 Jul 2010 16:35:14 +0200 Subject: Shorten LLEmail delay to 15s. With the external spam protection, we can afford to do that --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b196642..a947b3d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3314,7 +3314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } emailModule.SendEmail(m_host.UUID, address, subject, message); - ScriptSleep(20000); + ScriptSleep(15000); } public void llGetNextEmail(string address, string subject) -- cgit v1.1 From 17412389f3cbc4a98c3fb11963ebec821fcd5e11 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 17 Jul 2010 14:34:35 -0700 Subject: Revert 233c872.. "* Call client.Start() sunchronously. Calling thos async avoids some stuttering", pending fix for the core issue --- OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index f2bcc0b..cda461c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -900,16 +900,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Start the IClientAPI // Spin it off so that it doesn't clog up the LLUDPServer - //Util.FireAndForget(delegate(object o) { client.Start(); }); - - // NOTE: DO NOT CALL THIS ASYNCHRONOUSLY!!!!! - // This method will ultimately cause the modules to hook - // client events in OnNewClient. If they can't do this - // before further packets are processed, packets WILL BE LOST. - // This includes the all-important EconomyDataRequest! - // So using FireAndForget here WILL screw up money. Badly. - // You have been warned! - client.Start(); + Util.FireAndForget(delegate(object o) { client.Start(); }); } else { -- cgit v1.1 From fabe2206db37be39a90254da8a7fff973f2dd977 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sat, 17 Jul 2010 15:08:59 -0700 Subject: Ensure that packets do NOT get delivered to a client before the modules that can deal with the client's response have finished loading. --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 9 +++++++++ .../Region/ClientStack/LindenUDP/LLUDPClient.cs | 10 ++++++++++ .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 23 +++++++++++++++++++++- 3 files changed, 41 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 754127d..a9f9d60 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -334,6 +334,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // protected HashSet m_attachmentsSent; private int m_moneyBalance; + private bool m_deliverPackets = true; private int m_animationSequenceNumber = 1; private bool m_SendLogoutPacketWhenClosing = true; private AgentUpdateArgs lastarg; @@ -378,6 +379,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP get { return m_startpos; } set { m_startpos = value; } } + public bool DeliverPackets + { + get { return m_deliverPackets; } + set { + m_deliverPackets = value; + m_udpClient.m_deliverPackets = value; + } + } public UUID AgentId { get { return m_agentId; } } public UUID ActiveGroupId { get { return m_activeGroupID; } } public string ActiveGroupName { get { return m_activeGroupName; } } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 6232c48..eebbfa5 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs @@ -149,6 +149,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_defaultRTO = 3000; private int m_maxRTO = 60000; + public bool m_deliverPackets = true; /// /// Default constructor @@ -389,6 +390,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (category >= 0 && category < m_packetOutboxes.Length) { OpenSim.Framework.LocklessQueue queue = m_packetOutboxes[category]; + + if (m_deliverPackets == false) + { + queue.Enqueue(packet); + return true; + } + TokenBucket bucket = m_throttleCategories[category]; if (bucket.RemoveTokens(packet.Buffer.DataLength)) @@ -419,6 +427,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// True if any packets were sent, otherwise false public bool DequeueOutgoing() { + if (m_deliverPackets == false) return false; + OutgoingPacket packet; OpenSim.Framework.LocklessQueue queue; TokenBucket bucket; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index cda461c..3b63bcd 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -900,7 +900,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Start the IClientAPI // Spin it off so that it doesn't clog up the LLUDPServer - Util.FireAndForget(delegate(object o) { client.Start(); }); + + //First, and very importantly: + // + //Set our DeliverPackets flag in the client to *false* + //this will prevent us from missing important messages + //before the modules are bound + client.DeliverPackets = false; + + Util.FireAndForget( + delegate + { + try + { + client.Start(); + } + finally + { + //Now, release the hounds. er, packets. + client.DeliverPackets = true; + } + } + ); } else { -- cgit v1.1 From c088397ec72916dfb2914b44f2be8df827fd89d9 Mon Sep 17 00:00:00 2001 From: Tom Grimshaw Date: Sun, 18 Jul 2010 06:01:26 -0700 Subject: If the client requests that an object be deleted, and the SOG/SOP is null and/or is marked as deleted, just send the KillObject --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4575068..989ec37 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1700,11 +1700,19 @@ namespace OpenSim.Region.Framework.Scenes // Invalid id SceneObjectPart part = GetSceneObjectPart(localID); if (part == null) + { + //Client still thinks the object exists, kill it + SendKillObject(localID); continue; + } // Already deleted by someone else if (part.ParentGroup == null || part.ParentGroup.IsDeleted) + { + //Client still thinks the object exists, kill it + SendKillObject(localID); continue; + } // Can't delete child prims if (part != part.ParentGroup.RootPart) -- cgit v1.1 From c263fc54ac04ab494a62b6157623d936d966940c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 18 Jul 2010 21:05:50 +0200 Subject: Add a state change method to the Async commands handler to allow timers and http requests to survive state changes --- .../Shared/Api/Implementation/AsyncCommandManager.cs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index ee32755..61e4934 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs @@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } + public static void StateChange(IScriptEngine engine, uint localID, UUID itemID) + { + // Remove a specific script + + // Remove dataserver events + m_Dataserver[engine].RemoveEvents(localID, itemID); + + IWorldComm comms = engine.World.RequestModuleInterface(); + if (comms != null) + comms.DeleteListener(itemID); + + IXMLRPC xmlrpc = engine.World.RequestModuleInterface(); + xmlrpc.DeleteChannels(itemID); + xmlrpc.CancelSRDRequests(itemID); + + // Remove Sensors + m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); + + } + public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) { List data = new List(); -- cgit v1.1 From 54da64acacec9703b95f375aab58890766cc16a4 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 20 Jul 2010 00:46:39 +0200 Subject: Remove exception badness in the LSL Types. Who ever came up with that.....?! --- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index c9049e2..bab5156 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -615,10 +615,10 @@ namespace OpenSim.Region.ScriptEngine.Shared { int la = -1; int lb = -1; - try { la = a.Length; } - catch (NullReferenceException) { } - try { lb = b.Length; } - catch (NullReferenceException) { } + if (a != null) + la = a.Length; + if (b != null) + lb = b.Length; return la == lb; } @@ -627,10 +627,10 @@ namespace OpenSim.Region.ScriptEngine.Shared { int la = -1; int lb = -1; - try { la = a.Length; } - catch (NullReferenceException) { } - try {lb = b.Length;} - catch (NullReferenceException) { } + if (a != null) + la = a.Length; + if (b != null) + lb = b.Length; return la != lb; } -- cgit v1.1 From 191bee2ed0903b23f5d93f79650daf7662480b17 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 20 Jul 2010 00:55:31 +0200 Subject: Remove the null checks altogether --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 +-------- OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs | 16 ++++------------ 2 files changed, 5 insertions(+), 20 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a947b3d..138bcc9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5027,14 +5027,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - if (src == null) - { - return 0; - } - else - { - return src.Length; - } + return src.Length; } public LSL_Integer llList2Integer(LSL_List src, int index) diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs index bab5156..a3a2fdf 100644 --- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs +++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs @@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared public static bool operator ==(list a, list b) { - int la = -1; - int lb = -1; - if (a != null) - la = a.Length; - if (b != null) - lb = b.Length; + int la = a.Length; + int lb = b.Length; return la == lb; } public static bool operator !=(list a, list b) { - int la = -1; - int lb = -1; - if (a != null) - la = a.Length; - if (b != null) - lb = b.Length; + int la = a.Length; + int lb = b.Length; return la != lb; } -- cgit v1.1 From fd66ee57f3b091e6e4b6c619645595b300c94fbb Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 20 Jul 2010 14:45:46 +0200 Subject: When a god uses mass permission setting, the V bit is cleared from next perms, rendering the item unmoveable for the next owenr. Make god mods conform to the rules, too. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 989ec37..59731f7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1383,6 +1383,9 @@ namespace OpenSim.Region.Framework.Scenes remoteClient.SendAgentAlertMessage("Item saved", false); } + // Base ALWAYS has move + currentItem.BasePermissions |= (uint)PermissionMask.Move; + // Check if we're allowed to mess with permissions if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god { @@ -1399,18 +1402,18 @@ namespace OpenSim.Region.Framework.Scenes { // Owner can't change base, and can change other // only up to base - // Base ALWAYS has move - currentItem.BasePermissions |= (uint)PermissionMask.Move; itemInfo.BasePermissions = currentItem.BasePermissions; itemInfo.EveryonePermissions &= currentItem.BasePermissions; itemInfo.GroupPermissions &= currentItem.BasePermissions; itemInfo.CurrentPermissions &= currentItem.BasePermissions; itemInfo.NextPermissions &= currentItem.BasePermissions; - // Next ALWAYS has move - itemInfo.NextPermissions |= (uint)PermissionMask.Move; } } + + // Next ALWAYS has move + itemInfo.NextPermissions |= (uint)PermissionMask.Move; + if (part.Inventory.UpdateInventoryItem(itemInfo)) { part.GetProperties(remoteClient); -- cgit v1.1 From 4ccc141764083ae6dfc0b5b8e303a4395e66b684 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 20 Jul 2010 21:49:31 +0100 Subject: Resync with master --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 44b76b7..8b4f0ed 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -749,13 +749,7 @@ namespace OpenSim.Region.Framework.Scenes item.GroupID = m_part.GroupID; if (item.AssetID == UUID.Zero) - item.AssetID = it.AssetID; - - lock (m_items) - { - m_items[item.ItemID] = item; - m_inventorySerial++; - } + item.AssetID = m_items[item.ItemID].AssetID; m_items[item.ItemID] = item; m_inventorySerial++; -- cgit v1.1 From c72c84b4559ea164bcb77c2d64a046729662bf04 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 21 Jul 2010 12:16:17 +0200 Subject: Refine autoreturn a bit --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 5 ++++- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 ---------- 2 files changed, 4 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 7053c02..e738dd2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1681,7 +1681,10 @@ namespace OpenSim.Region.Framework.Scenes try { - if (!m_scene.ShuttingDown) // if shutting down then there will be nothing to handle the return so leave till next restart + if (!m_scene.ShuttingDown || // if shutting down then there will be nothing to handle the return so leave till next restart + m_scene.LoginsDisabled || // We're starting up or doing maintenance, don't mess with things + m_scene.LoadingPrims) // Land may not be valid yet + { ILandObject parcel = m_scene.LandChannel.GetLandObject( m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1d4c235..a6f0cdd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6348,16 +6348,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api prules.OuterAngle = (float)tempf; prules.PartFlags |= 0x02; // Set new angle format. break; - - case (int)ScriptBaseClass.PSYS_SRC_INNERANGLE: - tempf = (float)rules.GetLSLFloatItem(i + 1); - prules.InnerAngle = (float)tempf; - break; - - case (int)ScriptBaseClass.PSYS_SRC_OUTERANGLE: - tempf = (float)rules.GetLSLFloatItem(i + 1); - prules.OuterAngle = (float)tempf; - break; } } -- cgit v1.1 From fb89d0ff4eb4636a6a70fd45c85b935e0a6b388a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 21 Jul 2010 12:31:59 +0200 Subject: Allow megaregions to be used in M7, should we so decide --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 47 ++++++++++++++------------- 2 files changed, 27 insertions(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index f79bd23..2a498cc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -137,6 +137,7 @@ namespace OpenSim.Region.Framework.Scenes protected SceneCommunicationService m_sceneGridService; public bool LoginsDisabled = true; public bool LoadingPrims = false; + public bool CombineRegions = false; public new float TimeDilation { @@ -768,6 +769,7 @@ namespace OpenSim.Region.Framework.Scenes } m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); + CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); #region BinaryStats diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a36800b..12c1c20 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -283,30 +283,33 @@ namespace OpenSim.Region.Framework.Scenes protected internal bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) { - // KF: Check for out-of-region, move inside and make static. - Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, - sceneObject.RootPart.GroupPosition.Y, - sceneObject.RootPart.GroupPosition.Z); - if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || - npos.X > Constants.RegionSize || - npos.Y > Constants.RegionSize)) - { - if (npos.X < 0.0) npos.X = 1.0f; - if (npos.Y < 0.0) npos.Y = 1.0f; - if (npos.Z < 0.0) npos.Z = 0.0f; - if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; - if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; - - foreach (SceneObjectPart part in sceneObject.Children.Values) + if (!m_parentScene.CombineRegions) + { + // KF: Check for out-of-region, move inside and make static. + Vector3 npos = new Vector3(sceneObject.RootPart.GroupPosition.X, + sceneObject.RootPart.GroupPosition.Y, + sceneObject.RootPart.GroupPosition.Z); + if (!(((sceneObject.RootPart.Shape.PCode == (byte)PCode.Prim) && (sceneObject.RootPart.Shape.State != 0))) && (npos.X < 0.0 || npos.Y < 0.0 || npos.Z < 0.0 || + npos.X > Constants.RegionSize || + npos.Y > Constants.RegionSize)) { - part.GroupPosition = npos; + if (npos.X < 0.0) npos.X = 1.0f; + if (npos.Y < 0.0) npos.Y = 1.0f; + if (npos.Z < 0.0) npos.Z = 0.0f; + if (npos.X > Constants.RegionSize) npos.X = Constants.RegionSize - 1.0f; + if (npos.Y > Constants.RegionSize) npos.Y = Constants.RegionSize - 1.0f; + + foreach (SceneObjectPart part in sceneObject.Children.Values) + { + part.GroupPosition = npos; + } + sceneObject.RootPart.Velocity = Vector3.Zero; + sceneObject.RootPart.AngularVelocity = Vector3.Zero; + sceneObject.RootPart.Acceleration = Vector3.Zero; + sceneObject.RootPart.Velocity = Vector3.Zero; } - sceneObject.RootPart.Velocity = Vector3.Zero; - sceneObject.RootPart.AngularVelocity = Vector3.Zero; - sceneObject.RootPart.Acceleration = Vector3.Zero; - sceneObject.RootPart.Velocity = Vector3.Zero; - } - + } + if (!alreadyPersisted) { sceneObject.ForceInventoryPersistence(); -- cgit v1.1 From ce8b9b41815f518488e123a16e0ef85f7c467631 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 22 Jul 2010 19:20:09 +0200 Subject: LSL compatibility fix. Add 0.1 s sleep to llSetLinkPrimitiveParams so fade scripts will time correctly. The -Fast version works without a delay --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a6f0cdd..de00db3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7165,7 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetPrimParams(m_host, rules); } - public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) + public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) { m_host.AddScriptLPS(1); @@ -7191,9 +7191,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) + public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) { llSetLinkPrimitiveParams(linknumber, rules); + ScriptSleep(100); } protected void SetPrimParams(ScenePresence av, LSL_List rules) -- cgit v1.1 From 7ebabf185ef96c193f6afbe3bdfcdc92c0a2150e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 22 Jul 2010 19:31:02 +0200 Subject: change the delay to 0.2s. My bad. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index de00db3..fb79356 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7194,7 +7194,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) { llSetLinkPrimitiveParams(linknumber, rules); - ScriptSleep(100); + ScriptSleep(200); } protected void SetPrimParams(ScenePresence av, LSL_List rules) -- cgit v1.1 From 83aec1ec94e6c946862794d3e13bc9541d1e10dc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 22 Jul 2010 23:47:10 +0200 Subject: Fix a little infinite recursion i added just for sh.ts and giggles. NOT. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fb79356..8dc83c3 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7193,7 +7193,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) { - llSetLinkPrimitiveParams(linknumber, rules); + llSetLinkPrimitiveParamsFast(linknumber, rules); ScriptSleep(200); } -- cgit v1.1 From 516ec4acd01d70276329d251155775cedf7b8941 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 25 Jul 2010 08:11:39 +0200 Subject: Eat a lockign exception that kills scripts. May bear more investigation in the long run. --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 24d260e..dbf493c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -136,12 +136,21 @@ namespace OpenSim.Region.Framework.Scenes if (m_partsLock.RecursiveReadCount > 0) { m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); - m_partsLock.ExitReadLock(); + try + { + m_partsLock.ExitReadLock(); + } + catch { } // Ignore errors, to allow resync } if (m_partsLock.RecursiveWriteCount > 0) { m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested (write lock exists on this thread). This should not happen and means something needs to be fixed."); - m_partsLock.ExitWriteLock(); + try + { + m_partsLock.ExitWriteLock(); + } + catch { } + } while (!m_partsLock.TryEnterReadLock(60000)) -- cgit v1.1 From 7871dd606eb8c827101ee4ee3c64d00139e1a0b4 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 29 Jul 2010 16:33:20 +0200 Subject: Allow gods and estate managers/owners to be unaffected by parcel bans --- OpenSim/Region/CoreModules/World/Land/LandObject.cs | 6 ++++++ .../CoreModules/World/Permissions/PermissionsModule.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.Permissions.cs | 17 +++++++++++++++++ 3 files changed, 24 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 2a87da2..6864629 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -283,6 +283,9 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsBannedFromLand(UUID avatar) { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); @@ -301,6 +304,9 @@ namespace OpenSim.Region.CoreModules.World.Land public bool IsRestrictedFromLand(UUID avatar) { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) { ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 69b247c..1d70546 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -209,6 +209,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnDeedParcel += CanDeedParcel; m_scene.Permissions.OnDeedObject += CanDeedObject; m_scene.Permissions.OnIsGod += IsGod; + m_scene.Permissions.OnIsAdministrator += IsAdministrator; m_scene.Permissions.OnDuplicateObject += CanDuplicateObject; m_scene.Permissions.OnDeleteObject += CanDeleteObject; //MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnEditObject += CanEditObject; //MAYBE FULLY IMPLEMENTED diff --git a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs index 7dab04f..a523351 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Permissions.cs @@ -64,6 +64,7 @@ namespace OpenSim.Region.Framework.Scenes public delegate bool RunConsoleCommandHandler(UUID user, Scene requestFromScene); public delegate bool IssueEstateCommandHandler(UUID user, Scene requestFromScene, bool ownerCommand); public delegate bool IsGodHandler(UUID user, Scene requestFromScene); + public delegate bool IsAdministratorHandler(UUID user); public delegate bool EditParcelHandler(UUID user, ILandObject parcel, Scene scene); public delegate bool SellParcelHandler(UUID user, ILandObject parcel, Scene scene); public delegate bool AbandonParcelHandler(UUID user, ILandObject parcel, Scene scene); @@ -122,6 +123,7 @@ namespace OpenSim.Region.Framework.Scenes public event RunConsoleCommandHandler OnRunConsoleCommand; public event IssueEstateCommandHandler OnIssueEstateCommand; public event IsGodHandler OnIsGod; + public event IsAdministratorHandler OnIsAdministrator; public event EditParcelHandler OnEditParcel; public event SellParcelHandler OnSellParcel; public event AbandonParcelHandler OnAbandonParcel; @@ -652,6 +654,21 @@ namespace OpenSim.Region.Framework.Scenes } return true; } + + public bool IsAdministrator(UUID user) + { + IsAdministratorHandler handler = OnIsAdministrator; + if (handler != null) + { + Delegate[] list = handler.GetInvocationList(); + foreach (IsAdministratorHandler h in list) + { + if (h(user) == false) + return false; + } + } + return true; + } #endregion #region EDIT PARCEL -- cgit v1.1 From f9280374d2e44f66145718c880119383c2dc2a71 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 30 Jul 2010 15:03:03 +0200 Subject: Bannination fixes. Objects in nonpublic parcels were muted by default. Gods were muted, too. --- OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | 6 +++++- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 9c8cbc6..50d2f9d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -244,7 +244,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat ILandObject Presencecheck = s.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); if (Presencecheck != null) { - if (Presencecheck.IsEitherBannedOrRestricted(c.SenderUUID) != true) + // This will pass all chat from objects. Not + // perfect, but it will do. For now. Better + // than the prior behavior of muting all + // objects on a parcel with access restrictions + if (c.Sender == null || Presencecheck.IsEitherBannedOrRestricted(c.Sender.AgentId) != true) { TrySendChatMessage(presence, fromPos, regionPos, fromID, fromNamePrefix+fromName, c.Type, message, sourceType); } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8dc83c3..15af8b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6075,7 +6075,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_host.ParentGroup.RootPart.AttachmentPoint; } - public LSL_Integer llGetFreeMemory() + public virtual LSL_Integer llGetFreeMemory() { m_host.AddScriptLPS(1); // Make scripts designed for LSO happy -- cgit v1.1 From d5f497478a371107c568844321a4663bccfbf527 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 1 Aug 2010 10:21:56 -0700 Subject: Add config option securePermissionsLoading which will stop the region from loading if the specified permissions modules fail to load. --- OpenSim/Region/Application/OpenSimBase.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 27cb137..9267721 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -88,6 +88,10 @@ namespace OpenSim protected List m_plugins = new List(); + private List m_permsModules; + + private bool m_securePermissionsLoading = true; + /// /// The config information passed into the OpenSimulator region server. /// @@ -185,6 +189,11 @@ namespace OpenSim CreatePIDFile(pidFile); userStatsURI = startupConfig.GetString("Stats_URI", String.Empty); + + m_securePermissionsLoading = startupConfig.GetBoolean("SecurePermissionsLoading", true); + + string permissionModules = startupConfig.GetString("permissionmodules", "DefaultPermissionsModule"); + m_permsModules = new List(permissionModules.Split(',')); } base.StartupSpecific(); @@ -342,6 +351,18 @@ namespace OpenSim } else m_log.Error("[MODULES]: The new RegionModulesController is missing..."); + if (m_securePermissionsLoading) + { + foreach (string s in m_permsModules) + { + if (!scene.RegionModules.ContainsKey(s)) + { + m_log.Fatal("[MODULES]: Required module " + s + " not found."); + Environment.Exit(0); + } + } + } + scene.SetModuleInterfaces(); // First Step of bootreport sequence if (scene.SnmpService != null) -- cgit v1.1 From b860c8021e2fcc2522c931d7e503299079924743 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 1 Aug 2010 10:23:48 -0700 Subject: First, change DefaultPermissionsModule so it returns the correct name... ... Then, make sure we also check the old-style module stack before we throw a tantrum --- OpenSim/Region/Application/OpenSimBase.cs | 15 +++++++++++++-- .../CoreModules/World/Permissions/PermissionsModule.cs | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 9267721..fc67f94 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -357,8 +357,19 @@ namespace OpenSim { if (!scene.RegionModules.ContainsKey(s)) { - m_log.Fatal("[MODULES]: Required module " + s + " not found."); - Environment.Exit(0); + bool found = false; + foreach (IRegionModule m in modules) + { + if (m.Name == s) + { + found = true; + } + } + if (!found) + { + m_log.Fatal("[MODULES]: Required module " + s + " not found."); + Environment.Exit(0); + } } } } diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index 1d70546..8223f12 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -402,7 +402,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions public string Name { - get { return "PermissionsModule"; } + get { return "DefaultPermissionsModule"; } } public bool IsSharedModule -- cgit v1.1 From 763dc8bb76396aeea515b2c7c745cc2eb3a510a9 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 1 Aug 2010 10:24:17 -0700 Subject: Add an m_enabled flag to XmlRpcRouterModule so it won't try to bind the xmlrpc_uri event if it's not mentioned in the ini. --- .../Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index 32659c8..dcac4a9 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule public class XmlRpcRouter : IRegionModule, IXmlRpcRouter { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - + private bool m_enabled = false; public void Initialise(Scene scene, IConfigSource config) { IConfig startupConfig = config.Configs["Startup"]; @@ -53,6 +53,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule "XmlRpcRouterModule") == "XmlRpcRouterModule") { scene.RegisterModuleInterface(this); + m_enabled = true; + } + else + { + m_enabled = false; } } @@ -76,7 +81,10 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule public void RegisterNewReceiver(IScriptModule scriptEngine, UUID channel, UUID objectID, UUID itemID, string uri) { - scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] {uri}); + if (m_enabled) + { + scriptEngine.PostScriptEvent(itemID, "xmlrpc_uri", new Object[] { uri }); + } } public void ScriptRemoved(UUID itemID) -- cgit v1.1 From d2d56494b221be4aa202ac0a965c5b697ac38163 Mon Sep 17 00:00:00 2001 From: Tom Date: Sun, 1 Aug 2010 10:24:43 -0700 Subject: Fix the XmlRpcRouterModule so it reads from the correct config section ([XMLRPC] not [Startup]) and disable by default (since it's disabled in the ini by default) --- .../Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs index dcac4a9..11c87f8 100644 --- a/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/XmlRpcRouterModule/XmlRpcRouterModule.cs @@ -45,12 +45,12 @@ namespace OpenSim.Region.OptionalModules.Scripting.XmlRpcRouterModule private bool m_enabled = false; public void Initialise(Scene scene, IConfigSource config) { - IConfig startupConfig = config.Configs["Startup"]; + IConfig startupConfig = config.Configs["XMLRPC"]; if (startupConfig == null) return; if (startupConfig.GetString("XmlRpcRouterModule", - "XmlRpcRouterModule") == "XmlRpcRouterModule") + "") == "XmlRpcRouterModule") { scene.RegisterModuleInterface(this); m_enabled = true; -- cgit v1.1 From 16e90809a92095f1d0f3a54ca3a7def6dd5ae3b1 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 2 Aug 2010 00:54:58 +0200 Subject: Remove the (wrong) implementation if llPointAt. It never worked on the LL grid and is officially deprecated. There is no way to rotate an avatar programmatically. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 ------ 1 file changed, 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c08c246..52d3285 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3517,17 +3517,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llPointAt(LSL_Vector pos) { m_host.AddScriptLPS(1); - ScenePresence Owner = World.GetScenePresence(m_host.UUID); - LSL_Rotation rot = llEuler2Rot(pos); - Owner.PreviousRotation = Owner.Rotation; - Owner.Rotation = (new Quaternion((float)rot.x,(float)rot.y,(float)rot.z,(float)rot.s)); } public void llStopPointAt() { m_host.AddScriptLPS(1); - ScenePresence Owner = m_host.ParentGroup.Scene.GetScenePresence(m_host.OwnerID); - Owner.Rotation = Owner.PreviousRotation; } public void llTargetOmega(LSL_Vector axis, double spinrate, double gain) -- cgit v1.1 From 8f2986bc6a438ea9f5de912a5b76a196e7933175 Mon Sep 17 00:00:00 2001 From: Tom Date: Mon, 2 Aug 2010 21:54:47 -0700 Subject: Catch meshing error in Meshmerizer --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index fded95e..fb2b462 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -336,16 +336,24 @@ namespace OpenSim.Region.Physics.Meshing bool mirror = ((primShape.SculptType & 128) != 0); bool invert = ((primShape.SculptType & 64) != 0); - sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); - - idata.Dispose(); + try + { + sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); + + idata.Dispose(); - sculptMesh.DumpRaw(baseDir, primName, "primMesh"); + sculptMesh.DumpRaw(baseDir, primName, "primMesh"); - sculptMesh.Scale(size.X, size.Y, size.Z); + sculptMesh.Scale(size.X, size.Y, size.Z); - coords = sculptMesh.coords; - faces = sculptMesh.faces; + coords = sculptMesh.coords; + faces = sculptMesh.faces; + } + catch(Exception ex) + { + m_log.Error("[Meshing]: Unable to generate a Sculpty mesh. " + ex.Message); + return null; + } } else { -- cgit v1.1 From d2d1c63b17a55ed1f324fafff89cfbcbd6618d11 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 3 Aug 2010 05:25:01 +0200 Subject: Revert "Catch meshing error in Meshmerizer" This reverts commit 8f2986bc6a438ea9f5de912a5b76a196e7933175. In favor of a fix that tells us where the issue is instead of eating the error --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index fb2b462..fded95e 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -336,24 +336,16 @@ namespace OpenSim.Region.Physics.Meshing bool mirror = ((primShape.SculptType & 128) != 0); bool invert = ((primShape.SculptType & 64) != 0); - try - { - sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); - - idata.Dispose(); + sculptMesh = new PrimMesher.SculptMesh((Bitmap)idata, sculptType, (int)lod, false, mirror, invert); + + idata.Dispose(); - sculptMesh.DumpRaw(baseDir, primName, "primMesh"); + sculptMesh.DumpRaw(baseDir, primName, "primMesh"); - sculptMesh.Scale(size.X, size.Y, size.Z); + sculptMesh.Scale(size.X, size.Y, size.Z); - coords = sculptMesh.coords; - faces = sculptMesh.faces; - } - catch(Exception ex) - { - m_log.Error("[Meshing]: Unable to generate a Sculpty mesh. " + ex.Message); - return null; - } + coords = sculptMesh.coords; + faces = sculptMesh.faces; } else { -- cgit v1.1 From e3184753a6956078a2e34c449d5e30843b5d7f94 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 3 Aug 2010 05:25:23 +0200 Subject: Log the UUID of a prim that fails meshing and set the prim to phantom during region startup --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b19c443..032fbe8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1497,14 +1497,21 @@ namespace OpenSim.Region.Framework.Scenes // or flexible if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) { - PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( - Name, - Shape, - AbsolutePosition, - Scale, - RotationOffset, - RigidBody); - + try + { + PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( + Name, + Shape, + AbsolutePosition, + Scale, + RotationOffset, + RigidBody); + } + catch + { + m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid); + PhysActor = null; + } // Basic Physics returns null.. joy joy joy. if (PhysActor != null) { -- cgit v1.1 From f04d51378f864d2eb522678b3fb1e239f746bd35 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Aug 2010 11:06:41 -0700 Subject: Drop the RestClient timeout from 15 minutes to 30 seconds. This does not address the problem, but it will allow the regions to recover in the event that the remote server goes away. --- OpenSim/Framework/Communications/RestClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Communications/RestClient.cs b/OpenSim/Framework/Communications/RestClient.cs index 97b3b60..42c0b18 100644 --- a/OpenSim/Framework/Communications/RestClient.cs +++ b/OpenSim/Framework/Communications/RestClient.cs @@ -363,7 +363,7 @@ namespace OpenSim.Framework.Communications _request = (HttpWebRequest) WebRequest.Create(buildUri()); _request.KeepAlive = false; _request.ContentType = "application/xml"; - _request.Timeout = 900000; + _request.Timeout = 30000; _request.Method = RequestMethod; _asyncException = null; _request.ContentLength = src.Length; -- cgit v1.1 From 6e3c79f31e4a552ef81e73156d3f84cbcfbdb2cf Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Tue, 3 Aug 2010 20:09:00 +0000 Subject: don't mask current time reads (since we don't mask the corresponding subtract) if you mask the reads you have to mask the subtract as well. simplest is just don't mask any of it. --- OpenSim/Framework/Watchdog.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 5d46905..bc19dd1 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -51,7 +51,7 @@ namespace OpenSim.Framework public ThreadWatchdogInfo(Thread thread) { Thread = thread; - LastTick = Environment.TickCount & Int32.MaxValue; + LastTick = Environment.TickCount; } } @@ -143,7 +143,7 @@ namespace OpenSim.Framework try { if (m_threads.TryGetValue(threadID, out threadInfo)) - threadInfo.LastTick = Environment.TickCount & Int32.MaxValue; + threadInfo.LastTick = Environment.TickCount; else AddThread(new ThreadWatchdogInfo(Thread.CurrentThread)); } @@ -160,7 +160,7 @@ namespace OpenSim.Framework lock (m_threads) { - int now = Environment.TickCount & Int32.MaxValue; + int now = Environment.TickCount; foreach (ThreadWatchdogInfo threadInfo in m_threads.Values) { -- cgit v1.1 From 1d1da5069ca91282228f453476bee2444138b230 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Aug 2010 14:11:11 -0700 Subject: Catch a meshing exception caused by corrupt or missing sculpt maps, and mark the prim as "mesh failed" so it doesn't try meshing continuously --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 7e70db9..60eda41 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -131,6 +131,7 @@ namespace OpenSim.Region.Physics.OdePlugin //public GCHandle gc; private CollisionLocker ode; + private bool m_meshfailed = false; private bool m_taintforce = false; private bool m_taintaddangularforce = false; private Vector3 m_force; @@ -1882,12 +1883,20 @@ namespace OpenSim.Region.Physics.OdePlugin m_targetSpace = targetspace; - if (_mesh == null) + if (_mesh == null && m_meshfailed == false) { if (_parent_scene.needsMeshing(_pbs)) { // Don't need to re-enable body.. it's done in SetMesh - _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); + try + { + _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size, _parent_scene.meshSculptLOD, IsPhysical); + } + catch + { + //Don't continuously try to mesh prims when meshing has failed + m_meshfailed = true; + } // createmesh returns null when it's a shape that isn't a cube. // m_log.Debug(m_localID); } -- cgit v1.1 From ae99c1393d4555d4cd26249b149078e4cd3d439f Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Aug 2010 15:31:04 -0700 Subject: Fix scripted sit offset in child prims --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index efe3365..1fc4a81 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1935,8 +1935,14 @@ namespace OpenSim.Region.Framework.Scenes //Console.WriteLine("Scripted, unoccupied"); part.SetAvatarOnSitTarget(UUID); // set that Av will be on it offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one - sitOrientation = avSitOrientation; // Change rotatione to the scripted one - OffsetRotation = avSitOrientation; + + Quaternion nrot = avSitOrientation; + if (!part.IsRoot) + { + nrot = nrot * part.RotationOffset; + } + sitOrientation = nrot; // Change rotatione to the scripted one + OffsetRotation = nrot; autopilot = false; // Jump direct to scripted llSitPos() } else @@ -2010,7 +2016,7 @@ namespace OpenSim.Region.Framework.Scenes // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. // { // Single, or Root prim of linkset, target is ClickOffset * RootRot - offsetr = offset * partIRot; + //offsetr = offset * partIRot; // // else // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) @@ -2029,7 +2035,7 @@ namespace OpenSim.Region.Framework.Scenes //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child - ControllingClient.SendSitResponse(part.ParentGroup.UUID, offsetr + part.OffsetPosition, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target // This calls HandleAgentSit twice, once from here, and the client calls @@ -2343,6 +2349,10 @@ namespace OpenSim.Region.Framework.Scenes Quaternion sitTargetOrient = part.SitTargetOrientation; m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); m_pos += SIT_TARGET_ADJUSTMENT; + if (!part.IsRoot) + { + m_pos *= part.RotationOffset; + } m_bodyRot = sitTargetOrient; m_parentPosition = part.AbsolutePosition; part.IsOccupied = true; -- cgit v1.1 From e3cea888fba0afbb97e55b1a2aa8335f78a4ac26 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Aug 2010 16:07:18 -0700 Subject: Fix some more issues causing regions with corrupt sculpts to freeze. --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 60eda41..1604c4b 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -2136,7 +2136,7 @@ Console.WriteLine(" JointCreateFixed"); // we don't need to do space calculation because the client sends a position update also. // Construction of new prim - if (_parent_scene.needsMeshing(_pbs)) + if (_parent_scene.needsMeshing(_pbs) && m_meshfailed == false) { float meshlod = _parent_scene.meshSculptLOD; @@ -2146,8 +2146,15 @@ Console.WriteLine(" JointCreateFixed"); IMesh mesh = null; - if (_parent_scene.needsMeshing(_pbs)) - mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + try + { + if (_parent_scene.needsMeshing(_pbs)) + mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + } + catch + { + m_meshfailed = true; + } //IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); //Console.WriteLine("changesize 1"); @@ -2242,17 +2249,23 @@ Console.WriteLine(" JointCreateFixed"); if (_size.Z <= 0) _size.Z = 0.01f; // Construction of new prim - if (_parent_scene.needsMeshing(_pbs)) + if (_parent_scene.needsMeshing(_pbs) && m_meshfailed == false) { // Don't need to re-enable body.. it's done in SetMesh float meshlod = _parent_scene.meshSculptLOD; if (IsPhysical) meshlod = _parent_scene.MeshSculptphysicalLOD; - - IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + try + { + IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size, meshlod, IsPhysical); + CreateGeom(m_targetSpace, mesh); + } + catch + { + m_meshfailed = true; + } // createmesh returns null when it doesn't mesh. - CreateGeom(m_targetSpace, mesh); } else { -- cgit v1.1 From d9ae8370632810ae10bc1ca4e7a2c51431200d0d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 00:45:15 +0200 Subject: Allow specifying default region flags. Correct a typo. --- OpenSim/Services/GridService/GridService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index f49d86d..ebaed42 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -124,7 +124,7 @@ namespace OpenSim.Services.GridService { // Regions reserved for the null key cannot be taken. if ((string)region.Data["PrincipalID"] == UUID.Zero.ToString()) - return "Region location us reserved"; + return "Region location is reserved"; // Treat it as an auth request // @@ -210,6 +210,7 @@ namespace OpenSim.Services.GridService { int newFlags = 0; string regionName = rdata.RegionName.Trim().Replace(' ', '_'); + newFlags = ParseFlags(newFlags, gridConfig.GetString("DefaultRegionFlags", String.Empty)); newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + regionName, String.Empty)); newFlags = ParseFlags(newFlags, gridConfig.GetString("Region_" + rdata.RegionID.ToString(), String.Empty)); rdata.Data["flags"] = newFlags.ToString(); -- cgit v1.1 From d57bfec702fd6eb067ab5d46cb791690ae81e10d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 02:16:46 +0200 Subject: A god is a god is a god is a god. Right? Right. You're a god from 200, let's show it! --- OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs index 50d2f9d..06b1b00 100644 --- a/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Chat/ChatModule.cs @@ -218,7 +218,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Chat fromPos = avatar.AbsolutePosition; fromName = avatar.Name; fromID = c.Sender.AgentId; - if (avatar.GodLevel > 200) + if (avatar.GodLevel >= 200) { fromNamePrefix = m_adminPrefix; } -- cgit v1.1 From 5ff9db7388b5b05e49092d8ee59b3d1b5c963e78 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 02:51:41 +0200 Subject: Clean up some messiness in IM sending. Having offline IM enabled now no longer suppresses "Inventory Saved" messages. --- .../Avatar/InstantMessage/InstantMessageModule.cs | 3 ++- .../Avatar/InstantMessage/MessageTransferModule.cs | 13 ++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index ffdac58..cbea54c 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -187,7 +187,8 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage delegate(bool success) { if (dialog == (uint)InstantMessageDialog.StartTyping || - dialog == (uint)InstantMessageDialog.StopTyping) + dialog == (uint)InstantMessageDialog.StopTyping || + dialog == (uint)InstantMessageDialog.MessageFromObject) { return; } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index 83209fc..d025f0c 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -185,13 +185,16 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { UndeliveredMessage handlerUndeliveredMessage = OnUndeliveredMessage; - // If this event has handlers, then the IM will be considered - // delivered. This will suppress the error message. + // If this event has handlers, then an IM from an agent will be + // considered delivered. This will suppress the error message. // if (handlerUndeliveredMessage != null) { handlerUndeliveredMessage(im); - result(true); + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + result(true); + else + result(false); return; } @@ -504,14 +507,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // if (upd.RegionID == prevRegionID) { - m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); HandleUndeliveredMessage(im, result); return; } } else { - m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); + // m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); HandleUndeliveredMessage(im, result); return; } -- cgit v1.1 From 0020dbee23bf0bab979225dbcdcc9cbcbe72f27b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 03:23:19 +0200 Subject: Remove StandAlone from default hardcoded config --- OpenSim/Region/Application/ConfigurationLoader.cs | 15 --------------- OpenSim/Tools/Configger/ConfigurationLoader.cs | 15 --------------- 2 files changed, 30 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index cac5fa9..09f7bea 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -308,21 +308,6 @@ namespace OpenSim } { - IConfig config = defaultConfig.Configs["StandAlone"]; - - if (null == config) - config = defaultConfig.AddConfig("StandAlone"); - - config.Set("accounts_authenticate", true); - config.Set("welcome_message", "Welcome to OpenSimulator"); - config.Set("inventory_plugin", "OpenSim.Data.SQLite.dll"); - config.Set("inventory_source", ""); - config.Set("userDatabase_plugin", "OpenSim.Data.SQLite.dll"); - config.Set("user_source", ""); - config.Set("LibrariesXMLFile", string.Format(".{0}inventory{0}Libraries.xml", Path.DirectorySeparatorChar)); - } - - { IConfig config = defaultConfig.Configs["Network"]; if (null == config) diff --git a/OpenSim/Tools/Configger/ConfigurationLoader.cs b/OpenSim/Tools/Configger/ConfigurationLoader.cs index 1619a22..3d1b668 100644 --- a/OpenSim/Tools/Configger/ConfigurationLoader.cs +++ b/OpenSim/Tools/Configger/ConfigurationLoader.cs @@ -242,21 +242,6 @@ namespace OpenSim.Tools.Configger } { - IConfig config = defaultConfig.Configs["StandAlone"]; - - if (null == config) - config = defaultConfig.AddConfig("StandAlone"); - - config.Set("accounts_authenticate", true); - config.Set("welcome_message", "Welcome to OpenSimulator"); - config.Set("inventory_plugin", "OpenSim.Data.SQLite.dll"); - config.Set("inventory_source", ""); - config.Set("userDatabase_plugin", "OpenSim.Data.SQLite.dll"); - config.Set("user_source", ""); - config.Set("LibrariesXMLFile", string.Format(".{0}inventory{0}Libraries.xml", Path.DirectorySeparatorChar)); - } - - { IConfig config = defaultConfig.Configs["Network"]; if (null == config) -- cgit v1.1 From f1c51c8bb4c634cedf9eb57a1bb339d3e8052b10 Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Aug 2010 19:51:32 -0700 Subject: Scripted sit target fixes --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 1fc4a81..d857a1c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1939,7 +1939,7 @@ namespace OpenSim.Region.Framework.Scenes Quaternion nrot = avSitOrientation; if (!part.IsRoot) { - nrot = nrot * part.RotationOffset; + nrot = part.RotationOffset * avSitOrientation; } sitOrientation = nrot; // Change rotatione to the scripted one OffsetRotation = nrot; -- cgit v1.1 From cd9506e8428da7b984bdd833e6855534a90f3b5e Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 3 Aug 2010 22:41:02 -0700 Subject: Don't know HOW we missed this, llSetPos was broken in child prims (and in the llSetPrimitveParams family), it was using the global coordinate as a start location. This resolves mantis #204 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 52d3285..0a1a10c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2116,7 +2116,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { - LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); + LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos); part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); SceneObjectGroup parent = part.ParentGroup; parent.HasGroupChanged = true; -- cgit v1.1 From 463fbb4990226661238f1cc30587a5d1e270d44f Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 4 Aug 2010 00:17:02 -0700 Subject: If a user has no home position set, tell them so instead of leaving the request dangling --- .../Framework/EntityTransfer/EntityTransferModule.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 927eeab..1d1a0a1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -549,6 +549,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (uinfo != null) { + if (uinfo.HomeRegionID == UUID.Zero) + { + // can't find the Home region: Tell viewer and abort + client.SendTeleportFailed("You don't have a home position set."); + return; + } GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); if (regionInfo == null) { @@ -556,7 +562,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.SendTeleportFailed("Your home region could not be found."); return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", regionInfo.RegionName, regionInfo.RegionID, regionInfo.RegionLocX / Constants.RegionSize, regionInfo.RegionLocY / Constants.RegionSize); // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... @@ -564,6 +570,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client, regionInfo.RegionHandle, uinfo.HomePosition, uinfo.HomeLookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); } + else + { + // can't find the Home region: Tell viewer and abort + client.SendTeleportFailed("Your home region could not be found."); + return; + } } #endregion -- cgit v1.1 From a48c4932108c68156ee62e9e39da618e55d85902 Mon Sep 17 00:00:00 2001 From: sacha Date: Wed, 4 Aug 2010 08:16:55 +0000 Subject: Cost Reduction : Removing verbose message.... --- .../CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 0d04491..98545f9 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { - m_log.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog); + //m_log.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog); Scene scene = FindClientScene(client.AgentId); -- cgit v1.1 From 4a3321077163f4e93ac67609428c0e6fa4d31b9e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 4 Aug 2010 18:12:31 +0200 Subject: Send attachment updates only to the owner if it's a HUD --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index a9f9d60..4ab719d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3485,6 +3485,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// public void SendPrimUpdate(ISceneEntity entity, PrimUpdateFlags updateFlags) { + if (entity is SceneObjectPart) + { + SceneObjectPart e = (SceneObjectPart)entity; + SceneObjectGroup g = e.ParentGroup; + if (g.RootPart.Shape.State > 30) // HUD + if (g.OwnerID != AgentId) + return; // Don't send updates for other people's HUDs + } + double priority = m_prioritizer.GetUpdatePriority(this, entity); lock (m_entityUpdates.SyncRoot) -- cgit v1.1 From cb3b124df9213bf12383a5625ac4e545fcc91b87 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Wed, 4 Aug 2010 21:08:00 +0000 Subject: Fixes fresh hollowed prim collision shape. --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 7e70db9..6aa28e0 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -1331,10 +1331,10 @@ namespace OpenSim.Region.Physics.OdePlugin _parent_scene.waitForSpaceUnlock(m_targetSpace); try { - if (prim_geom == IntPtr.Zero) - { + // if (prim_geom == IntPtr.Zero) // setGeom takes care of phys engine recreate and prim_geom pointer + // { SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null)); - } + // } } catch (AccessViolationException) { -- cgit v1.1 From 663e25fd3a67654ea60f91850302f2f17496ba59 Mon Sep 17 00:00:00 2001 From: Tom Date: Wed, 4 Aug 2010 19:46:41 -0700 Subject: Pacify osGetAvatarList to provide LSL types instead of omv types --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index db43902..80b021f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2222,9 +2222,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { if (avatar.IsChildAgent == false) { - result.Add(avatar.UUID); - result.Add(avatar.AbsolutePosition); - result.Add(avatar.Name); + result.Add(new LSL_Key(avatar.UUID.ToString())); + result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z)); + result.Add(new LSL_String(avatar.Name)); } } }); -- cgit v1.1 From 85fd2def9ce04d68d838439e7931b8358db84ebd Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 5 Aug 2010 08:15:05 -0700 Subject: Enforce a 0.2 second sleep on llDie() before the command is executed - this should get rid of ghost prims (which are much rarer, but still occuring) --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0a1a10c..411c811 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1173,7 +1173,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public virtual void llDie() { m_host.AddScriptLPS(1); - if (!m_host.IsAttachment) throw new SelfDeleteException(); + if (!m_host.IsAttachment) + { + //Enforce a sleep here to avoid ghost prims + llSleep(0.2d); + throw new SelfDeleteException(); + } } public LSL_Float llGround(LSL_Vector offset) -- cgit v1.1 From 0eda6714f332b2883e109312b134b102b732bcea Mon Sep 17 00:00:00 2001 From: Tom Date: Thu, 5 Aug 2010 08:41:08 -0700 Subject: llRequestSimulatorData DATA_SIM_POS : Divide by RegionSize, don't multiply. This resolves mantis #215 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 411c811..d61715e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8881,8 +8881,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } reply = new LSL_Vector( - info.RegionLocX * Constants.RegionSize, - info.RegionLocY * Constants.RegionSize, + info.RegionLocX / Constants.RegionSize, + info.RegionLocY / Constants.RegionSize, 0).ToString(); break; case 6: // DATA_SIM_STATUS -- cgit v1.1 From 05520d676ccee950c94d1f8c079afaaaabdb6a49 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 5 Aug 2010 18:45:17 +0200 Subject: Revert "Enforce a 0.2 second sleep on llDie() before the command is executed - this should get rid of ghost prims (which are much rarer, but still occuring)" This reverts commit 85fd2def9ce04d68d838439e7931b8358db84ebd. The sleep helps in only one case: static prims rezzed by script. In other cases (physical prims, bullets) it's harmful. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d61715e..bc47fa1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1173,12 +1173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public virtual void llDie() { m_host.AddScriptLPS(1); - if (!m_host.IsAttachment) - { - //Enforce a sleep here to avoid ghost prims - llSleep(0.2d); - throw new SelfDeleteException(); - } + if (!m_host.IsAttachment) throw new SelfDeleteException(); } public LSL_Float llGround(LSL_Vector offset) -- cgit v1.1 From 8bdbcda2b70ede033c38a604af573554dd2776ad Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 5 Aug 2010 18:50:17 +0200 Subject: We already have a record of killed prims. It just wasn't used by the new JHurlicane code anymore. Use it to prevent sending updates after kills. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 9 +++++++++ OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 9 +++++++++ 2 files changed, 18 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 4ab719d..0b8b95b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3514,6 +3514,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP EntityUpdate update; while (updatesThisCall < maxUpdates && m_entityUpdates.TryDequeue(out update)) { + // If we have sent a kill packet for this object + // drop any updates on the floor + if (update.Entity is SceneObjectPart) + { + SceneObjectPart part = (SceneObjectPart)update.Entity; + if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId)) + continue; + } + ++updatesThisCall; #region UpdateFlags to packet type conversion diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 032fbe8..67cb7cc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3043,6 +3043,15 @@ namespace OpenSim.Region.Framework.Scenes UUID ownerID = _ownerID; UUID objectID = UUID; UUID parentID = GetRootPartUUID(); + + if (ParentGroup.IsAttachment && ParentGroup.RootPart.Shape.State > 30) + { + // Use the avatar as the parent for HUDs, since the prims + // are not sent to other avatars + objectID = _ownerID; + parentID = _ownerID; + } + UUID soundID = UUID.Zero; Vector3 position = AbsolutePosition; // region local ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle; -- cgit v1.1 From d8f9b98c4ab700efcf4016b605461053c3b50fba Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 5 Aug 2010 22:50:09 +0200 Subject: Prevent hammering the grid services with llRequestAgentData requests. Cache the user information permanently, and the online status for 20 seconds. Also cache negatives. --- .../Shared/Api/Implementation/LSL_Api.cs | 55 +++++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index bc47fa1..ad7d650 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -69,6 +69,14 @@ using System.Reflection; namespace OpenSim.Region.ScriptEngine.Shared.Api { + // MUST be a ref type + public class UserInfoCacheEntry + { + public int time; + public UserAccount account; + public PresenceInfo pinfo; + } + /// /// Contains all LSL ll-functions. This class will be in Default AppDomain. /// @@ -93,6 +101,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int m_scriptConsoleChannel = 0; protected bool m_scriptConsoleChannelEnabled = false; protected IUrlModule m_UrlModule = null; + protected Dictionary m_userInfoCache = + new Dictionary(); public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) { @@ -4244,16 +4254,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID uuid = (UUID)id; + PresenceInfo pinfo = null; + UserAccount account; - UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); - if (account == null) - return UUID.Zero.ToString(); + UserInfoCacheEntry ce; + if (!m_userInfoCache.TryGetValue(uuid, out ce)) + { + account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); + if (account == null) + { + m_userInfoCache[uuid] = null; // Cache negative + return UUID.Zero.ToString(); + } - PresenceInfo pinfo = null; - PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); - if (pinfos != null && pinfos.Length > 0) - pinfo = pinfos[0]; + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + pinfo = pinfos[0]; + + ce = new UserInfoCacheEntry(); + ce.time = Util.EnvironmentTickCount(); + ce.account = account; + ce.pinfo = pinfo; + } + else + { + if (ce == null) + return UUID.Zero.ToString(); + + account = ce.account; + pinfo = ce.pinfo; + } + + if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) + { + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + pinfo = pinfos[0]; + + ce.time = Util.EnvironmentTickCount(); + ce.pinfo = pinfo; + } string reply = String.Empty; -- cgit v1.1 From 7368992ee9bbf1aeb5034715e693c82d8ddd4b97 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 5 Aug 2010 23:48:55 +0200 Subject: Actually cache positives --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ad7d650..0f38261 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4276,6 +4276,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ce.time = Util.EnvironmentTickCount(); ce.account = account; ce.pinfo = pinfo; + m_userInfoCache[uuid] = ce; } else { -- cgit v1.1 From d7fe9f7b44311df517a8755dd6cf5603b380c3b8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 6 Aug 2010 00:02:38 +0200 Subject: Prevent users from becoming stuck online. This affects only 0.7 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 0f38261..236458c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4292,6 +4292,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); if (pinfos != null && pinfos.Length > 0) pinfo = pinfos[0]; + else + pinfo = null; ce.time = Util.EnvironmentTickCount(); ce.pinfo = pinfo; -- cgit v1.1 From c5c6627adb79644b93c5871243a9eeeff553829c Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Aug 2010 02:39:42 -0700 Subject: Implement CHANGED_REGION_(RE)START and also fix various CHANGED_* constants which had the wrong values (checked using LSL in SL). This addresses mantis #217 and mantis #53. --- .../Framework/Scenes/Animation/ScenePresenceAnimator.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 7 ++++--- .../Region/Framework/Scenes/SceneObjectPartInventory.cs | 16 ++++++++++++++++ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- .../ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 8 ++++---- .../ScriptEngine/Shared/Instance/ScriptInstance.cs | 4 ++-- 6 files changed, 28 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 702a1e2..b847d87 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -130,7 +130,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, m_scenePresence.UUID)) { // 16384 is CHANGED_ANIMATION - m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 }); + m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { (int)Changed.ANIMATION}); SendAnimPack(); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 032fbe8..a0fabff 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -56,9 +56,10 @@ namespace OpenSim.Region.Framework.Scenes LINK = 32, ALLOWED_DROP = 64, OWNER = 128, - REGION_RESTART = 256, - REGION = 512, - TELEPORT = 1024 + REGION = 256, + TELEPORT = 512, + REGION_RESTART = 1024, + ANIMATION = 16384 } // I don't really know where to put this except here. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8b4f0ed..4f80a7e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -321,6 +321,22 @@ namespace OpenSim.Region.Framework.Scenes StoreScriptErrors(item.ItemID, null); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); + + //This should play nice with XEngine since XEngine loads scripts /after/ the region starts + if (stateSource == 0 && m_part.ParentGroup.Scene.LoginsDisabled == true) + { + IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); + if (engines != null) + { + foreach (IScriptModule xengine in engines) + { + if (xengine != null) + { + xengine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.REGION_RESTART }); + } + } + } + } } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d857a1c..5fcd1c2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3939,7 +3939,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); if (m == null) // No script engine loaded continue; - m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { 16384 }); + m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 96f6486..69f48c9 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -273,10 +273,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int CHANGED_LINK = 32; public const int CHANGED_ALLOWED_DROP = 64; public const int CHANGED_OWNER = 128; - public const int CHANGED_REGION_RESTART = 256; - public const int CHANGED_REGION_START = 256; //LL Changed the constant from CHANGED_REGION_RESTART - public const int CHANGED_REGION = 512; - public const int CHANGED_TELEPORT = 1024; + public const int CHANGED_REGION = 256; + public const int CHANGED_TELEPORT = 512; + public const int CHANGED_REGION_RESTART = 1024; + public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART public const int CHANGED_ANIMATION = 16384; public const int TYPE_INVALID = 0; public const int TYPE_INTEGER = 1; diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index b348403..dcbe0c4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -392,13 +392,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { // m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); PostEvent(new EventParams("changed", - new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0])); + new Object[] { (int)Changed.REGION_RESTART }, new DetectParams[0])); } else if (m_stateSource == StateSource.PrimCrossing) { // CHANGED_REGION PostEvent(new EventParams("changed", - new Object[] {new LSL_Types.LSLInteger(512)}, new DetectParams[0])); + new Object[] { (int)Changed.REGION }, new DetectParams[0])); } } else -- cgit v1.1 From a390541e1c114db419d9a2eb1ac576a582c35e67 Mon Sep 17 00:00:00 2001 From: sacha Date: Fri, 6 Aug 2010 14:38:11 +0000 Subject: Allowing the expected purge trash folder... Please validate !!! --- OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs | 1 + OpenSim/Services/InventoryService/XInventoryService.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index ac6a3ab..e3d30e5 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -408,6 +408,7 @@ namespace OpenSim.Server.Handlers.Asset byte[] HandlePurgeFolder(Dictionary request) { + Dictionary result = new Dictionary(); UUID folderID = UUID.Zero; UUID.TryParse(request["ID"].ToString(), out folderID); diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index f581f76..fc5020d 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -329,8 +329,8 @@ namespace OpenSim.Services.InventoryService if (!m_AllowDelete) return false; - if (!ParentIsTrash(folder.ID)) - return false; +// if (!ParentIsTrash(folder.ID)) +// return false; XInventoryFolder[] subFolders = m_Database.GetFolders( new string[] { "parentFolderID" }, @@ -342,6 +342,7 @@ namespace OpenSim.Services.InventoryService m_Database.DeleteFolders("folderID", x.folderID.ToString()); } + if (!ParentIsTrash(folder.ID)) m_Database.DeleteItems("parentFolderID", folder.ID.ToString()); return true; -- cgit v1.1 From 5da272d0425cc6a971b60a1e5fad556d4d66eb52 Mon Sep 17 00:00:00 2001 From: sacha Date: Fri, 6 Aug 2010 14:45:54 +0000 Subject: reverese my last commit --- OpenSim/Services/InventoryService/XInventoryService.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index fc5020d..541489f 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -329,8 +329,8 @@ namespace OpenSim.Services.InventoryService if (!m_AllowDelete) return false; -// if (!ParentIsTrash(folder.ID)) -// return false; + if (!ParentIsTrash(folder.ID)) + return false; XInventoryFolder[] subFolders = m_Database.GetFolders( new string[] { "parentFolderID" }, @@ -342,8 +342,6 @@ namespace OpenSim.Services.InventoryService m_Database.DeleteFolders("folderID", x.folderID.ToString()); } - if (!ParentIsTrash(folder.ID)) - m_Database.DeleteItems("parentFolderID", folder.ID.ToString()); return true; } -- cgit v1.1 From 42613ec53602093335ebe3ce5127d797318bdf23 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 6 Aug 2010 15:18:48 +0200 Subject: Allow the trash folder itself to be passed to PurgeFolder --- OpenSim/Services/InventoryService/XInventoryService.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 541489f..26c5b33 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -541,6 +541,9 @@ namespace OpenSim.Services.InventoryService if (folder.Length < 1) return false; + if (folder[0].type == (int)AssetType.TrashFolder) + return true; + UUID parentFolder = folder[0].parentFolderID; while (parentFolder != UUID.Zero) -- cgit v1.1 From 696c2c429b3240d775053444943dcfc69c1b814a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 6 Aug 2010 15:33:22 +0200 Subject: Change XEngine to use the new constant --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index dcbe0c4..b4da246 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -388,7 +388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance PostEvent(new EventParams("attach", new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); } - else if (m_stateSource == StateSource.NewRez) + else if (m_stateSource == StateSource.RegionStart) { // m_log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script"); PostEvent(new EventParams("changed", -- cgit v1.1 From a636af13e77aae588f425b7bc9504854a7ed1261 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Aug 2010 06:37:40 -0700 Subject: Make sure the avatar position gets moved along with a prim it is sitting on. This fixes mantis #208 and (maybe) issues with chat and sound coming from the wrong place when sat on a vehicle. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 13 +++++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 22 ++++++++-------------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 13 +++++++++++++ 3 files changed, 32 insertions(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index dbf493c..5a3dc20 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -469,13 +469,22 @@ namespace OpenSim.Region.Framework.Scenes return; } } - foreach (SceneObjectPart part in m_parts.Values) + List parts = new List(m_parts.Values); + lockPartsForRead(false); + foreach (SceneObjectPart part in parts) { part.IgnoreUndoUpdate = false; part.StoreUndoState(UndoType.STATE_GROUP_POSITION); part.GroupPosition = val; } - lockPartsForRead(false); + + foreach (ScenePresence av in m_linkedAvatars) + { + Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; + av.AbsolutePosition += offset; + av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition + av.SendFullUpdateToAllClients(); + } //if (m_rootPart.PhysActor != null) //{ diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index ba84b88..badd357 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -682,25 +682,13 @@ namespace OpenSim.Region.Framework.Scenes // Tell the physics engines that this prim changed. m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); + } catch (Exception e) { m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); } } - - // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too - if (m_sitTargetAvatar != UUID.Zero) - { - if (m_parentGroup != null) // TODO can there be a SOP without a SOG? - { - ScenePresence avatar; - if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar)) - { - avatar.ParentPosition = GetWorldPosition(); - } - } - } } } @@ -709,6 +697,7 @@ namespace OpenSim.Region.Framework.Scenes get { return m_offsetPosition; } set { + Vector3 oldpos = m_offsetPosition; StoreUndoState(UndoType.STATE_PRIM_POSITION); m_offsetPosition = value; @@ -727,7 +716,12 @@ namespace OpenSim.Region.Framework.Scenes List avs = ParentGroup.GetLinkedAvatars(); foreach (ScenePresence av in avs) { - av.SendFullUpdateToAllClients(); + if (av.LinkedPrim == m_uuid) + { + Vector3 offset = (m_offsetPosition - oldpos); + av.OffsetPosition += offset; + av.SendFullUpdateToAllClients(); + } } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5fcd1c2..44c3d12 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -595,11 +595,21 @@ namespace OpenSim.Region.Framework.Scenes private uint m_parentID; + + private UUID m_linkedPrim; + public uint ParentID { get { return m_parentID; } set { m_parentID = value; } } + + public UUID LinkedPrim + { + get { return m_linkedPrim; } + set { m_linkedPrim = value; } + } + public float Health { get { return m_health; } @@ -1835,6 +1845,7 @@ namespace OpenSim.Region.Framework.Scenes m_parentPosition = Vector3.Zero; m_parentID = 0; + m_linkedPrim = UUID.Zero; m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); SendFullUpdateToAllClients(); m_requestedSitTargetID = 0; @@ -2422,6 +2433,8 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); m_parentID = m_requestedSitTargetID; } + m_linkedPrim = part.UUID; + Velocity = Vector3.Zero; RemoveFromPhysicalScene(); -- cgit v1.1 From 3ce335c6f865e1b42fbefd44f38f9a2da09ef853 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Aug 2010 06:41:25 -0700 Subject: Fix StateSource constants, provide RegionStart --- OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs index 9f6ea35..0c99d8c 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs @@ -38,10 +38,11 @@ namespace OpenSim.Region.ScriptEngine.Interfaces { public enum StateSource { - NewRez = 0, - PrimCrossing = 1, - ScriptedRez = 2, - AttachedRez = 3 + RegionStart = 0, + NewRez = 1, + PrimCrossing = 2, + ScriptedRez = 3, + AttachedRez = 4 } public interface IScriptWorkItem -- cgit v1.1 From c48be64d9ab82676a2c1894193db42f0a849ae4d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 6 Aug 2010 16:08:50 +0200 Subject: Remove posting region restart event from SOP, as it's now in XMRe --- .../Region/Framework/Scenes/SceneObjectPartInventory.cs | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 4f80a7e..8b4f0ed 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -321,22 +321,6 @@ namespace OpenSim.Region.Framework.Scenes StoreScriptErrors(item.ItemID, null); m_part.ParentGroup.AddActiveScriptCount(1); m_part.ScheduleFullUpdate(); - - //This should play nice with XEngine since XEngine loads scripts /after/ the region starts - if (stateSource == 0 && m_part.ParentGroup.Scene.LoginsDisabled == true) - { - IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces(); - if (engines != null) - { - foreach (IScriptModule xengine in engines) - { - if (xengine != null) - { - xengine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.REGION_RESTART }); - } - } - } - } } } } -- cgit v1.1 From 52e2360e9178394664d6925e14da8468cbf90cd5 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Aug 2010 08:08:43 -0700 Subject: Since i've narrowed the fault down to one function, add some spammy debug to try and fix ghost prims on HUDs in future. Note, the console only gets messages if there is a problem, so it's harmless. --- .../InventoryAccess/InventoryAccessModule.cs | 57 ++++++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index c300250..2517a23 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -496,6 +496,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (item != null) { + if (item.ID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 1"); + } + AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); if (rezAsset != null) @@ -518,11 +523,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess itemId = item.ID; } + if (item.ID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 2"); + } + string xmlData = Utils.BytesToString(rezAsset.Data); SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); Vector3 storedPosition = group.AbsolutePosition; - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); + } group.RootPart.FromFolderID = item.Folder; // If it's rezzed in world, select it. Much easier to @@ -548,9 +561,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess remoteClient.SendBulkUpdateInventory(item); return null; } - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 4"); + } group.ResetIDs(); - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 5"); + } if (attachment) { group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom; @@ -582,7 +601,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { group.SetFromItemID(itemID); } - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 6"); + } SceneObjectPart rootPart = null; try { @@ -597,7 +619,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); } - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 7"); + } // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. @@ -625,7 +650,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.ApplyNextOwnerPermissions(); } } - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 8"); + } foreach (SceneObjectPart part in partList) { if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) @@ -638,9 +666,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 9"); + } rootPart.TrimPermissions(); - + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 10"); + } if (!attachment) { if (group.RootPart.Shape.PCode == (byte)PCode.Prim) @@ -674,8 +708,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } - - return rootPart.ParentGroup; + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 11"); + } + return group; } } -- cgit v1.1 From 03da22378e23ae5c74d320d09878e7e2fa7756c8 Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Aug 2010 09:53:40 -0700 Subject: Estate managers should be allowed to add and remove new users, groups and bans to/from the estate settings. --- OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 940b535..ee151da 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -250,7 +250,7 @@ namespace OpenSim.Region.CoreModules.World.Estate if ((estateAccessType & 4) != 0) // User add { - if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) + if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.AddEstateUser(user); m_scene.RegionInfo.EstateSettings.Save(); @@ -265,7 +265,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } if ((estateAccessType & 8) != 0) // User remove { - if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) + if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.RemoveEstateUser(user); m_scene.RegionInfo.EstateSettings.Save(); @@ -280,7 +280,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } if ((estateAccessType & 16) != 0) // Group add { - if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) + if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.AddEstateGroup(user); m_scene.RegionInfo.EstateSettings.Save(); @@ -294,7 +294,7 @@ namespace OpenSim.Region.CoreModules.World.Estate } if ((estateAccessType & 32) != 0) // Group remove { - if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) + if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.RemoveEstateGroup(user); m_scene.RegionInfo.EstateSettings.Save(); -- cgit v1.1 From 330343505ca2d6d109e89b4767f4351ab9bec91d Mon Sep 17 00:00:00 2001 From: Tom Date: Fri, 6 Aug 2010 11:39:10 -0700 Subject: Implement CreateNewOutfitAttachments. This addresses mantis #199. --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 1 + .../Sirikata/ClientStack/SirikataClientView.cs | 1 + .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 1 + OpenSim/Framework/IClientAPI.cs | 4 +++ .../Region/ClientStack/LindenUDP/LLClientView.cs | 33 ++++++++++++++++++++++ .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 20 +++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 1 + .../Server/IRCClientView.cs | 1 + .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- OpenSim/Tests/Common/Mock/TestClient.cs | 2 +- 11 files changed, 65 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index ce2e9a1..84c6916 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -593,6 +593,7 @@ namespace OpenSim.Client.MXP.ClientStack public event DisconnectUser OnDisconnectUser; public event RequestAvatarProperties OnRequestAvatarProperties; public event SetAlwaysRun OnSetAlwaysRun; + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event TeleportLandmarkRequest OnTeleportLandmarkRequest; public event DeRezObject OnDeRezObject; public event Action OnRegionHandShakeReply; diff --git a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs index 2063616..6ad5f5a 100644 --- a/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs +++ b/OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs @@ -253,6 +253,7 @@ namespace OpenSim.Client.Sirikata.ClientStack public event AddNewPrim OnAddPrim; public event FetchInventory OnAgentDataUpdateRequest; public event TeleportLocationRequest OnSetStartLocationRequest; + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event RequestGodlikePowers OnRequestGodlikePowers; public event GodKickUser OnGodKickUser; public event ObjectDuplicate OnObjectDuplicate; diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 841f9a4..8ef411b 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -290,6 +290,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack public event GenericCall2 OnStopMovement = delegate { }; public event Action OnRemoveAvatar = delegate { }; public event ObjectPermissions OnObjectPermissions = delegate { }; + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy = delegate { }; public event CreateNewInventoryItem OnCreateNewInventoryItem = delegate { }; public event LinkInventoryItem OnLinkInventoryItem = delegate { }; public event CreateInventoryFolder OnCreateNewInventoryFolder = delegate { }; diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 95aec94..07bded6 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -264,6 +264,9 @@ namespace OpenSim.Framework public delegate void MoveInventoryItem( IClientAPI remoteClient, List items); + public delegate void MoveItemsAndLeaveCopy( + IClientAPI remoteClient, List items, UUID destFolder); + public delegate void RemoveInventoryItem( IClientAPI remoteClient, List itemIDs); @@ -772,6 +775,7 @@ namespace OpenSim.Framework event RequestTaskInventory OnRequestTaskInventory; event UpdateInventoryItem OnUpdateInventoryItem; event CopyInventoryItem OnCopyInventoryItem; + event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; event MoveInventoryItem OnMoveInventoryItem; event RemoveInventoryFolder OnRemoveInventoryFolder; event RemoveInventoryItem OnRemoveInventoryItem; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 0b8b95b..cd7c11b 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -154,6 +154,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP public event RequestTaskInventory OnRequestTaskInventory; public event UpdateInventoryItem OnUpdateInventoryItem; public event CopyInventoryItem OnCopyInventoryItem; + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event MoveInventoryItem OnMoveInventoryItem; public event RemoveInventoryItem OnRemoveInventoryItem; public event RemoveInventoryFolder OnRemoveInventoryFolder; @@ -4840,6 +4841,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AddLocalPacketHandler(PacketType.TransferAbort, HandleTransferAbort, false); AddLocalPacketHandler(PacketType.MuteListRequest, HandleMuteListRequest, false); AddLocalPacketHandler(PacketType.UseCircuitCode, HandleUseCircuitCode); + AddLocalPacketHandler(PacketType.CreateNewOutfitAttachments, HandleCreateNewOutfitAttachments); AddLocalPacketHandler(PacketType.AgentHeightWidth, HandleAgentHeightWidth, false); AddLocalPacketHandler(PacketType.InventoryDescendents, HandleInventoryDescendents); AddLocalPacketHandler(PacketType.DirPlacesQuery, HandleDirPlacesQuery); @@ -9349,6 +9351,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP { return true; } + + private bool HandleCreateNewOutfitAttachments(IClientAPI sender, Packet Pack) + { + CreateNewOutfitAttachmentsPacket packet = (CreateNewOutfitAttachmentsPacket)Pack; + + #region Packet Session and User Check + if (m_checkPackets) + { + if (packet.AgentData.SessionID != SessionId || + packet.AgentData.AgentID != AgentId) + return true; + } + #endregion + MoveItemsAndLeaveCopy handlerMoveItemsAndLeaveCopy = null; + List items = new List(); + foreach (CreateNewOutfitAttachmentsPacket.ObjectDataBlock n in packet.ObjectData) + { + InventoryItemBase b = new InventoryItemBase(); + b.ID = n.OldItemID; + b.Folder = n.OldFolderID; + items.Add(b); + } + + handlerMoveItemsAndLeaveCopy = OnMoveItemsAndLeaveCopy; + if (handlerMoveItemsAndLeaveCopy != null) + { + handlerMoveItemsAndLeaveCopy(this, items, packet.HeaderData.NewFolderID); + } + + return true; + } private bool HandleAgentHeightWidth(IClientAPI sender, Packet Pack) { diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 4db8f9e..cdc56a2 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -79,7 +79,7 @@ namespace OpenSim.Region.Examples.SimpleModule public event DisconnectUser OnDisconnectUser; public event RequestAvatarProperties OnRequestAvatarProperties; public event SetAlwaysRun OnSetAlwaysRun; - + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event DeRezObject OnDeRezObject; public event Action OnRegionHandShakeReply; public event GenericCall2 OnRequestWearables; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 59731f7..17159b4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -648,6 +648,8 @@ namespace OpenSim.Region.Framework.Scenes return; } + if (newName == null) newName = item.Name; + AssetBase asset = AssetService.Get(item.AssetID.ToString()); if (asset != null) @@ -695,6 +697,24 @@ namespace OpenSim.Region.Framework.Scenes } /// + /// Move an item within the agent's inventory, and leave a copy (used in making a new outfit) + /// + public void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List items, UUID destfolder) + { + List moveitems = new List(); + foreach (InventoryItemBase b in items) + { + CopyInventoryItem(remoteClient, 0, remoteClient.AgentId, b.ID, b.Folder, null); + InventoryItemBase n = InventoryService.GetItem(b); + n.Folder = destfolder; + moveitems.Add(n); + remoteClient.SendInventoryItemCreateUpdate(n, 0); + } + + MoveInventoryItem(remoteClient, moveitems); + } + + /// /// Move an item within the agent's inventory. /// /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 644fbb0..ea52ffb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2922,6 +2922,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnFetchInventory += HandleFetchInventory; client.OnUpdateInventoryItem += UpdateInventoryItemAsset; client.OnCopyInventoryItem += CopyInventoryItem; + client.OnMoveItemsAndLeaveCopy += MoveInventoryItemsLeaveCopy; client.OnMoveInventoryItem += MoveInventoryItem; client.OnRemoveInventoryItem += RemoveInventoryItem; client.OnRemoveInventoryFolder += RemoveInventoryFolder; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index c7a9484..91cbee9 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -815,6 +815,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public event ObjectOwner OnObjectOwner; public event DirPlacesQuery OnDirPlacesQuery; public event DirFindQuery OnDirFindQuery; + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event DirLandQuery OnDirLandQuery; public event DirPopularQuery OnDirPopularQuery; public event DirClassifiedQuery OnDirClassifiedQuery; diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 23255fb..d6f4d53 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -156,7 +156,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC #pragma warning disable 67 public event Action OnLogout; public event ObjectPermissions OnObjectPermissions; - + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event MoneyTransferRequest OnMoneyTransferRequest; public event ParcelBuy OnParcelBuy; public event Action OnConnectionClosed; diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 2993b46..1e4bc2a 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -65,7 +65,7 @@ namespace OpenSim.Tests.Common.Mock public event MoneyTransferRequest OnMoneyTransferRequest; public event ParcelBuy OnParcelBuy; public event Action OnConnectionClosed; - + public event MoveItemsAndLeaveCopy OnMoveItemsAndLeaveCopy; public event ImprovedInstantMessage OnInstantMessage; public event ChatMessage OnChatFromClient; public event TextureRequest OnRequestTexture; -- cgit v1.1 From a783f048a37e759e522cf73d482d6478ddc348d6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 7 Aug 2010 03:38:35 +0200 Subject: Make the landmark properties and search places work again --- .../CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs index b0ace39..153c2a5 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs @@ -90,7 +90,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land if (!m_Enabled) return; - m_GridService = scene.GridService; m_LocalService.AddRegion(scene); scene.RegisterModuleInterface(this); } @@ -103,6 +102,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land public void RegionLoaded(Scene scene) { + m_GridService = scene.GridService; } -- cgit v1.1 From fa11ac8c851d4471640dfb0381ca285d0e5299d7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 7 Aug 2010 05:42:30 +0200 Subject: Change the (hackish) constant to match the changed enum for attachs --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index e557d2c..c802490 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -293,8 +293,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } // Fire after attach, so we don't get messy perms dialogs - // 3 == AttachedRez - objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 3); + // 4 == AttachedRez + objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); objatt.ResumeScripts(); // Do this last so that event listeners have access to all the effects of the attachment -- cgit v1.1 From c554de75010a442753cce29ee06d2b60d7b4701a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 7 Aug 2010 05:45:52 +0200 Subject: Correct display of landmark about info. Also correct region maturity rating in LM info. Maturity is NOT the parcel's setting, that is only for the image and text. Parcel maturity is governed by region maturity. --- OpenSim/Framework/Util.cs | 12 +++++++++++- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 6 +++--- .../ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs | 4 +++- .../ServiceConnectorsOut/Land/LocalLandServiceConnector.cs | 4 +++- .../ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs | 6 +++--- .../Region/CoreModules/World/Land/LandManagementModule.cs | 6 +++++- OpenSim/Server/Handlers/Land/LandHandlers.cs | 4 +++- OpenSim/Services/Connectors/Land/LandServiceConnector.cs | 5 ++++- OpenSim/Services/Interfaces/ILandService.cs | 2 +- 9 files changed, 36 insertions(+), 13 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index c39fb6f..af5a0ce 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1171,6 +1171,16 @@ namespace OpenSim.Framework } + public static uint ConvertAccessLevelToMaturity(byte maturity) + { + if (maturity <= 13) + return 0; + else if (maturity <= 21) + return 1; + else + return 2; + } + /// /// Produces an OSDMap from its string representation on a stream /// @@ -1486,4 +1496,4 @@ namespace OpenSim.Framework } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index d2d1e8f..af2dd85 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2675,7 +2675,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Bit 0: Mature, bit 7: on sale, other bits: no idea reply.Data.Flags = (byte)( - ((land.Flags & (uint)ParcelFlags.MaturePublish) != 0 ? (1 << 0) : 0) + + (info.AccessLevel > 13 ? (1 << 0) : 0) + ((land.Flags & (uint)ParcelFlags.ForSale) != 0 ? (1 << 7) : 0)); Vector3 pos = land.UserLocation; @@ -2683,8 +2683,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { pos = (land.AABBMax + land.AABBMin) * 0.5f; } - reply.Data.GlobalX = info.RegionLocX * Constants.RegionSize + x; - reply.Data.GlobalY = info.RegionLocY * Constants.RegionSize + y; + reply.Data.GlobalX = info.RegionLocX + x; + reply.Data.GlobalY = info.RegionLocY + y; reply.Data.GlobalZ = pos.Z; reply.Data.SimName = Utils.StringToBytes(info.RegionName); reply.Data.SnapshotID = land.SnapshotID; diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs index bce160a..23251c9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Land/LandServiceInConnectorModule.cs @@ -121,7 +121,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land #region ILandService - public LandData GetLandData(ulong regionHandle, uint x, uint y) + public LandData GetLandData(ulong regionHandle, uint x, uint y, out byte regionAccess) { m_log.DebugFormat("[LAND IN CONNECTOR]: GetLandData for {0}. Count = {1}", regionHandle, m_Scenes.Count); @@ -130,10 +130,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Land if (s.RegionInfo.RegionHandle == regionHandle) { m_log.Debug("[LAND IN CONNECTOR]: Found region to GetLandData from"); + regionAccess = s.RegionInfo.AccessLevel; return s.GetLandData(x, y); } } m_log.DebugFormat("[LAND IN CONNECTOR]: region handle {0} not found", regionHandle); + regionAccess = 42; return null; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs index cb87f6f..e15f624 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/LocalLandServiceConnector.cs @@ -116,8 +116,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land #region ILandService - public LandData GetLandData(ulong regionHandle, uint x, uint y) + public LandData GetLandData(ulong regionHandle, uint x, uint y, out byte regionAccess) { + regionAccess = 2; m_log.DebugFormat("[LAND CONNECTOR]: request for land data in {0} at {1}, {2}", regionHandle, x, y); @@ -126,6 +127,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land if (s.RegionInfo.RegionHandle == regionHandle) { LandData land = s.GetLandData(x, y); + regionAccess = s.RegionInfo.AccessLevel; return land; } } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs index 153c2a5..2386060 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs @@ -108,13 +108,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land #region ILandService - public override LandData GetLandData(ulong regionHandle, uint x, uint y) + public override LandData GetLandData(ulong regionHandle, uint x, uint y, out byte regionAccess) { - LandData land = m_LocalService.GetLandData(regionHandle, x, y); + LandData land = m_LocalService.GetLandData(regionHandle, x, y, out regionAccess); if (land != null) return land; - return base.GetLandData(regionHandle, x, y); + return base.GetLandData(regionHandle, x, y, out regionAccess); } #endregion ILandService diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index cfee1b0..7e29a56 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -51,6 +51,7 @@ namespace OpenSim.Region.CoreModules.World.Land public LandData LandData; public ulong RegionHandle; public uint X, Y; + public byte RegionAccess; } public class LandManagementModule : INonSharedRegionModule @@ -1484,13 +1485,15 @@ namespace OpenSim.Region.CoreModules.World.Land if (extLandData.RegionHandle == m_scene.RegionInfo.RegionHandle) { extLandData.LandData = this.GetLandObject(extLandData.X, extLandData.Y).LandData; + extLandData.RegionAccess = m_scene.RegionInfo.AccessLevel; } else { ILandService landService = m_scene.RequestModuleInterface(); extLandData.LandData = landService.GetLandData(extLandData.RegionHandle, extLandData.X, - extLandData.Y); + extLandData.Y, + out extLandData.RegionAccess); if (extLandData.LandData == null) { // we didn't find the region/land => don't cache @@ -1522,6 +1525,7 @@ namespace OpenSim.Region.CoreModules.World.Land r.RegionName = info.RegionName; r.RegionLocX = (uint)info.RegionLocX; r.RegionLocY = (uint)info.RegionLocY; + r.RegionSettings.Maturity = (int)Util.ConvertAccessLevelToMaturity(data.RegionAccess); remoteClient.SendParcelInfo(r, data.LandData, parcelID, data.X, data.Y); } else diff --git a/OpenSim/Server/Handlers/Land/LandHandlers.cs b/OpenSim/Server/Handlers/Land/LandHandlers.cs index a21f9de..561f285 100644 --- a/OpenSim/Server/Handlers/Land/LandHandlers.cs +++ b/OpenSim/Server/Handlers/Land/LandHandlers.cs @@ -66,7 +66,8 @@ namespace OpenSim.Server.Handlers.Land uint y = Convert.ToUInt32(requestData["y"]); m_log.DebugFormat("[LAND HANDLER]: Got request for land data at {0}, {1} for region {2}", x, y, regionHandle); - LandData landData = m_LocalService.GetLandData(regionHandle, x, y); + byte regionAccess; + LandData landData = m_LocalService.GetLandData(regionHandle, x, y, out regionAccess); Hashtable hash = new Hashtable(); if (landData != null) { @@ -83,6 +84,7 @@ namespace OpenSim.Server.Handlers.Land hash["SalePrice"] = landData.SalePrice.ToString(); hash["SnapshotID"] = landData.SnapshotID.ToString(); hash["UserLocation"] = landData.UserLocation.ToString(); + hash["RegionAccess"] = regionAccess.ToString(); } XmlRpcResponse response = new XmlRpcResponse(); diff --git a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs index 0223a77..c439dc5 100644 --- a/OpenSim/Services/Connectors/Land/LandServiceConnector.cs +++ b/OpenSim/Services/Connectors/Land/LandServiceConnector.cs @@ -64,7 +64,7 @@ namespace OpenSim.Services.Connectors m_GridService = gridServices; } - public virtual LandData GetLandData(ulong regionHandle, uint x, uint y) + public virtual LandData GetLandData(ulong regionHandle, uint x, uint y, out byte regionAccess) { LandData landData = null; Hashtable hash = new Hashtable(); @@ -74,6 +74,7 @@ namespace OpenSim.Services.Connectors IList paramList = new ArrayList(); paramList.Add(hash); + regionAccess = 42; // Default to adult. Better safe... try { @@ -109,6 +110,8 @@ namespace OpenSim.Services.Connectors landData.SalePrice = Convert.ToInt32(hash["SalePrice"]); landData.SnapshotID = new UUID((string)hash["SnapshotID"]); landData.UserLocation = Vector3.Parse((string)hash["UserLocation"]); + if (hash["RegionAccess"] != null) + regionAccess = (byte)Convert.ToInt32((string)hash["RegionAccess"]); m_log.DebugFormat("[OGS1 GRID SERVICES] Got land data for parcel {0}", landData.Name); } catch (Exception e) diff --git a/OpenSim/Services/Interfaces/ILandService.cs b/OpenSim/Services/Interfaces/ILandService.cs index e2f1d1d..7a12aff 100644 --- a/OpenSim/Services/Interfaces/ILandService.cs +++ b/OpenSim/Services/Interfaces/ILandService.cs @@ -33,6 +33,6 @@ namespace OpenSim.Services.Interfaces { public interface ILandService { - LandData GetLandData(ulong regionHandle, uint x, uint y); + LandData GetLandData(ulong regionHandle, uint x, uint y, out byte regionAccess); } } -- cgit v1.1 From e69efdd4ce7e989d04adf685d6fa7a704c609377 Mon Sep 17 00:00:00 2001 From: sacha Date: Sat, 7 Aug 2010 13:13:27 +0000 Subject: Clean the loo after use please !!!!! No need to keep useless debug message ! Never heard of wasted cpucycle you darn kid ! --- .../CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index d025f0c..e1ee0b1 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -132,7 +132,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage { UUID toAgentID = new UUID(im.toAgentID); - m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString()); + //m_log.DebugFormat("[INSTANT MESSAGE]: Attempting delivery of IM from {0} to {1}", im.fromAgentName, toAgentID.ToString()); // Try root avatar only first foreach (Scene scene in m_Scenes) @@ -140,12 +140,12 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) { - m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName); + // m_log.DebugFormat("[INSTANT MESSAGE]: Looking for {0} in {1}", toAgentID.ToString(), scene.RegionInfo.RegionName); // Local message ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; if (!user.IsChildAgent) { - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); + // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); user.ControllingClient.SendInstantMessage(im); // Message sent @@ -167,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Local message ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; - m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); + // m_log.DebugFormat("[INSTANT MESSAGE]: Delivering to client"); user.ControllingClient.SendInstantMessage(im); // Message sent -- cgit v1.1 From 047a4764f22340667ea8c3b11a56ed54011aded9 Mon Sep 17 00:00:00 2001 From: sacha Date: Sat, 7 Aug 2010 13:19:53 +0000 Subject: and another one... --- .../Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs index cbea54c..1603c07 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/InstantMessageModule.cs @@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } catch { - m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp."); + //m_log.Info("[OFFLINE MESSAGING]: No PST timezone found on this machine. Saving with local timestamp."); } // And make it look local again to fool the unix time util -- cgit v1.1 From 4f80d75bf3fa6de226203c6752e7a8e53fda8108 Mon Sep 17 00:00:00 2001 From: Tom Date: Sat, 7 Aug 2010 06:28:04 -0700 Subject: Add a CHANGED_POSITION event so scripts don't have to run expensive loops to check for position changes --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 4 +++- OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8ce79a2..cac3df6 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -476,6 +476,7 @@ namespace OpenSim.Region.Framework.Scenes part.IgnoreUndoUpdate = false; part.StoreUndoState(UndoType.STATE_GROUP_POSITION); part.GroupPosition = val; + part.TriggerScriptChangedEvent(Changed.POSITION); } foreach (ScenePresence av in m_linkedAvatars) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index efdc19c..d544619 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -60,7 +60,8 @@ namespace OpenSim.Region.Framework.Scenes TELEPORT = 512, REGION_RESTART = 1024, MEDIA = 2048, - ANIMATION = 16384 + ANIMATION = 16384, + POSITION = 32768 } // I don't really know where to put this except here. @@ -730,6 +731,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + TriggerScriptChangedEvent(Changed.POSITION); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 5da6bb9..6e8435d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -279,6 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART public const int CHANGED_MEDIA = 2048; public const int CHANGED_ANIMATION = 16384; + public const int CHANGED_POSITION = 32768; public const int TYPE_INVALID = 0; public const int TYPE_INTEGER = 1; public const int TYPE_FLOAT = 2; -- cgit v1.1 From 00cc42a607c59add54af3c1113162576e6109e41 Mon Sep 17 00:00:00 2001 From: sacha Date: Sat, 7 Aug 2010 13:40:38 +0000 Subject: and another endless debug cleaning --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 8ce79a2..0dc63ef 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1734,9 +1734,9 @@ namespace OpenSim.Region.Framework.Scenes // don't backup while it's selected or you're asking for changes mid stream. if ((isTimeToPersist()) || (forcedBackup)) { - m_log.DebugFormat( - "[SCENE]: Storing {0}, {1} in {2}", - Name, UUID, m_scene.RegionInfo.RegionName); + // m_log.DebugFormat( + // "[SCENE]: Storing {0}, {1} in {2}", + // Name, UUID, m_scene.RegionInfo.RegionName); SceneObjectGroup backup_group = Copy(false); backup_group.RootPart.Velocity = RootPart.Velocity; -- cgit v1.1 From b017d985ab05044bf196f108516e6b0185c172f5 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 08:06:41 -0700 Subject: Add some nullref checks to the UnackedPacketCollection. --- .../LindenUDP/UnackedPacketCollection.cs | 353 +++++++++++---------- 1 file changed, 184 insertions(+), 169 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index e43f7cf..c120a12 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -1,169 +1,184 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Net; -using OpenMetaverse; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - /// - /// Special collection that is optimized for tracking unacknowledged packets - /// - public sealed class UnackedPacketCollection - { - /// - /// Holds information about a pending acknowledgement - /// - private struct PendingAck - { - /// Sequence number of the packet to remove - public uint SequenceNumber; - /// Environment.TickCount value when the remove was queued. - /// This is used to update round-trip times for packets - public int RemoveTime; - /// Whether or not this acknowledgement was attached to a - /// resent packet. If so, round-trip time will not be calculated - public bool FromResend; - - public PendingAck(uint sequenceNumber, int currentTime, bool fromResend) - { - SequenceNumber = sequenceNumber; - RemoveTime = currentTime; - FromResend = fromResend; - } - } - - /// Holds the actual unacked packet data, sorted by sequence number - private Dictionary m_packets = new Dictionary(); - /// Holds packets that need to be added to the unacknowledged list - private LocklessQueue m_pendingAdds = new LocklessQueue(); - /// Holds information about pending acknowledgements - private LocklessQueue m_pendingRemoves = new LocklessQueue(); - - /// - /// Add an unacked packet to the collection - /// - /// Packet that is awaiting acknowledgement - /// True if the packet was successfully added, false if the - /// packet already existed in the collection - /// This does not immediately add the ACK to the collection, - /// it only queues it so it can be added in a thread-safe way later - public void Add(OutgoingPacket packet) - { - m_pendingAdds.Enqueue(packet); - } - - /// - /// Marks a packet as acknowledged - /// - /// Sequence number of the packet to - /// acknowledge - /// Current value of Environment.TickCount - /// This does not immediately acknowledge the packet, it only - /// queues the ack so it can be handled in a thread-safe way later - public void Remove(uint sequenceNumber, int currentTime, bool fromResend) - { - m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); - } - - /// - /// Returns a list of all of the packets with a TickCount older than - /// the specified timeout - /// - /// Number of ticks (milliseconds) before a - /// packet is considered expired - /// A list of all expired packets according to the given - /// expiration timeout - /// This function is not thread safe, and cannot be called - /// multiple times concurrently - public List GetExpiredPackets(int timeoutMS) - { - ProcessQueues(); - - List expiredPackets = null; - - if (m_packets.Count > 0) - { - int now = Environment.TickCount & Int32.MaxValue; - - foreach (OutgoingPacket packet in m_packets.Values) - { - // TickCount of zero means a packet is in the resend queue - // but hasn't actually been sent over the wire yet - if (packet.TickCount == 0) - continue; - - if (now - packet.TickCount >= timeoutMS) - { - if (expiredPackets == null) - expiredPackets = new List(); - - // The TickCount will be set to the current time when the packet - // is actually sent out again - packet.TickCount = 0; - - expiredPackets.Add(packet); - } - } - } - - return expiredPackets; - } - - private void ProcessQueues() - { - // Process all the pending adds - OutgoingPacket pendingAdd; - while (m_pendingAdds.Dequeue(out pendingAdd)) - m_packets[pendingAdd.SequenceNumber] = pendingAdd; - - // Process all the pending removes, including updating statistics and round-trip times - PendingAck pendingRemove; - OutgoingPacket ackedPacket; - while (m_pendingRemoves.Dequeue(out pendingRemove)) - { - if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) - { - m_packets.Remove(pendingRemove.SequenceNumber); - - // Update stats - System.Threading.Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); - - if (!pendingRemove.FromResend) - { - // Calculate the round-trip time for this packet and its ACK - int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; - if (rtt > 0) - ackedPacket.Client.UpdateRoundTrip(rtt); - } - } - } - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Net; +using OpenMetaverse; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + /// + /// Special collection that is optimized for tracking unacknowledged packets + /// + public sealed class UnackedPacketCollection + { + /// + /// Holds information about a pending acknowledgement + /// + private struct PendingAck + { + /// Sequence number of the packet to remove + public uint SequenceNumber; + /// Environment.TickCount value when the remove was queued. + /// This is used to update round-trip times for packets + public int RemoveTime; + /// Whether or not this acknowledgement was attached to a + /// resent packet. If so, round-trip time will not be calculated + public bool FromResend; + + public PendingAck(uint sequenceNumber, int currentTime, bool fromResend) + { + SequenceNumber = sequenceNumber; + RemoveTime = currentTime; + FromResend = fromResend; + } + } + + /// Holds the actual unacked packet data, sorted by sequence number + private Dictionary m_packets = new Dictionary(); + /// Holds packets that need to be added to the unacknowledged list + private LocklessQueue m_pendingAdds = new LocklessQueue(); + /// Holds information about pending acknowledgements + private LocklessQueue m_pendingRemoves = new LocklessQueue(); + + /// + /// Add an unacked packet to the collection + /// + /// Packet that is awaiting acknowledgement + /// True if the packet was successfully added, false if the + /// packet already existed in the collection + /// This does not immediately add the ACK to the collection, + /// it only queues it so it can be added in a thread-safe way later + public void Add(OutgoingPacket packet) + { + m_pendingAdds.Enqueue(packet); + } + + /// + /// Marks a packet as acknowledged + /// + /// Sequence number of the packet to + /// acknowledge + /// Current value of Environment.TickCount + /// This does not immediately acknowledge the packet, it only + /// queues the ack so it can be handled in a thread-safe way later + public void Remove(uint sequenceNumber, int currentTime, bool fromResend) + { + m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); + } + + /// + /// Returns a list of all of the packets with a TickCount older than + /// the specified timeout + /// + /// Number of ticks (milliseconds) before a + /// packet is considered expired + /// A list of all expired packets according to the given + /// expiration timeout + /// This function is not thread safe, and cannot be called + /// multiple times concurrently + public List GetExpiredPackets(int timeoutMS) + { + ProcessQueues(); + + List expiredPackets = null; + + if (m_packets.Count > 0) + { + int now = Environment.TickCount & Int32.MaxValue; + + foreach (OutgoingPacket packet in m_packets.Values) + { + // TickCount of zero means a packet is in the resend queue + // but hasn't actually been sent over the wire yet + if (packet.TickCount == 0) + continue; + + if (now - packet.TickCount >= timeoutMS) + { + if (expiredPackets == null) + expiredPackets = new List(); + + // The TickCount will be set to the current time when the packet + // is actually sent out again + packet.TickCount = 0; + + expiredPackets.Add(packet); + } + } + } + + return expiredPackets; + } + + private void ProcessQueues() + { + // Process all the pending adds + + OutgoingPacket pendingAdd; + if (m_pendingAdds != null) + { + while (m_pendingAdds.Dequeue(out pendingAdd)) + { + if (pendingAdd != null && m_packets != null) + { + m_packets[pendingAdd.SequenceNumber] = pendingAdd; + } + } + } + + // Process all the pending removes, including updating statistics and round-trip times + PendingAck pendingRemove; + OutgoingPacket ackedPacket; + if (m_pendingRemoves != null) + { + while (m_pendingRemoves.Dequeue(out pendingRemove)) + { + if (m_pendingRemoves != null && m_packets != null) + { + if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) + { + m_packets.Remove(pendingRemove.SequenceNumber); + + // Update stats + System.Threading.Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); + + if (!pendingRemove.FromResend) + { + // Calculate the round-trip time for this packet and its ACK + int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; + if (rtt > 0) + ackedPacket.Client.UpdateRoundTrip(rtt); + } + } + } + } + } + } + } +} -- cgit v1.1 From 19debab060b246f61d633b06d926a068001f6510 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 08:17:11 -0700 Subject: Fix the general alert message so it doesn't get sent to child agents --- .../CoreModules/Avatar/Dialog/DialogModule.cs | 443 +++++++++++---------- 1 file changed, 223 insertions(+), 220 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs index fb0bd1a..1498dba 100644 --- a/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Dialog/DialogModule.cs @@ -1,220 +1,223 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenSim.Framework; - -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Services.Interfaces; - -namespace OpenSim.Region.CoreModules.Avatar.Dialog -{ - public class DialogModule : IRegionModule, IDialogModule - { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected Scene m_scene; - - public void Initialise(Scene scene, IConfigSource source) - { - m_scene = scene; - m_scene.RegisterModuleInterface(this); - - m_scene.AddCommand( - this, "alert", "alert ", "Send an alert to a user", HandleAlertConsoleCommand); - - m_scene.AddCommand( - this, "alert general", "alert general ", "Send an alert to everyone", HandleAlertConsoleCommand); - - m_scene.AddCommand( - this, "alert dialog", "alert dialog ", "Send a dialog alert to everyone", HandleAlertConsoleCommand); - - - } - - public void PostInitialise() {} - public void Close() {} - public string Name { get { return "Dialog Module"; } } - public bool IsSharedModule { get { return false; } } - - public void SendAlertToUser(IClientAPI client, string message) - { - SendAlertToUser(client, message, false); - } - - public void SendAlertToUser(IClientAPI client, string message, bool modal) - { - client.SendAgentAlertMessage(message, modal); - } - - public void SendAlertToUser(UUID agentID, string message) - { - SendAlertToUser(agentID, message, false); - } - - public void SendAlertToUser(UUID agentID, string message, bool modal) - { - ScenePresence sp = m_scene.GetScenePresence(agentID); - - if (sp != null) - sp.ControllingClient.SendAgentAlertMessage(message, modal); - } - - public void SendAlertToUser(string firstName, string lastName, string message, bool modal) - { - ScenePresence presence = m_scene.GetScenePresence(firstName, lastName); - if (presence != null) - presence.ControllingClient.SendAgentAlertMessage(message, modal); - } - - public void SendGeneralAlert(string message) - { - m_scene.ForEachScenePresence(delegate(ScenePresence presence) - { - presence.ControllingClient.SendAlertMessage(message); - }); - } - - public void SendDialogToUser( - UUID avatarID, string objectName, UUID objectID, UUID ownerID, - string message, UUID textureID, int ch, string[] buttonlabels) - { - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerID); - string ownerFirstName, ownerLastName; - if (account != null) - { - ownerFirstName = account.FirstName; - ownerLastName = account.LastName; - } - else - { - ownerFirstName = "(unknown"; - ownerLastName = "user)"; - } - - ScenePresence sp = m_scene.GetScenePresence(avatarID); - if (sp != null) - sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); - } - - public void SendUrlToUser( - UUID avatarID, string objectName, UUID objectID, UUID ownerID, bool groupOwned, string message, string url) - { - ScenePresence sp = m_scene.GetScenePresence(avatarID); - - if (sp != null) - sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); - } - - public void SendTextBoxToUser(UUID avatarid, string message, int chatChannel, string name, UUID objectid, UUID ownerid) - { - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); - string ownerFirstName, ownerLastName; - if (account != null) - { - ownerFirstName = account.FirstName; - ownerLastName = account.LastName; - } - else - { - ownerFirstName = "(unknown"; - ownerLastName = "user)"; - } - - ScenePresence sp = m_scene.GetScenePresence(avatarid); - - if (sp != null) - sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); - } - - public void SendNotificationToUsersInRegion( - UUID fromAvatarID, string fromAvatarName, string message) - { - m_scene.ForEachScenePresence(delegate(ScenePresence presence) - { - if (!presence.IsChildAgent) - presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message); - }); - } - - /// - /// Handle an alert command from the console. - /// - /// - /// - public void HandleAlertConsoleCommand(string module, string[] cmdparams) - { - if (m_scene.ConsoleScene() != null && m_scene.ConsoleScene() != m_scene) - return; - - if (cmdparams[1] == "general") - { - string message = CombineParams(cmdparams, 2); - - m_log.InfoFormat( - "[DIALOG]: Sending general alert in region {0} with message {1}", m_scene.RegionInfo.RegionName, message); - SendGeneralAlert(message); - } - else if (cmdparams[1] == "dialog") - { - string message = CombineParams(cmdparams, 2); - - m_log.InfoFormat( - "[DIALOG]: Sending dialog alert in region {0} with message {1}", m_scene.RegionInfo.RegionName, message); - SendNotificationToUsersInRegion(UUID.Zero, "System", message); - } - else - { - string firstName = cmdparams[1]; - string lastName = cmdparams[2]; - string message = CombineParams(cmdparams, 3); - - m_log.InfoFormat( - "[DIALOG]: Sending alert in region {0} to {1} {2} with message {3}", - m_scene.RegionInfo.RegionName, firstName, lastName, message); - SendAlertToUser(firstName, lastName, message, false); - } - } - - private string CombineParams(string[] commandParams, int pos) - { - string result = string.Empty; - for (int i = pos; i < commandParams.Length; i++) - { - result += commandParams[i] + " "; - } - - return result; - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; + +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.CoreModules.Avatar.Dialog +{ + public class DialogModule : IRegionModule, IDialogModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected Scene m_scene; + + public void Initialise(Scene scene, IConfigSource source) + { + m_scene = scene; + m_scene.RegisterModuleInterface(this); + + m_scene.AddCommand( + this, "alert", "alert ", "Send an alert to a user", HandleAlertConsoleCommand); + + m_scene.AddCommand( + this, "alert general", "alert general ", "Send an alert to everyone", HandleAlertConsoleCommand); + + m_scene.AddCommand( + this, "alert dialog", "alert dialog ", "Send a dialog alert to everyone", HandleAlertConsoleCommand); + + + } + + public void PostInitialise() {} + public void Close() {} + public string Name { get { return "Dialog Module"; } } + public bool IsSharedModule { get { return false; } } + + public void SendAlertToUser(IClientAPI client, string message) + { + SendAlertToUser(client, message, false); + } + + public void SendAlertToUser(IClientAPI client, string message, bool modal) + { + client.SendAgentAlertMessage(message, modal); + } + + public void SendAlertToUser(UUID agentID, string message) + { + SendAlertToUser(agentID, message, false); + } + + public void SendAlertToUser(UUID agentID, string message, bool modal) + { + ScenePresence sp = m_scene.GetScenePresence(agentID); + + if (sp != null) + sp.ControllingClient.SendAgentAlertMessage(message, modal); + } + + public void SendAlertToUser(string firstName, string lastName, string message, bool modal) + { + ScenePresence presence = m_scene.GetScenePresence(firstName, lastName); + if (presence != null) + presence.ControllingClient.SendAgentAlertMessage(message, modal); + } + + public void SendGeneralAlert(string message) + { + m_scene.ForEachScenePresence(delegate(ScenePresence presence) + { + if (!presence.IsChildAgent) + { + presence.ControllingClient.SendAlertMessage(message); + } + }); + } + + public void SendDialogToUser( + UUID avatarID, string objectName, UUID objectID, UUID ownerID, + string message, UUID textureID, int ch, string[] buttonlabels) + { + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerID); + string ownerFirstName, ownerLastName; + if (account != null) + { + ownerFirstName = account.FirstName; + ownerLastName = account.LastName; + } + else + { + ownerFirstName = "(unknown"; + ownerLastName = "user)"; + } + + ScenePresence sp = m_scene.GetScenePresence(avatarID); + if (sp != null) + sp.ControllingClient.SendDialog(objectName, objectID, ownerFirstName, ownerLastName, message, textureID, ch, buttonlabels); + } + + public void SendUrlToUser( + UUID avatarID, string objectName, UUID objectID, UUID ownerID, bool groupOwned, string message, string url) + { + ScenePresence sp = m_scene.GetScenePresence(avatarID); + + if (sp != null) + sp.ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, message, url); + } + + public void SendTextBoxToUser(UUID avatarid, string message, int chatChannel, string name, UUID objectid, UUID ownerid) + { + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, ownerid); + string ownerFirstName, ownerLastName; + if (account != null) + { + ownerFirstName = account.FirstName; + ownerLastName = account.LastName; + } + else + { + ownerFirstName = "(unknown"; + ownerLastName = "user)"; + } + + ScenePresence sp = m_scene.GetScenePresence(avatarid); + + if (sp != null) + sp.ControllingClient.SendTextBoxRequest(message, chatChannel, name, ownerFirstName, ownerLastName, objectid); + } + + public void SendNotificationToUsersInRegion( + UUID fromAvatarID, string fromAvatarName, string message) + { + m_scene.ForEachScenePresence(delegate(ScenePresence presence) + { + if (!presence.IsChildAgent) + presence.ControllingClient.SendBlueBoxMessage(fromAvatarID, fromAvatarName, message); + }); + } + + /// + /// Handle an alert command from the console. + /// + /// + /// + public void HandleAlertConsoleCommand(string module, string[] cmdparams) + { + if (m_scene.ConsoleScene() != null && m_scene.ConsoleScene() != m_scene) + return; + + if (cmdparams[1] == "general") + { + string message = CombineParams(cmdparams, 2); + + m_log.InfoFormat( + "[DIALOG]: Sending general alert in region {0} with message {1}", m_scene.RegionInfo.RegionName, message); + SendGeneralAlert(message); + } + else if (cmdparams[1] == "dialog") + { + string message = CombineParams(cmdparams, 2); + + m_log.InfoFormat( + "[DIALOG]: Sending dialog alert in region {0} with message {1}", m_scene.RegionInfo.RegionName, message); + SendNotificationToUsersInRegion(UUID.Zero, "System", message); + } + else + { + string firstName = cmdparams[1]; + string lastName = cmdparams[2]; + string message = CombineParams(cmdparams, 3); + + m_log.InfoFormat( + "[DIALOG]: Sending alert in region {0} to {1} {2} with message {3}", + m_scene.RegionInfo.RegionName, firstName, lastName, message); + SendAlertToUser(firstName, lastName, message, false); + } + } + + private string CombineParams(string[] commandParams, int pos) + { + string result = string.Empty; + for (int i = pos; i < commandParams.Length; i++) + { + result += commandParams[i] + " "; + } + + return result; + } + } +} -- cgit v1.1 From 413b0525db81ebc39a3a79cc2763553058056a5c Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 11:06:07 -0700 Subject: It seems hippo disregards velocities in full updates, so also send a terse update when an agent sits to avoid drifting off --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8656 +++++++++++----------- 1 file changed, 4328 insertions(+), 4328 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b3fa2f4..882f4a7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1,4328 +1,4328 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Xml; -using System.Collections.Generic; -using System.Reflection; -using System.Timers; -using OpenMetaverse; -using log4net; -using OpenSim.Framework; -using OpenSim.Framework.Client; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes.Animation; -using OpenSim.Region.Framework.Scenes.Types; -using OpenSim.Region.Physics.Manager; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; -using OpenSim.Services.Interfaces; - -namespace OpenSim.Region.Framework.Scenes -{ - enum ScriptControlled : uint - { - CONTROL_ZERO = 0, - CONTROL_FWD = 1, - CONTROL_BACK = 2, - CONTROL_LEFT = 4, - CONTROL_RIGHT = 8, - CONTROL_UP = 16, - CONTROL_DOWN = 32, - CONTROL_ROT_LEFT = 256, - CONTROL_ROT_RIGHT = 512, - CONTROL_LBUTTON = 268435456, - CONTROL_ML_LBUTTON = 1073741824 - } - - struct ScriptControllers - { - public UUID itemID; - public ScriptControlled ignoreControls; - public ScriptControlled eventControls; - } - - public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List coarseLocations, List avatarUUIDs); - - public class ScenePresence : EntityBase, ISceneEntity - { -// ~ScenePresence() -// { -// m_log.Debug("[ScenePresence] Destructor called"); -// } - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; -// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); - private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); - private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); - - /// - /// Experimentally determined "fudge factor" to make sit-target positions - /// the same as in SecondLife. Fudge factor was tested for 36 different - /// test cases including prims of type box, sphere, cylinder, and torus, - /// with varying parameters for sit target location, prim size, prim - /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis - /// issue #1716 - /// -// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); - // Value revised by KF 091121 by comparison with SL. - private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); - - public UUID currentParcelUUID = UUID.Zero; - - private ISceneViewer m_sceneViewer; - - /// - /// The animator for this avatar - /// - public ScenePresenceAnimator Animator - { - get { return m_animator; } - } - protected ScenePresenceAnimator m_animator; - - /// - /// The scene objects attached to this avatar. Do not change this list directly - use methods such as - /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. - /// - public List Attachments - { - get { return m_attachments; } - } - protected List m_attachments = new List(); - - private Dictionary scriptedcontrols = new Dictionary(); - private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; - private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; - private bool MouseDown = false; - private SceneObjectGroup proxyObjectGroup; - //private SceneObjectPart proxyObjectPart = null; - public Vector3 lastKnownAllowedPosition; - public bool sentMessageAboutRestrictedParcelFlyingDown; - public Vector4 CollisionPlane = Vector4.UnitW; - - private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation - private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; - private Vector3 m_lastWorldPosition; - private Quaternion m_lastRotation; - private Vector3 m_lastVelocity; - //private int m_lastTerseSent; - - private bool m_updateflag; - private byte m_movementflag; - private Vector3? m_forceToApply; - private uint m_requestedSitTargetID; - private UUID m_requestedSitTargetUUID; - public bool SitGround = false; - - private SendCourseLocationsMethod m_sendCourseLocationsMethod; - - private bool m_startAnimationSet; - - //private Vector3 m_requestedSitOffset = new Vector3(); - - private Vector3 m_LastFinitePos; - - private float m_sitAvatarHeight = 2.0f; - - private int m_godLevel; - private int m_userLevel; - - private bool m_invulnerable = true; - - private Vector3 m_lastChildAgentUpdatePosition; - private Vector3 m_lastChildAgentUpdateCamPosition; - - private int m_perfMonMS; - - private bool m_setAlwaysRun; - private bool m_forceFly; - private bool m_flyDisabled; - - private float m_speedModifier = 1.0f; - - private Quaternion m_bodyRot= Quaternion.Identity; - - private Quaternion m_bodyRotPrevious = Quaternion.Identity; - - private const int LAND_VELOCITYMAG_MAX = 12; - - public bool IsRestrictedToRegion; - - public string JID = String.Empty; - - private float m_health = 100f; - - // Default AV Height - private float m_avHeight = 127.0f; - - protected RegionInfo m_regionInfo; - protected ulong crossingFromRegion; - - private readonly Vector3[] Dir_Vectors = new Vector3[11]; - private bool m_isNudging = false; - - // Position of agent's camera in world (region cordinates) - protected Vector3 m_CameraCenter; - protected Vector3 m_lastCameraCenter; - - protected Timer m_reprioritization_timer; - protected bool m_reprioritizing; - protected bool m_reprioritization_called; - - // Use these three vectors to figure out what the agent is looking at - // Convert it to a Matrix and/or Quaternion - protected Vector3 m_CameraAtAxis; - protected Vector3 m_CameraLeftAxis; - protected Vector3 m_CameraUpAxis; - private AgentManager.ControlFlags m_AgentControlFlags; - private Quaternion m_headrotation = Quaternion.Identity; - private byte m_state; - - //Reuse the Vector3 instead of creating a new one on the UpdateMovement method -// private Vector3 movementvector; - - private bool m_autopilotMoving; - private Vector3 m_autoPilotTarget; - private bool m_sitAtAutoTarget; - private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit - - private string m_nextSitAnimation = String.Empty; - - //PauPaw:Proper PID Controler for autopilot************ - private bool m_moveToPositionInProgress; - private Vector3 m_moveToPositionTarget; - private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - - private bool m_followCamAuto; - - private int m_movementUpdateCount; - private int m_lastColCount = -1; //KF: Look for Collision chnages - private int m_updateCount = 0; //KF: Update Anims for a while - private static readonly int UPDATE_COUNT = 10; // how many frames to update for - private const int NumMovementsBetweenRayCast = 5; - private List m_lastColliders = new List(); - - private bool CameraConstraintActive; - //private int m_moveToPositionStateStatus; - //***************************************************** - - // Agent's Draw distance. - protected float m_DrawDistance; - - protected AvatarAppearance m_appearance; - - // neighbouring regions we have enabled a child agent in - // holds the seed cap for the child agent in that region - private Dictionary m_knownChildRegions = new Dictionary(); - - /// - /// Implemented Control Flags - /// - private enum Dir_ControlFlags - { - DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, - DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, - DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, - DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, - DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, - DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, - DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, - DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, - DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, - DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, - DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG - } - - /// - /// Position at which a significant movement was made - /// - private Vector3 posLastSignificantMove; - - // For teleports and crossings callbacks - string m_callbackURI; - UUID m_originRegionID; - - ulong m_rootRegionHandle; - - /// - /// Script engines present in the scene - /// - private IScriptModule[] m_scriptEngines; - - #region Properties - - /// - /// Physical scene representation of this Avatar. - /// - public PhysicsActor PhysicsActor - { - set { m_physicsActor = value; } - get { return m_physicsActor; } - } - - public byte MovementFlag - { - set { m_movementflag = value; } - get { return m_movementflag; } - } - - public bool Updated - { - set { m_updateflag = value; } - get { return m_updateflag; } - } - - public bool Invulnerable - { - set { m_invulnerable = value; } - get { return m_invulnerable; } - } - - public int UserLevel - { - get { return m_userLevel; } - } - - public int GodLevel - { - get { return m_godLevel; } - } - - public ulong RegionHandle - { - get { return m_rootRegionHandle; } - } - - public Vector3 CameraPosition - { - get { return m_CameraCenter; } - } - - public Quaternion CameraRotation - { - get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } - } - - public Vector3 CameraAtAxis - { - get { return m_CameraAtAxis; } - } - - public Vector3 CameraLeftAxis - { - get { return m_CameraLeftAxis; } - } - - public Vector3 CameraUpAxis - { - get { return m_CameraUpAxis; } - } - - public Vector3 Lookat - { - get - { - Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0); - - if (a == Vector3.Zero) - return a; - - return Util.GetNormalizedVector(a); - } - } - - private readonly string m_firstname; - - public string Firstname - { - get { return m_firstname; } - } - - private readonly string m_lastname; - - public string Lastname - { - get { return m_lastname; } - } - - private string m_grouptitle; - - public string Grouptitle - { - get { return m_grouptitle; } - set { m_grouptitle = value; } - } - - public float DrawDistance - { - get { return m_DrawDistance; } - } - - protected bool m_allowMovement = true; - - public bool AllowMovement - { - get { return m_allowMovement; } - set { m_allowMovement = value; } - } - - public bool SetAlwaysRun - { - get - { - if (PhysicsActor != null) - { - return PhysicsActor.SetAlwaysRun; - } - else - { - return m_setAlwaysRun; - } - } - set - { - m_setAlwaysRun = value; - if (PhysicsActor != null) - { - PhysicsActor.SetAlwaysRun = value; - } - } - } - - public byte State - { - get { return m_state; } - set { m_state = value; } - } - - public uint AgentControlFlags - { - get { return (uint)m_AgentControlFlags; } - set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } - } - - /// - /// This works out to be the ClientView object associated with this avatar, or it's client connection manager - /// - private IClientAPI m_controllingClient; - - protected PhysicsActor m_physicsActor; - - /// - /// The client controlling this presence - /// - public IClientAPI ControllingClient - { - get { return m_controllingClient; } - } - - public IClientCore ClientView - { - get { return (IClientCore) m_controllingClient; } - } - - protected Vector3 m_parentPosition; - public Vector3 ParentPosition - { - get { return m_parentPosition; } - set { m_parentPosition = value; } - } - - /// - /// Position of this avatar relative to the region the avatar is in - /// - public override Vector3 AbsolutePosition - { - get - { - PhysicsActor actor = m_physicsActor; -// if (actor != null) - if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! - m_pos = actor.Position; - - // If we're sitting, we need to update our position - if (m_parentID != 0) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); - if (part != null) - m_parentPosition = part.AbsolutePosition; - } - - return m_parentPosition + m_pos; - } - set - { - PhysicsActor actor = m_physicsActor; - if (actor != null) - { - try - { - lock (m_scene.SyncRoot) - m_physicsActor.Position = value; - } - catch (Exception e) - { - m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); - } - } - - if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! - m_pos = value; - m_parentPosition = Vector3.Zero; - } - } - - public Vector3 OffsetPosition - { - get { return m_pos; } - set { m_pos = value; } - } - - /// - /// Current velocity of the avatar. - /// - public override Vector3 Velocity - { - get - { - PhysicsActor actor = m_physicsActor; - if (actor != null) - m_velocity = actor.Velocity; - - return m_velocity; - } - set - { - PhysicsActor actor = m_physicsActor; - if (actor != null) - { - try - { - lock (m_scene.SyncRoot) - actor.Velocity = value; - } - catch (Exception e) - { - m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); - } - } - - m_velocity = value; - } - } - - public Quaternion OffsetRotation - { - get { return m_offsetRotation; } - set { m_offsetRotation = value; } - } - - public Quaternion Rotation - { - get { - if (m_parentID != 0) - { - if (m_offsetRotation != null) - { - return m_offsetRotation; - } - else - { - return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - - } - else - { - return m_bodyRot; - } - } - set { - m_bodyRot = value; - if (m_parentID != 0) - { - m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - } - } - - public Quaternion PreviousRotation - { - get { return m_bodyRotPrevious; } - set { m_bodyRotPrevious = value; } - } - - /// - /// If this is true, agent doesn't have a representation in this scene. - /// this is an agent 'looking into' this scene from a nearby scene(region) - /// - /// if False, this agent has a representation in this scene - /// - private bool m_isChildAgent = true; - - public bool IsChildAgent - { - get { return m_isChildAgent; } - set { m_isChildAgent = value; } - } - - private uint m_parentID; - - - private UUID m_linkedPrim; - - public uint ParentID - { - get { return m_parentID; } - set { m_parentID = value; } - } - - public UUID LinkedPrim - { - get { return m_linkedPrim; } - set { m_linkedPrim = value; } - } - - public float Health - { - get { return m_health; } - set { m_health = value; } - } - - /// - /// These are the region handles known by the avatar. - /// - public List KnownChildRegionHandles - { - get - { - if (m_knownChildRegions.Count == 0) - return new List(); - else - return new List(m_knownChildRegions.Keys); - } - } - - public Dictionary KnownRegions - { - get { return m_knownChildRegions; } - set - { - m_knownChildRegions = value; - } - } - - public ISceneViewer SceneViewer - { - get { return m_sceneViewer; } - } - - public void AdjustKnownSeeds() - { - Dictionary seeds; - - if (Scene.CapsModule != null) - seeds = Scene.CapsModule.GetChildrenSeeds(UUID); - else - seeds = new Dictionary(); - - List old = new List(); - foreach (ulong handle in seeds.Keys) - { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) - { - old.Add(handle); - } - } - DropOldNeighbours(old); - - if (Scene.CapsModule != null) - Scene.CapsModule.SetChildrenSeed(UUID, seeds); - - KnownRegions = seeds; - //m_log.Debug(" ++++++++++AFTER+++++++++++++ "); - //DumpKnownRegions(); - } - - public void DumpKnownRegions() - { - m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================"); - foreach (KeyValuePair kvp in KnownRegions) - { - uint x, y; - Utils.LongToUInts(kvp.Key, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - m_log.Info(" >> "+x+", "+y+": "+kvp.Value); - } - } - - private bool m_inTransit; - private bool m_mouseLook; - private bool m_leftButtonDown; - - public bool IsInTransit - { - get { return m_inTransit; } - set { m_inTransit = value; } - } - - public float SpeedModifier - { - get { return m_speedModifier; } - set { m_speedModifier = value; } - } - - public bool ForceFly - { - get { return m_forceFly; } - set { m_forceFly = value; } - } - - public bool FlyDisabled - { - get { return m_flyDisabled; } - set { m_flyDisabled = value; } - } - - public string Viewer - { - get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } - } - - #endregion - - #region Constructor(s) - - public ScenePresence() - { - m_sendCourseLocationsMethod = SendCoarseLocationsDefault; - CreateSceneViewer(); - m_animator = new ScenePresenceAnimator(this); - } - - private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() - { - m_rootRegionHandle = reginfo.RegionHandle; - m_controllingClient = client; - m_firstname = m_controllingClient.FirstName; - m_lastname = m_controllingClient.LastName; - m_name = String.Format("{0} {1}", m_firstname, m_lastname); - m_scene = world; - m_uuid = client.AgentId; - m_regionInfo = reginfo; - m_localId = m_scene.AllocateLocalId(); - - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); - - if (account != null) - m_userLevel = account.UserLevel; - - IGroupsModule gm = m_scene.RequestModuleInterface(); - if (gm != null) - m_grouptitle = gm.GetGroupTitle(m_uuid); - - m_scriptEngines = m_scene.RequestModuleInterfaces(); - - AbsolutePosition = posLastSignificantMove = m_CameraCenter = - m_lastCameraCenter = m_controllingClient.StartPos; - - m_reprioritization_timer = new Timer(world.ReprioritizationInterval); - m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); - m_reprioritization_timer.AutoReset = false; - - AdjustKnownSeeds(); - Animator.TrySetMovementAnimation("STAND"); - // we created a new ScenePresence (a new child agent) in a fresh region. - // Request info about all the (root) agents in this region - // Note: This won't send data *to* other clients in that region (children don't send) - SendInitialFullUpdateToAllClients(); - RegisterToEvents(); - if (m_controllingClient != null) - { - m_controllingClient.ProcessPendingPackets(); - } - SetDirectionVectors(); - } - - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, - AvatarWearable[] wearables) - : this(client, world, reginfo) - { - m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); - } - - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) - : this(client, world, reginfo) - { - m_appearance = appearance; - } - - private void CreateSceneViewer() - { - m_sceneViewer = new SceneViewer(this); - } - - public void RegisterToEvents() - { - m_controllingClient.OnRequestWearables += SendWearables; - m_controllingClient.OnSetAppearance += SetAppearance; - m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; - //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; - m_controllingClient.OnAgentUpdate += HandleAgentUpdate; - m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; - m_controllingClient.OnAgentSit += HandleAgentSit; - m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; - m_controllingClient.OnStartAnim += HandleStartAnim; - m_controllingClient.OnStopAnim += HandleStopAnim; - m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; - m_controllingClient.OnAutoPilotGo += DoAutoPilot; - m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); - - // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); - // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); - } - - private void SetDirectionVectors() - { - Dir_Vectors[0] = Vector3.UnitX; //FORWARD - Dir_Vectors[1] = -Vector3.UnitX; //BACK - Dir_Vectors[2] = Vector3.UnitY; //LEFT - Dir_Vectors[3] = -Vector3.UnitY; //RIGHT - Dir_Vectors[4] = Vector3.UnitZ; //UP - Dir_Vectors[5] = -Vector3.UnitZ; //DOWN - Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE - Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE - Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE - Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE - Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge - } - - private Vector3[] GetWalkDirectionVectors() - { - Vector3[] vector = new Vector3[11]; - vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD - vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK - vector[2] = Vector3.UnitY; //LEFT - vector[3] = -Vector3.UnitY; //RIGHT - vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP - vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN - vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE - vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE - vector[8] = Vector3.UnitY; //LEFT_NUDGE - vector[9] = -Vector3.UnitY; //RIGHT_NUDGE - vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE - return vector; - } - - private bool[] GetDirectionIsNudge() - { - bool[] isNudge = new bool[11]; - isNudge[0] = false; //FORWARD - isNudge[1] = false; //BACK - isNudge[2] = false; //LEFT - isNudge[3] = false; //RIGHT - isNudge[4] = false; //UP - isNudge[5] = false; //DOWN - isNudge[6] = true; //FORWARD_NUDGE - isNudge[7] = true; //BACK_NUDGE - isNudge[8] = true; //LEFT_NUDGE - isNudge[9] = true; //RIGHT_NUDGE - isNudge[10] = true; //DOWN_Nudge - return isNudge; - } - - - #endregion - - public uint GenerateClientFlags(UUID ObjectID) - { - return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); - } - - /// - /// Send updates to the client about prims which have been placed on the update queue. We don't - /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent - /// timestamp has already been sent. - /// - public void SendPrimUpdates() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - m_sceneViewer.SendPrimUpdates(); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - #region Status Methods - - /// - /// This turns a child agent, into a root agent - /// This is called when an agent teleports into a region, or if an - /// agent crosses into this region from a neighbor over the border - /// - public void MakeRootAgent(Vector3 pos, bool isFlying) - { - m_log.DebugFormat( - "[SCENE]: Upgrading child to root agent for {0} in {1}", - Name, m_scene.RegionInfo.RegionName); - - //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); - - IGroupsModule gm = m_scene.RequestModuleInterface(); - if (gm != null) - m_grouptitle = gm.GetGroupTitle(m_uuid); - - m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; - m_scene.SetRootAgentScene(m_uuid); - - // Moved this from SendInitialData to ensure that m_appearance is initialized - // before the inventory is processed in MakeRootAgent. This fixes a race condition - // related to the handling of attachments - //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); - if (m_scene.TestBorderCross(pos, Cardinals.E)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); - pos.X = crossedBorder.BorderLine.Z - 1; - } - - if (m_scene.TestBorderCross(pos, Cardinals.N)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); - pos.Y = crossedBorder.BorderLine.Z - 1; - } - - //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. - //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, - //they'll bypass the landing point. But I can't think of any decent way of fixing this. - if (KnownChildRegionHandles.Count == 0) - { - ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (land != null) - { - //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) - { - pos = land.LandData.UserLocation; - } - } - } - - if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) - { - Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); - - if (pos.X < 0) - { - emergencyPos.X = (int)Constants.RegionSize + pos.X; - if (!(pos.Y < 0)) - emergencyPos.Y = pos.Y; - if (!(pos.Z < 0)) - emergencyPos.Z = pos.Z; - } - if (pos.Y < 0) - { - emergencyPos.Y = (int)Constants.RegionSize + pos.Y; - if (!(pos.X < 0)) - emergencyPos.X = pos.X; - if (!(pos.Z < 0)) - emergencyPos.Z = pos.Z; - } - if (pos.Z < 0) - { - emergencyPos.Z = 128; - if (!(pos.Y < 0)) - emergencyPos.Y = pos.Y; - if (!(pos.X < 0)) - emergencyPos.X = pos.X; - } - } - - if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) - { - m_log.WarnFormat( - "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", - pos, Name, UUID); - - if (pos.X < 0f) pos.X = 0f; - if (pos.Y < 0f) pos.Y = 0f; - if (pos.Z < 0f) pos.Z = 0f; - } - - float localAVHeight = 1.56f; - if (m_avHeight != 127.0f) - { - localAVHeight = m_avHeight; - } - - float posZLimit = 0; - - if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) - posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; - - float newPosZ = posZLimit + localAVHeight / 2; - if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - pos.Z = newPosZ; - } - AbsolutePosition = pos; - - AddToPhysicalScene(isFlying); - - if (m_forceFly) - { - m_physicsActor.Flying = true; - } - else if (m_flyDisabled) - { - m_physicsActor.Flying = false; - } - - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - else - { - m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); - // emergency; this really shouldn't happen - m_appearance = new AvatarAppearance(UUID); - } - - // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying - // avatar to return to the standing position in mid-air. On login it looks like this is being sent - // elsewhere anyway - // Animator.SendAnimPack(); - - m_scene.SwapRootAgentCount(false); - - //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); - //if (userInfo != null) - // userInfo.FetchInventory(); - //else - // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); - - // On the next prim update, all objects will be sent - // - m_sceneViewer.Reset(); - - m_isChildAgent = false; - - // send the animations of the other presences to me - m_scene.ForEachScenePresence(delegate(ScenePresence presence) - { - if (presence != this) - presence.Animator.SendAnimPackToClient(ControllingClient); - }); - - m_scene.EventManager.TriggerOnMakeRootAgent(this); - } - - /// - /// This turns a root agent into a child agent - /// when an agent departs this region for a neighbor, this gets called. - /// - /// It doesn't get called for a teleport. Reason being, an agent that - /// teleports out may not end up anywhere near this region - /// - public void MakeChildAgent() - { - // It looks like m_animator is set to null somewhere, and MakeChild - // is called after that. Probably in aborted teleports. - if (m_animator == null) - m_animator = new ScenePresenceAnimator(this); - else - Animator.ResetAnimations(); - -// m_log.DebugFormat( -// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", -// Name, UUID, m_scene.RegionInfo.RegionName); - - // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, - // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. - //Velocity = new Vector3(0, 0, 0); - - m_isChildAgent = true; - m_scene.SwapRootAgentCount(true); - RemoveFromPhysicalScene(); - - // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into - - m_scene.EventManager.TriggerOnMakeChildAgent(this); - } - - /// - /// Removes physics plugin scene representation of this agent if it exists. - /// - private void RemoveFromPhysicalScene() - { - if (PhysicsActor != null) - { - m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; - m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; - m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); - m_physicsActor.UnSubscribeEvents(); - m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; - PhysicsActor = null; - } - } - - /// - /// - /// - /// - public void Teleport(Vector3 pos) - { - bool isFlying = false; - - if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - - RemoveFromPhysicalScene(); - Velocity = Vector3.Zero; - AbsolutePosition = pos; - AddToPhysicalScene(isFlying); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - - SendTerseUpdateToAllClients(); - - } - - public void TeleportWithMomentum(Vector3 pos) - { - bool isFlying = false; - if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - - RemoveFromPhysicalScene(); - AbsolutePosition = pos; - AddToPhysicalScene(isFlying); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - - SendTerseUpdateToAllClients(); - } - - /// - /// - /// - public void StopMovement() - { - } - - public void StopFlying() - { - ControllingClient.StopFlying(this); - } - - public void AddNeighbourRegion(ulong regionHandle, string cap) - { - lock (m_knownChildRegions) - { - if (!m_knownChildRegions.ContainsKey(regionHandle)) - { - uint x, y; - Utils.LongToUInts(regionHandle, out x, out y); - m_knownChildRegions.Add(regionHandle, cap); - } - } - } - - public void RemoveNeighbourRegion(ulong regionHandle) - { - lock (m_knownChildRegions) - { - if (m_knownChildRegions.ContainsKey(regionHandle)) - { - m_knownChildRegions.Remove(regionHandle); - //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); - } - } - } - - public void DropOldNeighbours(List oldRegions) - { - foreach (ulong handle in oldRegions) - { - RemoveNeighbourRegion(handle); - Scene.CapsModule.DropChildSeed(UUID, handle); - } - } - - public List GetKnownRegionList() - { - return new List(m_knownChildRegions.Keys); - } - - #endregion - - #region Event Handlers - - /// - /// Sets avatar height in the phyiscs plugin - /// - internal void SetHeight(float height) - { - m_avHeight = height; - if (PhysicsActor != null && !IsChildAgent) - { - Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight); - PhysicsActor.Size = SetSize; - } - } - - /// - /// Complete Avatar's movement into the region. - /// This is called upon a very important packet sent from the client, - /// so it's client-controlled. Never call this method directly. - /// - public void CompleteMovement(IClientAPI client) - { - //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); - - Vector3 look = Velocity; - if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) - { - look = new Vector3(0.99f, 0.042f, 0); - } - - // Prevent teleporting to an underground location - // (may crash client otherwise) - // - Vector3 pos = AbsolutePosition; - float ground = m_scene.GetGroundHeight(pos.X, pos.Y); - if (pos.Z < ground + 1.5f) - { - pos.Z = ground + 1.5f; - AbsolutePosition = pos; - } - m_isChildAgent = false; - bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - MakeRootAgent(AbsolutePosition, m_flying); - - if ((m_callbackURI != null) && !m_callbackURI.Equals("")) - { - m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); - Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); - m_callbackURI = null; - } - - //m_log.DebugFormat("Completed movement"); - - m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); - SendInitialData(); - - // Create child agents in neighbouring regions - if (!m_isChildAgent) - { - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); - if (m_agentTransfer != null) - m_agentTransfer.EnableChildAgents(this); - else - m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); - - IFriendsModule friendsModule = m_scene.RequestModuleInterface(); - if (friendsModule != null) - friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); - } - - } - - /// - /// Callback for the Camera view block check. Gets called with the results of the camera view block test - /// hitYN is true when there's something in the way. - /// - /// - /// - /// - /// - public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) - { - const float POSITION_TOLERANCE = 0.02f; - const float VELOCITY_TOLERANCE = 0.02f; - const float ROTATION_TOLERANCE = 0.02f; - - if (m_followCamAuto) - { - if (hitYN) - { - CameraConstraintActive = true; - //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); - - Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); - ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); - } - else - { - if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) - { - if (CameraConstraintActive) - { - ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); - CameraConstraintActive = false; - } - } - } - } - } - - /// - /// This is the event handler for client movement. If a client is moving, this event is triggering. - /// - public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) - { - //if (m_isChildAgent) - //{ - // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); - // return; - //} - - m_perfMonMS = Util.EnvironmentTickCount(); - - ++m_movementUpdateCount; - if (m_movementUpdateCount < 1) - m_movementUpdateCount = 1; - - #region Sanity Checking - - // This is irritating. Really. - if (!AbsolutePosition.IsFinite()) - { - RemoveFromPhysicalScene(); - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); - - m_pos = m_LastFinitePos; - - if (!m_pos.IsFinite()) - { - m_pos.X = 127f; - m_pos.Y = 127f; - m_pos.Z = 127f; - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); - } - - AddToPhysicalScene(false); - } - else - { - m_LastFinitePos = m_pos; - } - - #endregion Sanity Checking - - #region Inputs - - AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; - Quaternion bodyRotation = agentData.BodyRotation; - - // Camera location in world. We'll need to raytrace - // from this location from time to time. - m_CameraCenter = agentData.CameraCenter; - if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) - { - ReprioritizeUpdates(); - m_lastCameraCenter = m_CameraCenter; - } - - // Use these three vectors to figure out what the agent is looking at - // Convert it to a Matrix and/or Quaternion - m_CameraAtAxis = agentData.CameraAtAxis; - m_CameraLeftAxis = agentData.CameraLeftAxis; - m_CameraUpAxis = agentData.CameraUpAxis; - - // The Agent's Draw distance setting - m_DrawDistance = agentData.Far; - - // Check if Client has camera in 'follow cam' or 'build' mode. - Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); - - m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) - && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; - - m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; - m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; - - #endregion Inputs - - if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) - { - StandUp(); - } - - //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); - // Raycast from the avatar's head to the camera to see if there's anything blocking the view - if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) - { - if (m_followCamAuto) - { - Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; - m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); - } - } - lock (scriptedcontrols) - { - if (scriptedcontrols.Count > 0) - { - SendControlToScripts((uint)flags); - flags = RemoveIgnoredControls(flags, IgnoredControls); - } - } - - if (m_autopilotMoving) - CheckAtSitTarget(); - - if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) - { - m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. - Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - - // TODO: This doesn't prevent the user from walking yet. - // Setting parent ID would fix this, if we knew what value - // to use. Or we could add a m_isSitting variable. - //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - SitGround = true; - } - - // In the future, these values might need to go global. - // Here's where you get them. - m_AgentControlFlags = flags; - m_headrotation = agentData.HeadRotation; - m_state = agentData.State; - - PhysicsActor actor = PhysicsActor; - if (actor == null) - { - return; - } - - bool update_movementflag = false; - - if (m_allowMovement && !SitGround) - { - if (agentData.UseClientAgentPosition) - { - m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; - m_moveToPositionTarget = agentData.ClientAgentPosition; - } - - int i = 0; - - bool update_rotation = false; - bool DCFlagKeyPressed = false; - Vector3 agent_control_v3 = Vector3.Zero; - Quaternion q = bodyRotation; - - bool oldflying = PhysicsActor.Flying; - - if (m_forceFly) - actor.Flying = true; - else if (m_flyDisabled) - actor.Flying = false; - else - actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - - if (actor.Flying != oldflying) - update_movementflag = true; - - if (q != m_bodyRot) - { - m_bodyRot = q; - update_rotation = true; - } - - //guilty until proven innocent.. - bool Nudging = true; - //Basically, if there is at least one non-nudge control then we don't need - //to worry about stopping the avatar - - if (m_parentID == 0) - { - bool bAllowUpdateMoveToPosition = false; - bool bResetMoveToPosition = false; - - Vector3[] dirVectors; - - // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying - // this prevents 'jumping' in inappropriate situations. - if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) - dirVectors = GetWalkDirectionVectors(); - else - dirVectors = Dir_Vectors; - - bool[] isNudge = GetDirectionIsNudge(); - - - - - - foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) - { - if (((uint)flags & (uint)DCF) != 0) - { - bResetMoveToPosition = true; - DCFlagKeyPressed = true; - try - { - agent_control_v3 += dirVectors[i]; - if (isNudge[i] == false) - { - Nudging = false; - } - } - catch (IndexOutOfRangeException) - { - // Why did I get this? - } - - if ((m_movementflag & (uint)DCF) == 0) - { - m_movementflag += (byte)(uint)DCF; - update_movementflag = true; - } - } - else - { - if ((m_movementflag & (uint)DCF) != 0) - { - m_movementflag -= (byte)(uint)DCF; - update_movementflag = true; - } - else - { - bAllowUpdateMoveToPosition = true; - } - } - i++; - } - //Paupaw:Do Proper PID for Autopilot here - if (bResetMoveToPosition) - { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - bAllowUpdateMoveToPosition = false; - } - - if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) - { - //Check the error term of the current position in relation to the target position - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) - { - // we are close enough to the target - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - } - else - { - try - { - // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - Vector3 LocalVectorToTarget3D = - (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords - // Ignore z component of vector - Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget2D.Normalize(); - - //We're not nudging - Nudging = false; - agent_control_v3 += LocalVectorToTarget2D; - - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // - - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - if (LocalVectorToTarget2D.Y > 0)//MoveLeft - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - //AgentControlFlags - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.Y < 0) //MoveRight - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - update_movementflag = true; - } - if (LocalVectorToTarget2D.X < 0) //MoveBack - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.X > 0) //Move Forward - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - update_movementflag = true; - } - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } - } - } - } - - // Cause the avatar to stop flying if it's colliding - // with something with the down arrow pressed. - - // Only do this if we're flying - if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) - { - // Landing detection code - - // Are the landing controls requirements filled? - bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || - ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - - // Are the collision requirements fulfilled? - bool colliding = (m_physicsActor.IsColliding == true); - - if (m_physicsActor.Flying && colliding && controlland) - { - // nesting this check because LengthSquared() is expensive and we don't - // want to do it every step when flying. - if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) - StopFlying(); - } - } - - if (update_movementflag || (update_rotation && DCFlagKeyPressed)) - { - // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); - // m_log.DebugFormat( - // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); - - AddNewMovement(agent_control_v3, q, Nudging); - - - } - } - - if (update_movementflag && !SitGround) - Animator.UpdateMovementAnimations(); - - m_scene.EventManager.TriggerOnClientMovement(this); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) - { - m_autopilotMoving = true; - m_autoPilotTarget = Pos; - m_sitAtAutoTarget = false; - PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; - proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); - proxyObjectGroup.AttachToScene(m_scene); - - // Commented out this code since it could never have executed, but might still be informative. -// if (proxyObjectGroup != null) -// { - proxyObjectGroup.SendGroupFullUpdate(); - remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - m_scene.DeleteSceneObject(proxyObjectGroup, false); -// } -// else -// { -// m_autopilotMoving = false; -// m_autoPilotTarget = Vector3.Zero; -// ControllingClient.SendAlertMessage("Autopilot cancelled"); -// } - } - - public void DoMoveToPosition(Object sender, string method, List args) - { - try - { - float locx = 0f; - float locy = 0f; - float locz = 0f; - uint regionX = 0; - uint regionY = 0; - try - { - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(args[0]) - (float)regionX; - locy = Convert.ToSingle(args[1]) - (float)regionY; - locz = Convert.ToSingle(args[2]); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } - m_moveToPositionInProgress = true; - m_moveToPositionTarget = new Vector3(locx, locy, locz); - } - catch (Exception ex) - { - //Why did I get this error? - m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); - } - } - - private void CheckAtSitTarget() - { - //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); - if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) - { - if (m_sitAtAutoTarget) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); - if (part != null) - { - AbsolutePosition = part.AbsolutePosition; - Velocity = Vector3.Zero; - SendFullUpdateToAllClients(); - - HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? - } - //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); - m_requestedSitTargetUUID = UUID.Zero; - } - /* - else - { - //ControllingClient.SendAlertMessage("Autopilot cancelled"); - //SendTerseUpdateToAllClients(); - //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; - ////uint nextUUID = m_scene.NextLocalId; - - //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); - //if (proxyObjectGroup != null) - //{ - //proxyObjectGroup.SendGroupFullUpdate(); - //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - //m_scene.DeleteSceneObject(proxyObjectGroup); - //} - } - */ - m_autoPilotTarget = Vector3.Zero; - m_autopilotMoving = false; - } - } - /// - /// Perform the logic necessary to stand the avatar up. This method also executes - /// the stand animation. - /// - public void StandUp() - { - SitGround = false; - - if (m_parentID != 0) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - if (part != null) - { - part.TaskInventory.LockItemsForRead(true); - TaskInventoryDictionary taskIDict = part.TaskInventory; - if (taskIDict != null) - { - foreach (UUID taskID in taskIDict.Keys) - { - UnRegisterControlEventsToScript(LocalId, taskID); - taskIDict[taskID].PermsMask &= ~( - 2048 | //PERMISSION_CONTROL_CAMERA - 4); // PERMISSION_TAKE_CONTROLS - } - } - part.TaskInventory.LockItemsForRead(false); - // Reset sit target. - if (part.GetAvatarOnSitTarget() == UUID) - part.SetAvatarOnSitTarget(UUID.Zero); - m_parentPosition = part.GetWorldPosition(); - ControllingClient.SendClearFollowCamProperties(part.ParentUUID); - } - // part.GetWorldRotation() is the rotation of the object being sat on - // Rotation is the sittiing Av's rotation - - Quaternion partRot; -// if (part.LinkNum == 1) -// { // Root prim of linkset -// partRot = part.ParentGroup.RootPart.RotationOffset; -// } -// else -// { // single or child prim - -// } - if (part == null) //CW: Part may be gone. llDie() for example. - { - partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - partRot = part.GetWorldRotation(); - } - - Quaternion partIRot = Quaternion.Inverse(partRot); - - Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av - Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av - - - if (m_physicsActor == null) - { - AddToPhysicalScene(false); - } - //CW: If the part isn't null then we can set the current position - if (part != null) - { - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! - AbsolutePosition = avWorldStandUp; //KF: Fix stand up. - part.IsOccupied = false; - part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); - } - else - { - //CW: Since the part doesn't exist, a coarse standup position isn't an issue - AbsolutePosition = m_lastWorldPosition; - } - - m_parentPosition = Vector3.Zero; - m_parentID = 0; - m_linkedPrim = UUID.Zero; - m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - SendFullUpdateToAllClients(); - m_requestedSitTargetID = 0; - - if ((m_physicsActor != null) && (m_avHeight > 0)) - { - SetHeight(m_avHeight); - } - } - Animator.TrySetMovementAnimation("STAND"); - } - - private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) - { - SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID); - if (targetPart == null) - return null; - - // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used. - // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. - - // Get our own copy of the part array, and sort into the order we want to test - SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); - Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) - { - // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) - int linkNum1 = p1==targetPart ? -1 : p1.LinkNum; - int linkNum2 = p2==targetPart ? -1 : p2.LinkNum; - return linkNum1 - linkNum2; - } - ); - - //look for prims with explicit sit targets that are available - foreach (SceneObjectPart part in partArray) - { - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); - bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); - bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. - if (SitTargetisSet && !SitTargetOccupied) - { - //switch the target to this prim - return part; - } - } - - // no explicit sit target found - use original target - return targetPart; - } - - private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) - { - bool autopilot = true; - Vector3 autopilotTarget = new Vector3(); - Quaternion sitOrientation = Quaternion.Identity; - Vector3 pos = new Vector3(); - Vector3 cameraEyeOffset = Vector3.Zero; - Vector3 cameraAtOffset = Vector3.Zero; - bool forceMouselook = false; - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part == null) return; - - // TODO: determine position to sit at based on scene geometry; don't trust offset from client - // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - - // part is the prim to sit on - // offset is the world-ref vector distance from that prim center to the click-spot - // UUID is the UUID of the Avatar doing the clicking - - m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation - - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - - bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. - // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); - Quaternion partRot; -// if (part.LinkNum == 1) -// { // Root prim of linkset -// partRot = part.ParentGroup.RootPart.RotationOffset; -// } -// else -// { // single or child prim - partRot = part.GetWorldRotation(); -// } - Quaternion partIRot = Quaternion.Inverse(partRot); -//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); - // Sit analysis rewritten by KF 091125 - if (SitTargetisSet) // scipted sit - { - if (!part.IsOccupied) - { -//Console.WriteLine("Scripted, unoccupied"); - part.SetAvatarOnSitTarget(UUID); // set that Av will be on it - offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one - - Quaternion nrot = avSitOrientation; - if (!part.IsRoot) - { - nrot = part.RotationOffset * avSitOrientation; - } - sitOrientation = nrot; // Change rotatione to the scripted one - OffsetRotation = nrot; - autopilot = false; // Jump direct to scripted llSitPos() - } - else - { -//Console.WriteLine("Scripted, occupied"); - return; - } - } - else // Not Scripted - { - if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) - { - // large prim & offset, ignore if other Avs sitting -// offset.Z -= 0.05f; - m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked - autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point - -//Console.WriteLine(" offset ={0}", offset); -//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); -//Console.WriteLine(" autopilotTarget={0}", autopilotTarget); - - } - else // small offset - { -//Console.WriteLine("Small offset"); - if (!part.IsOccupied) - { - m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center - autopilotTarget = part.AbsolutePosition; -//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); - } - else return; // occupied small - } // end large/small - } // end Scripted/not - cameraAtOffset = part.GetCameraAtOffset(); - cameraEyeOffset = part.GetCameraEyeOffset(); - forceMouselook = part.GetForceMouselook(); - if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // - if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // - - if (m_physicsActor != null) - { - // If we're not using the client autopilot, we're immediately warping the avatar to the location - // We can remove the physicsActor until they stand up. - m_sitAvatarHeight = m_physicsActor.Size.Z; - if (autopilot) - { // its not a scripted sit -// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) - if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) - { - autopilot = false; // close enough - m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. - Not using the part's position because returning the AV to the last known standing - position is likely to be more friendly, isn't it? */ - RemoveFromPhysicalScene(); - AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target - } // else the autopilot will get us close - } - else - { // its a scripted sit - m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. - I *am* using the part's position this time because we have no real idea how far away - the avatar is from the sit target. */ - RemoveFromPhysicalScene(); - } - } - else return; // physactor is null! - - Vector3 offsetr; // = offset * partIRot; - // KF: In a linkset, offsetr needs to be relative to the group root! 091208 - // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); - // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. - // { // Single, or Root prim of linkset, target is ClickOffset * RootRot - //offsetr = offset * partIRot; -// - // else - // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) - // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + - // (offset * partRot); - // } - -//Console.WriteLine(" "); -//Console.WriteLine("link number ={0}", part.LinkNum); -//Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); -//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); -//Console.WriteLine("Click offst ={0}", offset); -//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); -//Console.WriteLine("offsetr ={0}", offsetr); -//Console.WriteLine("Camera At ={0}", cameraAtOffset); -//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); - - //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child - ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); - - m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target - // This calls HandleAgentSit twice, once from here, and the client calls - // HandleAgentSit itself after it gets to the location - // It doesn't get to the location until we've moved them there though - // which happens in HandleAgentSit :P - m_autopilotMoving = autopilot; - m_autoPilotTarget = autopilotTarget; - m_sitAtAutoTarget = autopilot; - m_initialSitTarget = autopilotTarget; - if (!autopilot) - HandleAgentSit(remoteClient, UUID); - } - - public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) - { - if (m_parentID != 0) - { - StandUp(); - } - m_nextSitAnimation = "SIT"; - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - - if (part != null) - { - if (!String.IsNullOrEmpty(part.SitAnimation)) - { - m_nextSitAnimation = part.SitAnimation; - } - m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; - m_requestedSitTargetUUID = targetID; - - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); - //SitRayCastAvatarPosition(part); - //return; - } - } - else - { - - m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); - } - - - - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); - } - /* - public void SitRayCastAvatarPosition(SceneObjectPart part) - { - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = AbsolutePosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse); - } - - public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); - } - else - { - SitRayCastAvatarPositionCameraZ(part); - } - } - else - { - SitRayCastAvatarPositionCameraZ(part); - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) - { - // Next, try to raycast from the camera Z position - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse); - } - - public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal); - } - else - { - SitRayCastCameraPosition(part); - } - } - else - { - SitRayCastCameraPosition(part); - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - public void SitRayCastCameraPosition(SceneObjectPart part) - { - // Next, try to raycast from the camera position - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = CameraPosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse); - } - - public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); - } - else - { - SitRayHorizontal(part); - } - } - else - { - SitRayHorizontal(part); - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - public void SitRayHorizontal(SceneObjectPart part) - { - // Next, try to raycast from the avatar position to fwd - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = CameraPosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); - } - - public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); - // Next, try to raycast from the camera position - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = CameraPosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition); - } - else - { - ControllingClient.SendAlertMessage("Sit position not accessable."); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - } - else - { - ControllingClient.SendAlertMessage("Sit position not accessable."); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) - { - int i = 0; - //throw new NotImplementedException(); - //m_requestedSitTargetUUID = UUID.Zero; - //m_requestedSitTargetID = 0; - //m_requestedSitOffset = Vector3.Zero; - - SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); - } - */ - public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) - { - if (m_parentID != 0) - { - StandUp(); - } - if (!String.IsNullOrEmpty(sitAnimation)) - { - m_nextSitAnimation = sitAnimation; - } - else - { - m_nextSitAnimation = "SIT"; - } - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part != null) - { - m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; - m_requestedSitTargetUUID = targetID; - - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //SitRayCastAvatarPosition(part); - //return; - } - } - else - { - m_log.Warn("Sit requested on unknown object: " + targetID); - } - - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); - } - - public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) - { - if (!String.IsNullOrEmpty(m_nextSitAnimation)) - { - HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); - } - else - { - HandleAgentSit(remoteClient, agentID, "SIT"); - } - } - - public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - - if (m_sitAtAutoTarget || !m_autopilotMoving) - { - if (part != null) - { -//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); - if (part.GetAvatarOnSitTarget() == UUID) - { -//Console.WriteLine("Scripted Sit"); - // Scripted sit - Vector3 sitTargetPos = part.SitTargetPosition; - Quaternion sitTargetOrient = part.SitTargetOrientation; - m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); - m_pos += SIT_TARGET_ADJUSTMENT; - if (!part.IsRoot) - { - m_pos *= part.RotationOffset; - } - m_bodyRot = sitTargetOrient; - m_parentPosition = part.AbsolutePosition; - part.IsOccupied = true; - part.ParentGroup.AddAvatar(agentID); -Console.WriteLine("Scripted Sit ofset {0}", m_pos); - } - else - { - // if m_avUnscriptedSitPos is zero then Av sits above center - // Else Av sits at m_avUnscriptedSitPos - - // Non-scripted sit by Kitto Flora 21Nov09 - // Calculate angle of line from prim to Av - Quaternion partIRot; -// if (part.LinkNum == 1) -// { // Root prim of linkset -// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); -// } -// else -// { // single or child prim - partIRot = Quaternion.Inverse(part.GetWorldRotation()); -// } - Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; - float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); - float x_diff = ( m_avInitialPos.X - sitTargetPos.X); - if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 - if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 - float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); - // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. - // Av sits at world euler <0,0, z>, translated by part rotation - m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click - - m_parentPosition = part.AbsolutePosition; - part.IsOccupied = true; - part.ParentGroup.AddAvatar(agentID); - m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation - (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center - (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + - m_avUnscriptedSitPos; // adds click offset, if any - //Set up raytrace to find top surface of prim - Vector3 size = part.Scale; - float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); - Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); - Vector3 down = new Vector3(0f, 0f, -1f); -//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); - m_scene.PhysicsScene.RaycastWorld( - start, // Vector3 position, - down, // Vector3 direction, - mag, // float length, - SitAltitudeCallback); // retMethod - } // end scripted/not - } - else // no Av - { - return; - } - } - - //We want our offsets to reference the root prim, not the child we may have sat on - if (!part.IsRoot) - { - m_parentID = part.ParentGroup.RootPart.LocalId; - m_pos += part.OffsetPosition; - } - else - { - m_parentID = m_requestedSitTargetID; - } - - m_linkedPrim = part.UUID; - - Velocity = Vector3.Zero; - RemoveFromPhysicalScene(); - - Animator.TrySetMovementAnimation(sitAnimation); - SendFullUpdateToAllClients(); - } - - public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) - { - // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer - // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. - if(hitYN) - { - // m_pos = Av offset from prim center to make look like on center - // m_parentPosition = Actual center pos of prim - // collisionPoint = spot on prim where we want to sit - // collisionPoint.Z = global sit surface height - SceneObjectPart part = m_scene.GetSceneObjectPart(localid); - Quaternion partIRot; -// if (part.LinkNum == 1) -/// { // Root prim of linkset -// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); -// } -// else -// { // single or child prim - partIRot = Quaternion.Inverse(part.GetWorldRotation()); -// } - if (m_initialSitTarget != null) - { - float offZ = collisionPoint.Z - m_initialSitTarget.Z; - Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction - //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); - m_pos += offset; - // ControllingClient.SendClearFollowCamProperties(part.UUID); - } - - } - } // End SitAltitudeCallback KF. - - /// - /// Event handler for the 'Always run' setting on the client - /// Tells the physics plugin to increase speed of movement. - /// - public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun) - { - m_setAlwaysRun = pSetAlwaysRun; - if (PhysicsActor != null) - { - PhysicsActor.SetAlwaysRun = pSetAlwaysRun; - } - } - - public void HandleStartAnim(IClientAPI remoteClient, UUID animID) - { - Animator.AddAnimation(animID, UUID.Zero); - } - - public void HandleStopAnim(IClientAPI remoteClient, UUID animID) - { - Animator.RemoveAnimation(animID); - } - - /// - /// Rotate the avatar to the given rotation and apply a movement in the given relative vector - /// - /// The vector in which to move. This is relative to the rotation argument - /// The direction in which this avatar should now face. - public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) - { - if (m_isChildAgent) - { - // WHAT??? - m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); - - // we have to reset the user's child agent connections. - // Likely, here they've lost the eventqueue for other regions so border - // crossings will fail at this point unless we reset them. - - List regions = new List(KnownChildRegionHandles); - regions.Remove(m_scene.RegionInfo.RegionHandle); - - MakeRootAgent(new Vector3(127f, 127f, 127f), true); - - // Async command - if (m_scene.SceneGridService != null) - { - m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions); - - // Give the above command some time to try and close the connections. - // this is really an emergency.. so sleep, or we'll get all discombobulated. - System.Threading.Thread.Sleep(500); - } - - if (m_scene.SceneGridService != null) - { - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); - if (m_agentTransfer != null) - m_agentTransfer.EnableChildAgents(this); - } - - return; - } - - m_perfMonMS = Util.EnvironmentTickCount(); - - Rotation = rotation; - Vector3 direc = vec * rotation; - direc.Normalize(); - PhysicsActor actor = m_physicsActor; - if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. - - direc *= 0.03f * 128f * m_speedModifier; - - if (actor != null) - { - if (actor.Flying) - { - direc *= 4.0f; - //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //bool colliding = (m_physicsActor.IsColliding==true); - //if (controlland) - // m_log.Info("[AGENT]: landCommand"); - //if (colliding) - // m_log.Info("[AGENT]: colliding"); - //if (m_physicsActor.Flying && colliding && controlland) - //{ - // StopFlying(); - // m_log.Info("[AGENT]: Stop FLying"); - //} - } - else if (!actor.Flying && actor.IsColliding) - { - if (direc.Z > 2.0f) - { - if(m_animator.m_animTickJump == -1) - { - direc.Z *= 3.0f; // jump - } - else - { - direc.Z *= 0.1f; // prejump - } - /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs - Animator.TrySetMovementAnimation("PREJUMP"); - Animator.TrySetMovementAnimation("JUMP"); - */ - } - } - } - - // TODO: Add the force instead of only setting it to support multiple forces per frame? - m_forceToApply = direc; - m_isNudging = Nudging; - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - #endregion - - #region Overridden Methods - - public override void Update() - { - const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; - //const int TIME_MS_TOLERANCE = 3000; - - - - if (m_isChildAgent == false) - { -// PhysicsActor actor = m_physicsActor; - - // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to - // grab the latest PhysicsActor velocity, whereas m_velocity is often - // storing a requested force instead of an actual traveling velocity - - // Throw away duplicate or insignificant updates - if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) - //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) - { - SendTerseUpdateToAllClients(); - - // Update the "last" values - m_lastPosition = m_pos; - m_lastRotation = m_bodyRot; - m_lastVelocity = Velocity; - //m_lastTerseSent = Environment.TickCount; - } - - // followed suggestion from mic bowman. reversed the two lines below. - if (m_parentID == 0 && m_physicsActor != null || m_parentID != 0) // Check that we have a physics actor or we're sitting on something - CheckForBorderCrossing(); - CheckForSignificantMovement(); // sends update to the modules. - } - - //Sending prim updates AFTER the avatar terse updates are sent - SendPrimUpdates(); - } - - #endregion - - #region Update Client(s) - - /// - /// Sends a location update to the client connected to this scenePresence - /// - /// - public void SendTerseUpdateToClient(IClientAPI remoteClient) - { - // If the client is inactive, it's getting its updates from another - // server. - if (remoteClient.IsActive) - { - m_perfMonMS = Util.EnvironmentTickCount(); - - PhysicsActor actor = m_physicsActor; - Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); - - remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - m_scene.StatsReporter.AddAgentUpdates(1); - } - } - - /// - /// Send a location/velocity/accelleration update to all agents in scene - /// - public void SendTerseUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - m_scene.ForEachClient(SendTerseUpdateToClient); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - public void SendCoarseLocations(List coarseLocations, List avatarUUIDs) - { - SendCourseLocationsMethod d = m_sendCourseLocationsMethod; - if (d != null) - { - d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); - } - } - - public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) - { - if (d != null) - m_sendCourseLocationsMethod = d; - } - - public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List coarseLocations, List avatarUUIDs) - { - m_perfMonMS = Util.EnvironmentTickCount(); - m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - /// - /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) - /// - /// - public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) - { - // 2 stage check is needed. - if (remoteAvatar == null) - return; - IClientAPI cl=remoteAvatar.ControllingClient; - if (cl == null) - return; - if (m_appearance.Texture == null) - return; - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); - m_scene.StatsReporter.AddAgentUpdates(1); - } - - /// - /// Tell *ALL* agents about this agent - /// - public void SendInitialFullUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - int avUpdates = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - ++avUpdates; - // only send if this is the root (children are only "listening posts" in a foreign region) - if (!IsChildAgent) - { - SendFullUpdateToOtherClient(avatar); - } - - if (avatar.LocalId != LocalId) - { - if (!avatar.IsChildAgent) - { - avatar.SendFullUpdateToOtherClient(this); - avatar.SendAppearanceToOtherAgent(this); - avatar.Animator.SendAnimPackToClient(ControllingClient); - } - } - }); - - m_scene.StatsReporter.AddAgentUpdates(avUpdates); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - //Animator.SendAnimPack(); - } - - public void SendFullUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - // only send update from root agents to other clients; children are only "listening posts" - int count = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence sp) - { - if (sp.IsChildAgent) - return; - SendFullUpdateToOtherClient(sp); - ++count; - }); - m_scene.StatsReporter.AddAgentUpdates(count); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - Animator.SendAnimPack(); - } - - /// - /// Do everything required once a client completes its movement into a region - /// - public void SendInitialData() - { - // Moved this into CompleteMovement to ensure that m_appearance is initialized before - // the inventory arrives - // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - m_controllingClient.SendAvatarDataImmediate(this); - - SendInitialFullUpdateToAllClients(); - SendAppearanceToAllOtherAgents(); - } - - /// - /// Tell the client for this scene presence what items it should be wearing now - /// - public void SendWearables() - { - m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); - - ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); - } - - /// - /// - /// - public void SendAppearanceToAllOtherAgents() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) - { - if (scenePresence.UUID != UUID) - { - SendAppearanceToOtherAgent(scenePresence); - } - }); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - /// - /// Send appearance data to an agent that isn't this one. - /// - /// - public void SendAppearanceToOtherAgent(ScenePresence avatar) - { - avatar.ControllingClient.SendAppearance( - m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); - } - - /// - /// Set appearance data (textureentry and slider settings) received from the client - /// - /// - /// - public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) - { - if (m_physicsActor != null) - { - if (!IsChildAgent) - { - // This may seem like it's redundant, remove the avatar from the physics scene - // just to add it back again, but it saves us from having to update - // 3 variables 10 times a second. - bool flyingTemp = m_physicsActor.Flying; - RemoveFromPhysicalScene(); - //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); - - //PhysicsActor = null; - - AddToPhysicalScene(flyingTemp); - } - } - - #region Bake Cache Check - - if (textureEntry != null) - { - for (int i = 0; i < BAKE_INDICES.Length; i++) - { - int j = BAKE_INDICES[i]; - Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; - - if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - { - if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) - { - m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); - this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); - } - } - } - - } - - - #endregion Bake Cache Check - - m_appearance.SetAppearance(textureEntry, visualParams); - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - - // This is not needed, because only the transient data changed - //AvatarData adata = new AvatarData(m_appearance); - //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); - - SendAppearanceToAllOtherAgents(); - if (!m_startAnimationSet) - { - Animator.UpdateMovementAnimations(); - m_startAnimationSet = true; - } - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - m_controllingClient.SendAvatarDataImmediate(this); - } - - public void SetWearable(int wearableId, AvatarWearable wearable) - { - m_appearance.SetWearable(wearableId, wearable); - AvatarData adata = new AvatarData(m_appearance); - m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); - m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); - } - - // Because appearance setting is in a module, we actually need - // to give it access to our appearance directly, otherwise we - // get a synchronization issue. - public AvatarAppearance Appearance - { - get { return m_appearance; } - set { m_appearance = value; } - } - - #endregion - - #region Significant Movement Method - - /// - /// This checks for a significant movement and sends a courselocationchange update - /// - protected void CheckForSignificantMovement() - { - // Movement updates for agents in neighboring regions are sent directly to clients. - // This value only affects how often agent positions are sent to neighbor regions - // for things such as distance-based update prioritization - const float SIGNIFICANT_MOVEMENT = 2.0f; - - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) - { - posLastSignificantMove = AbsolutePosition; - m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); - } - - // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m - if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || - Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) - { - m_lastChildAgentUpdatePosition = AbsolutePosition; - m_lastChildAgentUpdateCamPosition = CameraPosition; - - ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); - cadu.ActiveGroupID = UUID.Zero.Guid; - cadu.AgentID = UUID.Guid; - cadu.alwaysrun = m_setAlwaysRun; - cadu.AVHeight = m_avHeight; - Vector3 tempCameraCenter = m_CameraCenter; - cadu.cameraPosition = tempCameraCenter; - cadu.drawdistance = m_DrawDistance; - cadu.GroupAccess = 0; - cadu.Position = AbsolutePosition; - cadu.regionHandle = m_rootRegionHandle; - float multiplier = 1; - int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); - if (innacurateNeighbors != 0) - { - multiplier = 1f / (float)innacurateNeighbors; - } - if (multiplier <= 0f) - { - multiplier = 0.25f; - } - - //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); - cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); - cadu.Velocity = Velocity; - - AgentPosition agentpos = new AgentPosition(); - agentpos.CopyFrom(cadu); - - m_scene.SendOutChildAgentUpdates(agentpos, this); - } - } - - #endregion - - #region Border Crossing Methods - - /// - /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion - /// - protected void CheckForBorderCrossing() - { - if (IsChildAgent) - return; - - Vector3 pos2 = AbsolutePosition; - Vector3 vel = Velocity; - int neighbor = 0; - int[] fix = new int[2]; - - float timeStep = 0.1f; - pos2.X = pos2.X + (vel.X*timeStep); - pos2.Y = pos2.Y + (vel.Y*timeStep); - pos2.Z = pos2.Z + (vel.Z*timeStep); - - if (!IsInTransit) - { - // Checks if where it's headed exists a region - - bool needsTransit = false; - if (m_scene.TestBorderCross(pos2, Cardinals.W)) - { - if (m_scene.TestBorderCross(pos2, Cardinals.S)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.SW, ref fix); - } - else if (m_scene.TestBorderCross(pos2, Cardinals.N)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.NW, ref fix); - } - else - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.W, ref fix); - } - } - else if (m_scene.TestBorderCross(pos2, Cardinals.E)) - { - if (m_scene.TestBorderCross(pos2, Cardinals.S)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.SE, ref fix); - } - else if (m_scene.TestBorderCross(pos2, Cardinals.N)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.NE, ref fix); - } - else - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.E, ref fix); - } - } - else if (m_scene.TestBorderCross(pos2, Cardinals.S)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.S, ref fix); - } - else if (m_scene.TestBorderCross(pos2, Cardinals.N)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.N, ref fix); - } - - - // Makes sure avatar does not end up outside region - if (neighbor <= 0) - { - if (!needsTransit) - { - if (m_requestedSitTargetUUID == UUID.Zero) - { - Vector3 pos = AbsolutePosition; - if (AbsolutePosition.X < 0) - pos.X += Velocity.X; - else if (AbsolutePosition.X > Constants.RegionSize) - pos.X -= Velocity.X; - if (AbsolutePosition.Y < 0) - pos.Y += Velocity.Y; - else if (AbsolutePosition.Y > Constants.RegionSize) - pos.Y -= Velocity.Y; - AbsolutePosition = pos; - } - } - } - else if (neighbor > 0) - CrossToNewRegion(); - } - else - { - RemoveFromPhysicalScene(); - // This constant has been inferred from experimentation - // I'm not sure what this value should be, so I tried a few values. - timeStep = 0.04f; - pos2 = AbsolutePosition; - pos2.X = pos2.X + (vel.X * timeStep); - pos2.Y = pos2.Y + (vel.Y * timeStep); - pos2.Z = pos2.Z + (vel.Z * timeStep); - m_pos = pos2; - } - } - - protected int HaveNeighbor(Cardinals car, ref int[] fix) - { - uint neighbourx = m_regionInfo.RegionLocX; - uint neighboury = m_regionInfo.RegionLocY; - - int dir = (int)car; - - if (dir > 1 && dir < 5) //Heading East - neighbourx++; - else if (dir > 5) // Heading West - neighbourx--; - - if (dir < 3 || dir == 8) // Heading North - neighboury++; - else if (dir > 3 && dir < 7) // Heading Sout - neighboury--; - - int x = (int)(neighbourx * Constants.RegionSize); - int y = (int)(neighboury * Constants.RegionSize); - GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y); - - if (neighbourRegion == null) - { - fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); - fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); - return dir * (-1); - } - else - return dir; - } - - /// - /// Moves the agent outside the region bounds - /// Tells neighbor region that we're crossing to it - /// If the neighbor accepts, remove the agent's viewable avatar from this scene - /// set them to a child agent. - /// - protected void CrossToNewRegion() - { - InTransit(); - try - { - m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); - } - catch - { - m_scene.CrossAgentToNewRegion(this, false); - } - } - - public void InTransit() - { - m_inTransit = true; - - if ((m_physicsActor != null) && m_physicsActor.Flying) - m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; - else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) - m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; - } - - public void NotInTransit() - { - m_inTransit = false; - } - - public void RestoreInCurrentScene() - { - AddToPhysicalScene(false); // not exactly false - } - - public void Reset() - { - // Put the child agent back at the center - AbsolutePosition - = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); - Animator.ResetAnimations(); - } - - /// - /// Computes which child agents to close when the scene presence moves to another region. - /// Removes those regions from m_knownRegions. - /// - /// The new region's x on the map - /// The new region's y on the map - /// - public void CloseChildAgents(uint newRegionX, uint newRegionY) - { - List byebyeRegions = new List(); - m_log.DebugFormat( - "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", - m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); - //DumpKnownRegions(); - - lock (m_knownChildRegions) - { - foreach (ulong handle in m_knownChildRegions.Keys) - { - // Don't close the agent on this region yet - if (handle != Scene.RegionInfo.RegionHandle) - { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - - //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); - //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); - if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) - { - byebyeRegions.Add(handle); - } - } - } - } - - if (byebyeRegions.Count > 0) - { - m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); - m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); - } - - foreach (ulong handle in byebyeRegions) - { - RemoveNeighbourRegion(handle); - } - } - - #endregion - - /// - /// This allows the Sim owner the abiility to kick users from their sim currently. - /// It tells the client that the agent has permission to do so. - /// - public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) - { - if (godStatus) - { - // For now, assign god level 200 to anyone - // who is granted god powers, but has no god level set. - // - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID); - if (account != null) - { - if (account.UserLevel > 0) - m_godLevel = account.UserLevel; - else - m_godLevel = 200; - } - } - else - { - m_godLevel = 0; - } - - ControllingClient.SendAdminResponse(token, (uint)m_godLevel); - } - - #region Child Agent Updates - - public void ChildAgentDataUpdate(AgentData cAgentData) - { - //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); - if (!IsChildAgent) - return; - - CopyFrom(cAgentData); - } - - /// - /// This updates important decision making data about a child agent - /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region - /// - public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) - { - if (!IsChildAgent) - return; - - //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); - int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; - int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; - - Vector3 offset = new Vector3(shiftx, shifty, 0f); - - m_DrawDistance = cAgentData.Far; - if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! - m_pos = cAgentData.Position + offset; - - if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) - { - posLastSignificantMove = AbsolutePosition; - ReprioritizeUpdates(); - } - - m_CameraCenter = cAgentData.Center + offset; - - m_avHeight = cAgentData.Size.Z; - //SetHeight(cAgentData.AVHeight); - - if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) - ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); - - // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. - if (m_scene.m_seeIntoRegionFromNeighbor) - m_sceneViewer.Reset(); - - //cAgentData.AVHeight; - m_rootRegionHandle = cAgentData.RegionHandle; - //m_velocity = cAgentData.Velocity; - } - - public void CopyTo(AgentData cAgent) - { - cAgent.AgentID = UUID; - cAgent.RegionID = Scene.RegionInfo.RegionID; - - cAgent.Position = AbsolutePosition; - cAgent.Velocity = m_velocity; - cAgent.Center = m_CameraCenter; - // Don't copy the size; it is inferred from apearance parameters - //cAgent.Size = new Vector3(0, 0, m_avHeight); - cAgent.AtAxis = m_CameraAtAxis; - cAgent.LeftAxis = m_CameraLeftAxis; - cAgent.UpAxis = m_CameraUpAxis; - - cAgent.Far = m_DrawDistance; - - // Throttles - float multiplier = 1; - int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); - if (innacurateNeighbors != 0) - { - multiplier = 1f / innacurateNeighbors; - } - if (multiplier <= 0f) - { - multiplier = 0.25f; - } - //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); - cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); - - cAgent.HeadRotation = m_headrotation; - cAgent.BodyRotation = m_bodyRot; - cAgent.ControlFlags = (uint)m_AgentControlFlags; - - if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - cAgent.GodLevel = (byte)m_godLevel; - else - cAgent.GodLevel = (byte) 0; - - cAgent.AlwaysRun = m_setAlwaysRun; - - try - { - // We might not pass the Wearables in all cases... - // They're only needed so that persistent changes to the appearance - // are preserved in the new region where the user is moving to. - // But in Hypergrid we might not let this happen. - int i = 0; - UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; - foreach (AvatarWearable aw in m_appearance.Wearables) - { - if (aw != null) - { - wears[i++] = aw.ItemID; - wears[i++] = aw.AssetID; - } - else - { - wears[i++] = UUID.Zero; - wears[i++] = UUID.Zero; - } - } - cAgent.Wearables = wears; - - cAgent.VisualParams = m_appearance.VisualParams; - - if (m_appearance.Texture != null) - cAgent.AgentTextures = m_appearance.Texture.GetBytes(); - } - catch (Exception e) - { - m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); - } - - //Attachments - List attPoints = m_appearance.GetAttachedPoints(); - if (attPoints != null) - { - //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); - int i = 0; - AttachmentData[] attachs = new AttachmentData[attPoints.Count]; - foreach (int point in attPoints) - { - attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); - } - cAgent.Attachments = attachs; - } - - lock (scriptedcontrols) - { - ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; - int i = 0; - - foreach (ScriptControllers c in scriptedcontrols.Values) - { - controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); - } - cAgent.Controllers = controls; - } - - // Animations - try - { - cAgent.Anims = Animator.Animations.ToArray(); - } - catch { } - - // cAgent.GroupID = ?? - // Groups??? - - } - - public void CopyFrom(AgentData cAgent) - { - m_originRegionID = cAgent.RegionID; - - m_callbackURI = cAgent.CallbackURI; - - m_pos = cAgent.Position; - - m_velocity = cAgent.Velocity; - m_CameraCenter = cAgent.Center; - //m_avHeight = cAgent.Size.Z; - m_CameraAtAxis = cAgent.AtAxis; - m_CameraLeftAxis = cAgent.LeftAxis; - m_CameraUpAxis = cAgent.UpAxis; - - m_DrawDistance = cAgent.Far; - - if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) - ControllingClient.SetChildAgentThrottle(cAgent.Throttles); - - m_headrotation = cAgent.HeadRotation; - m_bodyRot = cAgent.BodyRotation; - m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; - - if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - m_godLevel = cAgent.GodLevel; - m_setAlwaysRun = cAgent.AlwaysRun; - - uint i = 0; - try - { - if (cAgent.Wearables == null) - cAgent.Wearables = new UUID[0]; - AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; - for (uint n = 0; n < cAgent.Wearables.Length; n += 2) - { - UUID itemId = cAgent.Wearables[n]; - UUID assetId = cAgent.Wearables[n + 1]; - wears[i++] = new AvatarWearable(itemId, assetId); - } - m_appearance.Wearables = wears; - Primitive.TextureEntry te; - if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) - te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); - else - te = AvatarAppearance.GetDefaultTexture(); - if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) - cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); - m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); - } - catch (Exception e) - { - m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); - } - - // Attachments - try - { - if (cAgent.Attachments != null) - { - m_appearance.ClearAttachments(); - foreach (AttachmentData att in cAgent.Attachments) - { - m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); - } - } - } - catch { } - - try - { - lock (scriptedcontrols) - { - if (cAgent.Controllers != null) - { - scriptedcontrols.Clear(); - - foreach (ControllerData c in cAgent.Controllers) - { - ScriptControllers sc = new ScriptControllers(); - sc.itemID = c.ItemID; - sc.ignoreControls = (ScriptControlled)c.IgnoreControls; - sc.eventControls = (ScriptControlled)c.EventControls; - - scriptedcontrols[sc.itemID] = sc; - } - } - } - } - catch { } - // Animations - try - { - Animator.ResetAnimations(); - Animator.Animations.FromArray(cAgent.Anims); - } - catch { } - - //cAgent.GroupID = ?? - //Groups??? - } - - public bool CopyAgent(out IAgentData agent) - { - agent = new CompleteAgentData(); - CopyTo((AgentData)agent); - return true; - } - - #endregion Child Agent Updates - - /// - /// Handles part of the PID controller function for moving an avatar. - /// - public override void UpdateMovement() - { - if (m_forceToApply.HasValue) - { - - Vector3 force = m_forceToApply.Value; - m_updateflag = true; - Velocity = force; - - m_forceToApply = null; - } - else - { - if (m_isNudging) - { - Vector3 force = Vector3.Zero; - - m_updateflag = true; - Velocity = force; - m_isNudging = false; - m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" - } - } - } - - public override void SetText(string text, Vector3 color, double alpha) - { - throw new Exception("Can't set Text on avatar."); - } - - /// - /// Adds a physical representation of the avatar to the Physics plugin - /// - public void AddToPhysicalScene(bool isFlying) - { - PhysicsScene scene = m_scene.PhysicsScene; - - Vector3 pVec = AbsolutePosition; - - // Old bug where the height was in centimeters instead of meters - if (m_avHeight == 127.0f) - { - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f), - isFlying); - } - else - { - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, - new Vector3(0f, 0f, m_avHeight), isFlying); - } - scene.AddPhysicsActorTaint(m_physicsActor); - //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; - m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; - m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong - m_physicsActor.SubscribeEvents(500); - m_physicsActor.LocalID = LocalId; - } - - private void OutOfBoundsCall(Vector3 pos) - { - //bool flying = m_physicsActor.Flying; - //RemoveFromPhysicalScene(); - - //AddToPhysicalScene(flying); - if (ControllingClient != null) - ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); - } - - // Event called by the physics plugin to tell the avatar about a collision. - private void PhysicsCollisionUpdate(EventArgs e) - { - if (e == null) - return; - - // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( - // as of this comment the interval is set in AddToPhysicalScene - if (Animator!=null) - { - if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, - { // else its will lock out other animation changes, like ground sit. - Animator.UpdateMovementAnimations(); - m_updateCount--; - } - } - - CollisionEventUpdate collisionData = (CollisionEventUpdate)e; - Dictionary coldata = collisionData.m_objCollisionList; - - CollisionPlane = Vector4.UnitW; - - if (m_lastColCount != coldata.Count) - { - m_updateCount = UPDATE_COUNT; - m_lastColCount = coldata.Count; - } - - if (coldata.Count != 0 && Animator != null) - { - switch (Animator.CurrentMovementAnimation) - { - case "STAND": - case "WALK": - case "RUN": - case "CROUCH": - case "CROUCHWALK": - { - ContactPoint lowest; - lowest.SurfaceNormal = Vector3.Zero; - lowest.Position = Vector3.Zero; - lowest.Position.Z = Single.NaN; - - foreach (ContactPoint contact in coldata.Values) - { - if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) - { - lowest = contact; - } - } - - CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); - } - break; - } - } - - List thisHitColliders = new List(); - List endedColliders = new List(); - List startedColliders = new List(); - - foreach (uint localid in coldata.Keys) - { - thisHitColliders.Add(localid); - if (!m_lastColliders.Contains(localid)) - { - startedColliders.Add(localid); - } - //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); - } - - // calculate things that ended colliding - foreach (uint localID in m_lastColliders) - { - if (!thisHitColliders.Contains(localID)) - { - endedColliders.Add(localID); - } - } - //add the items that started colliding this time to the last colliders list. - foreach (uint localID in startedColliders) - { - m_lastColliders.Add(localID); - } - // remove things that ended colliding from the last colliders list - foreach (uint localID in endedColliders) - { - m_lastColliders.Remove(localID); - } - - // do event notification - if (startedColliders.Count > 0) - { - ColliderArgs StartCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - continue; - - SceneObjectPart obj = Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - StartCollidingMessage.Colliders = colliding; - - foreach (SceneObjectGroup att in Attachments) - Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); - } - } - - if (endedColliders.Count > 0) - { - ColliderArgs EndCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in endedColliders) - { - if (localId == 0) - continue; - - SceneObjectPart obj = Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - EndCollidingMessage.Colliders = colliding; - - foreach (SceneObjectGroup att in Attachments) - Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); - } - } - - if (thisHitColliders.Count > 0) - { - ColliderArgs CollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in thisHitColliders) - { - if (localId == 0) - continue; - - SceneObjectPart obj = Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - CollidingMessage.Colliders = colliding; - - lock (m_attachments) - { - foreach (SceneObjectGroup att in m_attachments) - Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); - } - } - } - - if (m_invulnerable) - return; - - float starthealth = Health; - uint killerObj = 0; - foreach (uint localid in coldata.Keys) - { - SceneObjectPart part = Scene.GetSceneObjectPart(localid); - - if (part != null && part.ParentGroup.Damage != -1.0f) - Health -= part.ParentGroup.Damage; - else - { - if (coldata[localid].PenetrationDepth >= 0.10f) - Health -= coldata[localid].PenetrationDepth * 5.0f; - } - - if (Health <= 0.0f) - { - if (localid != 0) - killerObj = localid; - } - //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); - } - //Health = 100; - if (!m_invulnerable) - { - if (starthealth != Health) - { - ControllingClient.SendHealth(Health); - } - if (m_health <= 0) - m_scene.EventManager.TriggerAvatarKill(killerObj, this); - } - } - - public void setHealthWithUpdate(float health) - { - Health = health; - ControllingClient.SendHealth(Health); - } - - public void Close() - { - lock (m_attachments) - { - // Delete attachments from scene - // Don't try to save, as this thread won't live long - // enough to complete the save. This would cause no copy - // attachments to poof! - // - foreach (SceneObjectGroup grp in m_attachments) - { - m_scene.DeleteSceneObject(grp, false); - } - m_attachments.Clear(); - } - - lock (m_knownChildRegions) - { - m_knownChildRegions.Clear(); - } - - lock (m_reprioritization_timer) - { - m_reprioritization_timer.Enabled = false; - m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); - } - - // I don't get it but mono crashes when you try to dispose of this timer, - // unsetting the elapsed callback should be enough to allow for cleanup however. - // m_reprioritizationTimer.Dispose(); - - m_sceneViewer.Close(); - - RemoveFromPhysicalScene(); - m_animator.Close(); - m_animator = null; - } - - public void AddAttachment(SceneObjectGroup gobj) - { - lock (m_attachments) - { - m_attachments.Add(gobj); - } - } - - public bool HasAttachments() - { - return m_attachments.Count > 0; - } - - public bool HasScriptedAttachments() - { - lock (m_attachments) - { - foreach (SceneObjectGroup gobj in m_attachments) - { - if (gobj != null) - { - if (gobj.RootPart.Inventory.ContainsScripts()) - return true; - } - } - } - return false; - } - - public void RemoveAttachment(SceneObjectGroup gobj) - { - lock (m_attachments) - { - if (m_attachments.Contains(gobj)) - { - m_attachments.Remove(gobj); - } - } - } - - public bool ValidateAttachments() - { - lock (m_attachments) - { - // Validate - foreach (SceneObjectGroup gobj in m_attachments) - { - if (gobj == null) - return false; - - if (gobj.IsDeleted) - return false; - } - } - return true; - } - - /// - /// Send a script event to this scene presence's attachments - /// - /// The name of the event - /// The arguments for the event - public void SendScriptEventToAttachments(string eventName, Object[] args) - { - if (m_scriptEngines != null) - { - lock (m_attachments) - { - foreach (SceneObjectGroup grp in m_attachments) - { - // 16384 is CHANGED_ANIMATION - // - // Send this to all attachment root prims - // - foreach (IScriptModule m in m_scriptEngines) - { - if (m == null) // No script engine loaded - continue; - - m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); - } - } - } - } - } - - - public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) - { - m_controllingClient = client; - m_regionInfo = region; - m_scene = scene; - - RegisterToEvents(); - if (m_controllingClient != null) - { - m_controllingClient.ProcessPendingPackets(); - } - /* - AbsolutePosition = client.StartPos; - - Animations = new AvatarAnimations(); - Animations.LoadAnims(); - - m_animations = new List(); - m_animations.Add(Animations.AnimsUUID["STAND"]); - m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); - - SetDirectionVectors(); - */ - } - - internal void PushForce(Vector3 impulse) - { - if (PhysicsActor != null) - { - PhysicsActor.AddForce(impulse,true); - } - } - - public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) - { - ScriptControllers obj = new ScriptControllers(); - obj.ignoreControls = ScriptControlled.CONTROL_ZERO; - obj.eventControls = ScriptControlled.CONTROL_ZERO; - - obj.itemID = Script_item_UUID; - if (pass_on == 0 && accept == 0) - { - IgnoredControls |= (ScriptControlled)controls; - obj.ignoreControls = (ScriptControlled)controls; - } - - if (pass_on == 0 && accept == 1) - { - IgnoredControls |= (ScriptControlled)controls; - obj.ignoreControls = (ScriptControlled)controls; - obj.eventControls = (ScriptControlled)controls; - } - if (pass_on == 1 && accept == 1) - { - IgnoredControls = ScriptControlled.CONTROL_ZERO; - obj.eventControls = (ScriptControlled)controls; - obj.ignoreControls = ScriptControlled.CONTROL_ZERO; - } - - lock (scriptedcontrols) - { - if (pass_on == 1 && accept == 0) - { - IgnoredControls &= ~(ScriptControlled)controls; - if (scriptedcontrols.ContainsKey(Script_item_UUID)) - scriptedcontrols.Remove(Script_item_UUID); - } - else - { - scriptedcontrols[Script_item_UUID] = obj; - } - } - ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); - } - - public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) - { - IgnoredControls = ScriptControlled.CONTROL_ZERO; - lock (scriptedcontrols) - { - scriptedcontrols.Clear(); - } - ControllingClient.SendTakeControls(int.MaxValue, false, false); - } - - public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) - { - ScriptControllers takecontrols; - - lock (scriptedcontrols) - { - if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) - { - ScriptControlled sctc = takecontrols.eventControls; - - ControllingClient.SendTakeControls((int)sctc, false, false); - ControllingClient.SendTakeControls((int)sctc, true, false); - - scriptedcontrols.Remove(Script_item_UUID); - IgnoredControls = ScriptControlled.CONTROL_ZERO; - foreach (ScriptControllers scData in scriptedcontrols.Values) - { - IgnoredControls |= scData.ignoreControls; - } - } - } - } - - internal void SendControlToScripts(uint flags) - { - ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; - - if (MouseDown) - { - allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) - { - allflags = ScriptControlled.CONTROL_ZERO; - MouseDown = true; - } - } - - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) - { - allflags |= ScriptControlled.CONTROL_ML_LBUTTON; - MouseDown = true; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) - { - allflags |= ScriptControlled.CONTROL_LBUTTON; - MouseDown = true; - } - - // find all activated controls, whether the scripts are interested in them or not - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_FWD; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_BACK; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_UP; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_DOWN; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_LEFT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_RIGHT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_ROT_RIGHT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_ROT_LEFT; - } - // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that - if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) - { - lock (scriptedcontrols) - { - foreach (KeyValuePair kvp in scriptedcontrols) - { - UUID scriptUUID = kvp.Key; - ScriptControllers scriptControlData = kvp.Value; - - ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us - ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle - ScriptControlled localChange = localHeld ^ localLast; // the changed bits - if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) - { - // only send if still pressed or just changed - m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange); - } - } - } - } - - LastCommands = allflags; - } - - internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) - { - if (ignored == ScriptControlled.CONTROL_ZERO) - return flags; - - if ((ignored & ScriptControlled.CONTROL_BACK) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); - if ((ignored & ScriptControlled.CONTROL_FWD) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); - if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); - if ((ignored & ScriptControlled.CONTROL_UP) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); - if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); - if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); - if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); - if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); - if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); - if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); - - //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, - //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, - //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, - //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, - //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, - //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, - //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG - - return flags; - } - - /// - /// RezAttachments. This should only be called upon login on the first region. - /// Attachment rezzings on crossings and TPs are done in a different way. - /// - public void RezAttachments() - { - if (null == m_appearance) - { - m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); - return; - } - - XmlDocument doc = new XmlDocument(); - string stateData = String.Empty; - - IAttachmentsService attServ = m_scene.RequestModuleInterface(); - if (attServ != null) - { - m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); - stateData = attServ.Get(ControllingClient.AgentId.ToString()); - if (stateData != String.Empty) - { - try - { - doc.LoadXml(stateData); - } - catch { } - } - } - - Dictionary itemData = new Dictionary(); - - XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); - if (nodes.Count > 0) - { - foreach (XmlNode n in nodes) - { - XmlElement elem = (XmlElement)n; - string itemID = elem.GetAttribute("ItemID"); - string xml = elem.InnerXml; - - itemData[new UUID(itemID)] = xml; - } - } - - List attPoints = m_appearance.GetAttachedPoints(); - foreach (int p in attPoints) - { - if (m_isDeleted) - return; - - UUID itemID = m_appearance.GetAttachedItem(p); - UUID assetID = m_appearance.GetAttachedAsset(p); - - // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down - // But they're not used anyway, the item is being looked up for now, so let's proceed. - //if (UUID.Zero == assetID) - //{ - // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); - // continue; - //} - - try - { - string xmlData; - XmlDocument d = new XmlDocument(); - UUID asset; - if (itemData.TryGetValue(itemID, out xmlData)) - { - d.LoadXml(xmlData); - m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); - - // Rez from inventory - asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); - - } - else - { - // Rez from inventory (with a null doc to let - // CHANGED_OWNER happen) - asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); - } - - m_log.InfoFormat( - "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", - p, itemID, assetID, asset); - } - catch (Exception e) - { - m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); - } - } - } - - private void ReprioritizeUpdates() - { - if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) - { - lock (m_reprioritization_timer) - { - if (!m_reprioritizing) - m_reprioritization_timer.Enabled = m_reprioritizing = true; - else - m_reprioritization_called = true; - } - } - } - - private void Reprioritize(object sender, ElapsedEventArgs e) - { - m_controllingClient.ReprioritizeUpdates(); - - lock (m_reprioritization_timer) - { - m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; - m_reprioritization_called = false; - } - } - - private Vector3 Quat2Euler(Quaternion rot){ - float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , - (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); - float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); - float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , - (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); - return(new Vector3(x,y,z)); - } - - - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Xml; +using System.Collections.Generic; +using System.Reflection; +using System.Timers; +using OpenMetaverse; +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Region.Framework.Scenes.Types; +using OpenSim.Region.Physics.Manager; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.Framework.Scenes +{ + enum ScriptControlled : uint + { + CONTROL_ZERO = 0, + CONTROL_FWD = 1, + CONTROL_BACK = 2, + CONTROL_LEFT = 4, + CONTROL_RIGHT = 8, + CONTROL_UP = 16, + CONTROL_DOWN = 32, + CONTROL_ROT_LEFT = 256, + CONTROL_ROT_RIGHT = 512, + CONTROL_LBUTTON = 268435456, + CONTROL_ML_LBUTTON = 1073741824 + } + + struct ScriptControllers + { + public UUID itemID; + public ScriptControlled ignoreControls; + public ScriptControlled eventControls; + } + + public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List coarseLocations, List avatarUUIDs); + + public class ScenePresence : EntityBase, ISceneEntity + { +// ~ScenePresence() +// { +// m_log.Debug("[ScenePresence] Destructor called"); +// } + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; +// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); + private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); + private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); + + /// + /// Experimentally determined "fudge factor" to make sit-target positions + /// the same as in SecondLife. Fudge factor was tested for 36 different + /// test cases including prims of type box, sphere, cylinder, and torus, + /// with varying parameters for sit target location, prim size, prim + /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis + /// issue #1716 + /// +// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); + // Value revised by KF 091121 by comparison with SL. + private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); + + public UUID currentParcelUUID = UUID.Zero; + + private ISceneViewer m_sceneViewer; + + /// + /// The animator for this avatar + /// + public ScenePresenceAnimator Animator + { + get { return m_animator; } + } + protected ScenePresenceAnimator m_animator; + + /// + /// The scene objects attached to this avatar. Do not change this list directly - use methods such as + /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. + /// + public List Attachments + { + get { return m_attachments; } + } + protected List m_attachments = new List(); + + private Dictionary scriptedcontrols = new Dictionary(); + private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; + private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; + private bool MouseDown = false; + private SceneObjectGroup proxyObjectGroup; + //private SceneObjectPart proxyObjectPart = null; + public Vector3 lastKnownAllowedPosition; + public bool sentMessageAboutRestrictedParcelFlyingDown; + public Vector4 CollisionPlane = Vector4.UnitW; + + private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation + private Vector3 m_avUnscriptedSitPos; // for non-scripted prims + private Vector3 m_lastPosition; + private Vector3 m_lastWorldPosition; + private Quaternion m_lastRotation; + private Vector3 m_lastVelocity; + //private int m_lastTerseSent; + + private bool m_updateflag; + private byte m_movementflag; + private Vector3? m_forceToApply; + private uint m_requestedSitTargetID; + private UUID m_requestedSitTargetUUID; + public bool SitGround = false; + + private SendCourseLocationsMethod m_sendCourseLocationsMethod; + + private bool m_startAnimationSet; + + //private Vector3 m_requestedSitOffset = new Vector3(); + + private Vector3 m_LastFinitePos; + + private float m_sitAvatarHeight = 2.0f; + + private int m_godLevel; + private int m_userLevel; + + private bool m_invulnerable = true; + + private Vector3 m_lastChildAgentUpdatePosition; + private Vector3 m_lastChildAgentUpdateCamPosition; + + private int m_perfMonMS; + + private bool m_setAlwaysRun; + private bool m_forceFly; + private bool m_flyDisabled; + + private float m_speedModifier = 1.0f; + + private Quaternion m_bodyRot= Quaternion.Identity; + + private Quaternion m_bodyRotPrevious = Quaternion.Identity; + + private const int LAND_VELOCITYMAG_MAX = 12; + + public bool IsRestrictedToRegion; + + public string JID = String.Empty; + + private float m_health = 100f; + + // Default AV Height + private float m_avHeight = 127.0f; + + protected RegionInfo m_regionInfo; + protected ulong crossingFromRegion; + + private readonly Vector3[] Dir_Vectors = new Vector3[11]; + private bool m_isNudging = false; + + // Position of agent's camera in world (region cordinates) + protected Vector3 m_CameraCenter; + protected Vector3 m_lastCameraCenter; + + protected Timer m_reprioritization_timer; + protected bool m_reprioritizing; + protected bool m_reprioritization_called; + + // Use these three vectors to figure out what the agent is looking at + // Convert it to a Matrix and/or Quaternion + protected Vector3 m_CameraAtAxis; + protected Vector3 m_CameraLeftAxis; + protected Vector3 m_CameraUpAxis; + private AgentManager.ControlFlags m_AgentControlFlags; + private Quaternion m_headrotation = Quaternion.Identity; + private byte m_state; + + //Reuse the Vector3 instead of creating a new one on the UpdateMovement method +// private Vector3 movementvector; + + private bool m_autopilotMoving; + private Vector3 m_autoPilotTarget; + private bool m_sitAtAutoTarget; + private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit + + private string m_nextSitAnimation = String.Empty; + + //PauPaw:Proper PID Controler for autopilot************ + private bool m_moveToPositionInProgress; + private Vector3 m_moveToPositionTarget; + private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + + private bool m_followCamAuto; + + private int m_movementUpdateCount; + private int m_lastColCount = -1; //KF: Look for Collision chnages + private int m_updateCount = 0; //KF: Update Anims for a while + private static readonly int UPDATE_COUNT = 10; // how many frames to update for + private const int NumMovementsBetweenRayCast = 5; + private List m_lastColliders = new List(); + + private bool CameraConstraintActive; + //private int m_moveToPositionStateStatus; + //***************************************************** + + // Agent's Draw distance. + protected float m_DrawDistance; + + protected AvatarAppearance m_appearance; + + // neighbouring regions we have enabled a child agent in + // holds the seed cap for the child agent in that region + private Dictionary m_knownChildRegions = new Dictionary(); + + /// + /// Implemented Control Flags + /// + private enum Dir_ControlFlags + { + DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, + DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, + DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, + DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, + DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, + DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, + DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, + DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + } + + /// + /// Position at which a significant movement was made + /// + private Vector3 posLastSignificantMove; + + // For teleports and crossings callbacks + string m_callbackURI; + UUID m_originRegionID; + + ulong m_rootRegionHandle; + + /// + /// Script engines present in the scene + /// + private IScriptModule[] m_scriptEngines; + + #region Properties + + /// + /// Physical scene representation of this Avatar. + /// + public PhysicsActor PhysicsActor + { + set { m_physicsActor = value; } + get { return m_physicsActor; } + } + + public byte MovementFlag + { + set { m_movementflag = value; } + get { return m_movementflag; } + } + + public bool Updated + { + set { m_updateflag = value; } + get { return m_updateflag; } + } + + public bool Invulnerable + { + set { m_invulnerable = value; } + get { return m_invulnerable; } + } + + public int UserLevel + { + get { return m_userLevel; } + } + + public int GodLevel + { + get { return m_godLevel; } + } + + public ulong RegionHandle + { + get { return m_rootRegionHandle; } + } + + public Vector3 CameraPosition + { + get { return m_CameraCenter; } + } + + public Quaternion CameraRotation + { + get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } + } + + public Vector3 CameraAtAxis + { + get { return m_CameraAtAxis; } + } + + public Vector3 CameraLeftAxis + { + get { return m_CameraLeftAxis; } + } + + public Vector3 CameraUpAxis + { + get { return m_CameraUpAxis; } + } + + public Vector3 Lookat + { + get + { + Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0); + + if (a == Vector3.Zero) + return a; + + return Util.GetNormalizedVector(a); + } + } + + private readonly string m_firstname; + + public string Firstname + { + get { return m_firstname; } + } + + private readonly string m_lastname; + + public string Lastname + { + get { return m_lastname; } + } + + private string m_grouptitle; + + public string Grouptitle + { + get { return m_grouptitle; } + set { m_grouptitle = value; } + } + + public float DrawDistance + { + get { return m_DrawDistance; } + } + + protected bool m_allowMovement = true; + + public bool AllowMovement + { + get { return m_allowMovement; } + set { m_allowMovement = value; } + } + + public bool SetAlwaysRun + { + get + { + if (PhysicsActor != null) + { + return PhysicsActor.SetAlwaysRun; + } + else + { + return m_setAlwaysRun; + } + } + set + { + m_setAlwaysRun = value; + if (PhysicsActor != null) + { + PhysicsActor.SetAlwaysRun = value; + } + } + } + + public byte State + { + get { return m_state; } + set { m_state = value; } + } + + public uint AgentControlFlags + { + get { return (uint)m_AgentControlFlags; } + set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } + } + + /// + /// This works out to be the ClientView object associated with this avatar, or it's client connection manager + /// + private IClientAPI m_controllingClient; + + protected PhysicsActor m_physicsActor; + + /// + /// The client controlling this presence + /// + public IClientAPI ControllingClient + { + get { return m_controllingClient; } + } + + public IClientCore ClientView + { + get { return (IClientCore) m_controllingClient; } + } + + protected Vector3 m_parentPosition; + public Vector3 ParentPosition + { + get { return m_parentPosition; } + set { m_parentPosition = value; } + } + + /// + /// Position of this avatar relative to the region the avatar is in + /// + public override Vector3 AbsolutePosition + { + get + { + PhysicsActor actor = m_physicsActor; +// if (actor != null) + if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! + m_pos = actor.Position; + + // If we're sitting, we need to update our position + if (m_parentID != 0) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); + if (part != null) + m_parentPosition = part.AbsolutePosition; + } + + return m_parentPosition + m_pos; + } + set + { + PhysicsActor actor = m_physicsActor; + if (actor != null) + { + try + { + lock (m_scene.SyncRoot) + m_physicsActor.Position = value; + } + catch (Exception e) + { + m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); + } + } + + if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! + m_pos = value; + m_parentPosition = Vector3.Zero; + } + } + + public Vector3 OffsetPosition + { + get { return m_pos; } + set { m_pos = value; } + } + + /// + /// Current velocity of the avatar. + /// + public override Vector3 Velocity + { + get + { + PhysicsActor actor = m_physicsActor; + if (actor != null) + m_velocity = actor.Velocity; + + return m_velocity; + } + set + { + PhysicsActor actor = m_physicsActor; + if (actor != null) + { + try + { + lock (m_scene.SyncRoot) + actor.Velocity = value; + } + catch (Exception e) + { + m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); + } + } + + m_velocity = value; + } + } + + public Quaternion OffsetRotation + { + get { return m_offsetRotation; } + set { m_offsetRotation = value; } + } + + public Quaternion Rotation + { + get { + if (m_parentID != 0) + { + if (m_offsetRotation != null) + { + return m_offsetRotation; + } + else + { + return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + + } + else + { + return m_bodyRot; + } + } + set { + m_bodyRot = value; + if (m_parentID != 0) + { + m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + } + } + + public Quaternion PreviousRotation + { + get { return m_bodyRotPrevious; } + set { m_bodyRotPrevious = value; } + } + + /// + /// If this is true, agent doesn't have a representation in this scene. + /// this is an agent 'looking into' this scene from a nearby scene(region) + /// + /// if False, this agent has a representation in this scene + /// + private bool m_isChildAgent = true; + + public bool IsChildAgent + { + get { return m_isChildAgent; } + set { m_isChildAgent = value; } + } + + private uint m_parentID; + + + private UUID m_linkedPrim; + + public uint ParentID + { + get { return m_parentID; } + set { m_parentID = value; } + } + + public UUID LinkedPrim + { + get { return m_linkedPrim; } + set { m_linkedPrim = value; } + } + + public float Health + { + get { return m_health; } + set { m_health = value; } + } + + /// + /// These are the region handles known by the avatar. + /// + public List KnownChildRegionHandles + { + get + { + if (m_knownChildRegions.Count == 0) + return new List(); + else + return new List(m_knownChildRegions.Keys); + } + } + + public Dictionary KnownRegions + { + get { return m_knownChildRegions; } + set + { + m_knownChildRegions = value; + } + } + + public ISceneViewer SceneViewer + { + get { return m_sceneViewer; } + } + + public void AdjustKnownSeeds() + { + Dictionary seeds; + + if (Scene.CapsModule != null) + seeds = Scene.CapsModule.GetChildrenSeeds(UUID); + else + seeds = new Dictionary(); + + List old = new List(); + foreach (ulong handle in seeds.Keys) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) + { + old.Add(handle); + } + } + DropOldNeighbours(old); + + if (Scene.CapsModule != null) + Scene.CapsModule.SetChildrenSeed(UUID, seeds); + + KnownRegions = seeds; + //m_log.Debug(" ++++++++++AFTER+++++++++++++ "); + //DumpKnownRegions(); + } + + public void DumpKnownRegions() + { + m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================"); + foreach (KeyValuePair kvp in KnownRegions) + { + uint x, y; + Utils.LongToUInts(kvp.Key, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.Info(" >> "+x+", "+y+": "+kvp.Value); + } + } + + private bool m_inTransit; + private bool m_mouseLook; + private bool m_leftButtonDown; + + public bool IsInTransit + { + get { return m_inTransit; } + set { m_inTransit = value; } + } + + public float SpeedModifier + { + get { return m_speedModifier; } + set { m_speedModifier = value; } + } + + public bool ForceFly + { + get { return m_forceFly; } + set { m_forceFly = value; } + } + + public bool FlyDisabled + { + get { return m_flyDisabled; } + set { m_flyDisabled = value; } + } + + public string Viewer + { + get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } + } + + #endregion + + #region Constructor(s) + + public ScenePresence() + { + m_sendCourseLocationsMethod = SendCoarseLocationsDefault; + CreateSceneViewer(); + m_animator = new ScenePresenceAnimator(this); + } + + private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() + { + m_rootRegionHandle = reginfo.RegionHandle; + m_controllingClient = client; + m_firstname = m_controllingClient.FirstName; + m_lastname = m_controllingClient.LastName; + m_name = String.Format("{0} {1}", m_firstname, m_lastname); + m_scene = world; + m_uuid = client.AgentId; + m_regionInfo = reginfo; + m_localId = m_scene.AllocateLocalId(); + + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); + + if (account != null) + m_userLevel = account.UserLevel; + + IGroupsModule gm = m_scene.RequestModuleInterface(); + if (gm != null) + m_grouptitle = gm.GetGroupTitle(m_uuid); + + m_scriptEngines = m_scene.RequestModuleInterfaces(); + + AbsolutePosition = posLastSignificantMove = m_CameraCenter = + m_lastCameraCenter = m_controllingClient.StartPos; + + m_reprioritization_timer = new Timer(world.ReprioritizationInterval); + m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); + m_reprioritization_timer.AutoReset = false; + + AdjustKnownSeeds(); + Animator.TrySetMovementAnimation("STAND"); + // we created a new ScenePresence (a new child agent) in a fresh region. + // Request info about all the (root) agents in this region + // Note: This won't send data *to* other clients in that region (children don't send) + SendInitialFullUpdateToAllClients(); + RegisterToEvents(); + if (m_controllingClient != null) + { + m_controllingClient.ProcessPendingPackets(); + } + SetDirectionVectors(); + } + + public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, + AvatarWearable[] wearables) + : this(client, world, reginfo) + { + m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); + } + + public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) + : this(client, world, reginfo) + { + m_appearance = appearance; + } + + private void CreateSceneViewer() + { + m_sceneViewer = new SceneViewer(this); + } + + public void RegisterToEvents() + { + m_controllingClient.OnRequestWearables += SendWearables; + m_controllingClient.OnSetAppearance += SetAppearance; + m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; + //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; + m_controllingClient.OnAgentUpdate += HandleAgentUpdate; + m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; + m_controllingClient.OnAgentSit += HandleAgentSit; + m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; + m_controllingClient.OnStartAnim += HandleStartAnim; + m_controllingClient.OnStopAnim += HandleStopAnim; + m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; + m_controllingClient.OnAutoPilotGo += DoAutoPilot; + m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); + + // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); + // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); + } + + private void SetDirectionVectors() + { + Dir_Vectors[0] = Vector3.UnitX; //FORWARD + Dir_Vectors[1] = -Vector3.UnitX; //BACK + Dir_Vectors[2] = Vector3.UnitY; //LEFT + Dir_Vectors[3] = -Vector3.UnitY; //RIGHT + Dir_Vectors[4] = Vector3.UnitZ; //UP + Dir_Vectors[5] = -Vector3.UnitZ; //DOWN + Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE + Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE + Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE + Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE + Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge + } + + private Vector3[] GetWalkDirectionVectors() + { + Vector3[] vector = new Vector3[11]; + vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD + vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK + vector[2] = Vector3.UnitY; //LEFT + vector[3] = -Vector3.UnitY; //RIGHT + vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP + vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN + vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE + vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE + vector[8] = Vector3.UnitY; //LEFT_NUDGE + vector[9] = -Vector3.UnitY; //RIGHT_NUDGE + vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE + return vector; + } + + private bool[] GetDirectionIsNudge() + { + bool[] isNudge = new bool[11]; + isNudge[0] = false; //FORWARD + isNudge[1] = false; //BACK + isNudge[2] = false; //LEFT + isNudge[3] = false; //RIGHT + isNudge[4] = false; //UP + isNudge[5] = false; //DOWN + isNudge[6] = true; //FORWARD_NUDGE + isNudge[7] = true; //BACK_NUDGE + isNudge[8] = true; //LEFT_NUDGE + isNudge[9] = true; //RIGHT_NUDGE + isNudge[10] = true; //DOWN_Nudge + return isNudge; + } + + + #endregion + + public uint GenerateClientFlags(UUID ObjectID) + { + return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); + } + + /// + /// Send updates to the client about prims which have been placed on the update queue. We don't + /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent + /// timestamp has already been sent. + /// + public void SendPrimUpdates() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + m_sceneViewer.SendPrimUpdates(); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + #region Status Methods + + /// + /// This turns a child agent, into a root agent + /// This is called when an agent teleports into a region, or if an + /// agent crosses into this region from a neighbor over the border + /// + public void MakeRootAgent(Vector3 pos, bool isFlying) + { + m_log.DebugFormat( + "[SCENE]: Upgrading child to root agent for {0} in {1}", + Name, m_scene.RegionInfo.RegionName); + + //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); + + IGroupsModule gm = m_scene.RequestModuleInterface(); + if (gm != null) + m_grouptitle = gm.GetGroupTitle(m_uuid); + + m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; + m_scene.SetRootAgentScene(m_uuid); + + // Moved this from SendInitialData to ensure that m_appearance is initialized + // before the inventory is processed in MakeRootAgent. This fixes a race condition + // related to the handling of attachments + //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); + if (m_scene.TestBorderCross(pos, Cardinals.E)) + { + Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); + pos.X = crossedBorder.BorderLine.Z - 1; + } + + if (m_scene.TestBorderCross(pos, Cardinals.N)) + { + Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); + pos.Y = crossedBorder.BorderLine.Z - 1; + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } + } + + if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) + { + Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); + + if (pos.X < 0) + { + emergencyPos.X = (int)Constants.RegionSize + pos.X; + if (!(pos.Y < 0)) + emergencyPos.Y = pos.Y; + if (!(pos.Z < 0)) + emergencyPos.Z = pos.Z; + } + if (pos.Y < 0) + { + emergencyPos.Y = (int)Constants.RegionSize + pos.Y; + if (!(pos.X < 0)) + emergencyPos.X = pos.X; + if (!(pos.Z < 0)) + emergencyPos.Z = pos.Z; + } + if (pos.Z < 0) + { + emergencyPos.Z = 128; + if (!(pos.Y < 0)) + emergencyPos.Y = pos.Y; + if (!(pos.X < 0)) + emergencyPos.X = pos.X; + } + } + + if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) + { + m_log.WarnFormat( + "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", + pos, Name, UUID); + + if (pos.X < 0f) pos.X = 0f; + if (pos.Y < 0f) pos.Y = 0f; + if (pos.Z < 0f) pos.Z = 0f; + } + + float localAVHeight = 1.56f; + if (m_avHeight != 127.0f) + { + localAVHeight = m_avHeight; + } + + float posZLimit = 0; + + if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) + posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; + + float newPosZ = posZLimit + localAVHeight / 2; + if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + pos.Z = newPosZ; + } + AbsolutePosition = pos; + + AddToPhysicalScene(isFlying); + + if (m_forceFly) + { + m_physicsActor.Flying = true; + } + else if (m_flyDisabled) + { + m_physicsActor.Flying = false; + } + + if (m_appearance != null) + { + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + } + else + { + m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); + // emergency; this really shouldn't happen + m_appearance = new AvatarAppearance(UUID); + } + + // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying + // avatar to return to the standing position in mid-air. On login it looks like this is being sent + // elsewhere anyway + // Animator.SendAnimPack(); + + m_scene.SwapRootAgentCount(false); + + //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); + //if (userInfo != null) + // userInfo.FetchInventory(); + //else + // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); + + // On the next prim update, all objects will be sent + // + m_sceneViewer.Reset(); + + m_isChildAgent = false; + + // send the animations of the other presences to me + m_scene.ForEachScenePresence(delegate(ScenePresence presence) + { + if (presence != this) + presence.Animator.SendAnimPackToClient(ControllingClient); + }); + + m_scene.EventManager.TriggerOnMakeRootAgent(this); + } + + /// + /// This turns a root agent into a child agent + /// when an agent departs this region for a neighbor, this gets called. + /// + /// It doesn't get called for a teleport. Reason being, an agent that + /// teleports out may not end up anywhere near this region + /// + public void MakeChildAgent() + { + // It looks like m_animator is set to null somewhere, and MakeChild + // is called after that. Probably in aborted teleports. + if (m_animator == null) + m_animator = new ScenePresenceAnimator(this); + else + Animator.ResetAnimations(); + +// m_log.DebugFormat( +// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", +// Name, UUID, m_scene.RegionInfo.RegionName); + + // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, + // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. + //Velocity = new Vector3(0, 0, 0); + + m_isChildAgent = true; + m_scene.SwapRootAgentCount(true); + RemoveFromPhysicalScene(); + + // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into + + m_scene.EventManager.TriggerOnMakeChildAgent(this); + } + + /// + /// Removes physics plugin scene representation of this agent if it exists. + /// + private void RemoveFromPhysicalScene() + { + if (PhysicsActor != null) + { + m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; + m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; + m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); + m_physicsActor.UnSubscribeEvents(); + m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; + PhysicsActor = null; + } + } + + /// + /// + /// + /// + public void Teleport(Vector3 pos) + { + bool isFlying = false; + + if (m_physicsActor != null) + isFlying = m_physicsActor.Flying; + + RemoveFromPhysicalScene(); + Velocity = Vector3.Zero; + AbsolutePosition = pos; + AddToPhysicalScene(isFlying); + if (m_appearance != null) + { + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + } + + SendTerseUpdateToAllClients(); + + } + + public void TeleportWithMomentum(Vector3 pos) + { + bool isFlying = false; + if (m_physicsActor != null) + isFlying = m_physicsActor.Flying; + + RemoveFromPhysicalScene(); + AbsolutePosition = pos; + AddToPhysicalScene(isFlying); + if (m_appearance != null) + { + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + } + + SendTerseUpdateToAllClients(); + } + + /// + /// + /// + public void StopMovement() + { + } + + public void StopFlying() + { + ControllingClient.StopFlying(this); + } + + public void AddNeighbourRegion(ulong regionHandle, string cap) + { + lock (m_knownChildRegions) + { + if (!m_knownChildRegions.ContainsKey(regionHandle)) + { + uint x, y; + Utils.LongToUInts(regionHandle, out x, out y); + m_knownChildRegions.Add(regionHandle, cap); + } + } + } + + public void RemoveNeighbourRegion(ulong regionHandle) + { + lock (m_knownChildRegions) + { + if (m_knownChildRegions.ContainsKey(regionHandle)) + { + m_knownChildRegions.Remove(regionHandle); + //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); + } + } + } + + public void DropOldNeighbours(List oldRegions) + { + foreach (ulong handle in oldRegions) + { + RemoveNeighbourRegion(handle); + Scene.CapsModule.DropChildSeed(UUID, handle); + } + } + + public List GetKnownRegionList() + { + return new List(m_knownChildRegions.Keys); + } + + #endregion + + #region Event Handlers + + /// + /// Sets avatar height in the phyiscs plugin + /// + internal void SetHeight(float height) + { + m_avHeight = height; + if (PhysicsActor != null && !IsChildAgent) + { + Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight); + PhysicsActor.Size = SetSize; + } + } + + /// + /// Complete Avatar's movement into the region. + /// This is called upon a very important packet sent from the client, + /// so it's client-controlled. Never call this method directly. + /// + public void CompleteMovement(IClientAPI client) + { + //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); + + Vector3 look = Velocity; + if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + { + look = new Vector3(0.99f, 0.042f, 0); + } + + // Prevent teleporting to an underground location + // (may crash client otherwise) + // + Vector3 pos = AbsolutePosition; + float ground = m_scene.GetGroundHeight(pos.X, pos.Y); + if (pos.Z < ground + 1.5f) + { + pos.Z = ground + 1.5f; + AbsolutePosition = pos; + } + m_isChildAgent = false; + bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + MakeRootAgent(AbsolutePosition, m_flying); + + if ((m_callbackURI != null) && !m_callbackURI.Equals("")) + { + m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); + Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); + m_callbackURI = null; + } + + //m_log.DebugFormat("Completed movement"); + + m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); + SendInitialData(); + + // Create child agents in neighbouring regions + if (!m_isChildAgent) + { + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); + if (m_agentTransfer != null) + m_agentTransfer.EnableChildAgents(this); + else + m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); + + IFriendsModule friendsModule = m_scene.RequestModuleInterface(); + if (friendsModule != null) + friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + } + + } + + /// + /// Callback for the Camera view block check. Gets called with the results of the camera view block test + /// hitYN is true when there's something in the way. + /// + /// + /// + /// + /// + public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) + { + const float POSITION_TOLERANCE = 0.02f; + const float VELOCITY_TOLERANCE = 0.02f; + const float ROTATION_TOLERANCE = 0.02f; + + if (m_followCamAuto) + { + if (hitYN) + { + CameraConstraintActive = true; + //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); + + Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); + ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); + } + else + { + if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) + { + if (CameraConstraintActive) + { + ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); + CameraConstraintActive = false; + } + } + } + } + } + + /// + /// This is the event handler for client movement. If a client is moving, this event is triggering. + /// + public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) + { + //if (m_isChildAgent) + //{ + // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); + // return; + //} + + m_perfMonMS = Util.EnvironmentTickCount(); + + ++m_movementUpdateCount; + if (m_movementUpdateCount < 1) + m_movementUpdateCount = 1; + + #region Sanity Checking + + // This is irritating. Really. + if (!AbsolutePosition.IsFinite()) + { + RemoveFromPhysicalScene(); + m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); + + m_pos = m_LastFinitePos; + + if (!m_pos.IsFinite()) + { + m_pos.X = 127f; + m_pos.Y = 127f; + m_pos.Z = 127f; + m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); + } + + AddToPhysicalScene(false); + } + else + { + m_LastFinitePos = m_pos; + } + + #endregion Sanity Checking + + #region Inputs + + AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; + Quaternion bodyRotation = agentData.BodyRotation; + + // Camera location in world. We'll need to raytrace + // from this location from time to time. + m_CameraCenter = agentData.CameraCenter; + if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) + { + ReprioritizeUpdates(); + m_lastCameraCenter = m_CameraCenter; + } + + // Use these three vectors to figure out what the agent is looking at + // Convert it to a Matrix and/or Quaternion + m_CameraAtAxis = agentData.CameraAtAxis; + m_CameraLeftAxis = agentData.CameraLeftAxis; + m_CameraUpAxis = agentData.CameraUpAxis; + + // The Agent's Draw distance setting + m_DrawDistance = agentData.Far; + + // Check if Client has camera in 'follow cam' or 'build' mode. + Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); + + m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) + && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; + + m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; + m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; + + #endregion Inputs + + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) + { + StandUp(); + } + + //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); + // Raycast from the avatar's head to the camera to see if there's anything blocking the view + if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) + { + if (m_followCamAuto) + { + Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; + m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); + } + } + lock (scriptedcontrols) + { + if (scriptedcontrols.Count > 0) + { + SendControlToScripts((uint)flags); + flags = RemoveIgnoredControls(flags, IgnoredControls); + } + } + + if (m_autopilotMoving) + CheckAtSitTarget(); + + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) + { + m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. + Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + + // TODO: This doesn't prevent the user from walking yet. + // Setting parent ID would fix this, if we knew what value + // to use. Or we could add a m_isSitting variable. + //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + SitGround = true; + } + + // In the future, these values might need to go global. + // Here's where you get them. + m_AgentControlFlags = flags; + m_headrotation = agentData.HeadRotation; + m_state = agentData.State; + + PhysicsActor actor = PhysicsActor; + if (actor == null) + { + return; + } + + bool update_movementflag = false; + + if (m_allowMovement && !SitGround) + { + if (agentData.UseClientAgentPosition) + { + m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; + m_moveToPositionTarget = agentData.ClientAgentPosition; + } + + int i = 0; + + bool update_rotation = false; + bool DCFlagKeyPressed = false; + Vector3 agent_control_v3 = Vector3.Zero; + Quaternion q = bodyRotation; + + bool oldflying = PhysicsActor.Flying; + + if (m_forceFly) + actor.Flying = true; + else if (m_flyDisabled) + actor.Flying = false; + else + actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + + if (actor.Flying != oldflying) + update_movementflag = true; + + if (q != m_bodyRot) + { + m_bodyRot = q; + update_rotation = true; + } + + //guilty until proven innocent.. + bool Nudging = true; + //Basically, if there is at least one non-nudge control then we don't need + //to worry about stopping the avatar + + if (m_parentID == 0) + { + bool bAllowUpdateMoveToPosition = false; + bool bResetMoveToPosition = false; + + Vector3[] dirVectors; + + // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying + // this prevents 'jumping' in inappropriate situations. + if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) + dirVectors = GetWalkDirectionVectors(); + else + dirVectors = Dir_Vectors; + + bool[] isNudge = GetDirectionIsNudge(); + + + + + + foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) + { + if (((uint)flags & (uint)DCF) != 0) + { + bResetMoveToPosition = true; + DCFlagKeyPressed = true; + try + { + agent_control_v3 += dirVectors[i]; + if (isNudge[i] == false) + { + Nudging = false; + } + } + catch (IndexOutOfRangeException) + { + // Why did I get this? + } + + if ((m_movementflag & (uint)DCF) == 0) + { + m_movementflag += (byte)(uint)DCF; + update_movementflag = true; + } + } + else + { + if ((m_movementflag & (uint)DCF) != 0) + { + m_movementflag -= (byte)(uint)DCF; + update_movementflag = true; + } + else + { + bAllowUpdateMoveToPosition = true; + } + } + i++; + } + //Paupaw:Do Proper PID for Autopilot here + if (bResetMoveToPosition) + { + m_moveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + update_movementflag = true; + bAllowUpdateMoveToPosition = false; + } + + if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) + { + //Check the error term of the current position in relation to the target position + if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) + { + // we are close enough to the target + m_moveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + update_movementflag = true; + } + else + { + try + { + // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. + // This movement vector gets added to the velocity through AddNewMovement(). + // Theoretically we might need a more complex PID approach here if other + // unknown forces are acting on the avatar and we need to adaptively respond + // to such forces, but the following simple approach seems to works fine. + Vector3 LocalVectorToTarget3D = + (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords + * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords + // Ignore z component of vector + Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); + LocalVectorToTarget2D.Normalize(); + + //We're not nudging + Nudging = false; + agent_control_v3 += LocalVectorToTarget2D; + + // update avatar movement flags. the avatar coordinate system is as follows: + // + // +X (forward) + // + // ^ + // | + // | + // | + // | + // (left) +Y <--------o--------> -Y + // avatar + // | + // | + // | + // | + // v + // -X + // + + // based on the above avatar coordinate system, classify the movement into + // one of left/right/back/forward. + if (LocalVectorToTarget2D.Y > 0)//MoveLeft + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + //AgentControlFlags + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + update_movementflag = true; + } + else if (LocalVectorToTarget2D.Y < 0) //MoveRight + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + update_movementflag = true; + } + if (LocalVectorToTarget2D.X < 0) //MoveBack + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + update_movementflag = true; + } + else if (LocalVectorToTarget2D.X > 0) //Move Forward + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + update_movementflag = true; + } + } + catch (Exception e) + { + //Avoid system crash, can be slower but... + m_log.DebugFormat("Crash! {0}", e.ToString()); + } + } + } + } + + // Cause the avatar to stop flying if it's colliding + // with something with the down arrow pressed. + + // Only do this if we're flying + if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) + { + // Landing detection code + + // Are the landing controls requirements filled? + bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || + ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + + // Are the collision requirements fulfilled? + bool colliding = (m_physicsActor.IsColliding == true); + + if (m_physicsActor.Flying && colliding && controlland) + { + // nesting this check because LengthSquared() is expensive and we don't + // want to do it every step when flying. + if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) + StopFlying(); + } + } + + if (update_movementflag || (update_rotation && DCFlagKeyPressed)) + { + // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); + // m_log.DebugFormat( + // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); + + AddNewMovement(agent_control_v3, q, Nudging); + + + } + } + + if (update_movementflag && !SitGround) + Animator.UpdateMovementAnimations(); + + m_scene.EventManager.TriggerOnClientMovement(this); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) + { + m_autopilotMoving = true; + m_autoPilotTarget = Pos; + m_sitAtAutoTarget = false; + PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; + //proxy.PCode = (byte)PCode.ParticleSystem; + proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); + proxyObjectGroup.AttachToScene(m_scene); + + // Commented out this code since it could never have executed, but might still be informative. +// if (proxyObjectGroup != null) +// { + proxyObjectGroup.SendGroupFullUpdate(); + remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); + m_scene.DeleteSceneObject(proxyObjectGroup, false); +// } +// else +// { +// m_autopilotMoving = false; +// m_autoPilotTarget = Vector3.Zero; +// ControllingClient.SendAlertMessage("Autopilot cancelled"); +// } + } + + public void DoMoveToPosition(Object sender, string method, List args) + { + try + { + float locx = 0f; + float locy = 0f; + float locz = 0f; + uint regionX = 0; + uint regionY = 0; + try + { + Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); + locx = Convert.ToSingle(args[0]) - (float)regionX; + locy = Convert.ToSingle(args[1]) - (float)regionY; + locz = Convert.ToSingle(args[2]); + } + catch (InvalidCastException) + { + m_log.Error("[CLIENT]: Invalid autopilot request"); + return; + } + m_moveToPositionInProgress = true; + m_moveToPositionTarget = new Vector3(locx, locy, locz); + } + catch (Exception ex) + { + //Why did I get this error? + m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); + } + } + + private void CheckAtSitTarget() + { + //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); + if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) + { + if (m_sitAtAutoTarget) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); + if (part != null) + { + AbsolutePosition = part.AbsolutePosition; + Velocity = Vector3.Zero; + SendFullUpdateToAllClients(); + + HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? + } + //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); + m_requestedSitTargetUUID = UUID.Zero; + } + /* + else + { + //ControllingClient.SendAlertMessage("Autopilot cancelled"); + //SendTerseUpdateToAllClients(); + //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; + //proxy.PCode = (byte)PCode.ParticleSystem; + ////uint nextUUID = m_scene.NextLocalId; + + //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); + //if (proxyObjectGroup != null) + //{ + //proxyObjectGroup.SendGroupFullUpdate(); + //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); + //m_scene.DeleteSceneObject(proxyObjectGroup); + //} + } + */ + m_autoPilotTarget = Vector3.Zero; + m_autopilotMoving = false; + } + } + /// + /// Perform the logic necessary to stand the avatar up. This method also executes + /// the stand animation. + /// + public void StandUp() + { + SitGround = false; + + if (m_parentID != 0) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); + if (part != null) + { + part.TaskInventory.LockItemsForRead(true); + TaskInventoryDictionary taskIDict = part.TaskInventory; + if (taskIDict != null) + { + foreach (UUID taskID in taskIDict.Keys) + { + UnRegisterControlEventsToScript(LocalId, taskID); + taskIDict[taskID].PermsMask &= ~( + 2048 | //PERMISSION_CONTROL_CAMERA + 4); // PERMISSION_TAKE_CONTROLS + } + } + part.TaskInventory.LockItemsForRead(false); + // Reset sit target. + if (part.GetAvatarOnSitTarget() == UUID) + part.SetAvatarOnSitTarget(UUID.Zero); + m_parentPosition = part.GetWorldPosition(); + ControllingClient.SendClearFollowCamProperties(part.ParentUUID); + } + // part.GetWorldRotation() is the rotation of the object being sat on + // Rotation is the sittiing Av's rotation + + Quaternion partRot; +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partRot = part.ParentGroup.RootPart.RotationOffset; +// } +// else +// { // single or child prim + +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); + } + + Quaternion partIRot = Quaternion.Inverse(partRot); + + Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av + Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av + + + if (m_physicsActor == null) + { + AddToPhysicalScene(false); + } + //CW: If the part isn't null then we can set the current position + if (part != null) + { + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. + part.IsOccupied = false; + part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); + } + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; + } + + m_parentPosition = Vector3.Zero; + m_parentID = 0; + m_linkedPrim = UUID.Zero; + m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + SendFullUpdateToAllClients(); + m_requestedSitTargetID = 0; + + if ((m_physicsActor != null) && (m_avHeight > 0)) + { + SetHeight(m_avHeight); + } + } + Animator.TrySetMovementAnimation("STAND"); + } + + private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) + { + SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID); + if (targetPart == null) + return null; + + // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used. + // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. + + // Get our own copy of the part array, and sort into the order we want to test + SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); + Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) + { + // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) + int linkNum1 = p1==targetPart ? -1 : p1.LinkNum; + int linkNum2 = p2==targetPart ? -1 : p2.LinkNum; + return linkNum1 - linkNum2; + } + ); + + //look for prims with explicit sit targets that are available + foreach (SceneObjectPart part in partArray) + { + // Is a sit target available? + Vector3 avSitOffSet = part.SitTargetPosition; + Quaternion avSitOrientation = part.SitTargetOrientation; + UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); + bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); + bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. + if (SitTargetisSet && !SitTargetOccupied) + { + //switch the target to this prim + return part; + } + } + + // no explicit sit target found - use original target + return targetPart; + } + + private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) + { + bool autopilot = true; + Vector3 autopilotTarget = new Vector3(); + Quaternion sitOrientation = Quaternion.Identity; + Vector3 pos = new Vector3(); + Vector3 cameraEyeOffset = Vector3.Zero; + Vector3 cameraAtOffset = Vector3.Zero; + bool forceMouselook = false; + + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); + if (part == null) return; + + // TODO: determine position to sit at based on scene geometry; don't trust offset from client + // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it + + // part is the prim to sit on + // offset is the world-ref vector distance from that prim center to the click-spot + // UUID is the UUID of the Avatar doing the clicking + + m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation + + // Is a sit target available? + Vector3 avSitOffSet = part.SitTargetPosition; + Quaternion avSitOrientation = part.SitTargetOrientation; + + bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. + // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + Quaternion partRot; +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partRot = part.ParentGroup.RootPart.RotationOffset; +// } +// else +// { // single or child prim + partRot = part.GetWorldRotation(); +// } + Quaternion partIRot = Quaternion.Inverse(partRot); +//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); + // Sit analysis rewritten by KF 091125 + if (SitTargetisSet) // scipted sit + { + if (!part.IsOccupied) + { +//Console.WriteLine("Scripted, unoccupied"); + part.SetAvatarOnSitTarget(UUID); // set that Av will be on it + offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one + + Quaternion nrot = avSitOrientation; + if (!part.IsRoot) + { + nrot = part.RotationOffset * avSitOrientation; + } + sitOrientation = nrot; // Change rotatione to the scripted one + OffsetRotation = nrot; + autopilot = false; // Jump direct to scripted llSitPos() + } + else + { +//Console.WriteLine("Scripted, occupied"); + return; + } + } + else // Not Scripted + { + if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) + { + // large prim & offset, ignore if other Avs sitting +// offset.Z -= 0.05f; + m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked + autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point + +//Console.WriteLine(" offset ={0}", offset); +//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); +//Console.WriteLine(" autopilotTarget={0}", autopilotTarget); + + } + else // small offset + { +//Console.WriteLine("Small offset"); + if (!part.IsOccupied) + { + m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center + autopilotTarget = part.AbsolutePosition; +//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); + } + else return; // occupied small + } // end large/small + } // end Scripted/not + cameraAtOffset = part.GetCameraAtOffset(); + cameraEyeOffset = part.GetCameraEyeOffset(); + forceMouselook = part.GetForceMouselook(); + if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // + if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // + + if (m_physicsActor != null) + { + // If we're not using the client autopilot, we're immediately warping the avatar to the location + // We can remove the physicsActor until they stand up. + m_sitAvatarHeight = m_physicsActor.Size.Z; + if (autopilot) + { // its not a scripted sit +// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) + if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) + { + autopilot = false; // close enough + m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. + Not using the part's position because returning the AV to the last known standing + position is likely to be more friendly, isn't it? */ + RemoveFromPhysicalScene(); + AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target + } // else the autopilot will get us close + } + else + { // its a scripted sit + m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. + I *am* using the part's position this time because we have no real idea how far away + the avatar is from the sit target. */ + RemoveFromPhysicalScene(); + } + } + else return; // physactor is null! + + Vector3 offsetr; // = offset * partIRot; + // KF: In a linkset, offsetr needs to be relative to the group root! 091208 + // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); + // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. + // { // Single, or Root prim of linkset, target is ClickOffset * RootRot + //offsetr = offset * partIRot; +// + // else + // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) + // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + + // (offset * partRot); + // } + +//Console.WriteLine(" "); +//Console.WriteLine("link number ={0}", part.LinkNum); +//Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); +//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); +//Console.WriteLine("Click offst ={0}", offset); +//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); +//Console.WriteLine("offsetr ={0}", offsetr); +//Console.WriteLine("Camera At ={0}", cameraAtOffset); +//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); + + //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child + ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + + m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target + // This calls HandleAgentSit twice, once from here, and the client calls + // HandleAgentSit itself after it gets to the location + // It doesn't get to the location until we've moved them there though + // which happens in HandleAgentSit :P + m_autopilotMoving = autopilot; + m_autoPilotTarget = autopilotTarget; + m_sitAtAutoTarget = autopilot; + m_initialSitTarget = autopilotTarget; + if (!autopilot) + HandleAgentSit(remoteClient, UUID); + } + + public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) + { + if (m_parentID != 0) + { + StandUp(); + } + m_nextSitAnimation = "SIT"; + + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); + + if (part != null) + { + if (!String.IsNullOrEmpty(part.SitAnimation)) + { + m_nextSitAnimation = part.SitAnimation; + } + m_requestedSitTargetID = part.LocalId; + //m_requestedSitOffset = offset; + m_requestedSitTargetUUID = targetID; + + m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); + + if (m_scene.PhysicsScene.SupportsRayCast()) + { + //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); + //SitRayCastAvatarPosition(part); + //return; + } + } + else + { + + m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); + } + + + + SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); + } + /* + public void SitRayCastAvatarPosition(SceneObjectPart part) + { + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = AbsolutePosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse); + } + + public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); + } + else + { + SitRayCastAvatarPositionCameraZ(part); + } + } + else + { + SitRayCastAvatarPositionCameraZ(part); + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) + { + // Next, try to raycast from the camera Z position + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse); + } + + public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal); + } + else + { + SitRayCastCameraPosition(part); + } + } + else + { + SitRayCastCameraPosition(part); + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + public void SitRayCastCameraPosition(SceneObjectPart part) + { + // Next, try to raycast from the camera position + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = CameraPosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse); + } + + public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); + } + else + { + SitRayHorizontal(part); + } + } + else + { + SitRayHorizontal(part); + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + public void SitRayHorizontal(SceneObjectPart part) + { + // Next, try to raycast from the avatar position to fwd + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = CameraPosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); + } + + public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); + // Next, try to raycast from the camera position + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = CameraPosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition); + } + else + { + ControllingClient.SendAlertMessage("Sit position not accessable."); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + } + else + { + ControllingClient.SendAlertMessage("Sit position not accessable."); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) + { + int i = 0; + //throw new NotImplementedException(); + //m_requestedSitTargetUUID = UUID.Zero; + //m_requestedSitTargetID = 0; + //m_requestedSitOffset = Vector3.Zero; + + SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); + } + */ + public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) + { + if (m_parentID != 0) + { + StandUp(); + } + if (!String.IsNullOrEmpty(sitAnimation)) + { + m_nextSitAnimation = sitAnimation; + } + else + { + m_nextSitAnimation = "SIT"; + } + + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); + if (part != null) + { + m_requestedSitTargetID = part.LocalId; + //m_requestedSitOffset = offset; + m_requestedSitTargetUUID = targetID; + + m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); + + if (m_scene.PhysicsScene.SupportsRayCast()) + { + //SitRayCastAvatarPosition(part); + //return; + } + } + else + { + m_log.Warn("Sit requested on unknown object: " + targetID); + } + + SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); + } + + public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) + { + if (!String.IsNullOrEmpty(m_nextSitAnimation)) + { + HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); + } + else + { + HandleAgentSit(remoteClient, agentID, "SIT"); + } + } + + public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); + + if (m_sitAtAutoTarget || !m_autopilotMoving) + { + if (part != null) + { +//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); + if (part.GetAvatarOnSitTarget() == UUID) + { +//Console.WriteLine("Scripted Sit"); + // Scripted sit + Vector3 sitTargetPos = part.SitTargetPosition; + Quaternion sitTargetOrient = part.SitTargetOrientation; + m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); + m_pos += SIT_TARGET_ADJUSTMENT; + if (!part.IsRoot) + { + m_pos *= part.RotationOffset; + } + m_bodyRot = sitTargetOrient; + m_parentPosition = part.AbsolutePosition; + part.IsOccupied = true; + part.ParentGroup.AddAvatar(agentID); +Console.WriteLine("Scripted Sit ofset {0}", m_pos); + } + else + { + // if m_avUnscriptedSitPos is zero then Av sits above center + // Else Av sits at m_avUnscriptedSitPos + + // Non-scripted sit by Kitto Flora 21Nov09 + // Calculate angle of line from prim to Av + Quaternion partIRot; +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); +// } +// else +// { // single or child prim + partIRot = Quaternion.Inverse(part.GetWorldRotation()); +// } + Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; + float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); + float x_diff = ( m_avInitialPos.X - sitTargetPos.X); + if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 + if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 + float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); + // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. + // Av sits at world euler <0,0, z>, translated by part rotation + m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click + + m_parentPosition = part.AbsolutePosition; + part.IsOccupied = true; + part.ParentGroup.AddAvatar(agentID); + m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation + (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center + (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + + m_avUnscriptedSitPos; // adds click offset, if any + //Set up raytrace to find top surface of prim + Vector3 size = part.Scale; + float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); + Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); + Vector3 down = new Vector3(0f, 0f, -1f); +//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); + m_scene.PhysicsScene.RaycastWorld( + start, // Vector3 position, + down, // Vector3 direction, + mag, // float length, + SitAltitudeCallback); // retMethod + } // end scripted/not + } + else // no Av + { + return; + } + } + + //We want our offsets to reference the root prim, not the child we may have sat on + if (!part.IsRoot) + { + m_parentID = part.ParentGroup.RootPart.LocalId; + m_pos += part.OffsetPosition; + } + else + { + m_parentID = m_requestedSitTargetID; + } + + m_linkedPrim = part.UUID; + + Velocity = Vector3.Zero; + RemoveFromPhysicalScene(); + Animator.TrySetMovementAnimation(sitAnimation); + SendFullUpdateToAllClients(); + SendTerseUpdateToAllClients(); + } + + public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) + { + // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer + // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. + if(hitYN) + { + // m_pos = Av offset from prim center to make look like on center + // m_parentPosition = Actual center pos of prim + // collisionPoint = spot on prim where we want to sit + // collisionPoint.Z = global sit surface height + SceneObjectPart part = m_scene.GetSceneObjectPart(localid); + Quaternion partIRot; +// if (part.LinkNum == 1) +/// { // Root prim of linkset +// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); +// } +// else +// { // single or child prim + partIRot = Quaternion.Inverse(part.GetWorldRotation()); +// } + if (m_initialSitTarget != null) + { + float offZ = collisionPoint.Z - m_initialSitTarget.Z; + Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction + //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); + m_pos += offset; + // ControllingClient.SendClearFollowCamProperties(part.UUID); + } + + } + } // End SitAltitudeCallback KF. + + /// + /// Event handler for the 'Always run' setting on the client + /// Tells the physics plugin to increase speed of movement. + /// + public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun) + { + m_setAlwaysRun = pSetAlwaysRun; + if (PhysicsActor != null) + { + PhysicsActor.SetAlwaysRun = pSetAlwaysRun; + } + } + + public void HandleStartAnim(IClientAPI remoteClient, UUID animID) + { + Animator.AddAnimation(animID, UUID.Zero); + } + + public void HandleStopAnim(IClientAPI remoteClient, UUID animID) + { + Animator.RemoveAnimation(animID); + } + + /// + /// Rotate the avatar to the given rotation and apply a movement in the given relative vector + /// + /// The vector in which to move. This is relative to the rotation argument + /// The direction in which this avatar should now face. + public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) + { + if (m_isChildAgent) + { + // WHAT??? + m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); + + // we have to reset the user's child agent connections. + // Likely, here they've lost the eventqueue for other regions so border + // crossings will fail at this point unless we reset them. + + List regions = new List(KnownChildRegionHandles); + regions.Remove(m_scene.RegionInfo.RegionHandle); + + MakeRootAgent(new Vector3(127f, 127f, 127f), true); + + // Async command + if (m_scene.SceneGridService != null) + { + m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions); + + // Give the above command some time to try and close the connections. + // this is really an emergency.. so sleep, or we'll get all discombobulated. + System.Threading.Thread.Sleep(500); + } + + if (m_scene.SceneGridService != null) + { + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); + if (m_agentTransfer != null) + m_agentTransfer.EnableChildAgents(this); + } + + return; + } + + m_perfMonMS = Util.EnvironmentTickCount(); + + Rotation = rotation; + Vector3 direc = vec * rotation; + direc.Normalize(); + PhysicsActor actor = m_physicsActor; + if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. + + direc *= 0.03f * 128f * m_speedModifier; + + if (actor != null) + { + if (actor.Flying) + { + direc *= 4.0f; + //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + //bool colliding = (m_physicsActor.IsColliding==true); + //if (controlland) + // m_log.Info("[AGENT]: landCommand"); + //if (colliding) + // m_log.Info("[AGENT]: colliding"); + //if (m_physicsActor.Flying && colliding && controlland) + //{ + // StopFlying(); + // m_log.Info("[AGENT]: Stop FLying"); + //} + } + else if (!actor.Flying && actor.IsColliding) + { + if (direc.Z > 2.0f) + { + if(m_animator.m_animTickJump == -1) + { + direc.Z *= 3.0f; // jump + } + else + { + direc.Z *= 0.1f; // prejump + } + /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs + Animator.TrySetMovementAnimation("PREJUMP"); + Animator.TrySetMovementAnimation("JUMP"); + */ + } + } + } + + // TODO: Add the force instead of only setting it to support multiple forces per frame? + m_forceToApply = direc; + m_isNudging = Nudging; + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + #endregion + + #region Overridden Methods + + public override void Update() + { + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; + //const int TIME_MS_TOLERANCE = 3000; + + + + if (m_isChildAgent == false) + { +// PhysicsActor actor = m_physicsActor; + + // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to + // grab the latest PhysicsActor velocity, whereas m_velocity is often + // storing a requested force instead of an actual traveling velocity + + // Throw away duplicate or insignificant updates + if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) + { + SendTerseUpdateToAllClients(); + + // Update the "last" values + m_lastPosition = m_pos; + m_lastRotation = m_bodyRot; + m_lastVelocity = Velocity; + //m_lastTerseSent = Environment.TickCount; + } + + // followed suggestion from mic bowman. reversed the two lines below. + if (m_parentID == 0 && m_physicsActor != null || m_parentID != 0) // Check that we have a physics actor or we're sitting on something + CheckForBorderCrossing(); + CheckForSignificantMovement(); // sends update to the modules. + } + + //Sending prim updates AFTER the avatar terse updates are sent + SendPrimUpdates(); + } + + #endregion + + #region Update Client(s) + + /// + /// Sends a location update to the client connected to this scenePresence + /// + /// + public void SendTerseUpdateToClient(IClientAPI remoteClient) + { + // If the client is inactive, it's getting its updates from another + // server. + if (remoteClient.IsActive) + { + m_perfMonMS = Util.EnvironmentTickCount(); + + PhysicsActor actor = m_physicsActor; + Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); + + remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentUpdates(1); + } + } + + /// + /// Send a location/velocity/accelleration update to all agents in scene + /// + public void SendTerseUpdateToAllClients() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + m_scene.ForEachClient(SendTerseUpdateToClient); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + public void SendCoarseLocations(List coarseLocations, List avatarUUIDs) + { + SendCourseLocationsMethod d = m_sendCourseLocationsMethod; + if (d != null) + { + d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); + } + } + + public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) + { + if (d != null) + m_sendCourseLocationsMethod = d; + } + + public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List coarseLocations, List avatarUUIDs) + { + m_perfMonMS = Util.EnvironmentTickCount(); + m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) + /// + /// + public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) + { + // 2 stage check is needed. + if (remoteAvatar == null) + return; + IClientAPI cl=remoteAvatar.ControllingClient; + if (cl == null) + return; + if (m_appearance.Texture == null) + return; + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); + m_scene.StatsReporter.AddAgentUpdates(1); + } + + /// + /// Tell *ALL* agents about this agent + /// + public void SendInitialFullUpdateToAllClients() + { + m_perfMonMS = Util.EnvironmentTickCount(); + int avUpdates = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + ++avUpdates; + // only send if this is the root (children are only "listening posts" in a foreign region) + if (!IsChildAgent) + { + SendFullUpdateToOtherClient(avatar); + } + + if (avatar.LocalId != LocalId) + { + if (!avatar.IsChildAgent) + { + avatar.SendFullUpdateToOtherClient(this); + avatar.SendAppearanceToOtherAgent(this); + avatar.Animator.SendAnimPackToClient(ControllingClient); + } + } + }); + + m_scene.StatsReporter.AddAgentUpdates(avUpdates); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + + //Animator.SendAnimPack(); + } + + public void SendFullUpdateToAllClients() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + // only send update from root agents to other clients; children are only "listening posts" + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence sp) + { + if (sp.IsChildAgent) + return; + SendFullUpdateToOtherClient(sp); + ++count; + }); + m_scene.StatsReporter.AddAgentUpdates(count); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + + Animator.SendAnimPack(); + } + + /// + /// Do everything required once a client completes its movement into a region + /// + public void SendInitialData() + { + // Moved this into CompleteMovement to ensure that m_appearance is initialized before + // the inventory arrives + // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + m_controllingClient.SendAvatarDataImmediate(this); + + SendInitialFullUpdateToAllClients(); + SendAppearanceToAllOtherAgents(); + } + + /// + /// Tell the client for this scene presence what items it should be wearing now + /// + public void SendWearables() + { + m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); + + ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); + } + + /// + /// + /// + public void SendAppearanceToAllOtherAgents() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + if (scenePresence.UUID != UUID) + { + SendAppearanceToOtherAgent(scenePresence); + } + }); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Send appearance data to an agent that isn't this one. + /// + /// + public void SendAppearanceToOtherAgent(ScenePresence avatar) + { + avatar.ControllingClient.SendAppearance( + m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); + } + + /// + /// Set appearance data (textureentry and slider settings) received from the client + /// + /// + /// + public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) + { + if (m_physicsActor != null) + { + if (!IsChildAgent) + { + // This may seem like it's redundant, remove the avatar from the physics scene + // just to add it back again, but it saves us from having to update + // 3 variables 10 times a second. + bool flyingTemp = m_physicsActor.Flying; + RemoveFromPhysicalScene(); + //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); + + //PhysicsActor = null; + + AddToPhysicalScene(flyingTemp); + } + } + + #region Bake Cache Check + + if (textureEntry != null) + { + for (int i = 0; i < BAKE_INDICES.Length; i++) + { + int j = BAKE_INDICES[i]; + Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; + + if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + { + if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) + { + m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); + this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); + } + } + } + + } + + + #endregion Bake Cache Check + + m_appearance.SetAppearance(textureEntry, visualParams); + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + + // This is not needed, because only the transient data changed + //AvatarData adata = new AvatarData(m_appearance); + //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); + + SendAppearanceToAllOtherAgents(); + if (!m_startAnimationSet) + { + Animator.UpdateMovementAnimations(); + m_startAnimationSet = true; + } + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + m_controllingClient.SendAvatarDataImmediate(this); + } + + public void SetWearable(int wearableId, AvatarWearable wearable) + { + m_appearance.SetWearable(wearableId, wearable); + AvatarData adata = new AvatarData(m_appearance); + m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); + m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); + } + + // Because appearance setting is in a module, we actually need + // to give it access to our appearance directly, otherwise we + // get a synchronization issue. + public AvatarAppearance Appearance + { + get { return m_appearance; } + set { m_appearance = value; } + } + + #endregion + + #region Significant Movement Method + + /// + /// This checks for a significant movement and sends a courselocationchange update + /// + protected void CheckForSignificantMovement() + { + // Movement updates for agents in neighboring regions are sent directly to clients. + // This value only affects how often agent positions are sent to neighbor regions + // for things such as distance-based update prioritization + const float SIGNIFICANT_MOVEMENT = 2.0f; + + if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) + { + posLastSignificantMove = AbsolutePosition; + m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); + } + + // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m + if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || + Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) + { + m_lastChildAgentUpdatePosition = AbsolutePosition; + m_lastChildAgentUpdateCamPosition = CameraPosition; + + ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); + cadu.ActiveGroupID = UUID.Zero.Guid; + cadu.AgentID = UUID.Guid; + cadu.alwaysrun = m_setAlwaysRun; + cadu.AVHeight = m_avHeight; + Vector3 tempCameraCenter = m_CameraCenter; + cadu.cameraPosition = tempCameraCenter; + cadu.drawdistance = m_DrawDistance; + cadu.GroupAccess = 0; + cadu.Position = AbsolutePosition; + cadu.regionHandle = m_rootRegionHandle; + float multiplier = 1; + int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); + if (innacurateNeighbors != 0) + { + multiplier = 1f / (float)innacurateNeighbors; + } + if (multiplier <= 0f) + { + multiplier = 0.25f; + } + + //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); + cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); + cadu.Velocity = Velocity; + + AgentPosition agentpos = new AgentPosition(); + agentpos.CopyFrom(cadu); + + m_scene.SendOutChildAgentUpdates(agentpos, this); + } + } + + #endregion + + #region Border Crossing Methods + + /// + /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion + /// + protected void CheckForBorderCrossing() + { + if (IsChildAgent) + return; + + Vector3 pos2 = AbsolutePosition; + Vector3 vel = Velocity; + int neighbor = 0; + int[] fix = new int[2]; + + float timeStep = 0.1f; + pos2.X = pos2.X + (vel.X*timeStep); + pos2.Y = pos2.Y + (vel.Y*timeStep); + pos2.Z = pos2.Z + (vel.Z*timeStep); + + if (!IsInTransit) + { + // Checks if where it's headed exists a region + + bool needsTransit = false; + if (m_scene.TestBorderCross(pos2, Cardinals.W)) + { + if (m_scene.TestBorderCross(pos2, Cardinals.S)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.SW, ref fix); + } + else if (m_scene.TestBorderCross(pos2, Cardinals.N)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.NW, ref fix); + } + else + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.W, ref fix); + } + } + else if (m_scene.TestBorderCross(pos2, Cardinals.E)) + { + if (m_scene.TestBorderCross(pos2, Cardinals.S)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.SE, ref fix); + } + else if (m_scene.TestBorderCross(pos2, Cardinals.N)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.NE, ref fix); + } + else + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.E, ref fix); + } + } + else if (m_scene.TestBorderCross(pos2, Cardinals.S)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.S, ref fix); + } + else if (m_scene.TestBorderCross(pos2, Cardinals.N)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.N, ref fix); + } + + + // Makes sure avatar does not end up outside region + if (neighbor <= 0) + { + if (!needsTransit) + { + if (m_requestedSitTargetUUID == UUID.Zero) + { + Vector3 pos = AbsolutePosition; + if (AbsolutePosition.X < 0) + pos.X += Velocity.X; + else if (AbsolutePosition.X > Constants.RegionSize) + pos.X -= Velocity.X; + if (AbsolutePosition.Y < 0) + pos.Y += Velocity.Y; + else if (AbsolutePosition.Y > Constants.RegionSize) + pos.Y -= Velocity.Y; + AbsolutePosition = pos; + } + } + } + else if (neighbor > 0) + CrossToNewRegion(); + } + else + { + RemoveFromPhysicalScene(); + // This constant has been inferred from experimentation + // I'm not sure what this value should be, so I tried a few values. + timeStep = 0.04f; + pos2 = AbsolutePosition; + pos2.X = pos2.X + (vel.X * timeStep); + pos2.Y = pos2.Y + (vel.Y * timeStep); + pos2.Z = pos2.Z + (vel.Z * timeStep); + m_pos = pos2; + } + } + + protected int HaveNeighbor(Cardinals car, ref int[] fix) + { + uint neighbourx = m_regionInfo.RegionLocX; + uint neighboury = m_regionInfo.RegionLocY; + + int dir = (int)car; + + if (dir > 1 && dir < 5) //Heading East + neighbourx++; + else if (dir > 5) // Heading West + neighbourx--; + + if (dir < 3 || dir == 8) // Heading North + neighboury++; + else if (dir > 3 && dir < 7) // Heading Sout + neighboury--; + + int x = (int)(neighbourx * Constants.RegionSize); + int y = (int)(neighboury * Constants.RegionSize); + GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y); + + if (neighbourRegion == null) + { + fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); + fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); + return dir * (-1); + } + else + return dir; + } + + /// + /// Moves the agent outside the region bounds + /// Tells neighbor region that we're crossing to it + /// If the neighbor accepts, remove the agent's viewable avatar from this scene + /// set them to a child agent. + /// + protected void CrossToNewRegion() + { + InTransit(); + try + { + m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); + } + catch + { + m_scene.CrossAgentToNewRegion(this, false); + } + } + + public void InTransit() + { + m_inTransit = true; + + if ((m_physicsActor != null) && m_physicsActor.Flying) + m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; + else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) + m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; + } + + public void NotInTransit() + { + m_inTransit = false; + } + + public void RestoreInCurrentScene() + { + AddToPhysicalScene(false); // not exactly false + } + + public void Reset() + { + // Put the child agent back at the center + AbsolutePosition + = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); + Animator.ResetAnimations(); + } + + /// + /// Computes which child agents to close when the scene presence moves to another region. + /// Removes those regions from m_knownRegions. + /// + /// The new region's x on the map + /// The new region's y on the map + /// + public void CloseChildAgents(uint newRegionX, uint newRegionY) + { + List byebyeRegions = new List(); + m_log.DebugFormat( + "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", + m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); + //DumpKnownRegions(); + + lock (m_knownChildRegions) + { + foreach (ulong handle in m_knownChildRegions.Keys) + { + // Don't close the agent on this region yet + if (handle != Scene.RegionInfo.RegionHandle) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + + //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); + //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); + if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) + { + byebyeRegions.Add(handle); + } + } + } + } + + if (byebyeRegions.Count > 0) + { + m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); + m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); + } + + foreach (ulong handle in byebyeRegions) + { + RemoveNeighbourRegion(handle); + } + } + + #endregion + + /// + /// This allows the Sim owner the abiility to kick users from their sim currently. + /// It tells the client that the agent has permission to do so. + /// + public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) + { + if (godStatus) + { + // For now, assign god level 200 to anyone + // who is granted god powers, but has no god level set. + // + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID); + if (account != null) + { + if (account.UserLevel > 0) + m_godLevel = account.UserLevel; + else + m_godLevel = 200; + } + } + else + { + m_godLevel = 0; + } + + ControllingClient.SendAdminResponse(token, (uint)m_godLevel); + } + + #region Child Agent Updates + + public void ChildAgentDataUpdate(AgentData cAgentData) + { + //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); + if (!IsChildAgent) + return; + + CopyFrom(cAgentData); + } + + /// + /// This updates important decision making data about a child agent + /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region + /// + public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) + { + if (!IsChildAgent) + return; + + //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); + int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; + int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; + + Vector3 offset = new Vector3(shiftx, shifty, 0f); + + m_DrawDistance = cAgentData.Far; + if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! + m_pos = cAgentData.Position + offset; + + if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) + { + posLastSignificantMove = AbsolutePosition; + ReprioritizeUpdates(); + } + + m_CameraCenter = cAgentData.Center + offset; + + m_avHeight = cAgentData.Size.Z; + //SetHeight(cAgentData.AVHeight); + + if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) + ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); + + // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. + if (m_scene.m_seeIntoRegionFromNeighbor) + m_sceneViewer.Reset(); + + //cAgentData.AVHeight; + m_rootRegionHandle = cAgentData.RegionHandle; + //m_velocity = cAgentData.Velocity; + } + + public void CopyTo(AgentData cAgent) + { + cAgent.AgentID = UUID; + cAgent.RegionID = Scene.RegionInfo.RegionID; + + cAgent.Position = AbsolutePosition; + cAgent.Velocity = m_velocity; + cAgent.Center = m_CameraCenter; + // Don't copy the size; it is inferred from apearance parameters + //cAgent.Size = new Vector3(0, 0, m_avHeight); + cAgent.AtAxis = m_CameraAtAxis; + cAgent.LeftAxis = m_CameraLeftAxis; + cAgent.UpAxis = m_CameraUpAxis; + + cAgent.Far = m_DrawDistance; + + // Throttles + float multiplier = 1; + int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); + if (innacurateNeighbors != 0) + { + multiplier = 1f / innacurateNeighbors; + } + if (multiplier <= 0f) + { + multiplier = 0.25f; + } + //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); + cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); + + cAgent.HeadRotation = m_headrotation; + cAgent.BodyRotation = m_bodyRot; + cAgent.ControlFlags = (uint)m_AgentControlFlags; + + if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) + cAgent.GodLevel = (byte)m_godLevel; + else + cAgent.GodLevel = (byte) 0; + + cAgent.AlwaysRun = m_setAlwaysRun; + + try + { + // We might not pass the Wearables in all cases... + // They're only needed so that persistent changes to the appearance + // are preserved in the new region where the user is moving to. + // But in Hypergrid we might not let this happen. + int i = 0; + UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; + foreach (AvatarWearable aw in m_appearance.Wearables) + { + if (aw != null) + { + wears[i++] = aw.ItemID; + wears[i++] = aw.AssetID; + } + else + { + wears[i++] = UUID.Zero; + wears[i++] = UUID.Zero; + } + } + cAgent.Wearables = wears; + + cAgent.VisualParams = m_appearance.VisualParams; + + if (m_appearance.Texture != null) + cAgent.AgentTextures = m_appearance.Texture.GetBytes(); + } + catch (Exception e) + { + m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); + } + + //Attachments + List attPoints = m_appearance.GetAttachedPoints(); + if (attPoints != null) + { + //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); + int i = 0; + AttachmentData[] attachs = new AttachmentData[attPoints.Count]; + foreach (int point in attPoints) + { + attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); + } + cAgent.Attachments = attachs; + } + + lock (scriptedcontrols) + { + ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; + int i = 0; + + foreach (ScriptControllers c in scriptedcontrols.Values) + { + controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); + } + cAgent.Controllers = controls; + } + + // Animations + try + { + cAgent.Anims = Animator.Animations.ToArray(); + } + catch { } + + // cAgent.GroupID = ?? + // Groups??? + + } + + public void CopyFrom(AgentData cAgent) + { + m_originRegionID = cAgent.RegionID; + + m_callbackURI = cAgent.CallbackURI; + + m_pos = cAgent.Position; + + m_velocity = cAgent.Velocity; + m_CameraCenter = cAgent.Center; + //m_avHeight = cAgent.Size.Z; + m_CameraAtAxis = cAgent.AtAxis; + m_CameraLeftAxis = cAgent.LeftAxis; + m_CameraUpAxis = cAgent.UpAxis; + + m_DrawDistance = cAgent.Far; + + if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) + ControllingClient.SetChildAgentThrottle(cAgent.Throttles); + + m_headrotation = cAgent.HeadRotation; + m_bodyRot = cAgent.BodyRotation; + m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; + + if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) + m_godLevel = cAgent.GodLevel; + m_setAlwaysRun = cAgent.AlwaysRun; + + uint i = 0; + try + { + if (cAgent.Wearables == null) + cAgent.Wearables = new UUID[0]; + AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; + for (uint n = 0; n < cAgent.Wearables.Length; n += 2) + { + UUID itemId = cAgent.Wearables[n]; + UUID assetId = cAgent.Wearables[n + 1]; + wears[i++] = new AvatarWearable(itemId, assetId); + } + m_appearance.Wearables = wears; + Primitive.TextureEntry te; + if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) + te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); + else + te = AvatarAppearance.GetDefaultTexture(); + if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) + cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); + m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); + } + catch (Exception e) + { + m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); + } + + // Attachments + try + { + if (cAgent.Attachments != null) + { + m_appearance.ClearAttachments(); + foreach (AttachmentData att in cAgent.Attachments) + { + m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); + } + } + } + catch { } + + try + { + lock (scriptedcontrols) + { + if (cAgent.Controllers != null) + { + scriptedcontrols.Clear(); + + foreach (ControllerData c in cAgent.Controllers) + { + ScriptControllers sc = new ScriptControllers(); + sc.itemID = c.ItemID; + sc.ignoreControls = (ScriptControlled)c.IgnoreControls; + sc.eventControls = (ScriptControlled)c.EventControls; + + scriptedcontrols[sc.itemID] = sc; + } + } + } + } + catch { } + // Animations + try + { + Animator.ResetAnimations(); + Animator.Animations.FromArray(cAgent.Anims); + } + catch { } + + //cAgent.GroupID = ?? + //Groups??? + } + + public bool CopyAgent(out IAgentData agent) + { + agent = new CompleteAgentData(); + CopyTo((AgentData)agent); + return true; + } + + #endregion Child Agent Updates + + /// + /// Handles part of the PID controller function for moving an avatar. + /// + public override void UpdateMovement() + { + if (m_forceToApply.HasValue) + { + + Vector3 force = m_forceToApply.Value; + m_updateflag = true; + Velocity = force; + + m_forceToApply = null; + } + else + { + if (m_isNudging) + { + Vector3 force = Vector3.Zero; + + m_updateflag = true; + Velocity = force; + m_isNudging = false; + m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" + } + } + } + + public override void SetText(string text, Vector3 color, double alpha) + { + throw new Exception("Can't set Text on avatar."); + } + + /// + /// Adds a physical representation of the avatar to the Physics plugin + /// + public void AddToPhysicalScene(bool isFlying) + { + PhysicsScene scene = m_scene.PhysicsScene; + + Vector3 pVec = AbsolutePosition; + + // Old bug where the height was in centimeters instead of meters + if (m_avHeight == 127.0f) + { + m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f), + isFlying); + } + else + { + m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, + new Vector3(0f, 0f, m_avHeight), isFlying); + } + scene.AddPhysicsActorTaint(m_physicsActor); + //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; + m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; + m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong + m_physicsActor.SubscribeEvents(500); + m_physicsActor.LocalID = LocalId; + } + + private void OutOfBoundsCall(Vector3 pos) + { + //bool flying = m_physicsActor.Flying; + //RemoveFromPhysicalScene(); + + //AddToPhysicalScene(flying); + if (ControllingClient != null) + ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); + } + + // Event called by the physics plugin to tell the avatar about a collision. + private void PhysicsCollisionUpdate(EventArgs e) + { + if (e == null) + return; + + // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( + // as of this comment the interval is set in AddToPhysicalScene + if (Animator!=null) + { + if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, + { // else its will lock out other animation changes, like ground sit. + Animator.UpdateMovementAnimations(); + m_updateCount--; + } + } + + CollisionEventUpdate collisionData = (CollisionEventUpdate)e; + Dictionary coldata = collisionData.m_objCollisionList; + + CollisionPlane = Vector4.UnitW; + + if (m_lastColCount != coldata.Count) + { + m_updateCount = UPDATE_COUNT; + m_lastColCount = coldata.Count; + } + + if (coldata.Count != 0 && Animator != null) + { + switch (Animator.CurrentMovementAnimation) + { + case "STAND": + case "WALK": + case "RUN": + case "CROUCH": + case "CROUCHWALK": + { + ContactPoint lowest; + lowest.SurfaceNormal = Vector3.Zero; + lowest.Position = Vector3.Zero; + lowest.Position.Z = Single.NaN; + + foreach (ContactPoint contact in coldata.Values) + { + if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) + { + lowest = contact; + } + } + + CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); + } + break; + } + } + + List thisHitColliders = new List(); + List endedColliders = new List(); + List startedColliders = new List(); + + foreach (uint localid in coldata.Keys) + { + thisHitColliders.Add(localid); + if (!m_lastColliders.Contains(localid)) + { + startedColliders.Add(localid); + } + //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); + } + + // calculate things that ended colliding + foreach (uint localID in m_lastColliders) + { + if (!thisHitColliders.Contains(localID)) + { + endedColliders.Add(localID); + } + } + //add the items that started colliding this time to the last colliders list. + foreach (uint localID in startedColliders) + { + m_lastColliders.Add(localID); + } + // remove things that ended colliding from the last colliders list + foreach (uint localID in endedColliders) + { + m_lastColliders.Remove(localID); + } + + // do event notification + if (startedColliders.Count > 0) + { + ColliderArgs StartCollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in startedColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + StartCollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); + } + } + + if (endedColliders.Count > 0) + { + ColliderArgs EndCollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in endedColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + EndCollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); + } + } + + if (thisHitColliders.Count > 0) + { + ColliderArgs CollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in thisHitColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + CollidingMessage.Colliders = colliding; + + lock (m_attachments) + { + foreach (SceneObjectGroup att in m_attachments) + Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); + } + } + } + + if (m_invulnerable) + return; + + float starthealth = Health; + uint killerObj = 0; + foreach (uint localid in coldata.Keys) + { + SceneObjectPart part = Scene.GetSceneObjectPart(localid); + + if (part != null && part.ParentGroup.Damage != -1.0f) + Health -= part.ParentGroup.Damage; + else + { + if (coldata[localid].PenetrationDepth >= 0.10f) + Health -= coldata[localid].PenetrationDepth * 5.0f; + } + + if (Health <= 0.0f) + { + if (localid != 0) + killerObj = localid; + } + //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); + } + //Health = 100; + if (!m_invulnerable) + { + if (starthealth != Health) + { + ControllingClient.SendHealth(Health); + } + if (m_health <= 0) + m_scene.EventManager.TriggerAvatarKill(killerObj, this); + } + } + + public void setHealthWithUpdate(float health) + { + Health = health; + ControllingClient.SendHealth(Health); + } + + public void Close() + { + lock (m_attachments) + { + // Delete attachments from scene + // Don't try to save, as this thread won't live long + // enough to complete the save. This would cause no copy + // attachments to poof! + // + foreach (SceneObjectGroup grp in m_attachments) + { + m_scene.DeleteSceneObject(grp, false); + } + m_attachments.Clear(); + } + + lock (m_knownChildRegions) + { + m_knownChildRegions.Clear(); + } + + lock (m_reprioritization_timer) + { + m_reprioritization_timer.Enabled = false; + m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); + } + + // I don't get it but mono crashes when you try to dispose of this timer, + // unsetting the elapsed callback should be enough to allow for cleanup however. + // m_reprioritizationTimer.Dispose(); + + m_sceneViewer.Close(); + + RemoveFromPhysicalScene(); + m_animator.Close(); + m_animator = null; + } + + public void AddAttachment(SceneObjectGroup gobj) + { + lock (m_attachments) + { + m_attachments.Add(gobj); + } + } + + public bool HasAttachments() + { + return m_attachments.Count > 0; + } + + public bool HasScriptedAttachments() + { + lock (m_attachments) + { + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj != null) + { + if (gobj.RootPart.Inventory.ContainsScripts()) + return true; + } + } + } + return false; + } + + public void RemoveAttachment(SceneObjectGroup gobj) + { + lock (m_attachments) + { + if (m_attachments.Contains(gobj)) + { + m_attachments.Remove(gobj); + } + } + } + + public bool ValidateAttachments() + { + lock (m_attachments) + { + // Validate + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj == null) + return false; + + if (gobj.IsDeleted) + return false; + } + } + return true; + } + + /// + /// Send a script event to this scene presence's attachments + /// + /// The name of the event + /// The arguments for the event + public void SendScriptEventToAttachments(string eventName, Object[] args) + { + if (m_scriptEngines != null) + { + lock (m_attachments) + { + foreach (SceneObjectGroup grp in m_attachments) + { + // 16384 is CHANGED_ANIMATION + // + // Send this to all attachment root prims + // + foreach (IScriptModule m in m_scriptEngines) + { + if (m == null) // No script engine loaded + continue; + + m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); + } + } + } + } + } + + + public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) + { + m_controllingClient = client; + m_regionInfo = region; + m_scene = scene; + + RegisterToEvents(); + if (m_controllingClient != null) + { + m_controllingClient.ProcessPendingPackets(); + } + /* + AbsolutePosition = client.StartPos; + + Animations = new AvatarAnimations(); + Animations.LoadAnims(); + + m_animations = new List(); + m_animations.Add(Animations.AnimsUUID["STAND"]); + m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); + + SetDirectionVectors(); + */ + } + + internal void PushForce(Vector3 impulse) + { + if (PhysicsActor != null) + { + PhysicsActor.AddForce(impulse,true); + } + } + + public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) + { + ScriptControllers obj = new ScriptControllers(); + obj.ignoreControls = ScriptControlled.CONTROL_ZERO; + obj.eventControls = ScriptControlled.CONTROL_ZERO; + + obj.itemID = Script_item_UUID; + if (pass_on == 0 && accept == 0) + { + IgnoredControls |= (ScriptControlled)controls; + obj.ignoreControls = (ScriptControlled)controls; + } + + if (pass_on == 0 && accept == 1) + { + IgnoredControls |= (ScriptControlled)controls; + obj.ignoreControls = (ScriptControlled)controls; + obj.eventControls = (ScriptControlled)controls; + } + if (pass_on == 1 && accept == 1) + { + IgnoredControls = ScriptControlled.CONTROL_ZERO; + obj.eventControls = (ScriptControlled)controls; + obj.ignoreControls = ScriptControlled.CONTROL_ZERO; + } + + lock (scriptedcontrols) + { + if (pass_on == 1 && accept == 0) + { + IgnoredControls &= ~(ScriptControlled)controls; + if (scriptedcontrols.ContainsKey(Script_item_UUID)) + scriptedcontrols.Remove(Script_item_UUID); + } + else + { + scriptedcontrols[Script_item_UUID] = obj; + } + } + ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); + } + + public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) + { + IgnoredControls = ScriptControlled.CONTROL_ZERO; + lock (scriptedcontrols) + { + scriptedcontrols.Clear(); + } + ControllingClient.SendTakeControls(int.MaxValue, false, false); + } + + public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) + { + ScriptControllers takecontrols; + + lock (scriptedcontrols) + { + if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) + { + ScriptControlled sctc = takecontrols.eventControls; + + ControllingClient.SendTakeControls((int)sctc, false, false); + ControllingClient.SendTakeControls((int)sctc, true, false); + + scriptedcontrols.Remove(Script_item_UUID); + IgnoredControls = ScriptControlled.CONTROL_ZERO; + foreach (ScriptControllers scData in scriptedcontrols.Values) + { + IgnoredControls |= scData.ignoreControls; + } + } + } + } + + internal void SendControlToScripts(uint flags) + { + ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; + + if (MouseDown) + { + allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) + { + allflags = ScriptControlled.CONTROL_ZERO; + MouseDown = true; + } + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) + { + allflags |= ScriptControlled.CONTROL_ML_LBUTTON; + MouseDown = true; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) + { + allflags |= ScriptControlled.CONTROL_LBUTTON; + MouseDown = true; + } + + // find all activated controls, whether the scripts are interested in them or not + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_FWD; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_BACK; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_UP; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_DOWN; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_LEFT; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_RIGHT; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_ROT_RIGHT; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_ROT_LEFT; + } + // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that + if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) + { + lock (scriptedcontrols) + { + foreach (KeyValuePair kvp in scriptedcontrols) + { + UUID scriptUUID = kvp.Key; + ScriptControllers scriptControlData = kvp.Value; + + ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us + ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle + ScriptControlled localChange = localHeld ^ localLast; // the changed bits + if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) + { + // only send if still pressed or just changed + m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange); + } + } + } + } + + LastCommands = allflags; + } + + internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) + { + if (ignored == ScriptControlled.CONTROL_ZERO) + return flags; + + if ((ignored & ScriptControlled.CONTROL_BACK) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); + if ((ignored & ScriptControlled.CONTROL_FWD) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); + if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); + if ((ignored & ScriptControlled.CONTROL_UP) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); + if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); + if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); + if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); + if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); + if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); + if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); + + //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, + //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, + //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, + //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, + //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, + //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + + return flags; + } + + /// + /// RezAttachments. This should only be called upon login on the first region. + /// Attachment rezzings on crossings and TPs are done in a different way. + /// + public void RezAttachments() + { + if (null == m_appearance) + { + m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); + return; + } + + XmlDocument doc = new XmlDocument(); + string stateData = String.Empty; + + IAttachmentsService attServ = m_scene.RequestModuleInterface(); + if (attServ != null) + { + m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); + stateData = attServ.Get(ControllingClient.AgentId.ToString()); + if (stateData != String.Empty) + { + try + { + doc.LoadXml(stateData); + } + catch { } + } + } + + Dictionary itemData = new Dictionary(); + + XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); + if (nodes.Count > 0) + { + foreach (XmlNode n in nodes) + { + XmlElement elem = (XmlElement)n; + string itemID = elem.GetAttribute("ItemID"); + string xml = elem.InnerXml; + + itemData[new UUID(itemID)] = xml; + } + } + + List attPoints = m_appearance.GetAttachedPoints(); + foreach (int p in attPoints) + { + if (m_isDeleted) + return; + + UUID itemID = m_appearance.GetAttachedItem(p); + UUID assetID = m_appearance.GetAttachedAsset(p); + + // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down + // But they're not used anyway, the item is being looked up for now, so let's proceed. + //if (UUID.Zero == assetID) + //{ + // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); + // continue; + //} + + try + { + string xmlData; + XmlDocument d = new XmlDocument(); + UUID asset; + if (itemData.TryGetValue(itemID, out xmlData)) + { + d.LoadXml(xmlData); + m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); + + // Rez from inventory + asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); + + } + else + { + // Rez from inventory (with a null doc to let + // CHANGED_OWNER happen) + asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); + } + + m_log.InfoFormat( + "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", + p, itemID, assetID, asset); + } + catch (Exception e) + { + m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); + } + } + } + + private void ReprioritizeUpdates() + { + if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) + { + lock (m_reprioritization_timer) + { + if (!m_reprioritizing) + m_reprioritization_timer.Enabled = m_reprioritizing = true; + else + m_reprioritization_called = true; + } + } + } + + private void Reprioritize(object sender, ElapsedEventArgs e) + { + m_controllingClient.ReprioritizeUpdates(); + + lock (m_reprioritization_timer) + { + m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; + m_reprioritization_called = false; + } + } + + private Vector3 Quat2Euler(Quaternion rot){ + float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , + (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); + float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); + float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , + (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); + return(new Vector3(x,y,z)); + } + + + } +} -- cgit v1.1 From cabbd187e7945329c2f0700180f400b11096d33c Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 11:13:05 -0700 Subject: Fix the distance from which autopilot is negated when sitting on an unscripted prim - and also add some more Velocity code to ensure it gets set to zero in all cases --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 882f4a7..56e7e93 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2007,13 +2007,14 @@ namespace OpenSim.Region.Framework.Scenes if (autopilot) { // its not a scripted sit // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) - if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 2.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 2.0f) ) + if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 10.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 10.0f) ) { autopilot = false; // close enough m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. Not using the part's position because returning the AV to the last known standing position is likely to be more friendly, isn't it? */ RemoveFromPhysicalScene(); + Velocity = Vector3.Zero; AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target } // else the autopilot will get us close } @@ -2023,6 +2024,7 @@ namespace OpenSim.Region.Framework.Scenes I *am* using the part's position this time because we have no real idea how far away the avatar is from the sit target. */ RemoveFromPhysicalScene(); + Velocity = Vector3.Zero; } } else return; // physactor is null! -- cgit v1.1 From 7bac069976b31ecb39c2d667b51aaa555f8207e3 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 7 Aug 2010 22:10:46 +0200 Subject: Mantis #229. Fix Global sim ccordinates --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a711ebf..9c630ef 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9145,8 +9145,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } reply = new LSL_Vector( - info.RegionLocX / Constants.RegionSize, - info.RegionLocY / Constants.RegionSize, + info.RegionLocX; + info.RegionLocY; 0).ToString(); break; case 6: // DATA_SIM_STATUS -- cgit v1.1 From 478d83539244157992b1849648e5e4cf758543e0 Mon Sep 17 00:00:00 2001 From: sacha Date: Sat, 7 Aug 2010 21:04:16 +0000 Subject: removing more stains ... --- OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index a9ecde8..59e4037 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -168,7 +168,7 @@ namespace OpenSim.Region.Framework.Scenes if (neighbour != null) { - m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); + // m_log.DebugFormat("[INTERGRID]: Successfully informed neighbour {0}-{1} that I'm here", x / Constants.RegionSize, y / Constants.RegionSize); m_scene.EventManager.TriggerOnRegionUp(neighbour); } else @@ -183,7 +183,7 @@ namespace OpenSim.Region.Framework.Scenes //m_log.Info("[INTER]: " + debugRegionName + ": SceneCommunicationService: Sending InterRegion Notification that region is up " + region.RegionName); List neighbours = m_scene.GridService.GetNeighbours(m_scene.RegionInfo.ScopeID, m_scene.RegionInfo.RegionID); - m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count); + //m_log.DebugFormat("[INTERGRID]: Informing {0} neighbours that this region is up", neighbours.Count); foreach (GridRegion n in neighbours) { InformNeighbourThatRegionUpDelegate d = InformNeighboursThatRegionIsUpAsync; @@ -267,7 +267,7 @@ namespace OpenSim.Region.Framework.Scenes protected void SendCloseChildAgentAsync(UUID agentID, ulong regionHandle) { - m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); + //m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); // let's do our best, but there's not much we can do if the neighbour doesn't accept. //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); -- cgit v1.1 From 68e4b1115a5545a40e7a410855e39724d45b958c Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 7 Aug 2010 22:23:51 +0100 Subject: Dumb error in fix --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9c630ef..68b645e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9145,8 +9145,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero.ToString(); } reply = new LSL_Vector( - info.RegionLocX; - info.RegionLocY; + info.RegionLocX, + info.RegionLocY, 0).ToString(); break; case 6: // DATA_SIM_STATUS -- cgit v1.1 From 4c5788c4c0975dbf3af58e2184a90965fcf0e893 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 7 Aug 2010 22:24:17 +0100 Subject: Add search URL to Login Service --- OpenSim/Services/LLLoginService/LLLoginResponse.cs | 18 +++++++++++++++++- OpenSim/Services/LLLoginService/LLLoginService.cs | 4 +++- 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/LLLoginService/LLLoginResponse.cs b/OpenSim/Services/LLLoginService/LLLoginResponse.cs index 240f5b1..c1da463 100644 --- a/OpenSim/Services/LLLoginService/LLLoginResponse.cs +++ b/OpenSim/Services/LLLoginService/LLLoginResponse.cs @@ -178,6 +178,8 @@ namespace OpenSim.Services.LLLoginService // Web map private string mapTileURL; + private string searchURL; + // Error Flags private string errorReason; private string errorMessage; @@ -226,7 +228,7 @@ namespace OpenSim.Services.LLLoginService public LLLoginResponse(UserAccount account, AgentCircuitData aCircuit, GridUserInfo pinfo, GridRegion destination, List invSkel, FriendInfo[] friendsList, ILibraryService libService, string where, string startlocation, Vector3 position, Vector3 lookAt, List gestures, string message, - GridRegion home, IPEndPoint clientIP, string mapTileURL) + GridRegion home, IPEndPoint clientIP, string mapTileURL, string searchURL) : this() { FillOutInventoryData(invSkel, libService); @@ -243,6 +245,7 @@ namespace OpenSim.Services.LLLoginService BuddList = ConvertFriendListItem(friendsList); StartLocation = where; MapTileURL = mapTileURL; + SearchURL = searchURL; FillOutHomeData(pinfo, home); LookAt = String.Format("[r{0},r{1},r{2}]", lookAt.X, lookAt.Y, lookAt.Z); @@ -416,6 +419,7 @@ namespace OpenSim.Services.LLLoginService InitialOutfitHash["gender"] = "female"; initialOutfit.Add(InitialOutfitHash); mapTileURL = String.Empty; + searchURL = String.Empty; } @@ -479,6 +483,9 @@ namespace OpenSim.Services.LLLoginService responseData["region_x"] = (Int32)(RegionX); responseData["region_y"] = (Int32)(RegionY); + if (searchURL != String.Empty) + responseData["search"] = searchURL; + if (mapTileURL != String.Empty) responseData["map-server-url"] = mapTileURL; @@ -581,6 +588,9 @@ namespace OpenSim.Services.LLLoginService if (mapTileURL != String.Empty) map["map-server-url"] = OSD.FromString(mapTileURL); + if (searchURL != String.Empty) + map["search"] = OSD.FromString(searchURL); + if (m_buddyList != null) { map["buddy-list"] = ArrayListToOSDArray(m_buddyList.ToArray()); @@ -938,6 +948,12 @@ namespace OpenSim.Services.LLLoginService set { mapTileURL = value; } } + public string SearchURL + { + get { return searchURL; } + set { searchURL = value; } + } + public string Message { get { return welcomeMessage; } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 9446126..f9fe7f0 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -74,6 +74,7 @@ namespace OpenSim.Services.LLLoginService protected string m_GatekeeperURL; protected bool m_AllowRemoteSetLoginLevel; protected string m_MapTileURL; + protected string m_SearchURL; IConfig m_LoginServerConfig; @@ -102,6 +103,7 @@ namespace OpenSim.Services.LLLoginService m_MinLoginLevel = m_LoginServerConfig.GetInt("MinLoginLevel", 0); m_GatekeeperURL = m_LoginServerConfig.GetString("GatekeeperURI", string.Empty); m_MapTileURL = m_LoginServerConfig.GetString("MapTileURL", string.Empty); + m_SearchURL = m_LoginServerConfig.GetString("SearchURL", string.Empty); // These are required; the others aren't if (accountService == string.Empty || authService == string.Empty) @@ -364,7 +366,7 @@ namespace OpenSim.Services.LLLoginService // Finally, fill out the response and return it // LLLoginResponse response = new LLLoginResponse(account, aCircuit, guinfo, destination, inventorySkel, friendsList, m_LibraryService, - where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL); + where, startLocation, position, lookAt, gestures, m_WelcomeMessage, home, clientIP, m_MapTileURL, m_SearchURL); m_log.DebugFormat("[LLOGIN SERVICE]: All clear. Sending login response to client."); return response; -- cgit v1.1 From a6048518b7afb27cb523c0074d38c849ea0b6884 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 16:18:44 -0700 Subject: Repair lsGetWindlightScene, the constant was added to the list as a uint, which is bad - convert to LSL_Integer first. --- .../Shared/Api/Implementation/LS_Api.cs | 1014 ++++++++++---------- 1 file changed, 507 insertions(+), 507 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index fffe65c..f0384f8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -1,507 +1,507 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.Remoting.Lifetime; -using OpenMetaverse; -using Nini.Config; -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.World.LightShare; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.ScriptEngine.Shared; -using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; -using OpenSim.Region.ScriptEngine.Shared.ScriptBase; -using OpenSim.Region.ScriptEngine.Interfaces; -using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; - -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; - -namespace OpenSim.Region.ScriptEngine.Shared.Api -{ - [Serializable] - public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi - { - internal IScriptEngine m_ScriptEngine; - internal SceneObjectPart m_host; - internal uint m_localID; - internal UUID m_itemID; - internal bool m_LSFunctionsEnabled = false; - internal IScriptModuleComms m_comms = null; - - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) - { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_localID = localID; - m_itemID = itemID; - - if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) - m_LSFunctionsEnabled = true; - - if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) - m_LSFunctionsEnabled = true; - - m_comms = m_ScriptEngine.World.RequestModuleInterface(); - if (m_comms == null) - m_LSFunctionsEnabled = false; - } - - public override Object InitializeLifetimeService() - { - ILease lease = (ILease)base.InitializeLifetimeService(); - - if (lease.CurrentState == LeaseState.Initial) - { - lease.InitialLeaseTime = TimeSpan.FromMinutes(0); - // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); - // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); - } - return lease; - } - - public Scene World - { - get { return m_ScriptEngine.World; } - } - - // - //Dumps an error message on the debug console. - // - - internal void LSShoutError(string message) - { - if (message.Length > 1023) - message = message.Substring(0, 1023); - - World.SimChat(Utils.StringToBytes(message), - ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); - - IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); - wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); - } - - /// - /// Get the current Windlight scene - /// - /// List of windlight parameters - public LSL_List lsGetWindlightScene(LSL_List rules) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return new LSL_List(); - } - m_host.AddScriptLPS(1); - RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_List toadd = new LSL_List(); - - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - toadd.Add(new LSL_Float(wl.blurMultiplier)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - toadd.Add(new LSL_Float(wl.cloudCoverage)); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - toadd.Add(new LSL_Float(wl.cloudScale)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - toadd.Add(new LSL_Float(wl.cloudScrollX)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - toadd.Add(new LSL_Float(wl.cloudScrollY)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - toadd.Add(new LSL_Float(wl.densityMultiplier)); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - toadd.Add(new LSL_Float(wl.distanceMultiplier)); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - toadd.Add(new LSL_Float(wl.eastAngle)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - toadd.Add(new LSL_Float(wl.fresnelOffset)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - toadd.Add(new LSL_Float(wl.fresnelScale)); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - toadd.Add(new LSL_Float(wl.hazeDensity)); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - toadd.Add(new LSL_Float(wl.hazeHorizon)); - break; - case (int)ScriptBaseClass.WL_HORIZON: - toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - toadd.Add(new LSL_Integer(wl.maxAltitude)); - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - toadd.Add(new LSL_Float(wl.refractScaleAbove)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - toadd.Add(new LSL_Float(wl.refractScaleBelow)); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - toadd.Add(new LSL_Float(wl.sceneGamma)); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - toadd.Add(new LSL_Float(wl.starBrightness)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - toadd.Add(new LSL_Float(wl.sunGlowFocus)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - toadd.Add(new LSL_Float(wl.sunGlowSize)); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - toadd.Add(new LSL_Float(wl.underwaterFogModifier)); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); - break; - } - - if (toadd.Length > 0) - { - values.Add(rule); - values.Add(toadd.Data[0]); - } - idx++; - } - - - return values; - - } - - private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) - { - RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_Types.Quaternion iQ; - LSL_Types.Vector3 iV; - switch (rule) - { - case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: - idx++; - wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_AMBIENT: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - idx++; - wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - idx++; - wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - idx++; - wl.cloudScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - idx++; - wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - idx++; - wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - idx++; - wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - idx++; - wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - idx++; - wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - idx++; - wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - idx++; - wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - idx++; - wl.eastAngle = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - idx++; - wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - idx++; - wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - idx++; - wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - idx++; - wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HORIZON: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - idx++; - wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - idx++; - wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - idx++; - iV = rules.GetVector3Item(idx); - wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - idx++; - wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - idx++; - wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - idx++; - wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - idx++; - wl.starBrightness = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - idx++; - wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - idx++; - wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - idx++; - wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - idx++; - iV = rules.GetVector3Item(idx); - wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - idx++; - wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); - break; - } - idx++; - } - return wl; - } - /// - /// Set the current Windlight scene - /// - /// - /// success: true or false - public int lsSetWindlightScene(LSL_List rules) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; - } - else - { - LSShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - /// - /// Set the current Windlight scene to a target avatar - /// - /// - /// success: true or false - public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); - success = 1; - } - else - { - LSShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Lifetime; +using OpenMetaverse; +using Nini.Config; +using OpenSim; +using OpenSim.Framework; +using OpenSim.Region.CoreModules.World.LightShare; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.ScriptEngine.Shared; +using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; +using OpenSim.Region.ScriptEngine.Shared.ScriptBase; +using OpenSim.Region.ScriptEngine.Interfaces; +using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; + +using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; +using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; +using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; +using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; +using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; +using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; + +namespace OpenSim.Region.ScriptEngine.Shared.Api +{ + [Serializable] + public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi + { + internal IScriptEngine m_ScriptEngine; + internal SceneObjectPart m_host; + internal uint m_localID; + internal UUID m_itemID; + internal bool m_LSFunctionsEnabled = false; + internal IScriptModuleComms m_comms = null; + + public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) + { + m_ScriptEngine = ScriptEngine; + m_host = host; + m_localID = localID; + m_itemID = itemID; + + if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) + m_LSFunctionsEnabled = true; + + if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) + m_LSFunctionsEnabled = true; + + m_comms = m_ScriptEngine.World.RequestModuleInterface(); + if (m_comms == null) + m_LSFunctionsEnabled = false; + } + + public override Object InitializeLifetimeService() + { + ILease lease = (ILease)base.InitializeLifetimeService(); + + if (lease.CurrentState == LeaseState.Initial) + { + lease.InitialLeaseTime = TimeSpan.FromMinutes(0); + // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); + // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); + } + return lease; + } + + public Scene World + { + get { return m_ScriptEngine.World; } + } + + // + //Dumps an error message on the debug console. + // + + internal void LSShoutError(string message) + { + if (message.Length > 1023) + message = message.Substring(0, 1023); + + World.SimChat(Utils.StringToBytes(message), + ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); + + IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); + wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); + } + + /// + /// Get the current Windlight scene + /// + /// List of windlight parameters + public LSL_List lsGetWindlightScene(LSL_List rules) + { + if (!m_LSFunctionsEnabled) + { + LSShoutError("LightShare functions are not enabled."); + return new LSL_List(); + } + m_host.AddScriptLPS(1); + RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; + + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_List toadd = new LSL_List(); + + switch (rule) + { + case (int)ScriptBaseClass.WL_AMBIENT: + toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + toadd.Add(new LSL_Float(wl.blurMultiplier)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + toadd.Add(new LSL_Float(wl.cloudCoverage)); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + toadd.Add(new LSL_Float(wl.cloudScale)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + toadd.Add(new LSL_Float(wl.cloudScrollX)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + toadd.Add(new LSL_Float(wl.cloudScrollY)); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + toadd.Add(new LSL_Float(wl.densityMultiplier)); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + toadd.Add(new LSL_Float(wl.distanceMultiplier)); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + toadd.Add(new LSL_Float(wl.eastAngle)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + toadd.Add(new LSL_Float(wl.fresnelOffset)); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + toadd.Add(new LSL_Float(wl.fresnelScale)); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + toadd.Add(new LSL_Float(wl.hazeDensity)); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + toadd.Add(new LSL_Float(wl.hazeHorizon)); + break; + case (int)ScriptBaseClass.WL_HORIZON: + toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + toadd.Add(new LSL_Integer(wl.maxAltitude)); + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + toadd.Add(new LSL_Float(wl.refractScaleAbove)); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + toadd.Add(new LSL_Float(wl.refractScaleBelow)); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + toadd.Add(new LSL_Float(wl.sceneGamma)); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + toadd.Add(new LSL_Float(wl.starBrightness)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + toadd.Add(new LSL_Float(wl.sunGlowFocus)); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + toadd.Add(new LSL_Float(wl.sunGlowSize)); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + toadd.Add(new LSL_Float(wl.underwaterFogModifier)); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); + break; + } + + if (toadd.Length > 0) + { + values.Add(new LSL_Integer(rule)); + values.Add(toadd.Data[0]); + } + idx++; + } + + + return values; + + } + + private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) + { + RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); + + LSL_List values = new LSL_List(); + int idx = 0; + while (idx < rules.Length) + { + uint rule = (uint)rules.GetLSLIntegerItem(idx); + LSL_Types.Quaternion iQ; + LSL_Types.Vector3 iV; + switch (rule) + { + case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: + idx++; + wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_AMBIENT: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_BLUE_DENSITY: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: + idx++; + wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: + idx++; + wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCALE: + idx++; + wl.cloudScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: + idx++; + wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: + idx++; + wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: + idx++; + wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: + idx++; + wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: + idx++; + iV = rules.GetVector3Item(idx); + wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: + idx++; + wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: + idx++; + wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: + idx++; + wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; + break; + case (int)ScriptBaseClass.WL_EAST_ANGLE: + idx++; + wl.eastAngle = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: + idx++; + wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_FRESNEL_SCALE: + idx++; + wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_DENSITY: + idx++; + wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HAZE_HORIZON: + idx++; + wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_HORIZON: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: + idx++; + iV = rules.GetVector3Item(idx); + wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); + break; + case (int)ScriptBaseClass.WL_MAX_ALTITUDE: + idx++; + wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; + break; + case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: + idx++; + wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); + break; + case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: + idx++; + iV = rules.GetVector3Item(idx); + wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: + idx++; + wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: + idx++; + wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SCENE_GAMMA: + idx++; + wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: + idx++; + wl.starBrightness = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: + idx++; + wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: + idx++; + wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: + idx++; + iQ = rules.GetQuaternionItem(idx); + wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); + break; + case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: + idx++; + wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); + break; + case (int)ScriptBaseClass.WL_WATER_COLOR: + idx++; + iV = rules.GetVector3Item(idx); + wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); + break; + case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: + idx++; + wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); + break; + } + idx++; + } + return wl; + } + /// + /// Set the current Windlight scene + /// + /// + /// success: true or false + public int lsSetWindlightScene(LSL_List rules) + { + if (!m_LSFunctionsEnabled) + { + LSShoutError("LightShare functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (LightShareModule.EnableWindlight) + { + RegionLightShareData wl = getWindlightProfileFromRules(rules); + m_host.ParentGroup.Scene.StoreWindlightProfile(wl); + success = 1; + } + else + { + LSShoutError("Windlight module is disabled"); + return 0; + } + return success; + } + /// + /// Set the current Windlight scene to a target avatar + /// + /// + /// success: true or false + public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) + { + if (!m_LSFunctionsEnabled) + { + LSShoutError("LightShare functions are not enabled."); + return 0; + } + if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) + { + LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); + return 0; + } + int success = 0; + m_host.AddScriptLPS(1); + if (LightShareModule.EnableWindlight) + { + RegionLightShareData wl = getWindlightProfileFromRules(rules); + World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); + success = 1; + } + else + { + LSShoutError("Windlight module is disabled"); + return 0; + } + return success; + } + + } +} -- cgit v1.1 From 19ab4c950880beb3ac88a172b775c3973782ec3d Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 16:52:03 -0700 Subject: Fix a rather nasty issue where the Backup() process causes objects and avatars sitting on them to be pushed to the corner of the sim. --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 199 +++++++++++---------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 25 +-- 2 files changed, 120 insertions(+), 104 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a828127..0d15cb4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -317,8 +317,8 @@ namespace OpenSim.Region.Framework.Scenes private bool m_scriptListens_notAtTarget = false; private bool m_scriptListens_atRotTarget = false; - private bool m_scriptListens_notAtRotTarget = false; - + private bool m_scriptListens_notAtRotTarget = false; + public bool m_dupeInProgress = false; internal Dictionary m_savedScriptState = null; #region Properties @@ -475,16 +475,21 @@ namespace OpenSim.Region.Framework.Scenes { part.IgnoreUndoUpdate = false; part.StoreUndoState(UndoType.STATE_GROUP_POSITION); - part.GroupPosition = val; - part.TriggerScriptChangedEvent(Changed.POSITION); - } - - foreach (ScenePresence av in m_linkedAvatars) - { - Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; - av.AbsolutePosition += offset; - av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition - av.SendFullUpdateToAllClients(); + part.GroupPosition = val; + if (!m_dupeInProgress) + { + part.TriggerScriptChangedEvent(Changed.POSITION); + } + } + if (!m_dupeInProgress) + { + foreach (ScenePresence av in m_linkedAvatars) + { + Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; + av.AbsolutePosition += offset; + av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition + av.SendFullUpdateToAllClients(); + } } //if (m_rootPart.PhysActor != null) @@ -1800,88 +1805,96 @@ namespace OpenSim.Region.Framework.Scenes /// True if the duplicate will immediately be in the scene, false otherwise /// public SceneObjectGroup Copy(bool userExposed) - { - SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); - dupe.m_isBackedUp = false; - dupe.m_parts = new Dictionary(); - - // Warning, The following code related to previousAttachmentStatus is needed so that clones of - // attachments do not bordercross while they're being duplicated. This is hacktastic! - // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! - // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state - // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, - // then restore it's attachment state - - // This is only necessary when userExposed is false! - - bool previousAttachmentStatus = dupe.RootPart.IsAttachment; - - if (!userExposed) - dupe.RootPart.IsAttachment = true; - - dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); - - if (!userExposed) - { - dupe.RootPart.IsAttachment = previousAttachmentStatus; - } - - dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); - dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; - - if (userExposed) - dupe.m_rootPart.TrimPermissions(); - - /// may need to create a new Physics actor. - if (dupe.RootPart.PhysActor != null && userExposed) - { - PrimitiveBaseShape pbs = dupe.RootPart.Shape; - - dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - dupe.RootPart.Name, - pbs, - dupe.RootPart.AbsolutePosition, - dupe.RootPart.Scale, - dupe.RootPart.RotationOffset, - dupe.RootPart.PhysActor.IsPhysical); - - dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; - dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); + { + SceneObjectGroup dupe; + try + { + m_dupeInProgress = true; + dupe = (SceneObjectGroup)MemberwiseClone(); + dupe.m_isBackedUp = false; + dupe.m_parts = new Dictionary(); + + // Warning, The following code related to previousAttachmentStatus is needed so that clones of + // attachments do not bordercross while they're being duplicated. This is hacktastic! + // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! + // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state + // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, + // then restore it's attachment state + + // This is only necessary when userExposed is false! + + bool previousAttachmentStatus = dupe.RootPart.IsAttachment; + + if (!userExposed) + dupe.RootPart.IsAttachment = true; + + dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + + if (!userExposed) + { + dupe.RootPart.IsAttachment = previousAttachmentStatus; + } + + dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); + dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; + + if (userExposed) + dupe.m_rootPart.TrimPermissions(); + + /// may need to create a new Physics actor. + if (dupe.RootPart.PhysActor != null && userExposed) + { + PrimitiveBaseShape pbs = dupe.RootPart.Shape; + + dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( + dupe.RootPart.Name, + pbs, + dupe.RootPart.AbsolutePosition, + dupe.RootPart.Scale, + dupe.RootPart.RotationOffset, + dupe.RootPart.PhysActor.IsPhysical); + + dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); + } + + List partList; + + lockPartsForRead(true); + + partList = new List(m_parts.Values); + + lockPartsForRead(false); + + partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) + { + return p1.LinkNum.CompareTo(p2.LinkNum); + } + ); + + foreach (SceneObjectPart part in partList) + { + if (part.UUID != m_rootPart.UUID) + { + SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); + + newPart.LinkNum = part.LinkNum; + } + } + + if (userExposed) + { + dupe.UpdateParentIDs(); + dupe.HasGroupChanged = true; + dupe.AttachToBackup(); + + ScheduleGroupForFullUpdate(); + } + } + finally + { + m_dupeInProgress = false; } - - List partList; - - lockPartsForRead(true); - - partList = new List(m_parts.Values); - - lockPartsForRead(false); - - partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) - { - return p1.LinkNum.CompareTo(p2.LinkNum); - } - ); - - foreach (SceneObjectPart part in partList) - { - if (part.UUID != m_rootPart.UUID) - { - SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); - - newPart.LinkNum = part.LinkNum; - } - } - - if (userExposed) - { - dupe.UpdateParentIDs(); - dupe.HasGroupChanged = true; - dupe.AttachToBackup(); - - ScheduleGroupForFullUpdate(); - } - return dupe; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index b0ce450..77581af 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -718,17 +718,20 @@ namespace OpenSim.Region.Framework.Scenes // Tell the physics engines that this prim changed. m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); - } - - List avs = ParentGroup.GetLinkedAvatars(); - foreach (ScenePresence av in avs) - { - if (av.LinkedPrim == m_uuid) - { - Vector3 offset = (m_offsetPosition - oldpos); - av.OffsetPosition += offset; - av.SendFullUpdateToAllClients(); - } + } + + if (!m_parentGroup.m_dupeInProgress) + { + List avs = ParentGroup.GetLinkedAvatars(); + foreach (ScenePresence av in avs) + { + if (av.LinkedPrim == m_uuid) + { + Vector3 offset = (m_offsetPosition - oldpos); + av.OffsetPosition += offset; + av.SendFullUpdateToAllClients(); + } + } } } TriggerScriptChangedEvent(Changed.POSITION); -- cgit v1.1 From 50ac61e17f4e164931dc26f01ffbe58dced9e772 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 8 Aug 2010 02:01:24 +0200 Subject: In my crusade against facelights, I am striking the killing blow. Add a DisableFacelights option to OpenSim.ini to finally kill those immersion- breaking, silly vanity lights that destroy nighttime RP. Girls, you look just fine without them. Guys, you too. Thank you. Melanie has left the building. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 16 ++++++++++++++++ OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 4 ++++ 2 files changed, 20 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index af2dd85..a0e5521 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -315,6 +315,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_cachedTextureSerial; private PriorityQueue m_entityUpdates; private Prioritizer m_prioritizer; + private bool m_disableFacelights = false; /// /// List used in construction of data blocks for an object update packet. This is to stop us having to @@ -420,6 +421,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP set { m_IsLoggingOut = value; } } + public bool DisableFacelights + { + get { return m_disableFacelights; } + set { m_disableFacelights = value; } + } + public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } } #endregion Properties @@ -3522,6 +3529,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP SceneObjectPart part = (SceneObjectPart)update.Entity; if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId)) continue; + + if (part.ParentGroup.IsAttachment && m_disableFacelights) + { + if (part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.LeftHand && + part.ParentGroup.RootPart.Shape.State != (byte)AttachmentPoint.RightHand) + { + part.Shape.LightEntry = false; + } + } } ++updatesThisCall; diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 3b63bcd..bbbf0be 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -153,6 +153,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_defaultRTO = 0; private int m_maxRTO = 0; + private bool m_disableFacelights = false; + public Socket Server { get { return null; } } public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) @@ -190,6 +192,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_defaultRTO = config.GetInt("DefaultRTO", 0); m_maxRTO = config.GetInt("MaxRTO", 0); + m_disableFacelights = config.GetBoolean("DisableFacelights", false); } else { @@ -907,6 +910,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP //this will prevent us from missing important messages //before the modules are bound client.DeliverPackets = false; + client.DisableFacelights = m_disableFacelights; Util.FireAndForget( delegate -- cgit v1.1 From acb1590cf063769802f35c99dd5fb6398172296f Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 17:32:36 -0700 Subject: Fix the unscripted sit rotation being incorrect (relative to the prim). Note that unscripted sit offset is still really poor but this is not something i'm prepared to spend time on fixing. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 56e7e93..5191236 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2053,9 +2053,13 @@ namespace OpenSim.Region.Framework.Scenes //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child - ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + Quaternion roffset = Quaternion.Identity; + if (SitTargetisSet) + { + roffset = part.RotationOffset; + } + ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * roffset) + part.OffsetPosition), sitOrientation / part.RotationOffset, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); - m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target // This calls HandleAgentSit twice, once from here, and the client calls // HandleAgentSit itself after it gets to the location // It doesn't get to the location until we've moved them there though @@ -2441,7 +2445,7 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos); } m_linkedPrim = part.UUID; - + m_offsetRotation = m_offsetRotation / part.RotationOffset; Velocity = Vector3.Zero; RemoveFromPhysicalScene(); Animator.TrySetMovementAnimation(sitAnimation); -- cgit v1.1 From b771965f287af0cb5d46e4f652e9912dfaa40682 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 17:33:27 -0700 Subject: Get rid of some debug chatter that someone who can't spell left behind. ;) --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 5191236..6f92a41 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2378,8 +2378,7 @@ namespace OpenSim.Region.Framework.Scenes m_bodyRot = sitTargetOrient; m_parentPosition = part.AbsolutePosition; part.IsOccupied = true; - part.ParentGroup.AddAvatar(agentID); -Console.WriteLine("Scripted Sit ofset {0}", m_pos); + part.ParentGroup.AddAvatar(agentID); } else { -- cgit v1.1 From aa54e8d95eb920869da5c885fc536cfb1ffca90b Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 17:35:16 -0700 Subject: Increase sit distance to 256 meters, but leave the initial autopilot process in the picture so sit position can still be raycast by the existing code. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 6f92a41..cca296e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2007,7 +2007,7 @@ namespace OpenSim.Region.Framework.Scenes if (autopilot) { // its not a scripted sit // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) - if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 10.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 10.0f) ) + if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) ) { autopilot = false; // close enough m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. -- cgit v1.1 From 0794c6a941c9c98be32c05cd372ce53773a6e32f Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 20:13:45 -0700 Subject: Implement parcel group access control. This addresses mantis #158. --- .../Region/CoreModules/World/Land/LandObject.cs | 2058 ++++++++++---------- 1 file changed, 1045 insertions(+), 1013 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index 6864629..fcd993c 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -1,1013 +1,1045 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -namespace OpenSim.Region.CoreModules.World.Land -{ - /// - /// Keeps track of a specific piece of land's information - /// - public class LandObject : ILandObject - { - #region Member Variables - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - #pragma warning disable 0429 - private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; - #pragma warning restore 0429 - private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; - - private int m_lastSeqId = 0; - - protected LandData m_landData = new LandData(); - protected Scene m_scene; - protected List primsOverMe = new List(); - - public bool[,] LandBitmap - { - get { return m_landBitmap; } - set { m_landBitmap = value; } - } - - #endregion - - #region ILandObject Members - - public LandData LandData - { - get { return m_landData; } - - set { m_landData = value; } - } - - public UUID RegionUUID - { - get { return m_scene.RegionInfo.RegionID; } - } - - #region Constructors - - public LandObject(UUID owner_id, bool is_group_owned, Scene scene) - { - m_scene = scene; - LandData.OwnerID = owner_id; - if (is_group_owned) - LandData.GroupID = owner_id; - else - LandData.GroupID = UUID.Zero; - LandData.IsGroupOwned = is_group_owned; - } - - #endregion - - #region Member Functions - - #region General Functions - - /// - /// Checks to see if this land object contains a point - /// - /// - /// - /// Returns true if the piece of land contains the specified point - public bool ContainsPoint(int x, int y) - { - if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) - { - return (LandBitmap[x / 4, y / 4] == true); - } - else - { - return false; - } - } - - public ILandObject Copy() - { - ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); - - //Place all new variables here! - newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); - newLand.LandData = LandData.Copy(); - - return newLand; - } - - static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; - static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; - - public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) - { - overrideParcelMaxPrimCount = overrideDel; - } - public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) - { - overrideSimulatorMaxPrimCount = overrideDel; - } - - public int GetParcelMaxPrimCount(ILandObject thisObject) - { - if (overrideParcelMaxPrimCount != null) - { - return overrideParcelMaxPrimCount(thisObject); - } - else - { - // Normal Calculations - return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); - } - } - public int GetSimulatorMaxPrimCount(ILandObject thisObject) - { - if (overrideSimulatorMaxPrimCount != null) - { - return overrideSimulatorMaxPrimCount(thisObject); - } - else - { - //Normal Calculations - return m_scene.RegionInfo.ObjectCapacity; - } - } - #endregion - - #region Packet Request Handling - - public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) - { - IEstateModule estateModule = m_scene.RequestModuleInterface(); - uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); - if (estateModule != null) - regionFlags = estateModule.GetRegionFlags(); - - // In a perfect world, this would have worked. - // -// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) -// regionFlags |= (uint)RegionFlags.AllowLandmark; -// if (landData.OwnerID == remote_client.AgentId) -// regionFlags |= (uint)RegionFlags.AllowSetHome; - - int seq_id; - if (snap_selection && (sequence_id == 0)) - { - seq_id = m_lastSeqId; - } - else - { - seq_id = sequence_id; - m_lastSeqId = seq_id; - } - - remote_client.SendLandProperties(seq_id, - snap_selection, request_result, LandData, - (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, - GetParcelMaxPrimCount(this), - GetSimulatorMaxPrimCount(this), regionFlags); - } - - public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) - { - //Needs later group support - bool snap_selection = false; - LandData newData = LandData.Copy(); - - if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) - { - if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) - { - newData.AuthBuyerID = args.AuthBuyerID; - newData.SalePrice = args.SalePrice; - snap_selection = true; - } - } - newData.Category = args.Category; - newData.Description = args.Desc; - newData.GroupID = args.GroupID; - newData.LandingType = args.LandingType; - newData.MediaAutoScale = args.MediaAutoScale; - newData.MediaID = args.MediaID; - newData.MediaURL = args.MediaURL; - newData.MusicURL = args.MusicURL; - newData.Name = args.Name; - newData.Flags = args.ParcelFlags; - newData.PassHours = args.PassHours; - newData.PassPrice = args.PassPrice; - newData.SnapshotID = args.SnapshotID; - newData.UserLocation = args.UserLocation; - newData.UserLookAt = args.UserLookAt; - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(snap_selection); - } - } - - public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) - { - LandData newData = LandData.Copy(); - newData.OwnerID = avatarID; - newData.GroupID = groupID; - newData.IsGroupOwned = groupOwned; - //newData.auctionID = AuctionID; - newData.ClaimDate = Util.UnixTimeSinceEpoch(); - newData.ClaimPrice = claimprice; - newData.SalePrice = 0; - newData.AuthBuyerID = UUID.Zero; - newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(true); - } - - public void DeedToGroup(UUID groupID) - { - LandData newData = LandData.Copy(); - newData.OwnerID = groupID; - newData.GroupID = groupID; - newData.IsGroupOwned = true; - - // Reset show in directory flag on deed - newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(true); - } - - public bool IsEitherBannedOrRestricted(UUID avatar) - { - if (IsBannedFromLand(avatar)) - { - return true; - } - else if (IsRestrictedFromLand(avatar)) - { - return true; - } - return false; - } - - public bool IsBannedFromLand(UUID avatar) - { - if (m_scene.Permissions.IsAdministrator(avatar)) - return false; - - if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Ban; - entry.Time = new DateTime(); - //See if they are on the list, but make sure the owner isn't banned - if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) - { - //They are banned, so lets send them a notice about this parcel - return true; - } - } - return false; - } - - public bool IsRestrictedFromLand(UUID avatar) - { - if (m_scene.Permissions.IsAdministrator(avatar)) - return false; - - if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Access; - entry.Time = new DateTime(); - - //If they are not on the access list and are not the owner - if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) - { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel - return true; - } - } - return false; - } - - public void SendLandUpdateToClient(IClientAPI remote_client) - { - SendLandProperties(0, false, 0, remote_client); - } - - public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) - { - SendLandProperties(0, snap_selection, 0, remote_client); - } - - public void SendLandUpdateToAvatarsOverMe() - { - SendLandUpdateToAvatarsOverMe(false); - } - - public void SendLandUpdateToAvatarsOverMe(bool snap_selection) - { - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - if (avatar.IsChildAgent) - return; - - ILandObject over = null; - try - { - over = - m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), - Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); - } - catch (Exception) - { - m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + - Math.Round(avatar.AbsolutePosition.Y)); - } - - if (over != null) - { - if (over.LandData.LocalID == LandData.LocalID) - { - if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && - m_scene.RegionInfo.RegionSettings.AllowDamage) - avatar.Invulnerable = false; - else - avatar.Invulnerable = true; - - SendLandUpdateToClient(snap_selection, avatar.ControllingClient); - } - } - }); - } - - #endregion - - #region AccessList Functions - - public List CreateAccessListArrayByFlag(AccessList flag) - { - List list = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) - { - if (entry.Flags == flag) - { - list.Add(entry.AgentID); - } - } - if (list.Count == 0) - { - list.Add(UUID.Zero); - } - - return list; - } - - public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, - IClientAPI remote_client) - { - - if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) - { - List avatars = CreateAccessListArrayByFlag(AccessList.Access); - remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); - } - - if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) - { - List avatars = CreateAccessListArrayByFlag(AccessList.Ban); - remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); - } - } - - public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) - { - LandData newData = LandData.Copy(); - - if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) - { - entries.Clear(); - } - - List toRemove = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) - { - if (entry.Flags == (AccessList)flags) - { - toRemove.Add(entry); - } - } - - foreach (ParcelManager.ParcelAccessEntry entry in toRemove) - { - newData.ParcelAccessList.Remove(entry); - } - foreach (ParcelManager.ParcelAccessEntry entry in entries) - { - ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); - temp.AgentID = entry.AgentID; - temp.Time = new DateTime(); //Pointless? Yes. - temp.Flags = (AccessList)flags; - - if (!newData.ParcelAccessList.Contains(temp)) - { - newData.ParcelAccessList.Add(temp); - } - } - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - } - - #endregion - - #region Update Functions - - public void UpdateLandBitmapByteArray() - { - LandData.Bitmap = ConvertLandBitmapToBytes(); - } - - /// - /// Update all settings in land such as area, bitmap byte array, etc - /// - public void ForceUpdateLandInfo() - { - UpdateAABBAndAreaValues(); - UpdateLandBitmapByteArray(); - } - - public void SetLandBitmapFromByteArray() - { - LandBitmap = ConvertBytesToLandBitmap(); - } - - /// - /// Updates the AABBMin and AABBMax values after area/shape modification of the land object - /// - private void UpdateAABBAndAreaValues() - { - int min_x = 64; - int min_y = 64; - int max_x = 0; - int max_y = 0; - int tempArea = 0; - int x, y; - for (x = 0; x < 64; x++) - { - for (y = 0; y < 64; y++) - { - if (LandBitmap[x, y] == true) - { - if (min_x > x) min_x = x; - if (min_y > y) min_y = y; - if (max_x < x) max_x = x; - if (max_y < y) max_y = y; - tempArea += 16; //16sqm peice of land - } - } - } - int tx = min_x * 4; - if (tx > ((int)Constants.RegionSize - 1)) - tx = ((int)Constants.RegionSize - 1); - int ty = min_y * 4; - if (ty > ((int)Constants.RegionSize - 1)) - ty = ((int)Constants.RegionSize - 1); - LandData.AABBMin = - new Vector3((float) (min_x * 4), (float) (min_y * 4), - (float) m_scene.Heightmap[tx, ty]); - - tx = max_x * 4; - if (tx > ((int)Constants.RegionSize - 1)) - tx = ((int)Constants.RegionSize - 1); - ty = max_y * 4; - if (ty > ((int)Constants.RegionSize - 1)) - ty = ((int)Constants.RegionSize - 1); - LandData.AABBMax = - new Vector3((float) (max_x * 4), (float) (max_y * 4), - (float) m_scene.Heightmap[tx, ty]); - LandData.Area = tempArea; - } - - #endregion - - #region Land Bitmap Functions - - /// - /// Sets the land's bitmap manually - /// - /// 64x64 block representing where this land is on a map - public void SetLandBitmap(bool[,] bitmap) - { - if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - //throw new Exception("Error: Invalid Parcel Bitmap"); - } - else - { - //Valid: Lets set it - LandBitmap = bitmap; - ForceUpdateLandInfo(); - } - } - - /// - /// Gets the land's bitmap manually - /// - /// - public bool[,] GetLandBitmap() - { - return LandBitmap; - } - - /// - /// Full sim land object creation - /// - /// - public bool[,] BasicFullRegionLandBitmap() - { - return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); - } - - /// - /// Used to modify the bitmap between the x and y points. Points use 64 scale - /// - /// - /// - /// - /// - /// - public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) - { - bool[,] tempBitmap = new bool[64,64]; - tempBitmap.Initialize(); - - tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); - return tempBitmap; - } - - /// - /// Change a land bitmap at within a square and set those points to a specific value - /// - /// - /// - /// - /// - /// - /// - /// - public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, - bool set_value) - { - if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); - } - - int x, y; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - if (x >= start_x / 4 && x < end_x / 4 - && y >= start_y / 4 && y < end_y / 4) - { - land_bitmap[x, y] = set_value; - } - } - } - return land_bitmap; - } - - /// - /// Join the true values of 2 bitmaps together - /// - /// - /// - /// - public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) - { - if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); - } - if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); - } - - int x, y; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - if (bitmap_add[x, y]) - { - bitmap_base[x, y] = true; - } - } - } - return bitmap_base; - } - - /// - /// Converts the land bitmap to a packet friendly byte array - /// - /// - private byte[] ConvertLandBitmapToBytes() - { - byte[] tempConvertArr = new byte[512]; - byte tempByte = 0; - int x, y, i, byteNum = 0; - i = 0; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); - if (i % 8 == 0) - { - tempConvertArr[byteNum] = tempByte; - tempByte = (byte) 0; - i = 0; - byteNum++; - } - } - } - return tempConvertArr; - } - - private bool[,] ConvertBytesToLandBitmap() - { - bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; - tempConvertMap.Initialize(); - byte tempByte = 0; - int x = 0, y = 0, i = 0, bitNum = 0; - for (i = 0; i < 512; i++) - { - tempByte = LandData.Bitmap[i]; - for (bitNum = 0; bitNum < 8; bitNum++) - { - bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); - tempConvertMap[x, y] = bit; - x++; - if (x > 63) - { - x = 0; - y++; - } - } - } - return tempConvertMap; - } - - #endregion - - #region Object Select and Object Owner Listing - - public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) - { - List resultLocalIDs = new List(); - try - { - lock (primsOverMe) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.LocalId > 0) - { - if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && - obj.OwnerID != remote_client.AgentId) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) - { - resultLocalIDs.Add(obj.LocalId); - } - } - } - } - } catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); - } - - remote_client.SendForceClientSelectObjects(resultLocalIDs); - } - } - - /// - /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes - /// aggreagete details such as the number of prims. - /// - /// - /// - /// A - /// - public void SendLandObjectOwners(IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) - { - Dictionary primCount = new Dictionary(); - List groups = new List(); - - lock (primsOverMe) - { - try - { - - foreach (SceneObjectGroup obj in primsOverMe) - { - try - { - if (!primCount.ContainsKey(obj.OwnerID)) - { - primCount.Add(obj.OwnerID, 0); - } - } - catch (NullReferenceException) - { - m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); - } - try - { - primCount[obj.OwnerID] += obj.PrimCount; - } - catch (KeyNotFoundException) - { - m_log.Error("[LAND]: Unable to match a prim with it's owner."); - } - if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) - groups.Add(obj.OwnerID); - } - } - catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to Enumerate Land object arr."); - } - } - - remote_client.SendLandObjectOwners(LandData, groups, primCount); - } - } - - public Dictionary GetLandObjectOwners() - { - Dictionary ownersAndCount = new Dictionary(); - lock (primsOverMe) - { - try - { - - foreach (SceneObjectGroup obj in primsOverMe) - { - if (!ownersAndCount.ContainsKey(obj.OwnerID)) - { - ownersAndCount.Add(obj.OwnerID, 0); - } - ownersAndCount[obj.OwnerID] += obj.PrimCount; - } - } - catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to enumerate land owners. arr."); - } - - } - return ownersAndCount; - } - - #endregion - - #region Object Returning - - public void ReturnObject(SceneObjectGroup obj) - { - SceneObjectGroup[] objs = new SceneObjectGroup[1]; - objs[0] = obj; - m_scene.returnObjects(objs, obj.OwnerID); - } - - public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) - { - Dictionary> returns = - new Dictionary>(); - - lock (primsOverMe) - { - if (type == (uint)ObjectReturnType.Owner) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.OwnerID == m_landData.OwnerID) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.GroupID == m_landData.GroupID) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.Other) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.OwnerID != m_landData.OwnerID && - (obj.GroupID != m_landData.GroupID || - m_landData.GroupID == UUID.Zero)) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.List) - { - List ownerlist = new List(owners); - - foreach (SceneObjectGroup obj in primsOverMe) - { - if (ownerlist.Contains(obj.OwnerID)) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - } - - foreach (List ol in returns.Values) - { - if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) - m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); - } - } - - #endregion - - #region Object Adding/Removing from Parcel - - public void ResetLandPrimCounts() - { - LandData.GroupPrims = 0; - LandData.OwnerPrims = 0; - LandData.OtherPrims = 0; - LandData.SelectedPrims = 0; - - - lock (primsOverMe) - primsOverMe.Clear(); - } - - public void AddPrimToCount(SceneObjectGroup obj) - { - - UUID prim_owner = obj.OwnerID; - int prim_count = obj.PrimCount; - - if (obj.IsSelected) - { - LandData.SelectedPrims += prim_count; - } - else - { - if (prim_owner == LandData.OwnerID) - { - LandData.OwnerPrims += prim_count; - } - else if ((obj.GroupID == LandData.GroupID || - prim_owner == LandData.GroupID) && - LandData.GroupID != UUID.Zero) - { - LandData.GroupPrims += prim_count; - } - else - { - LandData.OtherPrims += prim_count; - } - } - - lock (primsOverMe) - primsOverMe.Add(obj); - } - - public void RemovePrimFromCount(SceneObjectGroup obj) - { - lock (primsOverMe) - { - if (primsOverMe.Contains(obj)) - { - UUID prim_owner = obj.OwnerID; - int prim_count = obj.PrimCount; - - if (prim_owner == LandData.OwnerID) - { - LandData.OwnerPrims -= prim_count; - } - else if (obj.GroupID == LandData.GroupID || - prim_owner == LandData.GroupID) - { - LandData.GroupPrims -= prim_count; - } - else - { - LandData.OtherPrims -= prim_count; - } - - primsOverMe.Remove(obj); - } - } - } - - #endregion - - #endregion - - #endregion - - /// - /// Set the media url for this land parcel - /// - /// - public void SetMediaUrl(string url) - { - LandData.MediaURL = url; - SendLandUpdateToAvatarsOverMe(); - } - - /// - /// Set the music url for this land parcel - /// - /// - public void SetMusicUrl(string url) - { - LandData.MusicURL = url; - SendLandUpdateToAvatarsOverMe(); - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.World.Land +{ + /// + /// Keeps track of a specific piece of land's information + /// + public class LandObject : ILandObject + { + #region Member Variables + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + #pragma warning disable 0429 + private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; + #pragma warning restore 0429 + private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; + + private int m_lastSeqId = 0; + + protected LandData m_landData = new LandData(); + protected Scene m_scene; + protected List primsOverMe = new List(); + + public bool[,] LandBitmap + { + get { return m_landBitmap; } + set { m_landBitmap = value; } + } + + #endregion + + #region ILandObject Members + + public LandData LandData + { + get { return m_landData; } + + set { m_landData = value; } + } + + public UUID RegionUUID + { + get { return m_scene.RegionInfo.RegionID; } + } + + #region Constructors + + public LandObject(UUID owner_id, bool is_group_owned, Scene scene) + { + m_scene = scene; + LandData.OwnerID = owner_id; + if (is_group_owned) + LandData.GroupID = owner_id; + else + LandData.GroupID = UUID.Zero; + LandData.IsGroupOwned = is_group_owned; + } + + #endregion + + #region Member Functions + + #region General Functions + + /// + /// Checks to see if this land object contains a point + /// + /// + /// + /// Returns true if the piece of land contains the specified point + public bool ContainsPoint(int x, int y) + { + if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) + { + return (LandBitmap[x / 4, y / 4] == true); + } + else + { + return false; + } + } + + public ILandObject Copy() + { + ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); + + //Place all new variables here! + newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); + newLand.LandData = LandData.Copy(); + + return newLand; + } + + static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; + static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; + + public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) + { + overrideParcelMaxPrimCount = overrideDel; + } + public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) + { + overrideSimulatorMaxPrimCount = overrideDel; + } + + public int GetParcelMaxPrimCount(ILandObject thisObject) + { + if (overrideParcelMaxPrimCount != null) + { + return overrideParcelMaxPrimCount(thisObject); + } + else + { + // Normal Calculations + return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); + } + } + public int GetSimulatorMaxPrimCount(ILandObject thisObject) + { + if (overrideSimulatorMaxPrimCount != null) + { + return overrideSimulatorMaxPrimCount(thisObject); + } + else + { + //Normal Calculations + return m_scene.RegionInfo.ObjectCapacity; + } + } + #endregion + + #region Packet Request Handling + + public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) + { + IEstateModule estateModule = m_scene.RequestModuleInterface(); + uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); + if (estateModule != null) + regionFlags = estateModule.GetRegionFlags(); + + // In a perfect world, this would have worked. + // +// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) +// regionFlags |= (uint)RegionFlags.AllowLandmark; +// if (landData.OwnerID == remote_client.AgentId) +// regionFlags |= (uint)RegionFlags.AllowSetHome; + + int seq_id; + if (snap_selection && (sequence_id == 0)) + { + seq_id = m_lastSeqId; + } + else + { + seq_id = sequence_id; + m_lastSeqId = seq_id; + } + + remote_client.SendLandProperties(seq_id, + snap_selection, request_result, LandData, + (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, + GetParcelMaxPrimCount(this), + GetSimulatorMaxPrimCount(this), regionFlags); + } + + public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) + { + //Needs later group support + bool snap_selection = false; + LandData newData = LandData.Copy(); + + if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) + { + if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) + { + newData.AuthBuyerID = args.AuthBuyerID; + newData.SalePrice = args.SalePrice; + snap_selection = true; + } + } + newData.Category = args.Category; + newData.Description = args.Desc; + newData.GroupID = args.GroupID; + newData.LandingType = args.LandingType; + newData.MediaAutoScale = args.MediaAutoScale; + newData.MediaID = args.MediaID; + newData.MediaURL = args.MediaURL; + newData.MusicURL = args.MusicURL; + newData.Name = args.Name; + newData.Flags = args.ParcelFlags; + newData.PassHours = args.PassHours; + newData.PassPrice = args.PassPrice; + newData.SnapshotID = args.SnapshotID; + newData.UserLocation = args.UserLocation; + newData.UserLookAt = args.UserLookAt; + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(snap_selection); + } + } + + public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) + { + LandData newData = LandData.Copy(); + newData.OwnerID = avatarID; + newData.GroupID = groupID; + newData.IsGroupOwned = groupOwned; + //newData.auctionID = AuctionID; + newData.ClaimDate = Util.UnixTimeSinceEpoch(); + newData.ClaimPrice = claimprice; + newData.SalePrice = 0; + newData.AuthBuyerID = UUID.Zero; + newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(true); + } + + public void DeedToGroup(UUID groupID) + { + LandData newData = LandData.Copy(); + newData.OwnerID = groupID; + newData.GroupID = groupID; + newData.IsGroupOwned = true; + + // Reset show in directory flag on deed + newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(true); + } + + public bool IsEitherBannedOrRestricted(UUID avatar) + { + if (IsBannedFromLand(avatar)) + { + return true; + } + else if (IsRestrictedFromLand(avatar)) + { + return true; + } + return false; + } + + public bool HasGroupAccess(UUID avatar) + { + if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) + { + IGroupsModule groupsModule = + m_scene.RequestModuleInterface(); + + List agentGroups = new List(); + if (groupsModule != null) + { + GroupMembershipData[] GroupMembership = + groupsModule.GetMembershipData(avatar); + + if (GroupMembership != null) + { + for (int i = 0; i < GroupMembership.Length; i++) + { + if (LandData.GroupID == GroupMembership[i].GroupID) + { + return true; + } + } + } + } + } + return false; + } + + public bool IsBannedFromLand(UUID avatar) + { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + + if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = avatar; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + //See if they are on the list, but make sure the owner isn't banned + if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + { + //They are banned, so lets send them a notice about this parcel + return true; + } + } + return false; + } + + public bool IsRestrictedFromLand(UUID avatar) + { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + + if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = avatar; + entry.Flags = AccessList.Access; + entry.Time = new DateTime(); + + //If they are not on the access list and are not the owner + if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + { + if (!HasGroupAccess(avatar)) + { + //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel + return true; + } + } + } + + return false; + } + + public void SendLandUpdateToClient(IClientAPI remote_client) + { + SendLandProperties(0, false, 0, remote_client); + } + + public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) + { + SendLandProperties(0, snap_selection, 0, remote_client); + } + + public void SendLandUpdateToAvatarsOverMe() + { + SendLandUpdateToAvatarsOverMe(false); + } + + public void SendLandUpdateToAvatarsOverMe(bool snap_selection) + { + m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + if (avatar.IsChildAgent) + return; + + ILandObject over = null; + try + { + over = + m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), + Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); + } + catch (Exception) + { + m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + + Math.Round(avatar.AbsolutePosition.Y)); + } + + if (over != null) + { + if (over.LandData.LocalID == LandData.LocalID) + { + if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && + m_scene.RegionInfo.RegionSettings.AllowDamage) + avatar.Invulnerable = false; + else + avatar.Invulnerable = true; + + SendLandUpdateToClient(snap_selection, avatar.ControllingClient); + } + } + }); + } + + #endregion + + #region AccessList Functions + + public List CreateAccessListArrayByFlag(AccessList flag) + { + List list = new List(); + foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) + { + if (entry.Flags == flag) + { + list.Add(entry.AgentID); + } + } + if (list.Count == 0) + { + list.Add(UUID.Zero); + } + + return list; + } + + public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, + IClientAPI remote_client) + { + + if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) + { + List avatars = CreateAccessListArrayByFlag(AccessList.Access); + remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); + } + + if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) + { + List avatars = CreateAccessListArrayByFlag(AccessList.Ban); + remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); + } + } + + public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) + { + LandData newData = LandData.Copy(); + + if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) + { + entries.Clear(); + } + + List toRemove = new List(); + foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) + { + if (entry.Flags == (AccessList)flags) + { + toRemove.Add(entry); + } + } + + foreach (ParcelManager.ParcelAccessEntry entry in toRemove) + { + newData.ParcelAccessList.Remove(entry); + } + foreach (ParcelManager.ParcelAccessEntry entry in entries) + { + ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); + temp.AgentID = entry.AgentID; + temp.Time = new DateTime(); //Pointless? Yes. + temp.Flags = (AccessList)flags; + + if (!newData.ParcelAccessList.Contains(temp)) + { + newData.ParcelAccessList.Add(temp); + } + } + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + } + + #endregion + + #region Update Functions + + public void UpdateLandBitmapByteArray() + { + LandData.Bitmap = ConvertLandBitmapToBytes(); + } + + /// + /// Update all settings in land such as area, bitmap byte array, etc + /// + public void ForceUpdateLandInfo() + { + UpdateAABBAndAreaValues(); + UpdateLandBitmapByteArray(); + } + + public void SetLandBitmapFromByteArray() + { + LandBitmap = ConvertBytesToLandBitmap(); + } + + /// + /// Updates the AABBMin and AABBMax values after area/shape modification of the land object + /// + private void UpdateAABBAndAreaValues() + { + int min_x = 64; + int min_y = 64; + int max_x = 0; + int max_y = 0; + int tempArea = 0; + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (LandBitmap[x, y] == true) + { + if (min_x > x) min_x = x; + if (min_y > y) min_y = y; + if (max_x < x) max_x = x; + if (max_y < y) max_y = y; + tempArea += 16; //16sqm peice of land + } + } + } + int tx = min_x * 4; + if (tx > ((int)Constants.RegionSize - 1)) + tx = ((int)Constants.RegionSize - 1); + int ty = min_y * 4; + if (ty > ((int)Constants.RegionSize - 1)) + ty = ((int)Constants.RegionSize - 1); + LandData.AABBMin = + new Vector3((float) (min_x * 4), (float) (min_y * 4), + (float) m_scene.Heightmap[tx, ty]); + + tx = max_x * 4; + if (tx > ((int)Constants.RegionSize - 1)) + tx = ((int)Constants.RegionSize - 1); + ty = max_y * 4; + if (ty > ((int)Constants.RegionSize - 1)) + ty = ((int)Constants.RegionSize - 1); + LandData.AABBMax = + new Vector3((float) (max_x * 4), (float) (max_y * 4), + (float) m_scene.Heightmap[tx, ty]); + LandData.Area = tempArea; + } + + #endregion + + #region Land Bitmap Functions + + /// + /// Sets the land's bitmap manually + /// + /// 64x64 block representing where this land is on a map + public void SetLandBitmap(bool[,] bitmap) + { + if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + //throw new Exception("Error: Invalid Parcel Bitmap"); + } + else + { + //Valid: Lets set it + LandBitmap = bitmap; + ForceUpdateLandInfo(); + } + } + + /// + /// Gets the land's bitmap manually + /// + /// + public bool[,] GetLandBitmap() + { + return LandBitmap; + } + + /// + /// Full sim land object creation + /// + /// + public bool[,] BasicFullRegionLandBitmap() + { + return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); + } + + /// + /// Used to modify the bitmap between the x and y points. Points use 64 scale + /// + /// + /// + /// + /// + /// + public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) + { + bool[,] tempBitmap = new bool[64,64]; + tempBitmap.Initialize(); + + tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); + return tempBitmap; + } + + /// + /// Change a land bitmap at within a square and set those points to a specific value + /// + /// + /// + /// + /// + /// + /// + /// + public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, + bool set_value) + { + if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (x >= start_x / 4 && x < end_x / 4 + && y >= start_y / 4 && y < end_y / 4) + { + land_bitmap[x, y] = set_value; + } + } + } + return land_bitmap; + } + + /// + /// Join the true values of 2 bitmaps together + /// + /// + /// + /// + public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) + { + if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); + } + if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (bitmap_add[x, y]) + { + bitmap_base[x, y] = true; + } + } + } + return bitmap_base; + } + + /// + /// Converts the land bitmap to a packet friendly byte array + /// + /// + private byte[] ConvertLandBitmapToBytes() + { + byte[] tempConvertArr = new byte[512]; + byte tempByte = 0; + int x, y, i, byteNum = 0; + i = 0; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); + if (i % 8 == 0) + { + tempConvertArr[byteNum] = tempByte; + tempByte = (byte) 0; + i = 0; + byteNum++; + } + } + } + return tempConvertArr; + } + + private bool[,] ConvertBytesToLandBitmap() + { + bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; + tempConvertMap.Initialize(); + byte tempByte = 0; + int x = 0, y = 0, i = 0, bitNum = 0; + for (i = 0; i < 512; i++) + { + tempByte = LandData.Bitmap[i]; + for (bitNum = 0; bitNum < 8; bitNum++) + { + bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); + tempConvertMap[x, y] = bit; + x++; + if (x > 63) + { + x = 0; + y++; + } + } + } + return tempConvertMap; + } + + #endregion + + #region Object Select and Object Owner Listing + + public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + { + List resultLocalIDs = new List(); + try + { + lock (primsOverMe) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.LocalId > 0) + { + if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && + obj.OwnerID != remote_client.AgentId) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) + { + resultLocalIDs.Add(obj.LocalId); + } + } + } + } + } catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); + } + + remote_client.SendForceClientSelectObjects(resultLocalIDs); + } + } + + /// + /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes + /// aggreagete details such as the number of prims. + /// + /// + /// + /// A + /// + public void SendLandObjectOwners(IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + { + Dictionary primCount = new Dictionary(); + List groups = new List(); + + lock (primsOverMe) + { + try + { + + foreach (SceneObjectGroup obj in primsOverMe) + { + try + { + if (!primCount.ContainsKey(obj.OwnerID)) + { + primCount.Add(obj.OwnerID, 0); + } + } + catch (NullReferenceException) + { + m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); + } + try + { + primCount[obj.OwnerID] += obj.PrimCount; + } + catch (KeyNotFoundException) + { + m_log.Error("[LAND]: Unable to match a prim with it's owner."); + } + if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) + groups.Add(obj.OwnerID); + } + } + catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to Enumerate Land object arr."); + } + } + + remote_client.SendLandObjectOwners(LandData, groups, primCount); + } + } + + public Dictionary GetLandObjectOwners() + { + Dictionary ownersAndCount = new Dictionary(); + lock (primsOverMe) + { + try + { + + foreach (SceneObjectGroup obj in primsOverMe) + { + if (!ownersAndCount.ContainsKey(obj.OwnerID)) + { + ownersAndCount.Add(obj.OwnerID, 0); + } + ownersAndCount[obj.OwnerID] += obj.PrimCount; + } + } + catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to enumerate land owners. arr."); + } + + } + return ownersAndCount; + } + + #endregion + + #region Object Returning + + public void ReturnObject(SceneObjectGroup obj) + { + SceneObjectGroup[] objs = new SceneObjectGroup[1]; + objs[0] = obj; + m_scene.returnObjects(objs, obj.OwnerID); + } + + public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) + { + Dictionary> returns = + new Dictionary>(); + + lock (primsOverMe) + { + if (type == (uint)ObjectReturnType.Owner) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.OwnerID == m_landData.OwnerID) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.GroupID == m_landData.GroupID) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.Other) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.OwnerID != m_landData.OwnerID && + (obj.GroupID != m_landData.GroupID || + m_landData.GroupID == UUID.Zero)) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.List) + { + List ownerlist = new List(owners); + + foreach (SceneObjectGroup obj in primsOverMe) + { + if (ownerlist.Contains(obj.OwnerID)) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + } + + foreach (List ol in returns.Values) + { + if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) + m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); + } + } + + #endregion + + #region Object Adding/Removing from Parcel + + public void ResetLandPrimCounts() + { + LandData.GroupPrims = 0; + LandData.OwnerPrims = 0; + LandData.OtherPrims = 0; + LandData.SelectedPrims = 0; + + + lock (primsOverMe) + primsOverMe.Clear(); + } + + public void AddPrimToCount(SceneObjectGroup obj) + { + + UUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (obj.IsSelected) + { + LandData.SelectedPrims += prim_count; + } + else + { + if (prim_owner == LandData.OwnerID) + { + LandData.OwnerPrims += prim_count; + } + else if ((obj.GroupID == LandData.GroupID || + prim_owner == LandData.GroupID) && + LandData.GroupID != UUID.Zero) + { + LandData.GroupPrims += prim_count; + } + else + { + LandData.OtherPrims += prim_count; + } + } + + lock (primsOverMe) + primsOverMe.Add(obj); + } + + public void RemovePrimFromCount(SceneObjectGroup obj) + { + lock (primsOverMe) + { + if (primsOverMe.Contains(obj)) + { + UUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (prim_owner == LandData.OwnerID) + { + LandData.OwnerPrims -= prim_count; + } + else if (obj.GroupID == LandData.GroupID || + prim_owner == LandData.GroupID) + { + LandData.GroupPrims -= prim_count; + } + else + { + LandData.OtherPrims -= prim_count; + } + + primsOverMe.Remove(obj); + } + } + } + + #endregion + + #endregion + + #endregion + + /// + /// Set the media url for this land parcel + /// + /// + public void SetMediaUrl(string url) + { + LandData.MediaURL = url; + SendLandUpdateToAvatarsOverMe(); + } + + /// + /// Set the music url for this land parcel + /// + /// + public void SetMusicUrl(string url) + { + LandData.MusicURL = url; + SendLandUpdateToAvatarsOverMe(); + } + } +} -- cgit v1.1 From f9b5f23383675abe0ae1c2ed83dd5ccce738d940 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 22:19:26 -0700 Subject: Reverted: * Fix the unscripted sit rotation being incorrect .. will commit a proper fix now. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cca296e..87cf135 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2053,13 +2053,9 @@ namespace OpenSim.Region.Framework.Scenes //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child - Quaternion roffset = Quaternion.Identity; - if (SitTargetisSet) - { - roffset = part.RotationOffset; - } - ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * roffset) + part.OffsetPosition), sitOrientation / part.RotationOffset, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target // This calls HandleAgentSit twice, once from here, and the client calls // HandleAgentSit itself after it gets to the location // It doesn't get to the location until we've moved them there though @@ -2444,7 +2440,7 @@ namespace OpenSim.Region.Framework.Scenes } m_linkedPrim = part.UUID; - m_offsetRotation = m_offsetRotation / part.RotationOffset; + Velocity = Vector3.Zero; RemoveFromPhysicalScene(); Animator.TrySetMovementAnimation(sitAnimation); -- cgit v1.1 From a1f2be5e69ef04a8520229e161bdd0527badb844 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 7 Aug 2010 22:25:37 -0700 Subject: The real fix for unscripted sit positions. This one doesn't fuck everything else up. Promise. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 87cf135..fc8e0d7 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2440,7 +2440,10 @@ namespace OpenSim.Region.Framework.Scenes } m_linkedPrim = part.UUID; - + if (part.GetAvatarOnSitTarget() != UUID) + { + m_offsetRotation = m_offsetRotation / part.RotationOffset; + } Velocity = Vector3.Zero; RemoveFromPhysicalScene(); Animator.TrySetMovementAnimation(sitAnimation); -- cgit v1.1 From 1cde77293e993c3a7329ea8e1fa013c8d7b898e5 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 8 Aug 2010 17:51:43 +0200 Subject: Thank you, Marck00, for a patch that implemented region distance sorting for fallback regions. Applied with changes. --- OpenSim/Data/IRegionData.cs | 22 ++++++++++++++++++++++ OpenSim/Data/MSSQL/MSSQLRegionData.cs | 7 +++++-- OpenSim/Data/MySQL/MySQLRegionData.cs | 6 ++++-- 3 files changed, 31 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/IRegionData.cs b/OpenSim/Data/IRegionData.cs index 42533c6..46dc4fb 100644 --- a/OpenSim/Data/IRegionData.cs +++ b/OpenSim/Data/IRegionData.cs @@ -79,4 +79,26 @@ namespace OpenSim.Data Authenticate = 256, // Require authentication Hyperlink = 512 // Record represents a HG link } + + public class RegionDataDistanceCompare : IComparer + { + private Vector2 m_origin; + + public RegionDataDistanceCompare(int x, int y) + { + m_origin = new Vector2(x, y); + } + + public int Compare(RegionData regionA, RegionData regionB) + { + Vector2 vectorA = new Vector2(regionA.posX, regionA.posY); + Vector2 vectorB = new Vector2(regionB.posX, regionB.posY); + return Math.Sign(VectorDistance(m_origin, vectorA) - VectorDistance(m_origin, vectorB)); + } + + private float VectorDistance(Vector2 x, Vector2 y) + { + return (x - y).Length(); + } + } } diff --git a/OpenSim/Data/MSSQL/MSSQLRegionData.cs b/OpenSim/Data/MSSQL/MSSQLRegionData.cs index 9656be1..cdf8ec0 100644 --- a/OpenSim/Data/MSSQL/MSSQLRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLRegionData.cs @@ -315,8 +315,11 @@ namespace OpenSim.Data.MSSQL public List GetFallbackRegions(UUID scopeID, int x, int y) { - // TODO: distance-sort results - return Get((int)RegionFlags.FallbackRegion, scopeID); + List regions = Get((int)RegionFlags.FallbackRegion, scopeID); + RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y); + regions.Sort(distanceComparer); + + return regions; } public List GetHyperlinks(UUID scopeID) diff --git a/OpenSim/Data/MySQL/MySQLRegionData.cs b/OpenSim/Data/MySQL/MySQLRegionData.cs index aec37e2..878b8e8 100644 --- a/OpenSim/Data/MySQL/MySQLRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLRegionData.cs @@ -289,8 +289,10 @@ namespace OpenSim.Data.MySQL public List GetFallbackRegions(UUID scopeID, int x, int y) { - // TODO: distance-sort results - return Get((int)RegionFlags.FallbackRegion, scopeID); + List regions = Get((int)RegionFlags.FallbackRegion, scopeID); + RegionDataDistanceCompare distanceComparer = new RegionDataDistanceCompare(x, y); + regions.Sort(distanceComparer); + return regions; } public List GetHyperlinks(UUID scopeID) -- cgit v1.1 From ca2a4bbded8c33125c5b96bb3b715e3f3925ddad Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 8 Aug 2010 19:35:20 +0200 Subject: Add debug messages to attachment receiving and cowardly refuse to create them if the owner can't be determined. --- OpenSim/Region/Framework/Scenes/Scene.cs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6c17be8..8a8dabc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2592,6 +2592,12 @@ namespace OpenSim.Region.Framework.Scenes /// True if the SceneObjectGroup was added, False if it was not public bool AddSceneObject(SceneObjectGroup sceneObject) { + if (sceneObject.OwnerID == UUID.Zero) + { + m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero", sceneObject.UUID); + return false; + } + // If the user is banned, we won't let any of their objects // enter. Period. // @@ -2641,15 +2647,27 @@ namespace OpenSim.Region.Framework.Scenes if (AttachmentsModule != null) AttachmentsModule.AttachObject(sp.ControllingClient, grp, 0, false); + m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was found, attaching", sceneObject.UUID); } else { + m_log.DebugFormat("[SCENE]: Attachment {0} arrived and scene presence was not found, setting to temp", sceneObject.UUID); RootPrim.RemFlag(PrimFlags.TemporaryOnRez); RootPrim.AddFlag(PrimFlags.TemporaryOnRez); } + if (sceneObject.OwnerID == UUID.Zero) + { + m_log.ErrorFormat("[SCENE]: Owner ID for {0} was zero after attachment processing. BUG!", sceneObject.UUID); + return false; + } } else { + if (sceneObject.OwnerID == UUID.Zero) + { + m_log.ErrorFormat("[SCENE]: Owner ID for non-attachment {0} was zero", sceneObject.UUID); + return false; + } AddRestoredSceneObject(sceneObject, true, false); if (!Permissions.CanObjectEntry(sceneObject.UUID, @@ -5333,4 +5351,4 @@ namespace OpenSim.Region.Framework.Scenes return offsets.ToArray(); } } -} \ No newline at end of file +} -- cgit v1.1 From 603b3a1606396e355416eae838f6bdaa5051bf1f Mon Sep 17 00:00:00 2001 From: meta7 Date: Sun, 8 Aug 2010 17:31:29 -0700 Subject: Fix minimap issues. This addresses mantis #228. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5acc227..94ec534 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -228,27 +228,8 @@ namespace OpenSim.Region.Framework.Scenes if (sp.IsChildAgent) return; - if (sp.ParentID != 0) - { - // sitting avatar - SceneObjectPart sop = m_parentScene.GetSceneObjectPart(sp.ParentID); - if (sop != null) - { - coarseLocations.Add(sop.AbsolutePosition + sp.AbsolutePosition); - avatarUUIDs.Add(sp.UUID); - } - else - { - // we can't find the parent.. ! arg! - coarseLocations.Add(sp.AbsolutePosition); - avatarUUIDs.Add(sp.UUID); - } - } - else - { - coarseLocations.Add(sp.AbsolutePosition); - avatarUUIDs.Add(sp.UUID); - } + coarseLocations.Add(sp.AbsolutePosition); + avatarUUIDs.Add(sp.UUID); } } -- cgit v1.1 From 680e801bf229d54dc57dbca24e841f7f2e8f43d4 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sun, 8 Aug 2010 17:32:20 -0700 Subject: Print a console message when we deny access because of no valid parcel found. --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 8a8dabc..779f898 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3513,7 +3513,8 @@ namespace OpenSim.Region.Framework.Scenes if (tp == TeleportFlags.ViaLogin) { if (land != null && !TestLandRestrictions(agent, land, out reason)) - { + { + m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); return false; } } -- cgit v1.1 From f20dc512e87983b9ba6b86f806489380d3cfef5a Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 9 Aug 2010 02:46:09 +0200 Subject: Whitespace conflict --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Services/LLLoginService/LLLoginService.cs | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 779f898..06bbe32 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3513,7 +3513,7 @@ namespace OpenSim.Region.Framework.Scenes if (tp == TeleportFlags.ViaLogin) { if (land != null && !TestLandRestrictions(agent, land, out reason)) - { + { m_log.DebugFormat("[CONNECTION BEGIN]: Denying access to {0} due to no land access", agent.AgentID.ToString()); return false; } diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 602616f..0bf75b0 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -691,11 +691,7 @@ namespace OpenSim.Services.LLLoginService } } } -<<<<<<< HEAD:OpenSim/Services/LLLoginService/LLLoginService.cs - } -======= } ->>>>>>> master:OpenSim/Services/LLLoginService/LLLoginService.cs dest = destination; if (success) return aCircuit; -- cgit v1.1 From 32ccc19a6238b2b0f4fa81efdc3115dd58578b00 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sun, 8 Aug 2010 18:56:47 -0700 Subject: Make fallbacks work, the destination was never actually updated with the fallback details. --- OpenSim/Services/LLLoginService/LLLoginService.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index f9fe7f0..2674eef 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -344,9 +344,10 @@ namespace OpenSim.Services.LLLoginService // // Instantiate/get the simulation interface and launch an agent at the destination // - string reason = string.Empty; - AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, clientIP, out where, out reason); - + string reason = string.Empty; + GridRegion dest; + AgentCircuitData aCircuit = LaunchAgentAtGrid(gatekeeper, destination, account, avatar, session, secureSession, position, where, clientVersion, clientIP, out where, out reason, out dest); + destination = dest; if (aCircuit == null) { m_PresenceService.LogoutAgent(session); @@ -605,7 +606,7 @@ namespace OpenSim.Services.LLLoginService } protected AgentCircuitData LaunchAgentAtGrid(GridRegion gatekeeper, GridRegion destination, UserAccount account, AvatarData avatar, - UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, IPEndPoint clientIP, out string where, out string reason) + UUID session, UUID secureSession, Vector3 position, string currentWhere, string viewer, IPEndPoint clientIP, out string where, out string reason, out GridRegion dest) { where = currentWhere; ISimulationService simConnector = null; @@ -690,8 +691,8 @@ namespace OpenSim.Services.LLLoginService } } } - } - + } + dest = destination; if (success) return aCircuit; else -- cgit v1.1 From 0f9eebdfb1e948bc1ffb148322e668b5a2f560a6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 10 Aug 2010 03:52:00 +0200 Subject: Change prejump from hardcoded true to default true so it can be disabled. It completely destroys roleplay jumping --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 06bbe32..05036f1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -726,8 +726,7 @@ namespace OpenSim.Region.Framework.Scenes //Animation states m_useFlySlow = startupConfig.GetBoolean("enableflyslow", false); // TODO: Change default to true once the feature is supported - m_usePreJump = startupConfig.GetBoolean("enableprejump", false); - m_usePreJump = true; // Above line fails!? + m_usePreJump = startupConfig.GetBoolean("enableprejump", true); m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); if (RegionInfo.NonphysPrimMax > 0) { -- cgit v1.1 From f0bad66d414e1c42875bc82d533cc7cd66af8a89 Mon Sep 17 00:00:00 2001 From: meta7 Date: Mon, 9 Aug 2010 23:34:37 -0700 Subject: For my own sanity, fix a bug in xengine --- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 916e27f..0f274f3 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1091,7 +1091,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine return false; uuids = m_PrimObjects[localID]; - } + foreach (UUID itemID in uuids) { @@ -1109,6 +1109,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine result = true; } } + } return result; } -- cgit v1.1 From eb5c508f8b396ea65d5d80c763aaea70a46c4653 Mon Sep 17 00:00:00 2001 From: meta7 Date: Mon, 9 Aug 2010 23:35:40 -0700 Subject: Add a DebuggerSafe option to the ini to help with debugging in visual studio. This essentially silences exceptions in the script engine. Disabled by default, naturally. --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 8 ++++++-- .../Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 68b645e..71d63bb 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -100,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int m_notecardLineReadCharsMax = 255; protected int m_scriptConsoleChannel = 0; protected bool m_scriptConsoleChannelEnabled = false; + protected bool m_debuggerSafe = false; protected IUrlModule m_UrlModule = null; protected Dictionary m_userInfoCache = new Dictionary(); @@ -110,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host = host; m_localID = localID; m_itemID = itemID; + m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); m_ScriptDelayFactor = m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); @@ -3220,13 +3222,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return m_host.OwnerID.ToString(); } - [DebuggerNonUserCode] public void llInstantMessage(string user, string message) { UUID result; if (!UUID.TryParse(user, out result)) { - throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user)); + if (!m_debuggerSafe) + { + throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user)); + } return; } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 80b021f..73e87b5 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; internal float m_ScriptDelayFactor = 1.0f; internal float m_ScriptDistanceFactor = 1.0f; + internal bool m_debuggerSafe = false; internal Dictionary m_FunctionPerms = new Dictionary(); public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) @@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host = host; m_localID = localID; m_itemID = itemID; + m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) m_OSFunctionsEnabled = true; @@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api internal void OSSLError(string msg) { - throw new Exception("OSSL Runtime Error: " + msg); + if (m_debuggerSafe) + { + OSSLShoutError(msg); + } + else + { + throw new Exception("OSSL Runtime Error: " + msg); + } } private void InitLSL() -- cgit v1.1 From 1ead2ed5eea379c500d2657e7bed8908b376e336 Mon Sep 17 00:00:00 2001 From: meta7 Date: Tue, 10 Aug 2010 09:07:17 -0700 Subject: Add a stack trace to the error output on the recursive read lock warning on my RWlocks. Whilst recursive locks are safe, coupled with other issues we're experiencing with the TaskInventoryDictionary it implies that somewhere the lock is not being freed possibly due to a merge error somewhere, and thus it needs to be looked into. --- OpenSim/Framework/TaskInventoryDictionary.cs | 14 ++ .../Region/Framework/Scenes/SceneObjectGroup.cs | 218 +++++++++++---------- 2 files changed, 128 insertions(+), 104 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 4b9a509..6b65fba 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -30,6 +30,7 @@ using System.Collections.Generic; using System.Threading; using System.Reflection; using System.Xml; +using System.Diagnostics; using System.Xml.Schema; using System.Xml.Serialization; using log4net; @@ -90,6 +91,19 @@ namespace OpenSim.Framework if (m_itemLock.RecursiveReadCount > 0) { m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); + try + { + StackTrace stackTrace = new StackTrace(); // get call stack + StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + + // write call stack method names + foreach (StackFrame stackFrame in stackFrames) + { + m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name); // write method name + } + } + catch + {} m_itemLock.ExitReadLock(); } if (m_itemLock.RecursiveWriteCount > 0) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3c3f4b7..4f6bc52 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Diagnostics; using System.Threading; using System.Xml; using System.Xml.Serialization; @@ -138,6 +139,15 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[SceneObjectGroup.m_parts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); try { + StackTrace stackTrace = new StackTrace(); // get call stack + StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) + + // write call stack method names + foreach (StackFrame stackFrame in stackFrames) + { + m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name); // write method name + } + m_partsLock.ExitReadLock(); } catch { } // Ignore errors, to allow resync @@ -317,7 +327,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_scriptListens_notAtTarget = false; private bool m_scriptListens_atRotTarget = false; - private bool m_scriptListens_notAtRotTarget = false; + private bool m_scriptListens_notAtRotTarget = false; public bool m_dupeInProgress = false; internal Dictionary m_savedScriptState = null; @@ -475,21 +485,21 @@ namespace OpenSim.Region.Framework.Scenes { part.IgnoreUndoUpdate = false; part.StoreUndoState(UndoType.STATE_GROUP_POSITION); - part.GroupPosition = val; - if (!m_dupeInProgress) - { - part.TriggerScriptChangedEvent(Changed.POSITION); + part.GroupPosition = val; + if (!m_dupeInProgress) + { + part.TriggerScriptChangedEvent(Changed.POSITION); + } + } + if (!m_dupeInProgress) + { + foreach (ScenePresence av in m_linkedAvatars) + { + Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; + av.AbsolutePosition += offset; + av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition + av.SendFullUpdateToAllClients(); } - } - if (!m_dupeInProgress) - { - foreach (ScenePresence av in m_linkedAvatars) - { - Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; - av.AbsolutePosition += offset; - av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition - av.SendFullUpdateToAllClients(); - } } //if (m_rootPart.PhysActor != null) @@ -1805,95 +1815,95 @@ namespace OpenSim.Region.Framework.Scenes /// True if the duplicate will immediately be in the scene, false otherwise /// public SceneObjectGroup Copy(bool userExposed) - { - SceneObjectGroup dupe; - try - { - m_dupeInProgress = true; - dupe = (SceneObjectGroup)MemberwiseClone(); - dupe.m_isBackedUp = false; - dupe.m_parts = new Dictionary(); - - // Warning, The following code related to previousAttachmentStatus is needed so that clones of - // attachments do not bordercross while they're being duplicated. This is hacktastic! - // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! - // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state - // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, - // then restore it's attachment state - - // This is only necessary when userExposed is false! - - bool previousAttachmentStatus = dupe.RootPart.IsAttachment; - - if (!userExposed) - dupe.RootPart.IsAttachment = true; - - dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); - - if (!userExposed) - { - dupe.RootPart.IsAttachment = previousAttachmentStatus; - } - - dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); - dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; - - if (userExposed) - dupe.m_rootPart.TrimPermissions(); - - /// may need to create a new Physics actor. - if (dupe.RootPart.PhysActor != null && userExposed) - { - PrimitiveBaseShape pbs = dupe.RootPart.Shape; - - dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - dupe.RootPart.Name, - pbs, - dupe.RootPart.AbsolutePosition, - dupe.RootPart.Scale, - dupe.RootPart.RotationOffset, - dupe.RootPart.PhysActor.IsPhysical); - - dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; - dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); - } - - List partList; - - lockPartsForRead(true); - - partList = new List(m_parts.Values); - - lockPartsForRead(false); - - partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) - { - return p1.LinkNum.CompareTo(p2.LinkNum); - } - ); - - foreach (SceneObjectPart part in partList) - { - if (part.UUID != m_rootPart.UUID) - { - SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); - - newPart.LinkNum = part.LinkNum; - } - } - - if (userExposed) - { - dupe.UpdateParentIDs(); - dupe.HasGroupChanged = true; - dupe.AttachToBackup(); - - ScheduleGroupForFullUpdate(); - } - } - finally - { - m_dupeInProgress = false; + { + SceneObjectGroup dupe; + try + { + m_dupeInProgress = true; + dupe = (SceneObjectGroup)MemberwiseClone(); + dupe.m_isBackedUp = false; + dupe.m_parts = new Dictionary(); + + // Warning, The following code related to previousAttachmentStatus is needed so that clones of + // attachments do not bordercross while they're being duplicated. This is hacktastic! + // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! + // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state + // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, + // then restore it's attachment state + + // This is only necessary when userExposed is false! + + bool previousAttachmentStatus = dupe.RootPart.IsAttachment; + + if (!userExposed) + dupe.RootPart.IsAttachment = true; + + dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + + if (!userExposed) + { + dupe.RootPart.IsAttachment = previousAttachmentStatus; + } + + dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); + dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; + + if (userExposed) + dupe.m_rootPart.TrimPermissions(); + + /// may need to create a new Physics actor. + if (dupe.RootPart.PhysActor != null && userExposed) + { + PrimitiveBaseShape pbs = dupe.RootPart.Shape; + + dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( + dupe.RootPart.Name, + pbs, + dupe.RootPart.AbsolutePosition, + dupe.RootPart.Scale, + dupe.RootPart.RotationOffset, + dupe.RootPart.PhysActor.IsPhysical); + + dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); + } + + List partList; + + lockPartsForRead(true); + + partList = new List(m_parts.Values); + + lockPartsForRead(false); + + partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) + { + return p1.LinkNum.CompareTo(p2.LinkNum); + } + ); + + foreach (SceneObjectPart part in partList) + { + if (part.UUID != m_rootPart.UUID) + { + SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); + + newPart.LinkNum = part.LinkNum; + } + } + + if (userExposed) + { + dupe.UpdateParentIDs(); + dupe.HasGroupChanged = true; + dupe.AttachToBackup(); + + ScheduleGroupForFullUpdate(); + } + } + finally + { + m_dupeInProgress = false; } return dupe; } -- cgit v1.1 From d98d5ee6be233cf644be5ee1011c4a7f4b86ae46 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 10 Aug 2010 19:42:18 +0100 Subject: Remove windows line endinge --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 208 ++++++++++----------- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 28 +-- 2 files changed, 118 insertions(+), 118 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3c3f4b7..a862fa2 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -317,7 +317,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_scriptListens_notAtTarget = false; private bool m_scriptListens_atRotTarget = false; - private bool m_scriptListens_notAtRotTarget = false; + private bool m_scriptListens_notAtRotTarget = false; public bool m_dupeInProgress = false; internal Dictionary m_savedScriptState = null; @@ -475,21 +475,21 @@ namespace OpenSim.Region.Framework.Scenes { part.IgnoreUndoUpdate = false; part.StoreUndoState(UndoType.STATE_GROUP_POSITION); - part.GroupPosition = val; - if (!m_dupeInProgress) - { - part.TriggerScriptChangedEvent(Changed.POSITION); + part.GroupPosition = val; + if (!m_dupeInProgress) + { + part.TriggerScriptChangedEvent(Changed.POSITION); + } + } + if (!m_dupeInProgress) + { + foreach (ScenePresence av in m_linkedAvatars) + { + Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; + av.AbsolutePosition += offset; + av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition + av.SendFullUpdateToAllClients(); } - } - if (!m_dupeInProgress) - { - foreach (ScenePresence av in m_linkedAvatars) - { - Vector3 offset = m_parts[av.LinkedPrim].GetWorldPosition() - av.ParentPosition; - av.AbsolutePosition += offset; - av.ParentPosition = m_parts[av.LinkedPrim].GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition - av.SendFullUpdateToAllClients(); - } } //if (m_rootPart.PhysActor != null) @@ -1805,95 +1805,95 @@ namespace OpenSim.Region.Framework.Scenes /// True if the duplicate will immediately be in the scene, false otherwise /// public SceneObjectGroup Copy(bool userExposed) - { - SceneObjectGroup dupe; - try - { - m_dupeInProgress = true; - dupe = (SceneObjectGroup)MemberwiseClone(); - dupe.m_isBackedUp = false; - dupe.m_parts = new Dictionary(); - - // Warning, The following code related to previousAttachmentStatus is needed so that clones of - // attachments do not bordercross while they're being duplicated. This is hacktastic! - // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! - // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state - // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, - // then restore it's attachment state - - // This is only necessary when userExposed is false! - - bool previousAttachmentStatus = dupe.RootPart.IsAttachment; - - if (!userExposed) - dupe.RootPart.IsAttachment = true; - - dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); - - if (!userExposed) - { - dupe.RootPart.IsAttachment = previousAttachmentStatus; - } - - dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); - dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; - - if (userExposed) - dupe.m_rootPart.TrimPermissions(); - - /// may need to create a new Physics actor. - if (dupe.RootPart.PhysActor != null && userExposed) - { - PrimitiveBaseShape pbs = dupe.RootPart.Shape; - - dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - dupe.RootPart.Name, - pbs, - dupe.RootPart.AbsolutePosition, - dupe.RootPart.Scale, - dupe.RootPart.RotationOffset, - dupe.RootPart.PhysActor.IsPhysical); - - dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; - dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); - } - - List partList; - - lockPartsForRead(true); - - partList = new List(m_parts.Values); - - lockPartsForRead(false); - - partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) - { - return p1.LinkNum.CompareTo(p2.LinkNum); - } - ); - - foreach (SceneObjectPart part in partList) - { - if (part.UUID != m_rootPart.UUID) - { - SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); - - newPart.LinkNum = part.LinkNum; - } - } - - if (userExposed) - { - dupe.UpdateParentIDs(); - dupe.HasGroupChanged = true; - dupe.AttachToBackup(); - - ScheduleGroupForFullUpdate(); - } - } - finally - { - m_dupeInProgress = false; + { + SceneObjectGroup dupe; + try + { + m_dupeInProgress = true; + dupe = (SceneObjectGroup)MemberwiseClone(); + dupe.m_isBackedUp = false; + dupe.m_parts = new Dictionary(); + + // Warning, The following code related to previousAttachmentStatus is needed so that clones of + // attachments do not bordercross while they're being duplicated. This is hacktastic! + // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! + // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state + // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, + // then restore it's attachment state + + // This is only necessary when userExposed is false! + + bool previousAttachmentStatus = dupe.RootPart.IsAttachment; + + if (!userExposed) + dupe.RootPart.IsAttachment = true; + + dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); + + if (!userExposed) + { + dupe.RootPart.IsAttachment = previousAttachmentStatus; + } + + dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); + dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; + + if (userExposed) + dupe.m_rootPart.TrimPermissions(); + + /// may need to create a new Physics actor. + if (dupe.RootPart.PhysActor != null && userExposed) + { + PrimitiveBaseShape pbs = dupe.RootPart.Shape; + + dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( + dupe.RootPart.Name, + pbs, + dupe.RootPart.AbsolutePosition, + dupe.RootPart.Scale, + dupe.RootPart.RotationOffset, + dupe.RootPart.PhysActor.IsPhysical); + + dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); + } + + List partList; + + lockPartsForRead(true); + + partList = new List(m_parts.Values); + + lockPartsForRead(false); + + partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) + { + return p1.LinkNum.CompareTo(p2.LinkNum); + } + ); + + foreach (SceneObjectPart part in partList) + { + if (part.UUID != m_rootPart.UUID) + { + SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); + + newPart.LinkNum = part.LinkNum; + } + } + + if (userExposed) + { + dupe.UpdateParentIDs(); + dupe.HasGroupChanged = true; + dupe.AttachToBackup(); + + ScheduleGroupForFullUpdate(); + } + } + finally + { + m_dupeInProgress = false; } return dupe; } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 77581af..277384e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -718,20 +718,20 @@ namespace OpenSim.Region.Framework.Scenes // Tell the physics engines that this prim changed. m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); - } - - if (!m_parentGroup.m_dupeInProgress) - { - List avs = ParentGroup.GetLinkedAvatars(); - foreach (ScenePresence av in avs) - { - if (av.LinkedPrim == m_uuid) - { - Vector3 offset = (m_offsetPosition - oldpos); - av.OffsetPosition += offset; - av.SendFullUpdateToAllClients(); - } - } + } + + if (!m_parentGroup.m_dupeInProgress) + { + List avs = ParentGroup.GetLinkedAvatars(); + foreach (ScenePresence av in avs) + { + if (av.LinkedPrim == m_uuid) + { + Vector3 offset = (m_offsetPosition - oldpos); + av.OffsetPosition += offset; + av.SendFullUpdateToAllClients(); + } + } } } TriggerScriptChangedEvent(Changed.POSITION); -- cgit v1.1 From 383ee0d647df245dcb933e71f2b4bcdfbc026a15 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 10 Aug 2010 19:48:45 +0100 Subject: Remove 4000+ DOS line endings. Grrr! --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8664 +++++++++++----------- 1 file changed, 4332 insertions(+), 4332 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index fc8e0d7..9d95324 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1,4332 +1,4332 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Xml; -using System.Collections.Generic; -using System.Reflection; -using System.Timers; -using OpenMetaverse; -using log4net; -using OpenSim.Framework; -using OpenSim.Framework.Client; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes.Animation; -using OpenSim.Region.Framework.Scenes.Types; -using OpenSim.Region.Physics.Manager; -using GridRegion = OpenSim.Services.Interfaces.GridRegion; -using OpenSim.Services.Interfaces; - -namespace OpenSim.Region.Framework.Scenes -{ - enum ScriptControlled : uint - { - CONTROL_ZERO = 0, - CONTROL_FWD = 1, - CONTROL_BACK = 2, - CONTROL_LEFT = 4, - CONTROL_RIGHT = 8, - CONTROL_UP = 16, - CONTROL_DOWN = 32, - CONTROL_ROT_LEFT = 256, - CONTROL_ROT_RIGHT = 512, - CONTROL_LBUTTON = 268435456, - CONTROL_ML_LBUTTON = 1073741824 - } - - struct ScriptControllers - { - public UUID itemID; - public ScriptControlled ignoreControls; - public ScriptControlled eventControls; - } - - public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List coarseLocations, List avatarUUIDs); - - public class ScenePresence : EntityBase, ISceneEntity - { -// ~ScenePresence() -// { -// m_log.Debug("[ScenePresence] Destructor called"); -// } - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; -// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); - private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); - private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); - - /// - /// Experimentally determined "fudge factor" to make sit-target positions - /// the same as in SecondLife. Fudge factor was tested for 36 different - /// test cases including prims of type box, sphere, cylinder, and torus, - /// with varying parameters for sit target location, prim size, prim - /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis - /// issue #1716 - /// -// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); - // Value revised by KF 091121 by comparison with SL. - private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); - - public UUID currentParcelUUID = UUID.Zero; - - private ISceneViewer m_sceneViewer; - - /// - /// The animator for this avatar - /// - public ScenePresenceAnimator Animator - { - get { return m_animator; } - } - protected ScenePresenceAnimator m_animator; - - /// - /// The scene objects attached to this avatar. Do not change this list directly - use methods such as - /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. - /// - public List Attachments - { - get { return m_attachments; } - } - protected List m_attachments = new List(); - - private Dictionary scriptedcontrols = new Dictionary(); - private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; - private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; - private bool MouseDown = false; - private SceneObjectGroup proxyObjectGroup; - //private SceneObjectPart proxyObjectPart = null; - public Vector3 lastKnownAllowedPosition; - public bool sentMessageAboutRestrictedParcelFlyingDown; - public Vector4 CollisionPlane = Vector4.UnitW; - - private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation - private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; - private Vector3 m_lastWorldPosition; - private Quaternion m_lastRotation; - private Vector3 m_lastVelocity; - //private int m_lastTerseSent; - - private bool m_updateflag; - private byte m_movementflag; - private Vector3? m_forceToApply; - private uint m_requestedSitTargetID; - private UUID m_requestedSitTargetUUID; - public bool SitGround = false; - - private SendCourseLocationsMethod m_sendCourseLocationsMethod; - - private bool m_startAnimationSet; - - //private Vector3 m_requestedSitOffset = new Vector3(); - - private Vector3 m_LastFinitePos; - - private float m_sitAvatarHeight = 2.0f; - - private int m_godLevel; - private int m_userLevel; - - private bool m_invulnerable = true; - - private Vector3 m_lastChildAgentUpdatePosition; - private Vector3 m_lastChildAgentUpdateCamPosition; - - private int m_perfMonMS; - - private bool m_setAlwaysRun; - private bool m_forceFly; - private bool m_flyDisabled; - - private float m_speedModifier = 1.0f; - - private Quaternion m_bodyRot= Quaternion.Identity; - - private Quaternion m_bodyRotPrevious = Quaternion.Identity; - - private const int LAND_VELOCITYMAG_MAX = 12; - - public bool IsRestrictedToRegion; - - public string JID = String.Empty; - - private float m_health = 100f; - - // Default AV Height - private float m_avHeight = 127.0f; - - protected RegionInfo m_regionInfo; - protected ulong crossingFromRegion; - - private readonly Vector3[] Dir_Vectors = new Vector3[11]; - private bool m_isNudging = false; - - // Position of agent's camera in world (region cordinates) - protected Vector3 m_CameraCenter; - protected Vector3 m_lastCameraCenter; - - protected Timer m_reprioritization_timer; - protected bool m_reprioritizing; - protected bool m_reprioritization_called; - - // Use these three vectors to figure out what the agent is looking at - // Convert it to a Matrix and/or Quaternion - protected Vector3 m_CameraAtAxis; - protected Vector3 m_CameraLeftAxis; - protected Vector3 m_CameraUpAxis; - private AgentManager.ControlFlags m_AgentControlFlags; - private Quaternion m_headrotation = Quaternion.Identity; - private byte m_state; - - //Reuse the Vector3 instead of creating a new one on the UpdateMovement method -// private Vector3 movementvector; - - private bool m_autopilotMoving; - private Vector3 m_autoPilotTarget; - private bool m_sitAtAutoTarget; - private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit - - private string m_nextSitAnimation = String.Empty; - - //PauPaw:Proper PID Controler for autopilot************ - private bool m_moveToPositionInProgress; - private Vector3 m_moveToPositionTarget; - private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - - private bool m_followCamAuto; - - private int m_movementUpdateCount; - private int m_lastColCount = -1; //KF: Look for Collision chnages - private int m_updateCount = 0; //KF: Update Anims for a while - private static readonly int UPDATE_COUNT = 10; // how many frames to update for - private const int NumMovementsBetweenRayCast = 5; - private List m_lastColliders = new List(); - - private bool CameraConstraintActive; - //private int m_moveToPositionStateStatus; - //***************************************************** - - // Agent's Draw distance. - protected float m_DrawDistance; - - protected AvatarAppearance m_appearance; - - // neighbouring regions we have enabled a child agent in - // holds the seed cap for the child agent in that region - private Dictionary m_knownChildRegions = new Dictionary(); - - /// - /// Implemented Control Flags - /// - private enum Dir_ControlFlags - { - DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, - DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, - DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, - DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, - DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, - DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, - DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, - DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, - DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, - DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, - DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG - } - - /// - /// Position at which a significant movement was made - /// - private Vector3 posLastSignificantMove; - - // For teleports and crossings callbacks - string m_callbackURI; - UUID m_originRegionID; - - ulong m_rootRegionHandle; - - /// - /// Script engines present in the scene - /// - private IScriptModule[] m_scriptEngines; - - #region Properties - - /// - /// Physical scene representation of this Avatar. - /// - public PhysicsActor PhysicsActor - { - set { m_physicsActor = value; } - get { return m_physicsActor; } - } - - public byte MovementFlag - { - set { m_movementflag = value; } - get { return m_movementflag; } - } - - public bool Updated - { - set { m_updateflag = value; } - get { return m_updateflag; } - } - - public bool Invulnerable - { - set { m_invulnerable = value; } - get { return m_invulnerable; } - } - - public int UserLevel - { - get { return m_userLevel; } - } - - public int GodLevel - { - get { return m_godLevel; } - } - - public ulong RegionHandle - { - get { return m_rootRegionHandle; } - } - - public Vector3 CameraPosition - { - get { return m_CameraCenter; } - } - - public Quaternion CameraRotation - { - get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } - } - - public Vector3 CameraAtAxis - { - get { return m_CameraAtAxis; } - } - - public Vector3 CameraLeftAxis - { - get { return m_CameraLeftAxis; } - } - - public Vector3 CameraUpAxis - { - get { return m_CameraUpAxis; } - } - - public Vector3 Lookat - { - get - { - Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0); - - if (a == Vector3.Zero) - return a; - - return Util.GetNormalizedVector(a); - } - } - - private readonly string m_firstname; - - public string Firstname - { - get { return m_firstname; } - } - - private readonly string m_lastname; - - public string Lastname - { - get { return m_lastname; } - } - - private string m_grouptitle; - - public string Grouptitle - { - get { return m_grouptitle; } - set { m_grouptitle = value; } - } - - public float DrawDistance - { - get { return m_DrawDistance; } - } - - protected bool m_allowMovement = true; - - public bool AllowMovement - { - get { return m_allowMovement; } - set { m_allowMovement = value; } - } - - public bool SetAlwaysRun - { - get - { - if (PhysicsActor != null) - { - return PhysicsActor.SetAlwaysRun; - } - else - { - return m_setAlwaysRun; - } - } - set - { - m_setAlwaysRun = value; - if (PhysicsActor != null) - { - PhysicsActor.SetAlwaysRun = value; - } - } - } - - public byte State - { - get { return m_state; } - set { m_state = value; } - } - - public uint AgentControlFlags - { - get { return (uint)m_AgentControlFlags; } - set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } - } - - /// - /// This works out to be the ClientView object associated with this avatar, or it's client connection manager - /// - private IClientAPI m_controllingClient; - - protected PhysicsActor m_physicsActor; - - /// - /// The client controlling this presence - /// - public IClientAPI ControllingClient - { - get { return m_controllingClient; } - } - - public IClientCore ClientView - { - get { return (IClientCore) m_controllingClient; } - } - - protected Vector3 m_parentPosition; - public Vector3 ParentPosition - { - get { return m_parentPosition; } - set { m_parentPosition = value; } - } - - /// - /// Position of this avatar relative to the region the avatar is in - /// - public override Vector3 AbsolutePosition - { - get - { - PhysicsActor actor = m_physicsActor; -// if (actor != null) - if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! - m_pos = actor.Position; - - // If we're sitting, we need to update our position - if (m_parentID != 0) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); - if (part != null) - m_parentPosition = part.AbsolutePosition; - } - - return m_parentPosition + m_pos; - } - set - { - PhysicsActor actor = m_physicsActor; - if (actor != null) - { - try - { - lock (m_scene.SyncRoot) - m_physicsActor.Position = value; - } - catch (Exception e) - { - m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); - } - } - - if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! - m_pos = value; - m_parentPosition = Vector3.Zero; - } - } - - public Vector3 OffsetPosition - { - get { return m_pos; } - set { m_pos = value; } - } - - /// - /// Current velocity of the avatar. - /// - public override Vector3 Velocity - { - get - { - PhysicsActor actor = m_physicsActor; - if (actor != null) - m_velocity = actor.Velocity; - - return m_velocity; - } - set - { - PhysicsActor actor = m_physicsActor; - if (actor != null) - { - try - { - lock (m_scene.SyncRoot) - actor.Velocity = value; - } - catch (Exception e) - { - m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); - } - } - - m_velocity = value; - } - } - - public Quaternion OffsetRotation - { - get { return m_offsetRotation; } - set { m_offsetRotation = value; } - } - - public Quaternion Rotation - { - get { - if (m_parentID != 0) - { - if (m_offsetRotation != null) - { - return m_offsetRotation; - } - else - { - return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - - } - else - { - return m_bodyRot; - } - } - set { - m_bodyRot = value; - if (m_parentID != 0) - { - m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - } - } - - public Quaternion PreviousRotation - { - get { return m_bodyRotPrevious; } - set { m_bodyRotPrevious = value; } - } - - /// - /// If this is true, agent doesn't have a representation in this scene. - /// this is an agent 'looking into' this scene from a nearby scene(region) - /// - /// if False, this agent has a representation in this scene - /// - private bool m_isChildAgent = true; - - public bool IsChildAgent - { - get { return m_isChildAgent; } - set { m_isChildAgent = value; } - } - - private uint m_parentID; - - - private UUID m_linkedPrim; - - public uint ParentID - { - get { return m_parentID; } - set { m_parentID = value; } - } - - public UUID LinkedPrim - { - get { return m_linkedPrim; } - set { m_linkedPrim = value; } - } - - public float Health - { - get { return m_health; } - set { m_health = value; } - } - - /// - /// These are the region handles known by the avatar. - /// - public List KnownChildRegionHandles - { - get - { - if (m_knownChildRegions.Count == 0) - return new List(); - else - return new List(m_knownChildRegions.Keys); - } - } - - public Dictionary KnownRegions - { - get { return m_knownChildRegions; } - set - { - m_knownChildRegions = value; - } - } - - public ISceneViewer SceneViewer - { - get { return m_sceneViewer; } - } - - public void AdjustKnownSeeds() - { - Dictionary seeds; - - if (Scene.CapsModule != null) - seeds = Scene.CapsModule.GetChildrenSeeds(UUID); - else - seeds = new Dictionary(); - - List old = new List(); - foreach (ulong handle in seeds.Keys) - { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) - { - old.Add(handle); - } - } - DropOldNeighbours(old); - - if (Scene.CapsModule != null) - Scene.CapsModule.SetChildrenSeed(UUID, seeds); - - KnownRegions = seeds; - //m_log.Debug(" ++++++++++AFTER+++++++++++++ "); - //DumpKnownRegions(); - } - - public void DumpKnownRegions() - { - m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================"); - foreach (KeyValuePair kvp in KnownRegions) - { - uint x, y; - Utils.LongToUInts(kvp.Key, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - m_log.Info(" >> "+x+", "+y+": "+kvp.Value); - } - } - - private bool m_inTransit; - private bool m_mouseLook; - private bool m_leftButtonDown; - - public bool IsInTransit - { - get { return m_inTransit; } - set { m_inTransit = value; } - } - - public float SpeedModifier - { - get { return m_speedModifier; } - set { m_speedModifier = value; } - } - - public bool ForceFly - { - get { return m_forceFly; } - set { m_forceFly = value; } - } - - public bool FlyDisabled - { - get { return m_flyDisabled; } - set { m_flyDisabled = value; } - } - - public string Viewer - { - get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } - } - - #endregion - - #region Constructor(s) - - public ScenePresence() - { - m_sendCourseLocationsMethod = SendCoarseLocationsDefault; - CreateSceneViewer(); - m_animator = new ScenePresenceAnimator(this); - } - - private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() - { - m_rootRegionHandle = reginfo.RegionHandle; - m_controllingClient = client; - m_firstname = m_controllingClient.FirstName; - m_lastname = m_controllingClient.LastName; - m_name = String.Format("{0} {1}", m_firstname, m_lastname); - m_scene = world; - m_uuid = client.AgentId; - m_regionInfo = reginfo; - m_localId = m_scene.AllocateLocalId(); - - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); - - if (account != null) - m_userLevel = account.UserLevel; - - IGroupsModule gm = m_scene.RequestModuleInterface(); - if (gm != null) - m_grouptitle = gm.GetGroupTitle(m_uuid); - - m_scriptEngines = m_scene.RequestModuleInterfaces(); - - AbsolutePosition = posLastSignificantMove = m_CameraCenter = - m_lastCameraCenter = m_controllingClient.StartPos; - - m_reprioritization_timer = new Timer(world.ReprioritizationInterval); - m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); - m_reprioritization_timer.AutoReset = false; - - AdjustKnownSeeds(); - Animator.TrySetMovementAnimation("STAND"); - // we created a new ScenePresence (a new child agent) in a fresh region. - // Request info about all the (root) agents in this region - // Note: This won't send data *to* other clients in that region (children don't send) - SendInitialFullUpdateToAllClients(); - RegisterToEvents(); - if (m_controllingClient != null) - { - m_controllingClient.ProcessPendingPackets(); - } - SetDirectionVectors(); - } - - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, - AvatarWearable[] wearables) - : this(client, world, reginfo) - { - m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); - } - - public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) - : this(client, world, reginfo) - { - m_appearance = appearance; - } - - private void CreateSceneViewer() - { - m_sceneViewer = new SceneViewer(this); - } - - public void RegisterToEvents() - { - m_controllingClient.OnRequestWearables += SendWearables; - m_controllingClient.OnSetAppearance += SetAppearance; - m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; - //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; - m_controllingClient.OnAgentUpdate += HandleAgentUpdate; - m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; - m_controllingClient.OnAgentSit += HandleAgentSit; - m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; - m_controllingClient.OnStartAnim += HandleStartAnim; - m_controllingClient.OnStopAnim += HandleStopAnim; - m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; - m_controllingClient.OnAutoPilotGo += DoAutoPilot; - m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); - - // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); - // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); - } - - private void SetDirectionVectors() - { - Dir_Vectors[0] = Vector3.UnitX; //FORWARD - Dir_Vectors[1] = -Vector3.UnitX; //BACK - Dir_Vectors[2] = Vector3.UnitY; //LEFT - Dir_Vectors[3] = -Vector3.UnitY; //RIGHT - Dir_Vectors[4] = Vector3.UnitZ; //UP - Dir_Vectors[5] = -Vector3.UnitZ; //DOWN - Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE - Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE - Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE - Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE - Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge - } - - private Vector3[] GetWalkDirectionVectors() - { - Vector3[] vector = new Vector3[11]; - vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD - vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK - vector[2] = Vector3.UnitY; //LEFT - vector[3] = -Vector3.UnitY; //RIGHT - vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP - vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN - vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE - vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE - vector[8] = Vector3.UnitY; //LEFT_NUDGE - vector[9] = -Vector3.UnitY; //RIGHT_NUDGE - vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE - return vector; - } - - private bool[] GetDirectionIsNudge() - { - bool[] isNudge = new bool[11]; - isNudge[0] = false; //FORWARD - isNudge[1] = false; //BACK - isNudge[2] = false; //LEFT - isNudge[3] = false; //RIGHT - isNudge[4] = false; //UP - isNudge[5] = false; //DOWN - isNudge[6] = true; //FORWARD_NUDGE - isNudge[7] = true; //BACK_NUDGE - isNudge[8] = true; //LEFT_NUDGE - isNudge[9] = true; //RIGHT_NUDGE - isNudge[10] = true; //DOWN_Nudge - return isNudge; - } - - - #endregion - - public uint GenerateClientFlags(UUID ObjectID) - { - return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); - } - - /// - /// Send updates to the client about prims which have been placed on the update queue. We don't - /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent - /// timestamp has already been sent. - /// - public void SendPrimUpdates() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - m_sceneViewer.SendPrimUpdates(); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - #region Status Methods - - /// - /// This turns a child agent, into a root agent - /// This is called when an agent teleports into a region, or if an - /// agent crosses into this region from a neighbor over the border - /// - public void MakeRootAgent(Vector3 pos, bool isFlying) - { - m_log.DebugFormat( - "[SCENE]: Upgrading child to root agent for {0} in {1}", - Name, m_scene.RegionInfo.RegionName); - - //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); - - IGroupsModule gm = m_scene.RequestModuleInterface(); - if (gm != null) - m_grouptitle = gm.GetGroupTitle(m_uuid); - - m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; - m_scene.SetRootAgentScene(m_uuid); - - // Moved this from SendInitialData to ensure that m_appearance is initialized - // before the inventory is processed in MakeRootAgent. This fixes a race condition - // related to the handling of attachments - //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); - if (m_scene.TestBorderCross(pos, Cardinals.E)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); - pos.X = crossedBorder.BorderLine.Z - 1; - } - - if (m_scene.TestBorderCross(pos, Cardinals.N)) - { - Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); - pos.Y = crossedBorder.BorderLine.Z - 1; - } - - //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. - //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, - //they'll bypass the landing point. But I can't think of any decent way of fixing this. - if (KnownChildRegionHandles.Count == 0) - { - ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (land != null) - { - //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) - { - pos = land.LandData.UserLocation; - } - } - } - - if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) - { - Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); - - if (pos.X < 0) - { - emergencyPos.X = (int)Constants.RegionSize + pos.X; - if (!(pos.Y < 0)) - emergencyPos.Y = pos.Y; - if (!(pos.Z < 0)) - emergencyPos.Z = pos.Z; - } - if (pos.Y < 0) - { - emergencyPos.Y = (int)Constants.RegionSize + pos.Y; - if (!(pos.X < 0)) - emergencyPos.X = pos.X; - if (!(pos.Z < 0)) - emergencyPos.Z = pos.Z; - } - if (pos.Z < 0) - { - emergencyPos.Z = 128; - if (!(pos.Y < 0)) - emergencyPos.Y = pos.Y; - if (!(pos.X < 0)) - emergencyPos.X = pos.X; - } - } - - if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) - { - m_log.WarnFormat( - "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", - pos, Name, UUID); - - if (pos.X < 0f) pos.X = 0f; - if (pos.Y < 0f) pos.Y = 0f; - if (pos.Z < 0f) pos.Z = 0f; - } - - float localAVHeight = 1.56f; - if (m_avHeight != 127.0f) - { - localAVHeight = m_avHeight; - } - - float posZLimit = 0; - - if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) - posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; - - float newPosZ = posZLimit + localAVHeight / 2; - if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - pos.Z = newPosZ; - } - AbsolutePosition = pos; - - AddToPhysicalScene(isFlying); - - if (m_forceFly) - { - m_physicsActor.Flying = true; - } - else if (m_flyDisabled) - { - m_physicsActor.Flying = false; - } - - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - else - { - m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); - // emergency; this really shouldn't happen - m_appearance = new AvatarAppearance(UUID); - } - - // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying - // avatar to return to the standing position in mid-air. On login it looks like this is being sent - // elsewhere anyway - // Animator.SendAnimPack(); - - m_scene.SwapRootAgentCount(false); - - //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); - //if (userInfo != null) - // userInfo.FetchInventory(); - //else - // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); - - // On the next prim update, all objects will be sent - // - m_sceneViewer.Reset(); - - m_isChildAgent = false; - - // send the animations of the other presences to me - m_scene.ForEachScenePresence(delegate(ScenePresence presence) - { - if (presence != this) - presence.Animator.SendAnimPackToClient(ControllingClient); - }); - - m_scene.EventManager.TriggerOnMakeRootAgent(this); - } - - /// - /// This turns a root agent into a child agent - /// when an agent departs this region for a neighbor, this gets called. - /// - /// It doesn't get called for a teleport. Reason being, an agent that - /// teleports out may not end up anywhere near this region - /// - public void MakeChildAgent() - { - // It looks like m_animator is set to null somewhere, and MakeChild - // is called after that. Probably in aborted teleports. - if (m_animator == null) - m_animator = new ScenePresenceAnimator(this); - else - Animator.ResetAnimations(); - -// m_log.DebugFormat( -// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", -// Name, UUID, m_scene.RegionInfo.RegionName); - - // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, - // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. - //Velocity = new Vector3(0, 0, 0); - - m_isChildAgent = true; - m_scene.SwapRootAgentCount(true); - RemoveFromPhysicalScene(); - - // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into - - m_scene.EventManager.TriggerOnMakeChildAgent(this); - } - - /// - /// Removes physics plugin scene representation of this agent if it exists. - /// - private void RemoveFromPhysicalScene() - { - if (PhysicsActor != null) - { - m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; - m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; - m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); - m_physicsActor.UnSubscribeEvents(); - m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; - PhysicsActor = null; - } - } - - /// - /// - /// - /// - public void Teleport(Vector3 pos) - { - bool isFlying = false; - - if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - - RemoveFromPhysicalScene(); - Velocity = Vector3.Zero; - AbsolutePosition = pos; - AddToPhysicalScene(isFlying); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - - SendTerseUpdateToAllClients(); - - } - - public void TeleportWithMomentum(Vector3 pos) - { - bool isFlying = false; - if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - - RemoveFromPhysicalScene(); - AbsolutePosition = pos; - AddToPhysicalScene(isFlying); - if (m_appearance != null) - { - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - } - - SendTerseUpdateToAllClients(); - } - - /// - /// - /// - public void StopMovement() - { - } - - public void StopFlying() - { - ControllingClient.StopFlying(this); - } - - public void AddNeighbourRegion(ulong regionHandle, string cap) - { - lock (m_knownChildRegions) - { - if (!m_knownChildRegions.ContainsKey(regionHandle)) - { - uint x, y; - Utils.LongToUInts(regionHandle, out x, out y); - m_knownChildRegions.Add(regionHandle, cap); - } - } - } - - public void RemoveNeighbourRegion(ulong regionHandle) - { - lock (m_knownChildRegions) - { - if (m_knownChildRegions.ContainsKey(regionHandle)) - { - m_knownChildRegions.Remove(regionHandle); - //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); - } - } - } - - public void DropOldNeighbours(List oldRegions) - { - foreach (ulong handle in oldRegions) - { - RemoveNeighbourRegion(handle); - Scene.CapsModule.DropChildSeed(UUID, handle); - } - } - - public List GetKnownRegionList() - { - return new List(m_knownChildRegions.Keys); - } - - #endregion - - #region Event Handlers - - /// - /// Sets avatar height in the phyiscs plugin - /// - internal void SetHeight(float height) - { - m_avHeight = height; - if (PhysicsActor != null && !IsChildAgent) - { - Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight); - PhysicsActor.Size = SetSize; - } - } - - /// - /// Complete Avatar's movement into the region. - /// This is called upon a very important packet sent from the client, - /// so it's client-controlled. Never call this method directly. - /// - public void CompleteMovement(IClientAPI client) - { - //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); - - Vector3 look = Velocity; - if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) - { - look = new Vector3(0.99f, 0.042f, 0); - } - - // Prevent teleporting to an underground location - // (may crash client otherwise) - // - Vector3 pos = AbsolutePosition; - float ground = m_scene.GetGroundHeight(pos.X, pos.Y); - if (pos.Z < ground + 1.5f) - { - pos.Z = ground + 1.5f; - AbsolutePosition = pos; - } - m_isChildAgent = false; - bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - MakeRootAgent(AbsolutePosition, m_flying); - - if ((m_callbackURI != null) && !m_callbackURI.Equals("")) - { - m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); - Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); - m_callbackURI = null; - } - - //m_log.DebugFormat("Completed movement"); - - m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); - SendInitialData(); - - // Create child agents in neighbouring regions - if (!m_isChildAgent) - { - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); - if (m_agentTransfer != null) - m_agentTransfer.EnableChildAgents(this); - else - m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); - - IFriendsModule friendsModule = m_scene.RequestModuleInterface(); - if (friendsModule != null) - friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); - } - - } - - /// - /// Callback for the Camera view block check. Gets called with the results of the camera view block test - /// hitYN is true when there's something in the way. - /// - /// - /// - /// - /// - public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) - { - const float POSITION_TOLERANCE = 0.02f; - const float VELOCITY_TOLERANCE = 0.02f; - const float ROTATION_TOLERANCE = 0.02f; - - if (m_followCamAuto) - { - if (hitYN) - { - CameraConstraintActive = true; - //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); - - Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); - ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); - } - else - { - if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) - { - if (CameraConstraintActive) - { - ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); - CameraConstraintActive = false; - } - } - } - } - } - - /// - /// This is the event handler for client movement. If a client is moving, this event is triggering. - /// - public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) - { - //if (m_isChildAgent) - //{ - // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); - // return; - //} - - m_perfMonMS = Util.EnvironmentTickCount(); - - ++m_movementUpdateCount; - if (m_movementUpdateCount < 1) - m_movementUpdateCount = 1; - - #region Sanity Checking - - // This is irritating. Really. - if (!AbsolutePosition.IsFinite()) - { - RemoveFromPhysicalScene(); - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); - - m_pos = m_LastFinitePos; - - if (!m_pos.IsFinite()) - { - m_pos.X = 127f; - m_pos.Y = 127f; - m_pos.Z = 127f; - m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); - } - - AddToPhysicalScene(false); - } - else - { - m_LastFinitePos = m_pos; - } - - #endregion Sanity Checking - - #region Inputs - - AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; - Quaternion bodyRotation = agentData.BodyRotation; - - // Camera location in world. We'll need to raytrace - // from this location from time to time. - m_CameraCenter = agentData.CameraCenter; - if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) - { - ReprioritizeUpdates(); - m_lastCameraCenter = m_CameraCenter; - } - - // Use these three vectors to figure out what the agent is looking at - // Convert it to a Matrix and/or Quaternion - m_CameraAtAxis = agentData.CameraAtAxis; - m_CameraLeftAxis = agentData.CameraLeftAxis; - m_CameraUpAxis = agentData.CameraUpAxis; - - // The Agent's Draw distance setting - m_DrawDistance = agentData.Far; - - // Check if Client has camera in 'follow cam' or 'build' mode. - Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); - - m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) - && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; - - m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; - m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; - - #endregion Inputs - - if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) - { - StandUp(); - } - - //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); - // Raycast from the avatar's head to the camera to see if there's anything blocking the view - if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) - { - if (m_followCamAuto) - { - Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; - m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); - } - } - lock (scriptedcontrols) - { - if (scriptedcontrols.Count > 0) - { - SendControlToScripts((uint)flags); - flags = RemoveIgnoredControls(flags, IgnoredControls); - } - } - - if (m_autopilotMoving) - CheckAtSitTarget(); - - if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) - { - m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. - Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - - // TODO: This doesn't prevent the user from walking yet. - // Setting parent ID would fix this, if we knew what value - // to use. Or we could add a m_isSitting variable. - //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - SitGround = true; - } - - // In the future, these values might need to go global. - // Here's where you get them. - m_AgentControlFlags = flags; - m_headrotation = agentData.HeadRotation; - m_state = agentData.State; - - PhysicsActor actor = PhysicsActor; - if (actor == null) - { - return; - } - - bool update_movementflag = false; - - if (m_allowMovement && !SitGround) - { - if (agentData.UseClientAgentPosition) - { - m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; - m_moveToPositionTarget = agentData.ClientAgentPosition; - } - - int i = 0; - - bool update_rotation = false; - bool DCFlagKeyPressed = false; - Vector3 agent_control_v3 = Vector3.Zero; - Quaternion q = bodyRotation; - - bool oldflying = PhysicsActor.Flying; - - if (m_forceFly) - actor.Flying = true; - else if (m_flyDisabled) - actor.Flying = false; - else - actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); - - if (actor.Flying != oldflying) - update_movementflag = true; - - if (q != m_bodyRot) - { - m_bodyRot = q; - update_rotation = true; - } - - //guilty until proven innocent.. - bool Nudging = true; - //Basically, if there is at least one non-nudge control then we don't need - //to worry about stopping the avatar - - if (m_parentID == 0) - { - bool bAllowUpdateMoveToPosition = false; - bool bResetMoveToPosition = false; - - Vector3[] dirVectors; - - // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying - // this prevents 'jumping' in inappropriate situations. - if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) - dirVectors = GetWalkDirectionVectors(); - else - dirVectors = Dir_Vectors; - - bool[] isNudge = GetDirectionIsNudge(); - - - - - - foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) - { - if (((uint)flags & (uint)DCF) != 0) - { - bResetMoveToPosition = true; - DCFlagKeyPressed = true; - try - { - agent_control_v3 += dirVectors[i]; - if (isNudge[i] == false) - { - Nudging = false; - } - } - catch (IndexOutOfRangeException) - { - // Why did I get this? - } - - if ((m_movementflag & (uint)DCF) == 0) - { - m_movementflag += (byte)(uint)DCF; - update_movementflag = true; - } - } - else - { - if ((m_movementflag & (uint)DCF) != 0) - { - m_movementflag -= (byte)(uint)DCF; - update_movementflag = true; - } - else - { - bAllowUpdateMoveToPosition = true; - } - } - i++; - } - //Paupaw:Do Proper PID for Autopilot here - if (bResetMoveToPosition) - { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - bAllowUpdateMoveToPosition = false; - } - - if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) - { - //Check the error term of the current position in relation to the target position - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) - { - // we are close enough to the target - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - } - else - { - try - { - // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - Vector3 LocalVectorToTarget3D = - (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords - // Ignore z component of vector - Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget2D.Normalize(); - - //We're not nudging - Nudging = false; - agent_control_v3 += LocalVectorToTarget2D; - - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // - - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - if (LocalVectorToTarget2D.Y > 0)//MoveLeft - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - //AgentControlFlags - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.Y < 0) //MoveRight - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - update_movementflag = true; - } - if (LocalVectorToTarget2D.X < 0) //MoveBack - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.X > 0) //Move Forward - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - update_movementflag = true; - } - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } - } - } - } - - // Cause the avatar to stop flying if it's colliding - // with something with the down arrow pressed. - - // Only do this if we're flying - if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) - { - // Landing detection code - - // Are the landing controls requirements filled? - bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || - ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - - // Are the collision requirements fulfilled? - bool colliding = (m_physicsActor.IsColliding == true); - - if (m_physicsActor.Flying && colliding && controlland) - { - // nesting this check because LengthSquared() is expensive and we don't - // want to do it every step when flying. - if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) - StopFlying(); - } - } - - if (update_movementflag || (update_rotation && DCFlagKeyPressed)) - { - // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); - // m_log.DebugFormat( - // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); - - AddNewMovement(agent_control_v3, q, Nudging); - - - } - } - - if (update_movementflag && !SitGround) - Animator.UpdateMovementAnimations(); - - m_scene.EventManager.TriggerOnClientMovement(this); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) - { - m_autopilotMoving = true; - m_autoPilotTarget = Pos; - m_sitAtAutoTarget = false; - PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; - proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); - proxyObjectGroup.AttachToScene(m_scene); - - // Commented out this code since it could never have executed, but might still be informative. -// if (proxyObjectGroup != null) -// { - proxyObjectGroup.SendGroupFullUpdate(); - remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - m_scene.DeleteSceneObject(proxyObjectGroup, false); -// } -// else -// { -// m_autopilotMoving = false; -// m_autoPilotTarget = Vector3.Zero; -// ControllingClient.SendAlertMessage("Autopilot cancelled"); -// } - } - - public void DoMoveToPosition(Object sender, string method, List args) - { - try - { - float locx = 0f; - float locy = 0f; - float locz = 0f; - uint regionX = 0; - uint regionY = 0; - try - { - Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); - locx = Convert.ToSingle(args[0]) - (float)regionX; - locy = Convert.ToSingle(args[1]) - (float)regionY; - locz = Convert.ToSingle(args[2]); - } - catch (InvalidCastException) - { - m_log.Error("[CLIENT]: Invalid autopilot request"); - return; - } - m_moveToPositionInProgress = true; - m_moveToPositionTarget = new Vector3(locx, locy, locz); - } - catch (Exception ex) - { - //Why did I get this error? - m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); - } - } - - private void CheckAtSitTarget() - { - //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); - if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) - { - if (m_sitAtAutoTarget) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); - if (part != null) - { - AbsolutePosition = part.AbsolutePosition; - Velocity = Vector3.Zero; - SendFullUpdateToAllClients(); - - HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? - } - //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); - m_requestedSitTargetUUID = UUID.Zero; - } - /* - else - { - //ControllingClient.SendAlertMessage("Autopilot cancelled"); - //SendTerseUpdateToAllClients(); - //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; - //proxy.PCode = (byte)PCode.ParticleSystem; - ////uint nextUUID = m_scene.NextLocalId; - - //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); - //if (proxyObjectGroup != null) - //{ - //proxyObjectGroup.SendGroupFullUpdate(); - //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); - //m_scene.DeleteSceneObject(proxyObjectGroup); - //} - } - */ - m_autoPilotTarget = Vector3.Zero; - m_autopilotMoving = false; - } - } - /// - /// Perform the logic necessary to stand the avatar up. This method also executes - /// the stand animation. - /// - public void StandUp() - { - SitGround = false; - - if (m_parentID != 0) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - if (part != null) - { - part.TaskInventory.LockItemsForRead(true); - TaskInventoryDictionary taskIDict = part.TaskInventory; - if (taskIDict != null) - { - foreach (UUID taskID in taskIDict.Keys) - { - UnRegisterControlEventsToScript(LocalId, taskID); - taskIDict[taskID].PermsMask &= ~( - 2048 | //PERMISSION_CONTROL_CAMERA - 4); // PERMISSION_TAKE_CONTROLS - } - } - part.TaskInventory.LockItemsForRead(false); - // Reset sit target. - if (part.GetAvatarOnSitTarget() == UUID) - part.SetAvatarOnSitTarget(UUID.Zero); - m_parentPosition = part.GetWorldPosition(); - ControllingClient.SendClearFollowCamProperties(part.ParentUUID); - } - // part.GetWorldRotation() is the rotation of the object being sat on - // Rotation is the sittiing Av's rotation - - Quaternion partRot; -// if (part.LinkNum == 1) -// { // Root prim of linkset -// partRot = part.ParentGroup.RootPart.RotationOffset; -// } -// else -// { // single or child prim - -// } - if (part == null) //CW: Part may be gone. llDie() for example. - { - partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - partRot = part.GetWorldRotation(); - } - - Quaternion partIRot = Quaternion.Inverse(partRot); - - Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av - Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av - - - if (m_physicsActor == null) - { - AddToPhysicalScene(false); - } - //CW: If the part isn't null then we can set the current position - if (part != null) - { - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! - AbsolutePosition = avWorldStandUp; //KF: Fix stand up. - part.IsOccupied = false; - part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); - } - else - { - //CW: Since the part doesn't exist, a coarse standup position isn't an issue - AbsolutePosition = m_lastWorldPosition; - } - - m_parentPosition = Vector3.Zero; - m_parentID = 0; - m_linkedPrim = UUID.Zero; - m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - SendFullUpdateToAllClients(); - m_requestedSitTargetID = 0; - - if ((m_physicsActor != null) && (m_avHeight > 0)) - { - SetHeight(m_avHeight); - } - } - Animator.TrySetMovementAnimation("STAND"); - } - - private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) - { - SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID); - if (targetPart == null) - return null; - - // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used. - // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. - - // Get our own copy of the part array, and sort into the order we want to test - SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); - Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) - { - // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) - int linkNum1 = p1==targetPart ? -1 : p1.LinkNum; - int linkNum2 = p2==targetPart ? -1 : p2.LinkNum; - return linkNum1 - linkNum2; - } - ); - - //look for prims with explicit sit targets that are available - foreach (SceneObjectPart part in partArray) - { - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); - bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); - bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. - if (SitTargetisSet && !SitTargetOccupied) - { - //switch the target to this prim - return part; - } - } - - // no explicit sit target found - use original target - return targetPart; - } - - private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) - { - bool autopilot = true; - Vector3 autopilotTarget = new Vector3(); - Quaternion sitOrientation = Quaternion.Identity; - Vector3 pos = new Vector3(); - Vector3 cameraEyeOffset = Vector3.Zero; - Vector3 cameraAtOffset = Vector3.Zero; - bool forceMouselook = false; - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part == null) return; - - // TODO: determine position to sit at based on scene geometry; don't trust offset from client - // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it - - // part is the prim to sit on - // offset is the world-ref vector distance from that prim center to the click-spot - // UUID is the UUID of the Avatar doing the clicking - - m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation - - // Is a sit target available? - Vector3 avSitOffSet = part.SitTargetPosition; - Quaternion avSitOrientation = part.SitTargetOrientation; - - bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. - // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); - Quaternion partRot; -// if (part.LinkNum == 1) -// { // Root prim of linkset -// partRot = part.ParentGroup.RootPart.RotationOffset; -// } -// else -// { // single or child prim - partRot = part.GetWorldRotation(); -// } - Quaternion partIRot = Quaternion.Inverse(partRot); -//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); - // Sit analysis rewritten by KF 091125 - if (SitTargetisSet) // scipted sit - { - if (!part.IsOccupied) - { -//Console.WriteLine("Scripted, unoccupied"); - part.SetAvatarOnSitTarget(UUID); // set that Av will be on it - offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one - - Quaternion nrot = avSitOrientation; - if (!part.IsRoot) - { - nrot = part.RotationOffset * avSitOrientation; - } - sitOrientation = nrot; // Change rotatione to the scripted one - OffsetRotation = nrot; - autopilot = false; // Jump direct to scripted llSitPos() - } - else - { -//Console.WriteLine("Scripted, occupied"); - return; - } - } - else // Not Scripted - { - if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) - { - // large prim & offset, ignore if other Avs sitting -// offset.Z -= 0.05f; - m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked - autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point - -//Console.WriteLine(" offset ={0}", offset); -//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); -//Console.WriteLine(" autopilotTarget={0}", autopilotTarget); - - } - else // small offset - { -//Console.WriteLine("Small offset"); - if (!part.IsOccupied) - { - m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center - autopilotTarget = part.AbsolutePosition; -//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); - } - else return; // occupied small - } // end large/small - } // end Scripted/not - cameraAtOffset = part.GetCameraAtOffset(); - cameraEyeOffset = part.GetCameraEyeOffset(); - forceMouselook = part.GetForceMouselook(); - if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // - if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // - - if (m_physicsActor != null) - { - // If we're not using the client autopilot, we're immediately warping the avatar to the location - // We can remove the physicsActor until they stand up. - m_sitAvatarHeight = m_physicsActor.Size.Z; - if (autopilot) - { // its not a scripted sit -// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) - if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) ) - { - autopilot = false; // close enough - m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. - Not using the part's position because returning the AV to the last known standing - position is likely to be more friendly, isn't it? */ - RemoveFromPhysicalScene(); - Velocity = Vector3.Zero; - AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target - } // else the autopilot will get us close - } - else - { // its a scripted sit - m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. - I *am* using the part's position this time because we have no real idea how far away - the avatar is from the sit target. */ - RemoveFromPhysicalScene(); - Velocity = Vector3.Zero; - } - } - else return; // physactor is null! - - Vector3 offsetr; // = offset * partIRot; - // KF: In a linkset, offsetr needs to be relative to the group root! 091208 - // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); - // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. - // { // Single, or Root prim of linkset, target is ClickOffset * RootRot - //offsetr = offset * partIRot; -// - // else - // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) - // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + - // (offset * partRot); - // } - -//Console.WriteLine(" "); -//Console.WriteLine("link number ={0}", part.LinkNum); -//Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); -//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); -//Console.WriteLine("Click offst ={0}", offset); -//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); -//Console.WriteLine("offsetr ={0}", offsetr); -//Console.WriteLine("Camera At ={0}", cameraAtOffset); -//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); - - //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child - ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); - - m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target - // This calls HandleAgentSit twice, once from here, and the client calls - // HandleAgentSit itself after it gets to the location - // It doesn't get to the location until we've moved them there though - // which happens in HandleAgentSit :P - m_autopilotMoving = autopilot; - m_autoPilotTarget = autopilotTarget; - m_sitAtAutoTarget = autopilot; - m_initialSitTarget = autopilotTarget; - if (!autopilot) - HandleAgentSit(remoteClient, UUID); - } - - public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) - { - if (m_parentID != 0) - { - StandUp(); - } - m_nextSitAnimation = "SIT"; - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - - if (part != null) - { - if (!String.IsNullOrEmpty(part.SitAnimation)) - { - m_nextSitAnimation = part.SitAnimation; - } - m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; - m_requestedSitTargetUUID = targetID; - - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); - //SitRayCastAvatarPosition(part); - //return; - } - } - else - { - - m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); - } - - - - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); - } - /* - public void SitRayCastAvatarPosition(SceneObjectPart part) - { - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = AbsolutePosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse); - } - - public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); - } - else - { - SitRayCastAvatarPositionCameraZ(part); - } - } - else - { - SitRayCastAvatarPositionCameraZ(part); - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) - { - // Next, try to raycast from the camera Z position - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse); - } - - public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal); - } - else - { - SitRayCastCameraPosition(part); - } - } - else - { - SitRayCastCameraPosition(part); - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - public void SitRayCastCameraPosition(SceneObjectPart part) - { - // Next, try to raycast from the camera position - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = CameraPosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse); - } - - public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); - } - else - { - SitRayHorizontal(part); - } - } - else - { - SitRayHorizontal(part); - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - public void SitRayHorizontal(SceneObjectPart part) - { - // Next, try to raycast from the avatar position to fwd - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = CameraPosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); - } - - public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) - { - SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); - if (part != null) - { - if (hitYN) - { - if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) - { - SitRaycastFindEdge(collisionPoint, normal); - m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); - // Next, try to raycast from the camera position - Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; - Vector3 StartRayCastPosition = CameraPosition; - Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); - float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); - //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition); - } - else - { - ControllingClient.SendAlertMessage("Sit position not accessable."); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - } - else - { - ControllingClient.SendAlertMessage("Sit position not accessable."); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - } - else - { - ControllingClient.SendAlertMessage("Sit position no longer exists"); - m_requestedSitTargetUUID = UUID.Zero; - m_requestedSitTargetID = 0; - m_requestedSitOffset = Vector3.Zero; - } - - } - - private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) - { - int i = 0; - //throw new NotImplementedException(); - //m_requestedSitTargetUUID = UUID.Zero; - //m_requestedSitTargetID = 0; - //m_requestedSitOffset = Vector3.Zero; - - SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); - } - */ - public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) - { - if (m_parentID != 0) - { - StandUp(); - } - if (!String.IsNullOrEmpty(sitAnimation)) - { - m_nextSitAnimation = sitAnimation; - } - else - { - m_nextSitAnimation = "SIT"; - } - - //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); - SceneObjectPart part = FindNextAvailableSitTarget(targetID); - if (part != null) - { - m_requestedSitTargetID = part.LocalId; - //m_requestedSitOffset = offset; - m_requestedSitTargetUUID = targetID; - - m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); - - if (m_scene.PhysicsScene.SupportsRayCast()) - { - //SitRayCastAvatarPosition(part); - //return; - } - } - else - { - m_log.Warn("Sit requested on unknown object: " + targetID); - } - - SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); - } - - public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) - { - if (!String.IsNullOrEmpty(m_nextSitAnimation)) - { - HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); - } - else - { - HandleAgentSit(remoteClient, agentID, "SIT"); - } - } - - public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) - { - SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); - - if (m_sitAtAutoTarget || !m_autopilotMoving) - { - if (part != null) - { -//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); - if (part.GetAvatarOnSitTarget() == UUID) - { -//Console.WriteLine("Scripted Sit"); - // Scripted sit - Vector3 sitTargetPos = part.SitTargetPosition; - Quaternion sitTargetOrient = part.SitTargetOrientation; - m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); - m_pos += SIT_TARGET_ADJUSTMENT; - if (!part.IsRoot) - { - m_pos *= part.RotationOffset; - } - m_bodyRot = sitTargetOrient; - m_parentPosition = part.AbsolutePosition; - part.IsOccupied = true; - part.ParentGroup.AddAvatar(agentID); - } - else - { - // if m_avUnscriptedSitPos is zero then Av sits above center - // Else Av sits at m_avUnscriptedSitPos - - // Non-scripted sit by Kitto Flora 21Nov09 - // Calculate angle of line from prim to Av - Quaternion partIRot; -// if (part.LinkNum == 1) -// { // Root prim of linkset -// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); -// } -// else -// { // single or child prim - partIRot = Quaternion.Inverse(part.GetWorldRotation()); -// } - Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; - float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); - float x_diff = ( m_avInitialPos.X - sitTargetPos.X); - if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 - if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 - float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); - // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. - // Av sits at world euler <0,0, z>, translated by part rotation - m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click - - m_parentPosition = part.AbsolutePosition; - part.IsOccupied = true; - part.ParentGroup.AddAvatar(agentID); - m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation - (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center - (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + - m_avUnscriptedSitPos; // adds click offset, if any - //Set up raytrace to find top surface of prim - Vector3 size = part.Scale; - float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); - Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); - Vector3 down = new Vector3(0f, 0f, -1f); -//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); - m_scene.PhysicsScene.RaycastWorld( - start, // Vector3 position, - down, // Vector3 direction, - mag, // float length, - SitAltitudeCallback); // retMethod - } // end scripted/not - } - else // no Av - { - return; - } - } - - //We want our offsets to reference the root prim, not the child we may have sat on - if (!part.IsRoot) - { - m_parentID = part.ParentGroup.RootPart.LocalId; - m_pos += part.OffsetPosition; - } - else - { - m_parentID = m_requestedSitTargetID; - } - - m_linkedPrim = part.UUID; - if (part.GetAvatarOnSitTarget() != UUID) - { - m_offsetRotation = m_offsetRotation / part.RotationOffset; - } - Velocity = Vector3.Zero; - RemoveFromPhysicalScene(); - Animator.TrySetMovementAnimation(sitAnimation); - SendFullUpdateToAllClients(); - SendTerseUpdateToAllClients(); - } - - public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) - { - // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer - // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. - if(hitYN) - { - // m_pos = Av offset from prim center to make look like on center - // m_parentPosition = Actual center pos of prim - // collisionPoint = spot on prim where we want to sit - // collisionPoint.Z = global sit surface height - SceneObjectPart part = m_scene.GetSceneObjectPart(localid); - Quaternion partIRot; -// if (part.LinkNum == 1) -/// { // Root prim of linkset -// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); -// } -// else -// { // single or child prim - partIRot = Quaternion.Inverse(part.GetWorldRotation()); -// } - if (m_initialSitTarget != null) - { - float offZ = collisionPoint.Z - m_initialSitTarget.Z; - Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction - //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); - m_pos += offset; - // ControllingClient.SendClearFollowCamProperties(part.UUID); - } - - } - } // End SitAltitudeCallback KF. - - /// - /// Event handler for the 'Always run' setting on the client - /// Tells the physics plugin to increase speed of movement. - /// - public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun) - { - m_setAlwaysRun = pSetAlwaysRun; - if (PhysicsActor != null) - { - PhysicsActor.SetAlwaysRun = pSetAlwaysRun; - } - } - - public void HandleStartAnim(IClientAPI remoteClient, UUID animID) - { - Animator.AddAnimation(animID, UUID.Zero); - } - - public void HandleStopAnim(IClientAPI remoteClient, UUID animID) - { - Animator.RemoveAnimation(animID); - } - - /// - /// Rotate the avatar to the given rotation and apply a movement in the given relative vector - /// - /// The vector in which to move. This is relative to the rotation argument - /// The direction in which this avatar should now face. - public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) - { - if (m_isChildAgent) - { - // WHAT??? - m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); - - // we have to reset the user's child agent connections. - // Likely, here they've lost the eventqueue for other regions so border - // crossings will fail at this point unless we reset them. - - List regions = new List(KnownChildRegionHandles); - regions.Remove(m_scene.RegionInfo.RegionHandle); - - MakeRootAgent(new Vector3(127f, 127f, 127f), true); - - // Async command - if (m_scene.SceneGridService != null) - { - m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions); - - // Give the above command some time to try and close the connections. - // this is really an emergency.. so sleep, or we'll get all discombobulated. - System.Threading.Thread.Sleep(500); - } - - if (m_scene.SceneGridService != null) - { - IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); - if (m_agentTransfer != null) - m_agentTransfer.EnableChildAgents(this); - } - - return; - } - - m_perfMonMS = Util.EnvironmentTickCount(); - - Rotation = rotation; - Vector3 direc = vec * rotation; - direc.Normalize(); - PhysicsActor actor = m_physicsActor; - if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. - - direc *= 0.03f * 128f * m_speedModifier; - - if (actor != null) - { - if (actor.Flying) - { - direc *= 4.0f; - //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); - //bool colliding = (m_physicsActor.IsColliding==true); - //if (controlland) - // m_log.Info("[AGENT]: landCommand"); - //if (colliding) - // m_log.Info("[AGENT]: colliding"); - //if (m_physicsActor.Flying && colliding && controlland) - //{ - // StopFlying(); - // m_log.Info("[AGENT]: Stop FLying"); - //} - } - else if (!actor.Flying && actor.IsColliding) - { - if (direc.Z > 2.0f) - { - if(m_animator.m_animTickJump == -1) - { - direc.Z *= 3.0f; // jump - } - else - { - direc.Z *= 0.1f; // prejump - } - /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs - Animator.TrySetMovementAnimation("PREJUMP"); - Animator.TrySetMovementAnimation("JUMP"); - */ - } - } - } - - // TODO: Add the force instead of only setting it to support multiple forces per frame? - m_forceToApply = direc; - m_isNudging = Nudging; - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - #endregion - - #region Overridden Methods - - public override void Update() - { - const float ROTATION_TOLERANCE = 0.01f; - const float VELOCITY_TOLERANCE = 0.001f; - const float POSITION_TOLERANCE = 0.05f; - //const int TIME_MS_TOLERANCE = 3000; - - - - if (m_isChildAgent == false) - { -// PhysicsActor actor = m_physicsActor; - - // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to - // grab the latest PhysicsActor velocity, whereas m_velocity is often - // storing a requested force instead of an actual traveling velocity - - // Throw away duplicate or insignificant updates - if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || - !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || - !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) - //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) - { - SendTerseUpdateToAllClients(); - - // Update the "last" values - m_lastPosition = m_pos; - m_lastRotation = m_bodyRot; - m_lastVelocity = Velocity; - //m_lastTerseSent = Environment.TickCount; - } - - // followed suggestion from mic bowman. reversed the two lines below. - if (m_parentID == 0 && m_physicsActor != null || m_parentID != 0) // Check that we have a physics actor or we're sitting on something - CheckForBorderCrossing(); - CheckForSignificantMovement(); // sends update to the modules. - } - - //Sending prim updates AFTER the avatar terse updates are sent - SendPrimUpdates(); - } - - #endregion - - #region Update Client(s) - - /// - /// Sends a location update to the client connected to this scenePresence - /// - /// - public void SendTerseUpdateToClient(IClientAPI remoteClient) - { - // If the client is inactive, it's getting its updates from another - // server. - if (remoteClient.IsActive) - { - m_perfMonMS = Util.EnvironmentTickCount(); - - PhysicsActor actor = m_physicsActor; - Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); - - remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - m_scene.StatsReporter.AddAgentUpdates(1); - } - } - - /// - /// Send a location/velocity/accelleration update to all agents in scene - /// - public void SendTerseUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - m_scene.ForEachClient(SendTerseUpdateToClient); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - public void SendCoarseLocations(List coarseLocations, List avatarUUIDs) - { - SendCourseLocationsMethod d = m_sendCourseLocationsMethod; - if (d != null) - { - d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); - } - } - - public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) - { - if (d != null) - m_sendCourseLocationsMethod = d; - } - - public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List coarseLocations, List avatarUUIDs) - { - m_perfMonMS = Util.EnvironmentTickCount(); - m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - /// - /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) - /// - /// - public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) - { - // 2 stage check is needed. - if (remoteAvatar == null) - return; - IClientAPI cl=remoteAvatar.ControllingClient; - if (cl == null) - return; - if (m_appearance.Texture == null) - return; - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); - m_scene.StatsReporter.AddAgentUpdates(1); - } - - /// - /// Tell *ALL* agents about this agent - /// - public void SendInitialFullUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - int avUpdates = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - ++avUpdates; - // only send if this is the root (children are only "listening posts" in a foreign region) - if (!IsChildAgent) - { - SendFullUpdateToOtherClient(avatar); - } - - if (avatar.LocalId != LocalId) - { - if (!avatar.IsChildAgent) - { - avatar.SendFullUpdateToOtherClient(this); - avatar.SendAppearanceToOtherAgent(this); - avatar.Animator.SendAnimPackToClient(ControllingClient); - } - } - }); - - m_scene.StatsReporter.AddAgentUpdates(avUpdates); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - //Animator.SendAnimPack(); - } - - public void SendFullUpdateToAllClients() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - // only send update from root agents to other clients; children are only "listening posts" - int count = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence sp) - { - if (sp.IsChildAgent) - return; - SendFullUpdateToOtherClient(sp); - ++count; - }); - m_scene.StatsReporter.AddAgentUpdates(count); - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - Animator.SendAnimPack(); - } - - /// - /// Do everything required once a client completes its movement into a region - /// - public void SendInitialData() - { - // Moved this into CompleteMovement to ensure that m_appearance is initialized before - // the inventory arrives - // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - m_controllingClient.SendAvatarDataImmediate(this); - - SendInitialFullUpdateToAllClients(); - SendAppearanceToAllOtherAgents(); - } - - /// - /// Tell the client for this scene presence what items it should be wearing now - /// - public void SendWearables() - { - m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); - - ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); - } - - /// - /// - /// - public void SendAppearanceToAllOtherAgents() - { - m_perfMonMS = Util.EnvironmentTickCount(); - - m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) - { - if (scenePresence.UUID != UUID) - { - SendAppearanceToOtherAgent(scenePresence); - } - }); - - m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - } - - /// - /// Send appearance data to an agent that isn't this one. - /// - /// - public void SendAppearanceToOtherAgent(ScenePresence avatar) - { - avatar.ControllingClient.SendAppearance( - m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); - } - - /// - /// Set appearance data (textureentry and slider settings) received from the client - /// - /// - /// - public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) - { - if (m_physicsActor != null) - { - if (!IsChildAgent) - { - // This may seem like it's redundant, remove the avatar from the physics scene - // just to add it back again, but it saves us from having to update - // 3 variables 10 times a second. - bool flyingTemp = m_physicsActor.Flying; - RemoveFromPhysicalScene(); - //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); - - //PhysicsActor = null; - - AddToPhysicalScene(flyingTemp); - } - } - - #region Bake Cache Check - - if (textureEntry != null) - { - for (int i = 0; i < BAKE_INDICES.Length; i++) - { - int j = BAKE_INDICES[i]; - Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; - - if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) - { - if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) - { - m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); - this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); - } - } - } - - } - - - #endregion Bake Cache Check - - m_appearance.SetAppearance(textureEntry, visualParams); - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); - - // This is not needed, because only the transient data changed - //AvatarData adata = new AvatarData(m_appearance); - //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); - - SendAppearanceToAllOtherAgents(); - if (!m_startAnimationSet) - { - Animator.UpdateMovementAnimations(); - m_startAnimationSet = true; - } - - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; - - m_controllingClient.SendAvatarDataImmediate(this); - } - - public void SetWearable(int wearableId, AvatarWearable wearable) - { - m_appearance.SetWearable(wearableId, wearable); - AvatarData adata = new AvatarData(m_appearance); - m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); - m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); - } - - // Because appearance setting is in a module, we actually need - // to give it access to our appearance directly, otherwise we - // get a synchronization issue. - public AvatarAppearance Appearance - { - get { return m_appearance; } - set { m_appearance = value; } - } - - #endregion - - #region Significant Movement Method - - /// - /// This checks for a significant movement and sends a courselocationchange update - /// - protected void CheckForSignificantMovement() - { - // Movement updates for agents in neighboring regions are sent directly to clients. - // This value only affects how often agent positions are sent to neighbor regions - // for things such as distance-based update prioritization - const float SIGNIFICANT_MOVEMENT = 2.0f; - - if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) - { - posLastSignificantMove = AbsolutePosition; - m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); - } - - // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m - if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || - Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) - { - m_lastChildAgentUpdatePosition = AbsolutePosition; - m_lastChildAgentUpdateCamPosition = CameraPosition; - - ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); - cadu.ActiveGroupID = UUID.Zero.Guid; - cadu.AgentID = UUID.Guid; - cadu.alwaysrun = m_setAlwaysRun; - cadu.AVHeight = m_avHeight; - Vector3 tempCameraCenter = m_CameraCenter; - cadu.cameraPosition = tempCameraCenter; - cadu.drawdistance = m_DrawDistance; - cadu.GroupAccess = 0; - cadu.Position = AbsolutePosition; - cadu.regionHandle = m_rootRegionHandle; - float multiplier = 1; - int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); - if (innacurateNeighbors != 0) - { - multiplier = 1f / (float)innacurateNeighbors; - } - if (multiplier <= 0f) - { - multiplier = 0.25f; - } - - //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); - cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); - cadu.Velocity = Velocity; - - AgentPosition agentpos = new AgentPosition(); - agentpos.CopyFrom(cadu); - - m_scene.SendOutChildAgentUpdates(agentpos, this); - } - } - - #endregion - - #region Border Crossing Methods - - /// - /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion - /// - protected void CheckForBorderCrossing() - { - if (IsChildAgent) - return; - - Vector3 pos2 = AbsolutePosition; - Vector3 vel = Velocity; - int neighbor = 0; - int[] fix = new int[2]; - - float timeStep = 0.1f; - pos2.X = pos2.X + (vel.X*timeStep); - pos2.Y = pos2.Y + (vel.Y*timeStep); - pos2.Z = pos2.Z + (vel.Z*timeStep); - - if (!IsInTransit) - { - // Checks if where it's headed exists a region - - bool needsTransit = false; - if (m_scene.TestBorderCross(pos2, Cardinals.W)) - { - if (m_scene.TestBorderCross(pos2, Cardinals.S)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.SW, ref fix); - } - else if (m_scene.TestBorderCross(pos2, Cardinals.N)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.NW, ref fix); - } - else - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.W, ref fix); - } - } - else if (m_scene.TestBorderCross(pos2, Cardinals.E)) - { - if (m_scene.TestBorderCross(pos2, Cardinals.S)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.SE, ref fix); - } - else if (m_scene.TestBorderCross(pos2, Cardinals.N)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.NE, ref fix); - } - else - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.E, ref fix); - } - } - else if (m_scene.TestBorderCross(pos2, Cardinals.S)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.S, ref fix); - } - else if (m_scene.TestBorderCross(pos2, Cardinals.N)) - { - needsTransit = true; - neighbor = HaveNeighbor(Cardinals.N, ref fix); - } - - - // Makes sure avatar does not end up outside region - if (neighbor <= 0) - { - if (!needsTransit) - { - if (m_requestedSitTargetUUID == UUID.Zero) - { - Vector3 pos = AbsolutePosition; - if (AbsolutePosition.X < 0) - pos.X += Velocity.X; - else if (AbsolutePosition.X > Constants.RegionSize) - pos.X -= Velocity.X; - if (AbsolutePosition.Y < 0) - pos.Y += Velocity.Y; - else if (AbsolutePosition.Y > Constants.RegionSize) - pos.Y -= Velocity.Y; - AbsolutePosition = pos; - } - } - } - else if (neighbor > 0) - CrossToNewRegion(); - } - else - { - RemoveFromPhysicalScene(); - // This constant has been inferred from experimentation - // I'm not sure what this value should be, so I tried a few values. - timeStep = 0.04f; - pos2 = AbsolutePosition; - pos2.X = pos2.X + (vel.X * timeStep); - pos2.Y = pos2.Y + (vel.Y * timeStep); - pos2.Z = pos2.Z + (vel.Z * timeStep); - m_pos = pos2; - } - } - - protected int HaveNeighbor(Cardinals car, ref int[] fix) - { - uint neighbourx = m_regionInfo.RegionLocX; - uint neighboury = m_regionInfo.RegionLocY; - - int dir = (int)car; - - if (dir > 1 && dir < 5) //Heading East - neighbourx++; - else if (dir > 5) // Heading West - neighbourx--; - - if (dir < 3 || dir == 8) // Heading North - neighboury++; - else if (dir > 3 && dir < 7) // Heading Sout - neighboury--; - - int x = (int)(neighbourx * Constants.RegionSize); - int y = (int)(neighboury * Constants.RegionSize); - GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y); - - if (neighbourRegion == null) - { - fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); - fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); - return dir * (-1); - } - else - return dir; - } - - /// - /// Moves the agent outside the region bounds - /// Tells neighbor region that we're crossing to it - /// If the neighbor accepts, remove the agent's viewable avatar from this scene - /// set them to a child agent. - /// - protected void CrossToNewRegion() - { - InTransit(); - try - { - m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); - } - catch - { - m_scene.CrossAgentToNewRegion(this, false); - } - } - - public void InTransit() - { - m_inTransit = true; - - if ((m_physicsActor != null) && m_physicsActor.Flying) - m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; - else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) - m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; - } - - public void NotInTransit() - { - m_inTransit = false; - } - - public void RestoreInCurrentScene() - { - AddToPhysicalScene(false); // not exactly false - } - - public void Reset() - { - // Put the child agent back at the center - AbsolutePosition - = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); - Animator.ResetAnimations(); - } - - /// - /// Computes which child agents to close when the scene presence moves to another region. - /// Removes those regions from m_knownRegions. - /// - /// The new region's x on the map - /// The new region's y on the map - /// - public void CloseChildAgents(uint newRegionX, uint newRegionY) - { - List byebyeRegions = new List(); - m_log.DebugFormat( - "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", - m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); - //DumpKnownRegions(); - - lock (m_knownChildRegions) - { - foreach (ulong handle in m_knownChildRegions.Keys) - { - // Don't close the agent on this region yet - if (handle != Scene.RegionInfo.RegionHandle) - { - uint x, y; - Utils.LongToUInts(handle, out x, out y); - x = x / Constants.RegionSize; - y = y / Constants.RegionSize; - - //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); - //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); - if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) - { - byebyeRegions.Add(handle); - } - } - } - } - - if (byebyeRegions.Count > 0) - { - m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); - m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); - } - - foreach (ulong handle in byebyeRegions) - { - RemoveNeighbourRegion(handle); - } - } - - #endregion - - /// - /// This allows the Sim owner the abiility to kick users from their sim currently. - /// It tells the client that the agent has permission to do so. - /// - public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) - { - if (godStatus) - { - // For now, assign god level 200 to anyone - // who is granted god powers, but has no god level set. - // - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID); - if (account != null) - { - if (account.UserLevel > 0) - m_godLevel = account.UserLevel; - else - m_godLevel = 200; - } - } - else - { - m_godLevel = 0; - } - - ControllingClient.SendAdminResponse(token, (uint)m_godLevel); - } - - #region Child Agent Updates - - public void ChildAgentDataUpdate(AgentData cAgentData) - { - //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); - if (!IsChildAgent) - return; - - CopyFrom(cAgentData); - } - - /// - /// This updates important decision making data about a child agent - /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region - /// - public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) - { - if (!IsChildAgent) - return; - - //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); - int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; - int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; - - Vector3 offset = new Vector3(shiftx, shifty, 0f); - - m_DrawDistance = cAgentData.Far; - if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! - m_pos = cAgentData.Position + offset; - - if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) - { - posLastSignificantMove = AbsolutePosition; - ReprioritizeUpdates(); - } - - m_CameraCenter = cAgentData.Center + offset; - - m_avHeight = cAgentData.Size.Z; - //SetHeight(cAgentData.AVHeight); - - if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) - ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); - - // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. - if (m_scene.m_seeIntoRegionFromNeighbor) - m_sceneViewer.Reset(); - - //cAgentData.AVHeight; - m_rootRegionHandle = cAgentData.RegionHandle; - //m_velocity = cAgentData.Velocity; - } - - public void CopyTo(AgentData cAgent) - { - cAgent.AgentID = UUID; - cAgent.RegionID = Scene.RegionInfo.RegionID; - - cAgent.Position = AbsolutePosition; - cAgent.Velocity = m_velocity; - cAgent.Center = m_CameraCenter; - // Don't copy the size; it is inferred from apearance parameters - //cAgent.Size = new Vector3(0, 0, m_avHeight); - cAgent.AtAxis = m_CameraAtAxis; - cAgent.LeftAxis = m_CameraLeftAxis; - cAgent.UpAxis = m_CameraUpAxis; - - cAgent.Far = m_DrawDistance; - - // Throttles - float multiplier = 1; - int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); - if (innacurateNeighbors != 0) - { - multiplier = 1f / innacurateNeighbors; - } - if (multiplier <= 0f) - { - multiplier = 0.25f; - } - //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); - cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); - - cAgent.HeadRotation = m_headrotation; - cAgent.BodyRotation = m_bodyRot; - cAgent.ControlFlags = (uint)m_AgentControlFlags; - - if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - cAgent.GodLevel = (byte)m_godLevel; - else - cAgent.GodLevel = (byte) 0; - - cAgent.AlwaysRun = m_setAlwaysRun; - - try - { - // We might not pass the Wearables in all cases... - // They're only needed so that persistent changes to the appearance - // are preserved in the new region where the user is moving to. - // But in Hypergrid we might not let this happen. - int i = 0; - UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; - foreach (AvatarWearable aw in m_appearance.Wearables) - { - if (aw != null) - { - wears[i++] = aw.ItemID; - wears[i++] = aw.AssetID; - } - else - { - wears[i++] = UUID.Zero; - wears[i++] = UUID.Zero; - } - } - cAgent.Wearables = wears; - - cAgent.VisualParams = m_appearance.VisualParams; - - if (m_appearance.Texture != null) - cAgent.AgentTextures = m_appearance.Texture.GetBytes(); - } - catch (Exception e) - { - m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); - } - - //Attachments - List attPoints = m_appearance.GetAttachedPoints(); - if (attPoints != null) - { - //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); - int i = 0; - AttachmentData[] attachs = new AttachmentData[attPoints.Count]; - foreach (int point in attPoints) - { - attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); - } - cAgent.Attachments = attachs; - } - - lock (scriptedcontrols) - { - ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; - int i = 0; - - foreach (ScriptControllers c in scriptedcontrols.Values) - { - controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); - } - cAgent.Controllers = controls; - } - - // Animations - try - { - cAgent.Anims = Animator.Animations.ToArray(); - } - catch { } - - // cAgent.GroupID = ?? - // Groups??? - - } - - public void CopyFrom(AgentData cAgent) - { - m_originRegionID = cAgent.RegionID; - - m_callbackURI = cAgent.CallbackURI; - - m_pos = cAgent.Position; - - m_velocity = cAgent.Velocity; - m_CameraCenter = cAgent.Center; - //m_avHeight = cAgent.Size.Z; - m_CameraAtAxis = cAgent.AtAxis; - m_CameraLeftAxis = cAgent.LeftAxis; - m_CameraUpAxis = cAgent.UpAxis; - - m_DrawDistance = cAgent.Far; - - if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) - ControllingClient.SetChildAgentThrottle(cAgent.Throttles); - - m_headrotation = cAgent.HeadRotation; - m_bodyRot = cAgent.BodyRotation; - m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; - - if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) - m_godLevel = cAgent.GodLevel; - m_setAlwaysRun = cAgent.AlwaysRun; - - uint i = 0; - try - { - if (cAgent.Wearables == null) - cAgent.Wearables = new UUID[0]; - AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; - for (uint n = 0; n < cAgent.Wearables.Length; n += 2) - { - UUID itemId = cAgent.Wearables[n]; - UUID assetId = cAgent.Wearables[n + 1]; - wears[i++] = new AvatarWearable(itemId, assetId); - } - m_appearance.Wearables = wears; - Primitive.TextureEntry te; - if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) - te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); - else - te = AvatarAppearance.GetDefaultTexture(); - if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) - cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); - m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); - } - catch (Exception e) - { - m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); - } - - // Attachments - try - { - if (cAgent.Attachments != null) - { - m_appearance.ClearAttachments(); - foreach (AttachmentData att in cAgent.Attachments) - { - m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); - } - } - } - catch { } - - try - { - lock (scriptedcontrols) - { - if (cAgent.Controllers != null) - { - scriptedcontrols.Clear(); - - foreach (ControllerData c in cAgent.Controllers) - { - ScriptControllers sc = new ScriptControllers(); - sc.itemID = c.ItemID; - sc.ignoreControls = (ScriptControlled)c.IgnoreControls; - sc.eventControls = (ScriptControlled)c.EventControls; - - scriptedcontrols[sc.itemID] = sc; - } - } - } - } - catch { } - // Animations - try - { - Animator.ResetAnimations(); - Animator.Animations.FromArray(cAgent.Anims); - } - catch { } - - //cAgent.GroupID = ?? - //Groups??? - } - - public bool CopyAgent(out IAgentData agent) - { - agent = new CompleteAgentData(); - CopyTo((AgentData)agent); - return true; - } - - #endregion Child Agent Updates - - /// - /// Handles part of the PID controller function for moving an avatar. - /// - public override void UpdateMovement() - { - if (m_forceToApply.HasValue) - { - - Vector3 force = m_forceToApply.Value; - m_updateflag = true; - Velocity = force; - - m_forceToApply = null; - } - else - { - if (m_isNudging) - { - Vector3 force = Vector3.Zero; - - m_updateflag = true; - Velocity = force; - m_isNudging = false; - m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" - } - } - } - - public override void SetText(string text, Vector3 color, double alpha) - { - throw new Exception("Can't set Text on avatar."); - } - - /// - /// Adds a physical representation of the avatar to the Physics plugin - /// - public void AddToPhysicalScene(bool isFlying) - { - PhysicsScene scene = m_scene.PhysicsScene; - - Vector3 pVec = AbsolutePosition; - - // Old bug where the height was in centimeters instead of meters - if (m_avHeight == 127.0f) - { - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f), - isFlying); - } - else - { - m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, - new Vector3(0f, 0f, m_avHeight), isFlying); - } - scene.AddPhysicsActorTaint(m_physicsActor); - //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; - m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; - m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong - m_physicsActor.SubscribeEvents(500); - m_physicsActor.LocalID = LocalId; - } - - private void OutOfBoundsCall(Vector3 pos) - { - //bool flying = m_physicsActor.Flying; - //RemoveFromPhysicalScene(); - - //AddToPhysicalScene(flying); - if (ControllingClient != null) - ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); - } - - // Event called by the physics plugin to tell the avatar about a collision. - private void PhysicsCollisionUpdate(EventArgs e) - { - if (e == null) - return; - - // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( - // as of this comment the interval is set in AddToPhysicalScene - if (Animator!=null) - { - if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, - { // else its will lock out other animation changes, like ground sit. - Animator.UpdateMovementAnimations(); - m_updateCount--; - } - } - - CollisionEventUpdate collisionData = (CollisionEventUpdate)e; - Dictionary coldata = collisionData.m_objCollisionList; - - CollisionPlane = Vector4.UnitW; - - if (m_lastColCount != coldata.Count) - { - m_updateCount = UPDATE_COUNT; - m_lastColCount = coldata.Count; - } - - if (coldata.Count != 0 && Animator != null) - { - switch (Animator.CurrentMovementAnimation) - { - case "STAND": - case "WALK": - case "RUN": - case "CROUCH": - case "CROUCHWALK": - { - ContactPoint lowest; - lowest.SurfaceNormal = Vector3.Zero; - lowest.Position = Vector3.Zero; - lowest.Position.Z = Single.NaN; - - foreach (ContactPoint contact in coldata.Values) - { - if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) - { - lowest = contact; - } - } - - CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); - } - break; - } - } - - List thisHitColliders = new List(); - List endedColliders = new List(); - List startedColliders = new List(); - - foreach (uint localid in coldata.Keys) - { - thisHitColliders.Add(localid); - if (!m_lastColliders.Contains(localid)) - { - startedColliders.Add(localid); - } - //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); - } - - // calculate things that ended colliding - foreach (uint localID in m_lastColliders) - { - if (!thisHitColliders.Contains(localID)) - { - endedColliders.Add(localID); - } - } - //add the items that started colliding this time to the last colliders list. - foreach (uint localID in startedColliders) - { - m_lastColliders.Add(localID); - } - // remove things that ended colliding from the last colliders list - foreach (uint localID in endedColliders) - { - m_lastColliders.Remove(localID); - } - - // do event notification - if (startedColliders.Count > 0) - { - ColliderArgs StartCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in startedColliders) - { - if (localId == 0) - continue; - - SceneObjectPart obj = Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - StartCollidingMessage.Colliders = colliding; - - foreach (SceneObjectGroup att in Attachments) - Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); - } - } - - if (endedColliders.Count > 0) - { - ColliderArgs EndCollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in endedColliders) - { - if (localId == 0) - continue; - - SceneObjectPart obj = Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - EndCollidingMessage.Colliders = colliding; - - foreach (SceneObjectGroup att in Attachments) - Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); - } - } - - if (thisHitColliders.Count > 0) - { - ColliderArgs CollidingMessage = new ColliderArgs(); - List colliding = new List(); - foreach (uint localId in thisHitColliders) - { - if (localId == 0) - continue; - - SceneObjectPart obj = Scene.GetSceneObjectPart(localId); - string data = ""; - if (obj != null) - { - DetectedObject detobj = new DetectedObject(); - detobj.keyUUID = obj.UUID; - detobj.nameStr = obj.Name; - detobj.ownerUUID = obj.OwnerID; - detobj.posVector = obj.AbsolutePosition; - detobj.rotQuat = obj.GetWorldRotation(); - detobj.velVector = obj.Velocity; - detobj.colliderType = 0; - detobj.groupUUID = obj.GroupID; - colliding.Add(detobj); - } - } - - if (colliding.Count > 0) - { - CollidingMessage.Colliders = colliding; - - lock (m_attachments) - { - foreach (SceneObjectGroup att in m_attachments) - Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); - } - } - } - - if (m_invulnerable) - return; - - float starthealth = Health; - uint killerObj = 0; - foreach (uint localid in coldata.Keys) - { - SceneObjectPart part = Scene.GetSceneObjectPart(localid); - - if (part != null && part.ParentGroup.Damage != -1.0f) - Health -= part.ParentGroup.Damage; - else - { - if (coldata[localid].PenetrationDepth >= 0.10f) - Health -= coldata[localid].PenetrationDepth * 5.0f; - } - - if (Health <= 0.0f) - { - if (localid != 0) - killerObj = localid; - } - //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); - } - //Health = 100; - if (!m_invulnerable) - { - if (starthealth != Health) - { - ControllingClient.SendHealth(Health); - } - if (m_health <= 0) - m_scene.EventManager.TriggerAvatarKill(killerObj, this); - } - } - - public void setHealthWithUpdate(float health) - { - Health = health; - ControllingClient.SendHealth(Health); - } - - public void Close() - { - lock (m_attachments) - { - // Delete attachments from scene - // Don't try to save, as this thread won't live long - // enough to complete the save. This would cause no copy - // attachments to poof! - // - foreach (SceneObjectGroup grp in m_attachments) - { - m_scene.DeleteSceneObject(grp, false); - } - m_attachments.Clear(); - } - - lock (m_knownChildRegions) - { - m_knownChildRegions.Clear(); - } - - lock (m_reprioritization_timer) - { - m_reprioritization_timer.Enabled = false; - m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); - } - - // I don't get it but mono crashes when you try to dispose of this timer, - // unsetting the elapsed callback should be enough to allow for cleanup however. - // m_reprioritizationTimer.Dispose(); - - m_sceneViewer.Close(); - - RemoveFromPhysicalScene(); - m_animator.Close(); - m_animator = null; - } - - public void AddAttachment(SceneObjectGroup gobj) - { - lock (m_attachments) - { - m_attachments.Add(gobj); - } - } - - public bool HasAttachments() - { - return m_attachments.Count > 0; - } - - public bool HasScriptedAttachments() - { - lock (m_attachments) - { - foreach (SceneObjectGroup gobj in m_attachments) - { - if (gobj != null) - { - if (gobj.RootPart.Inventory.ContainsScripts()) - return true; - } - } - } - return false; - } - - public void RemoveAttachment(SceneObjectGroup gobj) - { - lock (m_attachments) - { - if (m_attachments.Contains(gobj)) - { - m_attachments.Remove(gobj); - } - } - } - - public bool ValidateAttachments() - { - lock (m_attachments) - { - // Validate - foreach (SceneObjectGroup gobj in m_attachments) - { - if (gobj == null) - return false; - - if (gobj.IsDeleted) - return false; - } - } - return true; - } - - /// - /// Send a script event to this scene presence's attachments - /// - /// The name of the event - /// The arguments for the event - public void SendScriptEventToAttachments(string eventName, Object[] args) - { - if (m_scriptEngines != null) - { - lock (m_attachments) - { - foreach (SceneObjectGroup grp in m_attachments) - { - // 16384 is CHANGED_ANIMATION - // - // Send this to all attachment root prims - // - foreach (IScriptModule m in m_scriptEngines) - { - if (m == null) // No script engine loaded - continue; - - m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); - } - } - } - } - } - - - public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) - { - m_controllingClient = client; - m_regionInfo = region; - m_scene = scene; - - RegisterToEvents(); - if (m_controllingClient != null) - { - m_controllingClient.ProcessPendingPackets(); - } - /* - AbsolutePosition = client.StartPos; - - Animations = new AvatarAnimations(); - Animations.LoadAnims(); - - m_animations = new List(); - m_animations.Add(Animations.AnimsUUID["STAND"]); - m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); - - SetDirectionVectors(); - */ - } - - internal void PushForce(Vector3 impulse) - { - if (PhysicsActor != null) - { - PhysicsActor.AddForce(impulse,true); - } - } - - public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) - { - ScriptControllers obj = new ScriptControllers(); - obj.ignoreControls = ScriptControlled.CONTROL_ZERO; - obj.eventControls = ScriptControlled.CONTROL_ZERO; - - obj.itemID = Script_item_UUID; - if (pass_on == 0 && accept == 0) - { - IgnoredControls |= (ScriptControlled)controls; - obj.ignoreControls = (ScriptControlled)controls; - } - - if (pass_on == 0 && accept == 1) - { - IgnoredControls |= (ScriptControlled)controls; - obj.ignoreControls = (ScriptControlled)controls; - obj.eventControls = (ScriptControlled)controls; - } - if (pass_on == 1 && accept == 1) - { - IgnoredControls = ScriptControlled.CONTROL_ZERO; - obj.eventControls = (ScriptControlled)controls; - obj.ignoreControls = ScriptControlled.CONTROL_ZERO; - } - - lock (scriptedcontrols) - { - if (pass_on == 1 && accept == 0) - { - IgnoredControls &= ~(ScriptControlled)controls; - if (scriptedcontrols.ContainsKey(Script_item_UUID)) - scriptedcontrols.Remove(Script_item_UUID); - } - else - { - scriptedcontrols[Script_item_UUID] = obj; - } - } - ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); - } - - public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) - { - IgnoredControls = ScriptControlled.CONTROL_ZERO; - lock (scriptedcontrols) - { - scriptedcontrols.Clear(); - } - ControllingClient.SendTakeControls(int.MaxValue, false, false); - } - - public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) - { - ScriptControllers takecontrols; - - lock (scriptedcontrols) - { - if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) - { - ScriptControlled sctc = takecontrols.eventControls; - - ControllingClient.SendTakeControls((int)sctc, false, false); - ControllingClient.SendTakeControls((int)sctc, true, false); - - scriptedcontrols.Remove(Script_item_UUID); - IgnoredControls = ScriptControlled.CONTROL_ZERO; - foreach (ScriptControllers scData in scriptedcontrols.Values) - { - IgnoredControls |= scData.ignoreControls; - } - } - } - } - - internal void SendControlToScripts(uint flags) - { - ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; - - if (MouseDown) - { - allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) - { - allflags = ScriptControlled.CONTROL_ZERO; - MouseDown = true; - } - } - - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) - { - allflags |= ScriptControlled.CONTROL_ML_LBUTTON; - MouseDown = true; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) - { - allflags |= ScriptControlled.CONTROL_LBUTTON; - MouseDown = true; - } - - // find all activated controls, whether the scripts are interested in them or not - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_FWD; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_BACK; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_UP; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_DOWN; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_LEFT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_RIGHT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) - { - allflags |= ScriptControlled.CONTROL_ROT_RIGHT; - } - if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) - { - allflags |= ScriptControlled.CONTROL_ROT_LEFT; - } - // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that - if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) - { - lock (scriptedcontrols) - { - foreach (KeyValuePair kvp in scriptedcontrols) - { - UUID scriptUUID = kvp.Key; - ScriptControllers scriptControlData = kvp.Value; - - ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us - ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle - ScriptControlled localChange = localHeld ^ localLast; // the changed bits - if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) - { - // only send if still pressed or just changed - m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange); - } - } - } - } - - LastCommands = allflags; - } - - internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) - { - if (ignored == ScriptControlled.CONTROL_ZERO) - return flags; - - if ((ignored & ScriptControlled.CONTROL_BACK) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); - if ((ignored & ScriptControlled.CONTROL_FWD) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); - if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); - if ((ignored & ScriptControlled.CONTROL_UP) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); - if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); - if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); - if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); - if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); - if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); - if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) - flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); - - //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, - //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, - //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, - //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, - //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, - //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, - //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG - - return flags; - } - - /// - /// RezAttachments. This should only be called upon login on the first region. - /// Attachment rezzings on crossings and TPs are done in a different way. - /// - public void RezAttachments() - { - if (null == m_appearance) - { - m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); - return; - } - - XmlDocument doc = new XmlDocument(); - string stateData = String.Empty; - - IAttachmentsService attServ = m_scene.RequestModuleInterface(); - if (attServ != null) - { - m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); - stateData = attServ.Get(ControllingClient.AgentId.ToString()); - if (stateData != String.Empty) - { - try - { - doc.LoadXml(stateData); - } - catch { } - } - } - - Dictionary itemData = new Dictionary(); - - XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); - if (nodes.Count > 0) - { - foreach (XmlNode n in nodes) - { - XmlElement elem = (XmlElement)n; - string itemID = elem.GetAttribute("ItemID"); - string xml = elem.InnerXml; - - itemData[new UUID(itemID)] = xml; - } - } - - List attPoints = m_appearance.GetAttachedPoints(); - foreach (int p in attPoints) - { - if (m_isDeleted) - return; - - UUID itemID = m_appearance.GetAttachedItem(p); - UUID assetID = m_appearance.GetAttachedAsset(p); - - // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down - // But they're not used anyway, the item is being looked up for now, so let's proceed. - //if (UUID.Zero == assetID) - //{ - // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); - // continue; - //} - - try - { - string xmlData; - XmlDocument d = new XmlDocument(); - UUID asset; - if (itemData.TryGetValue(itemID, out xmlData)) - { - d.LoadXml(xmlData); - m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); - - // Rez from inventory - asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); - - } - else - { - // Rez from inventory (with a null doc to let - // CHANGED_OWNER happen) - asset - = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); - } - - m_log.InfoFormat( - "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", - p, itemID, assetID, asset); - } - catch (Exception e) - { - m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); - } - } - } - - private void ReprioritizeUpdates() - { - if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) - { - lock (m_reprioritization_timer) - { - if (!m_reprioritizing) - m_reprioritization_timer.Enabled = m_reprioritizing = true; - else - m_reprioritization_called = true; - } - } - } - - private void Reprioritize(object sender, ElapsedEventArgs e) - { - m_controllingClient.ReprioritizeUpdates(); - - lock (m_reprioritization_timer) - { - m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; - m_reprioritization_called = false; - } - } - - private Vector3 Quat2Euler(Quaternion rot){ - float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , - (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); - float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); - float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , - (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); - return(new Vector3(x,y,z)); - } - - - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Xml; +using System.Collections.Generic; +using System.Reflection; +using System.Timers; +using OpenMetaverse; +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes.Animation; +using OpenSim.Region.Framework.Scenes.Types; +using OpenSim.Region.Physics.Manager; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Services.Interfaces; + +namespace OpenSim.Region.Framework.Scenes +{ + enum ScriptControlled : uint + { + CONTROL_ZERO = 0, + CONTROL_FWD = 1, + CONTROL_BACK = 2, + CONTROL_LEFT = 4, + CONTROL_RIGHT = 8, + CONTROL_UP = 16, + CONTROL_DOWN = 32, + CONTROL_ROT_LEFT = 256, + CONTROL_ROT_RIGHT = 512, + CONTROL_LBUTTON = 268435456, + CONTROL_ML_LBUTTON = 1073741824 + } + + struct ScriptControllers + { + public UUID itemID; + public ScriptControlled ignoreControls; + public ScriptControlled eventControls; + } + + public delegate void SendCourseLocationsMethod(UUID scene, ScenePresence presence, List coarseLocations, List avatarUUIDs); + + public class ScenePresence : EntityBase, ISceneEntity + { +// ~ScenePresence() +// { +// m_log.Debug("[ScenePresence] Destructor called"); +// } + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static readonly byte[] BAKE_INDICES = new byte[] { 8, 9, 10, 11, 19, 20 }; +// private static readonly byte[] DEFAULT_TEXTURE = AvatarAppearance.GetDefaultTexture().GetBytes(); + private static readonly Array DIR_CONTROL_FLAGS = Enum.GetValues(typeof(Dir_ControlFlags)); + private static readonly Vector3 HEAD_ADJUSTMENT = new Vector3(0f, 0f, 0.3f); + + /// + /// Experimentally determined "fudge factor" to make sit-target positions + /// the same as in SecondLife. Fudge factor was tested for 36 different + /// test cases including prims of type box, sphere, cylinder, and torus, + /// with varying parameters for sit target location, prim size, prim + /// rotation, prim cut, prim twist, prim taper, and prim shear. See mantis + /// issue #1716 + /// +// private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.1f, 0.0f, 0.3f); + // Value revised by KF 091121 by comparison with SL. + private static readonly Vector3 SIT_TARGET_ADJUSTMENT = new Vector3(0.0f, 0.0f, 0.418f); + + public UUID currentParcelUUID = UUID.Zero; + + private ISceneViewer m_sceneViewer; + + /// + /// The animator for this avatar + /// + public ScenePresenceAnimator Animator + { + get { return m_animator; } + } + protected ScenePresenceAnimator m_animator; + + /// + /// The scene objects attached to this avatar. Do not change this list directly - use methods such as + /// AddAttachment() and RemoveAttachment(). Lock this list when performing any read operations upon it. + /// + public List Attachments + { + get { return m_attachments; } + } + protected List m_attachments = new List(); + + private Dictionary scriptedcontrols = new Dictionary(); + private ScriptControlled IgnoredControls = ScriptControlled.CONTROL_ZERO; + private ScriptControlled LastCommands = ScriptControlled.CONTROL_ZERO; + private bool MouseDown = false; + private SceneObjectGroup proxyObjectGroup; + //private SceneObjectPart proxyObjectPart = null; + public Vector3 lastKnownAllowedPosition; + public bool sentMessageAboutRestrictedParcelFlyingDown; + public Vector4 CollisionPlane = Vector4.UnitW; + + private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation + private Vector3 m_avUnscriptedSitPos; // for non-scripted prims + private Vector3 m_lastPosition; + private Vector3 m_lastWorldPosition; + private Quaternion m_lastRotation; + private Vector3 m_lastVelocity; + //private int m_lastTerseSent; + + private bool m_updateflag; + private byte m_movementflag; + private Vector3? m_forceToApply; + private uint m_requestedSitTargetID; + private UUID m_requestedSitTargetUUID; + public bool SitGround = false; + + private SendCourseLocationsMethod m_sendCourseLocationsMethod; + + private bool m_startAnimationSet; + + //private Vector3 m_requestedSitOffset = new Vector3(); + + private Vector3 m_LastFinitePos; + + private float m_sitAvatarHeight = 2.0f; + + private int m_godLevel; + private int m_userLevel; + + private bool m_invulnerable = true; + + private Vector3 m_lastChildAgentUpdatePosition; + private Vector3 m_lastChildAgentUpdateCamPosition; + + private int m_perfMonMS; + + private bool m_setAlwaysRun; + private bool m_forceFly; + private bool m_flyDisabled; + + private float m_speedModifier = 1.0f; + + private Quaternion m_bodyRot= Quaternion.Identity; + + private Quaternion m_bodyRotPrevious = Quaternion.Identity; + + private const int LAND_VELOCITYMAG_MAX = 12; + + public bool IsRestrictedToRegion; + + public string JID = String.Empty; + + private float m_health = 100f; + + // Default AV Height + private float m_avHeight = 127.0f; + + protected RegionInfo m_regionInfo; + protected ulong crossingFromRegion; + + private readonly Vector3[] Dir_Vectors = new Vector3[11]; + private bool m_isNudging = false; + + // Position of agent's camera in world (region cordinates) + protected Vector3 m_CameraCenter; + protected Vector3 m_lastCameraCenter; + + protected Timer m_reprioritization_timer; + protected bool m_reprioritizing; + protected bool m_reprioritization_called; + + // Use these three vectors to figure out what the agent is looking at + // Convert it to a Matrix and/or Quaternion + protected Vector3 m_CameraAtAxis; + protected Vector3 m_CameraLeftAxis; + protected Vector3 m_CameraUpAxis; + private AgentManager.ControlFlags m_AgentControlFlags; + private Quaternion m_headrotation = Quaternion.Identity; + private byte m_state; + + //Reuse the Vector3 instead of creating a new one on the UpdateMovement method +// private Vector3 movementvector; + + private bool m_autopilotMoving; + private Vector3 m_autoPilotTarget; + private bool m_sitAtAutoTarget; + private Vector3 m_initialSitTarget = Vector3.Zero; //KF: First estimate of where to sit + + private string m_nextSitAnimation = String.Empty; + + //PauPaw:Proper PID Controler for autopilot************ + private bool m_moveToPositionInProgress; + private Vector3 m_moveToPositionTarget; + private Quaternion m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + + private bool m_followCamAuto; + + private int m_movementUpdateCount; + private int m_lastColCount = -1; //KF: Look for Collision chnages + private int m_updateCount = 0; //KF: Update Anims for a while + private static readonly int UPDATE_COUNT = 10; // how many frames to update for + private const int NumMovementsBetweenRayCast = 5; + private List m_lastColliders = new List(); + + private bool CameraConstraintActive; + //private int m_moveToPositionStateStatus; + //***************************************************** + + // Agent's Draw distance. + protected float m_DrawDistance; + + protected AvatarAppearance m_appearance; + + // neighbouring regions we have enabled a child agent in + // holds the seed cap for the child agent in that region + private Dictionary m_knownChildRegions = new Dictionary(); + + /// + /// Implemented Control Flags + /// + private enum Dir_ControlFlags + { + DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, + DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, + DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, + DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, + DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + DIR_CONTROL_FLAG_FORWARD_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS, + DIR_CONTROL_FLAG_BACK_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG, + DIR_CONTROL_FLAG_LEFT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS, + DIR_CONTROL_FLAG_RIGHT_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG, + DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + } + + /// + /// Position at which a significant movement was made + /// + private Vector3 posLastSignificantMove; + + // For teleports and crossings callbacks + string m_callbackURI; + UUID m_originRegionID; + + ulong m_rootRegionHandle; + + /// + /// Script engines present in the scene + /// + private IScriptModule[] m_scriptEngines; + + #region Properties + + /// + /// Physical scene representation of this Avatar. + /// + public PhysicsActor PhysicsActor + { + set { m_physicsActor = value; } + get { return m_physicsActor; } + } + + public byte MovementFlag + { + set { m_movementflag = value; } + get { return m_movementflag; } + } + + public bool Updated + { + set { m_updateflag = value; } + get { return m_updateflag; } + } + + public bool Invulnerable + { + set { m_invulnerable = value; } + get { return m_invulnerable; } + } + + public int UserLevel + { + get { return m_userLevel; } + } + + public int GodLevel + { + get { return m_godLevel; } + } + + public ulong RegionHandle + { + get { return m_rootRegionHandle; } + } + + public Vector3 CameraPosition + { + get { return m_CameraCenter; } + } + + public Quaternion CameraRotation + { + get { return Util.Axes2Rot(m_CameraAtAxis, m_CameraLeftAxis, m_CameraUpAxis); } + } + + public Vector3 CameraAtAxis + { + get { return m_CameraAtAxis; } + } + + public Vector3 CameraLeftAxis + { + get { return m_CameraLeftAxis; } + } + + public Vector3 CameraUpAxis + { + get { return m_CameraUpAxis; } + } + + public Vector3 Lookat + { + get + { + Vector3 a = new Vector3(m_CameraAtAxis.X, m_CameraAtAxis.Y, 0); + + if (a == Vector3.Zero) + return a; + + return Util.GetNormalizedVector(a); + } + } + + private readonly string m_firstname; + + public string Firstname + { + get { return m_firstname; } + } + + private readonly string m_lastname; + + public string Lastname + { + get { return m_lastname; } + } + + private string m_grouptitle; + + public string Grouptitle + { + get { return m_grouptitle; } + set { m_grouptitle = value; } + } + + public float DrawDistance + { + get { return m_DrawDistance; } + } + + protected bool m_allowMovement = true; + + public bool AllowMovement + { + get { return m_allowMovement; } + set { m_allowMovement = value; } + } + + public bool SetAlwaysRun + { + get + { + if (PhysicsActor != null) + { + return PhysicsActor.SetAlwaysRun; + } + else + { + return m_setAlwaysRun; + } + } + set + { + m_setAlwaysRun = value; + if (PhysicsActor != null) + { + PhysicsActor.SetAlwaysRun = value; + } + } + } + + public byte State + { + get { return m_state; } + set { m_state = value; } + } + + public uint AgentControlFlags + { + get { return (uint)m_AgentControlFlags; } + set { m_AgentControlFlags = (AgentManager.ControlFlags)value; } + } + + /// + /// This works out to be the ClientView object associated with this avatar, or it's client connection manager + /// + private IClientAPI m_controllingClient; + + protected PhysicsActor m_physicsActor; + + /// + /// The client controlling this presence + /// + public IClientAPI ControllingClient + { + get { return m_controllingClient; } + } + + public IClientCore ClientView + { + get { return (IClientCore) m_controllingClient; } + } + + protected Vector3 m_parentPosition; + public Vector3 ParentPosition + { + get { return m_parentPosition; } + set { m_parentPosition = value; } + } + + /// + /// Position of this avatar relative to the region the avatar is in + /// + public override Vector3 AbsolutePosition + { + get + { + PhysicsActor actor = m_physicsActor; +// if (actor != null) + if ((actor != null) && (m_parentID == 0)) // KF Do NOT update m_pos here if Av is sitting! + m_pos = actor.Position; + + // If we're sitting, we need to update our position + if (m_parentID != 0) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); + if (part != null) + m_parentPosition = part.AbsolutePosition; + } + + return m_parentPosition + m_pos; + } + set + { + PhysicsActor actor = m_physicsActor; + if (actor != null) + { + try + { + lock (m_scene.SyncRoot) + m_physicsActor.Position = value; + } + catch (Exception e) + { + m_log.Error("[SCENEPRESENCE]: ABSOLUTE POSITION " + e.Message); + } + } + + if (m_parentID == 0) // KF Do NOT update m_pos here if Av is sitting! + m_pos = value; + m_parentPosition = Vector3.Zero; + } + } + + public Vector3 OffsetPosition + { + get { return m_pos; } + set { m_pos = value; } + } + + /// + /// Current velocity of the avatar. + /// + public override Vector3 Velocity + { + get + { + PhysicsActor actor = m_physicsActor; + if (actor != null) + m_velocity = actor.Velocity; + + return m_velocity; + } + set + { + PhysicsActor actor = m_physicsActor; + if (actor != null) + { + try + { + lock (m_scene.SyncRoot) + actor.Velocity = value; + } + catch (Exception e) + { + m_log.Error("[SCENEPRESENCE]: VELOCITY " + e.Message); + } + } + + m_velocity = value; + } + } + + public Quaternion OffsetRotation + { + get { return m_offsetRotation; } + set { m_offsetRotation = value; } + } + + public Quaternion Rotation + { + get { + if (m_parentID != 0) + { + if (m_offsetRotation != null) + { + return m_offsetRotation; + } + else + { + return new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + + } + else + { + return m_bodyRot; + } + } + set { + m_bodyRot = value; + if (m_parentID != 0) + { + m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + } + } + + public Quaternion PreviousRotation + { + get { return m_bodyRotPrevious; } + set { m_bodyRotPrevious = value; } + } + + /// + /// If this is true, agent doesn't have a representation in this scene. + /// this is an agent 'looking into' this scene from a nearby scene(region) + /// + /// if False, this agent has a representation in this scene + /// + private bool m_isChildAgent = true; + + public bool IsChildAgent + { + get { return m_isChildAgent; } + set { m_isChildAgent = value; } + } + + private uint m_parentID; + + + private UUID m_linkedPrim; + + public uint ParentID + { + get { return m_parentID; } + set { m_parentID = value; } + } + + public UUID LinkedPrim + { + get { return m_linkedPrim; } + set { m_linkedPrim = value; } + } + + public float Health + { + get { return m_health; } + set { m_health = value; } + } + + /// + /// These are the region handles known by the avatar. + /// + public List KnownChildRegionHandles + { + get + { + if (m_knownChildRegions.Count == 0) + return new List(); + else + return new List(m_knownChildRegions.Keys); + } + } + + public Dictionary KnownRegions + { + get { return m_knownChildRegions; } + set + { + m_knownChildRegions = value; + } + } + + public ISceneViewer SceneViewer + { + get { return m_sceneViewer; } + } + + public void AdjustKnownSeeds() + { + Dictionary seeds; + + if (Scene.CapsModule != null) + seeds = Scene.CapsModule.GetChildrenSeeds(UUID); + else + seeds = new Dictionary(); + + List old = new List(); + foreach (ulong handle in seeds.Keys) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + if (Util.IsOutsideView(x, Scene.RegionInfo.RegionLocX, y, Scene.RegionInfo.RegionLocY)) + { + old.Add(handle); + } + } + DropOldNeighbours(old); + + if (Scene.CapsModule != null) + Scene.CapsModule.SetChildrenSeed(UUID, seeds); + + KnownRegions = seeds; + //m_log.Debug(" ++++++++++AFTER+++++++++++++ "); + //DumpKnownRegions(); + } + + public void DumpKnownRegions() + { + m_log.Info("================ KnownRegions "+Scene.RegionInfo.RegionName+" ================"); + foreach (KeyValuePair kvp in KnownRegions) + { + uint x, y; + Utils.LongToUInts(kvp.Key, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.Info(" >> "+x+", "+y+": "+kvp.Value); + } + } + + private bool m_inTransit; + private bool m_mouseLook; + private bool m_leftButtonDown; + + public bool IsInTransit + { + get { return m_inTransit; } + set { m_inTransit = value; } + } + + public float SpeedModifier + { + get { return m_speedModifier; } + set { m_speedModifier = value; } + } + + public bool ForceFly + { + get { return m_forceFly; } + set { m_forceFly = value; } + } + + public bool FlyDisabled + { + get { return m_flyDisabled; } + set { m_flyDisabled = value; } + } + + public string Viewer + { + get { return m_scene.AuthenticateHandler.GetAgentCircuitData(ControllingClient.CircuitCode).Viewer; } + } + + #endregion + + #region Constructor(s) + + public ScenePresence() + { + m_sendCourseLocationsMethod = SendCoarseLocationsDefault; + CreateSceneViewer(); + m_animator = new ScenePresenceAnimator(this); + } + + private ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo) : this() + { + m_rootRegionHandle = reginfo.RegionHandle; + m_controllingClient = client; + m_firstname = m_controllingClient.FirstName; + m_lastname = m_controllingClient.LastName; + m_name = String.Format("{0} {1}", m_firstname, m_lastname); + m_scene = world; + m_uuid = client.AgentId; + m_regionInfo = reginfo; + m_localId = m_scene.AllocateLocalId(); + + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, m_uuid); + + if (account != null) + m_userLevel = account.UserLevel; + + IGroupsModule gm = m_scene.RequestModuleInterface(); + if (gm != null) + m_grouptitle = gm.GetGroupTitle(m_uuid); + + m_scriptEngines = m_scene.RequestModuleInterfaces(); + + AbsolutePosition = posLastSignificantMove = m_CameraCenter = + m_lastCameraCenter = m_controllingClient.StartPos; + + m_reprioritization_timer = new Timer(world.ReprioritizationInterval); + m_reprioritization_timer.Elapsed += new ElapsedEventHandler(Reprioritize); + m_reprioritization_timer.AutoReset = false; + + AdjustKnownSeeds(); + Animator.TrySetMovementAnimation("STAND"); + // we created a new ScenePresence (a new child agent) in a fresh region. + // Request info about all the (root) agents in this region + // Note: This won't send data *to* other clients in that region (children don't send) + SendInitialFullUpdateToAllClients(); + RegisterToEvents(); + if (m_controllingClient != null) + { + m_controllingClient.ProcessPendingPackets(); + } + SetDirectionVectors(); + } + + public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, byte[] visualParams, + AvatarWearable[] wearables) + : this(client, world, reginfo) + { + m_appearance = new AvatarAppearance(m_uuid, wearables, visualParams); + } + + public ScenePresence(IClientAPI client, Scene world, RegionInfo reginfo, AvatarAppearance appearance) + : this(client, world, reginfo) + { + m_appearance = appearance; + } + + private void CreateSceneViewer() + { + m_sceneViewer = new SceneViewer(this); + } + + public void RegisterToEvents() + { + m_controllingClient.OnRequestWearables += SendWearables; + m_controllingClient.OnSetAppearance += SetAppearance; + m_controllingClient.OnCompleteMovementToRegion += CompleteMovement; + //m_controllingClient.OnCompleteMovementToRegion += SendInitialData; + m_controllingClient.OnAgentUpdate += HandleAgentUpdate; + m_controllingClient.OnAgentRequestSit += HandleAgentRequestSit; + m_controllingClient.OnAgentSit += HandleAgentSit; + m_controllingClient.OnSetAlwaysRun += HandleSetAlwaysRun; + m_controllingClient.OnStartAnim += HandleStartAnim; + m_controllingClient.OnStopAnim += HandleStopAnim; + m_controllingClient.OnForceReleaseControls += HandleForceReleaseControls; + m_controllingClient.OnAutoPilotGo += DoAutoPilot; + m_controllingClient.AddGenericPacketHandler("autopilot", DoMoveToPosition); + + // ControllingClient.OnChildAgentStatus += new StatusChange(this.ChildStatusChange); + // ControllingClient.OnStopMovement += new GenericCall2(this.StopMovement); + } + + private void SetDirectionVectors() + { + Dir_Vectors[0] = Vector3.UnitX; //FORWARD + Dir_Vectors[1] = -Vector3.UnitX; //BACK + Dir_Vectors[2] = Vector3.UnitY; //LEFT + Dir_Vectors[3] = -Vector3.UnitY; //RIGHT + Dir_Vectors[4] = Vector3.UnitZ; //UP + Dir_Vectors[5] = -Vector3.UnitZ; //DOWN + Dir_Vectors[6] = new Vector3(0.5f, 0f, 0f); //FORWARD_NUDGE + Dir_Vectors[7] = new Vector3(-0.5f, 0f, 0f); //BACK_NUDGE + Dir_Vectors[8] = new Vector3(0f, 0.5f, 0f); //LEFT_NUDGE + Dir_Vectors[9] = new Vector3(0f, -0.5f, 0f); //RIGHT_NUDGE + Dir_Vectors[10] = new Vector3(0f, 0f, -0.5f); //DOWN_Nudge + } + + private Vector3[] GetWalkDirectionVectors() + { + Vector3[] vector = new Vector3[11]; + vector[0] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD + vector[1] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK + vector[2] = Vector3.UnitY; //LEFT + vector[3] = -Vector3.UnitY; //RIGHT + vector[4] = new Vector3(m_CameraAtAxis.Z, 0f, m_CameraUpAxis.Z); //UP + vector[5] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN + vector[6] = new Vector3(m_CameraUpAxis.Z, 0f, -m_CameraAtAxis.Z); //FORWARD_NUDGE + vector[7] = new Vector3(-m_CameraUpAxis.Z, 0f, m_CameraAtAxis.Z); //BACK_NUDGE + vector[8] = Vector3.UnitY; //LEFT_NUDGE + vector[9] = -Vector3.UnitY; //RIGHT_NUDGE + vector[10] = new Vector3(-m_CameraAtAxis.Z, 0f, -m_CameraUpAxis.Z); //DOWN_NUDGE + return vector; + } + + private bool[] GetDirectionIsNudge() + { + bool[] isNudge = new bool[11]; + isNudge[0] = false; //FORWARD + isNudge[1] = false; //BACK + isNudge[2] = false; //LEFT + isNudge[3] = false; //RIGHT + isNudge[4] = false; //UP + isNudge[5] = false; //DOWN + isNudge[6] = true; //FORWARD_NUDGE + isNudge[7] = true; //BACK_NUDGE + isNudge[8] = true; //LEFT_NUDGE + isNudge[9] = true; //RIGHT_NUDGE + isNudge[10] = true; //DOWN_Nudge + return isNudge; + } + + + #endregion + + public uint GenerateClientFlags(UUID ObjectID) + { + return m_scene.Permissions.GenerateClientFlags(m_uuid, ObjectID); + } + + /// + /// Send updates to the client about prims which have been placed on the update queue. We don't + /// necessarily send updates for all the parts on the queue, e.g. if an updates with a more recent + /// timestamp has already been sent. + /// + public void SendPrimUpdates() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + m_sceneViewer.SendPrimUpdates(); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + #region Status Methods + + /// + /// This turns a child agent, into a root agent + /// This is called when an agent teleports into a region, or if an + /// agent crosses into this region from a neighbor over the border + /// + public void MakeRootAgent(Vector3 pos, bool isFlying) + { + m_log.DebugFormat( + "[SCENE]: Upgrading child to root agent for {0} in {1}", + Name, m_scene.RegionInfo.RegionName); + + //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); + + IGroupsModule gm = m_scene.RequestModuleInterface(); + if (gm != null) + m_grouptitle = gm.GetGroupTitle(m_uuid); + + m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; + m_scene.SetRootAgentScene(m_uuid); + + // Moved this from SendInitialData to ensure that m_appearance is initialized + // before the inventory is processed in MakeRootAgent. This fixes a race condition + // related to the handling of attachments + //m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); + if (m_scene.TestBorderCross(pos, Cardinals.E)) + { + Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); + pos.X = crossedBorder.BorderLine.Z - 1; + } + + if (m_scene.TestBorderCross(pos, Cardinals.N)) + { + Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); + pos.Y = crossedBorder.BorderLine.Z - 1; + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } + } + + if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) + { + Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); + + if (pos.X < 0) + { + emergencyPos.X = (int)Constants.RegionSize + pos.X; + if (!(pos.Y < 0)) + emergencyPos.Y = pos.Y; + if (!(pos.Z < 0)) + emergencyPos.Z = pos.Z; + } + if (pos.Y < 0) + { + emergencyPos.Y = (int)Constants.RegionSize + pos.Y; + if (!(pos.X < 0)) + emergencyPos.X = pos.X; + if (!(pos.Z < 0)) + emergencyPos.Z = pos.Z; + } + if (pos.Z < 0) + { + emergencyPos.Z = 128; + if (!(pos.Y < 0)) + emergencyPos.Y = pos.Y; + if (!(pos.X < 0)) + emergencyPos.X = pos.X; + } + } + + if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) + { + m_log.WarnFormat( + "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", + pos, Name, UUID); + + if (pos.X < 0f) pos.X = 0f; + if (pos.Y < 0f) pos.Y = 0f; + if (pos.Z < 0f) pos.Z = 0f; + } + + float localAVHeight = 1.56f; + if (m_avHeight != 127.0f) + { + localAVHeight = m_avHeight; + } + + float posZLimit = 0; + + if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) + posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; + + float newPosZ = posZLimit + localAVHeight / 2; + if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + pos.Z = newPosZ; + } + AbsolutePosition = pos; + + AddToPhysicalScene(isFlying); + + if (m_forceFly) + { + m_physicsActor.Flying = true; + } + else if (m_flyDisabled) + { + m_physicsActor.Flying = false; + } + + if (m_appearance != null) + { + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + } + else + { + m_log.ErrorFormat("[SCENE PRESENCE]: null appearance in MakeRoot in {0}", Scene.RegionInfo.RegionName); + // emergency; this really shouldn't happen + m_appearance = new AvatarAppearance(UUID); + } + + // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying + // avatar to return to the standing position in mid-air. On login it looks like this is being sent + // elsewhere anyway + // Animator.SendAnimPack(); + + m_scene.SwapRootAgentCount(false); + + //CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(m_uuid); + //if (userInfo != null) + // userInfo.FetchInventory(); + //else + // m_log.ErrorFormat("[SCENE]: Could not find user info for {0} when making it a root agent", m_uuid); + + // On the next prim update, all objects will be sent + // + m_sceneViewer.Reset(); + + m_isChildAgent = false; + + // send the animations of the other presences to me + m_scene.ForEachScenePresence(delegate(ScenePresence presence) + { + if (presence != this) + presence.Animator.SendAnimPackToClient(ControllingClient); + }); + + m_scene.EventManager.TriggerOnMakeRootAgent(this); + } + + /// + /// This turns a root agent into a child agent + /// when an agent departs this region for a neighbor, this gets called. + /// + /// It doesn't get called for a teleport. Reason being, an agent that + /// teleports out may not end up anywhere near this region + /// + public void MakeChildAgent() + { + // It looks like m_animator is set to null somewhere, and MakeChild + // is called after that. Probably in aborted teleports. + if (m_animator == null) + m_animator = new ScenePresenceAnimator(this); + else + Animator.ResetAnimations(); + +// m_log.DebugFormat( +// "[SCENEPRESENCE]: Downgrading root agent {0}, {1} to a child agent in {2}", +// Name, UUID, m_scene.RegionInfo.RegionName); + + // Don't zero out the velocity since this can cause problems when an avatar is making a region crossing, + // depending on the exact timing. This shouldn't matter anyway since child agent positions are not updated. + //Velocity = new Vector3(0, 0, 0); + + m_isChildAgent = true; + m_scene.SwapRootAgentCount(true); + RemoveFromPhysicalScene(); + + // FIXME: Set m_rootRegionHandle to the region handle of the scene this agent is moving into + + m_scene.EventManager.TriggerOnMakeChildAgent(this); + } + + /// + /// Removes physics plugin scene representation of this agent if it exists. + /// + private void RemoveFromPhysicalScene() + { + if (PhysicsActor != null) + { + m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; + m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; + m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); + m_physicsActor.UnSubscribeEvents(); + m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; + PhysicsActor = null; + } + } + + /// + /// + /// + /// + public void Teleport(Vector3 pos) + { + bool isFlying = false; + + if (m_physicsActor != null) + isFlying = m_physicsActor.Flying; + + RemoveFromPhysicalScene(); + Velocity = Vector3.Zero; + AbsolutePosition = pos; + AddToPhysicalScene(isFlying); + if (m_appearance != null) + { + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + } + + SendTerseUpdateToAllClients(); + + } + + public void TeleportWithMomentum(Vector3 pos) + { + bool isFlying = false; + if (m_physicsActor != null) + isFlying = m_physicsActor.Flying; + + RemoveFromPhysicalScene(); + AbsolutePosition = pos; + AddToPhysicalScene(isFlying); + if (m_appearance != null) + { + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + } + + SendTerseUpdateToAllClients(); + } + + /// + /// + /// + public void StopMovement() + { + } + + public void StopFlying() + { + ControllingClient.StopFlying(this); + } + + public void AddNeighbourRegion(ulong regionHandle, string cap) + { + lock (m_knownChildRegions) + { + if (!m_knownChildRegions.ContainsKey(regionHandle)) + { + uint x, y; + Utils.LongToUInts(regionHandle, out x, out y); + m_knownChildRegions.Add(regionHandle, cap); + } + } + } + + public void RemoveNeighbourRegion(ulong regionHandle) + { + lock (m_knownChildRegions) + { + if (m_knownChildRegions.ContainsKey(regionHandle)) + { + m_knownChildRegions.Remove(regionHandle); + //m_log.Debug(" !!! removing known region {0} in {1}. Count = {2}", regionHandle, Scene.RegionInfo.RegionName, m_knownChildRegions.Count); + } + } + } + + public void DropOldNeighbours(List oldRegions) + { + foreach (ulong handle in oldRegions) + { + RemoveNeighbourRegion(handle); + Scene.CapsModule.DropChildSeed(UUID, handle); + } + } + + public List GetKnownRegionList() + { + return new List(m_knownChildRegions.Keys); + } + + #endregion + + #region Event Handlers + + /// + /// Sets avatar height in the phyiscs plugin + /// + internal void SetHeight(float height) + { + m_avHeight = height; + if (PhysicsActor != null && !IsChildAgent) + { + Vector3 SetSize = new Vector3(0.45f, 0.6f, m_avHeight); + PhysicsActor.Size = SetSize; + } + } + + /// + /// Complete Avatar's movement into the region. + /// This is called upon a very important packet sent from the client, + /// so it's client-controlled. Never call this method directly. + /// + public void CompleteMovement(IClientAPI client) + { + //m_log.Debug("[SCENE PRESENCE]: CompleteMovement"); + + Vector3 look = Velocity; + if ((look.X == 0) && (look.Y == 0) && (look.Z == 0)) + { + look = new Vector3(0.99f, 0.042f, 0); + } + + // Prevent teleporting to an underground location + // (may crash client otherwise) + // + Vector3 pos = AbsolutePosition; + float ground = m_scene.GetGroundHeight(pos.X, pos.Y); + if (pos.Z < ground + 1.5f) + { + pos.Z = ground + 1.5f; + AbsolutePosition = pos; + } + m_isChildAgent = false; + bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + MakeRootAgent(AbsolutePosition, m_flying); + + if ((m_callbackURI != null) && !m_callbackURI.Equals("")) + { + m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); + Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); + m_callbackURI = null; + } + + //m_log.DebugFormat("Completed movement"); + + m_controllingClient.MoveAgentIntoRegion(m_regionInfo, AbsolutePosition, look); + SendInitialData(); + + // Create child agents in neighbouring regions + if (!m_isChildAgent) + { + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); + if (m_agentTransfer != null) + m_agentTransfer.EnableChildAgents(this); + else + m_log.DebugFormat("[SCENE PRESENCE]: Unable to create child agents in neighbours, because AgentTransferModule is not active"); + + IFriendsModule friendsModule = m_scene.RequestModuleInterface(); + if (friendsModule != null) + friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); + } + + } + + /// + /// Callback for the Camera view block check. Gets called with the results of the camera view block test + /// hitYN is true when there's something in the way. + /// + /// + /// + /// + /// + public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal) + { + const float POSITION_TOLERANCE = 0.02f; + const float VELOCITY_TOLERANCE = 0.02f; + const float ROTATION_TOLERANCE = 0.02f; + + if (m_followCamAuto) + { + if (hitYN) + { + CameraConstraintActive = true; + //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance); + + Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint); + ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint))); + } + else + { + if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)) + { + if (CameraConstraintActive) + { + ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f)); + CameraConstraintActive = false; + } + } + } + } + } + + /// + /// This is the event handler for client movement. If a client is moving, this event is triggering. + /// + public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) + { + //if (m_isChildAgent) + //{ + // // m_log.Debug("DEBUG: HandleAgentUpdate: child agent"); + // return; + //} + + m_perfMonMS = Util.EnvironmentTickCount(); + + ++m_movementUpdateCount; + if (m_movementUpdateCount < 1) + m_movementUpdateCount = 1; + + #region Sanity Checking + + // This is irritating. Really. + if (!AbsolutePosition.IsFinite()) + { + RemoveFromPhysicalScene(); + m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); + + m_pos = m_LastFinitePos; + + if (!m_pos.IsFinite()) + { + m_pos.X = 127f; + m_pos.Y = 127f; + m_pos.Z = 127f; + m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999903"); + } + + AddToPhysicalScene(false); + } + else + { + m_LastFinitePos = m_pos; + } + + #endregion Sanity Checking + + #region Inputs + + AgentManager.ControlFlags flags = (AgentManager.ControlFlags)agentData.ControlFlags; + Quaternion bodyRotation = agentData.BodyRotation; + + // Camera location in world. We'll need to raytrace + // from this location from time to time. + m_CameraCenter = agentData.CameraCenter; + if (Vector3.Distance(m_lastCameraCenter, m_CameraCenter) >= Scene.RootReprioritizationDistance) + { + ReprioritizeUpdates(); + m_lastCameraCenter = m_CameraCenter; + } + + // Use these three vectors to figure out what the agent is looking at + // Convert it to a Matrix and/or Quaternion + m_CameraAtAxis = agentData.CameraAtAxis; + m_CameraLeftAxis = agentData.CameraLeftAxis; + m_CameraUpAxis = agentData.CameraUpAxis; + + // The Agent's Draw distance setting + m_DrawDistance = agentData.Far; + + // Check if Client has camera in 'follow cam' or 'build' mode. + Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation); + + m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f) + && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false; + + m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; + m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0; + + #endregion Inputs + + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_STAND_UP) != 0) + { + StandUp(); + } + + //m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto); + // Raycast from the avatar's head to the camera to see if there's anything blocking the view + if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast()) + { + if (m_followCamAuto) + { + Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT; + m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); + } + } + lock (scriptedcontrols) + { + if (scriptedcontrols.Count > 0) + { + SendControlToScripts((uint)flags); + flags = RemoveIgnoredControls(flags, IgnoredControls); + } + } + + if (m_autopilotMoving) + CheckAtSitTarget(); + + if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) + { + m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. + Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + + // TODO: This doesn't prevent the user from walking yet. + // Setting parent ID would fix this, if we knew what value + // to use. Or we could add a m_isSitting variable. + //Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); + SitGround = true; + } + + // In the future, these values might need to go global. + // Here's where you get them. + m_AgentControlFlags = flags; + m_headrotation = agentData.HeadRotation; + m_state = agentData.State; + + PhysicsActor actor = PhysicsActor; + if (actor == null) + { + return; + } + + bool update_movementflag = false; + + if (m_allowMovement && !SitGround) + { + if (agentData.UseClientAgentPosition) + { + m_moveToPositionInProgress = (agentData.ClientAgentPosition - AbsolutePosition).Length() > 0.2f; + m_moveToPositionTarget = agentData.ClientAgentPosition; + } + + int i = 0; + + bool update_rotation = false; + bool DCFlagKeyPressed = false; + Vector3 agent_control_v3 = Vector3.Zero; + Quaternion q = bodyRotation; + + bool oldflying = PhysicsActor.Flying; + + if (m_forceFly) + actor.Flying = true; + else if (m_flyDisabled) + actor.Flying = false; + else + actor.Flying = ((flags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); + + if (actor.Flying != oldflying) + update_movementflag = true; + + if (q != m_bodyRot) + { + m_bodyRot = q; + update_rotation = true; + } + + //guilty until proven innocent.. + bool Nudging = true; + //Basically, if there is at least one non-nudge control then we don't need + //to worry about stopping the avatar + + if (m_parentID == 0) + { + bool bAllowUpdateMoveToPosition = false; + bool bResetMoveToPosition = false; + + Vector3[] dirVectors; + + // use camera up angle when in mouselook and not flying or when holding the left mouse button down and not flying + // this prevents 'jumping' in inappropriate situations. + if ((m_mouseLook && !m_physicsActor.Flying) || (m_leftButtonDown && !m_physicsActor.Flying)) + dirVectors = GetWalkDirectionVectors(); + else + dirVectors = Dir_Vectors; + + bool[] isNudge = GetDirectionIsNudge(); + + + + + + foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) + { + if (((uint)flags & (uint)DCF) != 0) + { + bResetMoveToPosition = true; + DCFlagKeyPressed = true; + try + { + agent_control_v3 += dirVectors[i]; + if (isNudge[i] == false) + { + Nudging = false; + } + } + catch (IndexOutOfRangeException) + { + // Why did I get this? + } + + if ((m_movementflag & (uint)DCF) == 0) + { + m_movementflag += (byte)(uint)DCF; + update_movementflag = true; + } + } + else + { + if ((m_movementflag & (uint)DCF) != 0) + { + m_movementflag -= (byte)(uint)DCF; + update_movementflag = true; + } + else + { + bAllowUpdateMoveToPosition = true; + } + } + i++; + } + //Paupaw:Do Proper PID for Autopilot here + if (bResetMoveToPosition) + { + m_moveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + update_movementflag = true; + bAllowUpdateMoveToPosition = false; + } + + if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) + { + //Check the error term of the current position in relation to the target position + if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) + { + // we are close enough to the target + m_moveToPositionTarget = Vector3.Zero; + m_moveToPositionInProgress = false; + update_movementflag = true; + } + else + { + try + { + // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. + // This movement vector gets added to the velocity through AddNewMovement(). + // Theoretically we might need a more complex PID approach here if other + // unknown forces are acting on the avatar and we need to adaptively respond + // to such forces, but the following simple approach seems to works fine. + Vector3 LocalVectorToTarget3D = + (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords + * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords + // Ignore z component of vector + Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); + LocalVectorToTarget2D.Normalize(); + + //We're not nudging + Nudging = false; + agent_control_v3 += LocalVectorToTarget2D; + + // update avatar movement flags. the avatar coordinate system is as follows: + // + // +X (forward) + // + // ^ + // | + // | + // | + // | + // (left) +Y <--------o--------> -Y + // avatar + // | + // | + // | + // | + // v + // -X + // + + // based on the above avatar coordinate system, classify the movement into + // one of left/right/back/forward. + if (LocalVectorToTarget2D.Y > 0)//MoveLeft + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + //AgentControlFlags + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; + update_movementflag = true; + } + else if (LocalVectorToTarget2D.Y < 0) //MoveRight + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; + update_movementflag = true; + } + if (LocalVectorToTarget2D.X < 0) //MoveBack + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; + update_movementflag = true; + } + else if (LocalVectorToTarget2D.X > 0) //Move Forward + { + m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; + update_movementflag = true; + } + } + catch (Exception e) + { + //Avoid system crash, can be slower but... + m_log.DebugFormat("Crash! {0}", e.ToString()); + } + } + } + } + + // Cause the avatar to stop flying if it's colliding + // with something with the down arrow pressed. + + // Only do this if we're flying + if (m_physicsActor != null && m_physicsActor.Flying && !m_forceFly) + { + // Landing detection code + + // Are the landing controls requirements filled? + bool controlland = (((flags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || + ((flags & AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + + // Are the collision requirements fulfilled? + bool colliding = (m_physicsActor.IsColliding == true); + + if (m_physicsActor.Flying && colliding && controlland) + { + // nesting this check because LengthSquared() is expensive and we don't + // want to do it every step when flying. + if ((Velocity.LengthSquared() <= LAND_VELOCITYMAG_MAX)) + StopFlying(); + } + } + + if (update_movementflag || (update_rotation && DCFlagKeyPressed)) + { + // m_log.DebugFormat("{0} {1}", update_movementflag, (update_rotation && DCFlagKeyPressed)); + // m_log.DebugFormat( + // "In {0} adding velocity to {1} of {2}", m_scene.RegionInfo.RegionName, Name, agent_control_v3); + + AddNewMovement(agent_control_v3, q, Nudging); + + + } + } + + if (update_movementflag && !SitGround) + Animator.UpdateMovementAnimations(); + + m_scene.EventManager.TriggerOnClientMovement(this); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) + { + m_autopilotMoving = true; + m_autoPilotTarget = Pos; + m_sitAtAutoTarget = false; + PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; + //proxy.PCode = (byte)PCode.ParticleSystem; + proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy); + proxyObjectGroup.AttachToScene(m_scene); + + // Commented out this code since it could never have executed, but might still be informative. +// if (proxyObjectGroup != null) +// { + proxyObjectGroup.SendGroupFullUpdate(); + remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); + m_scene.DeleteSceneObject(proxyObjectGroup, false); +// } +// else +// { +// m_autopilotMoving = false; +// m_autoPilotTarget = Vector3.Zero; +// ControllingClient.SendAlertMessage("Autopilot cancelled"); +// } + } + + public void DoMoveToPosition(Object sender, string method, List args) + { + try + { + float locx = 0f; + float locy = 0f; + float locz = 0f; + uint regionX = 0; + uint regionY = 0; + try + { + Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); + locx = Convert.ToSingle(args[0]) - (float)regionX; + locy = Convert.ToSingle(args[1]) - (float)regionY; + locz = Convert.ToSingle(args[2]); + } + catch (InvalidCastException) + { + m_log.Error("[CLIENT]: Invalid autopilot request"); + return; + } + m_moveToPositionInProgress = true; + m_moveToPositionTarget = new Vector3(locx, locy, locz); + } + catch (Exception ex) + { + //Why did I get this error? + m_log.Error("[SCENEPRESENCE]: DoMoveToPosition" + ex); + } + } + + private void CheckAtSitTarget() + { + //m_log.Debug("[AUTOPILOT]: " + Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget).ToString()); + if (Util.GetDistanceTo(AbsolutePosition, m_autoPilotTarget) <= 1.5) + { + if (m_sitAtAutoTarget) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetUUID); + if (part != null) + { + AbsolutePosition = part.AbsolutePosition; + Velocity = Vector3.Zero; + SendFullUpdateToAllClients(); + + HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? + } + //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); + m_requestedSitTargetUUID = UUID.Zero; + } + /* + else + { + //ControllingClient.SendAlertMessage("Autopilot cancelled"); + //SendTerseUpdateToAllClients(); + //PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; + //proxy.PCode = (byte)PCode.ParticleSystem; + ////uint nextUUID = m_scene.NextLocalId; + + //proxyObjectGroup = new SceneObjectGroup(m_scene, m_scene.RegionInfo.RegionHandle, UUID, nextUUID, m_autoPilotTarget, Quaternion.Identity, proxy); + //if (proxyObjectGroup != null) + //{ + //proxyObjectGroup.SendGroupFullUpdate(); + //ControllingClient.SendSitResponse(UUID.Zero, m_autoPilotTarget, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); + //m_scene.DeleteSceneObject(proxyObjectGroup); + //} + } + */ + m_autoPilotTarget = Vector3.Zero; + m_autopilotMoving = false; + } + } + /// + /// Perform the logic necessary to stand the avatar up. This method also executes + /// the stand animation. + /// + public void StandUp() + { + SitGround = false; + + if (m_parentID != 0) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); + if (part != null) + { + part.TaskInventory.LockItemsForRead(true); + TaskInventoryDictionary taskIDict = part.TaskInventory; + if (taskIDict != null) + { + foreach (UUID taskID in taskIDict.Keys) + { + UnRegisterControlEventsToScript(LocalId, taskID); + taskIDict[taskID].PermsMask &= ~( + 2048 | //PERMISSION_CONTROL_CAMERA + 4); // PERMISSION_TAKE_CONTROLS + } + } + part.TaskInventory.LockItemsForRead(false); + // Reset sit target. + if (part.GetAvatarOnSitTarget() == UUID) + part.SetAvatarOnSitTarget(UUID.Zero); + m_parentPosition = part.GetWorldPosition(); + ControllingClient.SendClearFollowCamProperties(part.ParentUUID); + } + // part.GetWorldRotation() is the rotation of the object being sat on + // Rotation is the sittiing Av's rotation + + Quaternion partRot; +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partRot = part.ParentGroup.RootPart.RotationOffset; +// } +// else +// { // single or child prim + +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); + } + + Quaternion partIRot = Quaternion.Inverse(partRot); + + Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av + Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av + + + if (m_physicsActor == null) + { + AddToPhysicalScene(false); + } + //CW: If the part isn't null then we can set the current position + if (part != null) + { + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. + part.IsOccupied = false; + part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); + } + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; + } + + m_parentPosition = Vector3.Zero; + m_parentID = 0; + m_linkedPrim = UUID.Zero; + m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + SendFullUpdateToAllClients(); + m_requestedSitTargetID = 0; + + if ((m_physicsActor != null) && (m_avHeight > 0)) + { + SetHeight(m_avHeight); + } + } + Animator.TrySetMovementAnimation("STAND"); + } + + private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) + { + SceneObjectPart targetPart = m_scene.GetSceneObjectPart(targetID); + if (targetPart == null) + return null; + + // If the primitive the player clicked on has a sit target and that sit target is not full, that sit target is used. + // If the primitive the player clicked on has no sit target, and one or more other linked objects have sit targets that are not full, the sit target of the object with the lowest link number will be used. + + // Get our own copy of the part array, and sort into the order we want to test + SceneObjectPart[] partArray = targetPart.ParentGroup.GetParts(); + Array.Sort(partArray, delegate(SceneObjectPart p1, SceneObjectPart p2) + { + // we want the originally selected part first, then the rest in link order -- so make the selected part link num (-1) + int linkNum1 = p1==targetPart ? -1 : p1.LinkNum; + int linkNum2 = p2==targetPart ? -1 : p2.LinkNum; + return linkNum1 - linkNum2; + } + ); + + //look for prims with explicit sit targets that are available + foreach (SceneObjectPart part in partArray) + { + // Is a sit target available? + Vector3 avSitOffSet = part.SitTargetPosition; + Quaternion avSitOrientation = part.SitTargetOrientation; + UUID avOnTargetAlready = part.GetAvatarOnSitTarget(); + bool SitTargetOccupied = (avOnTargetAlready != UUID.Zero); + bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. + if (SitTargetisSet && !SitTargetOccupied) + { + //switch the target to this prim + return part; + } + } + + // no explicit sit target found - use original target + return targetPart; + } + + private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) + { + bool autopilot = true; + Vector3 autopilotTarget = new Vector3(); + Quaternion sitOrientation = Quaternion.Identity; + Vector3 pos = new Vector3(); + Vector3 cameraEyeOffset = Vector3.Zero; + Vector3 cameraAtOffset = Vector3.Zero; + bool forceMouselook = false; + + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); + if (part == null) return; + + // TODO: determine position to sit at based on scene geometry; don't trust offset from client + // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it + + // part is the prim to sit on + // offset is the world-ref vector distance from that prim center to the click-spot + // UUID is the UUID of the Avatar doing the clicking + + m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation + + // Is a sit target available? + Vector3 avSitOffSet = part.SitTargetPosition; + Quaternion avSitOrientation = part.SitTargetOrientation; + + bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. + // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); + Quaternion partRot; +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partRot = part.ParentGroup.RootPart.RotationOffset; +// } +// else +// { // single or child prim + partRot = part.GetWorldRotation(); +// } + Quaternion partIRot = Quaternion.Inverse(partRot); +//Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); + // Sit analysis rewritten by KF 091125 + if (SitTargetisSet) // scipted sit + { + if (!part.IsOccupied) + { +//Console.WriteLine("Scripted, unoccupied"); + part.SetAvatarOnSitTarget(UUID); // set that Av will be on it + offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one + + Quaternion nrot = avSitOrientation; + if (!part.IsRoot) + { + nrot = part.RotationOffset * avSitOrientation; + } + sitOrientation = nrot; // Change rotatione to the scripted one + OffsetRotation = nrot; + autopilot = false; // Jump direct to scripted llSitPos() + } + else + { +//Console.WriteLine("Scripted, occupied"); + return; + } + } + else // Not Scripted + { + if ( (Math.Abs(offset.X) > 0.5f) || (Math.Abs(offset.Y) > 0.5f) ) + { + // large prim & offset, ignore if other Avs sitting +// offset.Z -= 0.05f; + m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked + autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point + +//Console.WriteLine(" offset ={0}", offset); +//Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); +//Console.WriteLine(" autopilotTarget={0}", autopilotTarget); + + } + else // small offset + { +//Console.WriteLine("Small offset"); + if (!part.IsOccupied) + { + m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center + autopilotTarget = part.AbsolutePosition; +//Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); + } + else return; // occupied small + } // end large/small + } // end Scripted/not + cameraAtOffset = part.GetCameraAtOffset(); + cameraEyeOffset = part.GetCameraEyeOffset(); + forceMouselook = part.GetForceMouselook(); + if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // + if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // + + if (m_physicsActor != null) + { + // If we're not using the client autopilot, we're immediately warping the avatar to the location + // We can remove the physicsActor until they stand up. + m_sitAvatarHeight = m_physicsActor.Size.Z; + if (autopilot) + { // its not a scripted sit +// if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) + if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) ) + { + autopilot = false; // close enough + m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. + Not using the part's position because returning the AV to the last known standing + position is likely to be more friendly, isn't it? */ + RemoveFromPhysicalScene(); + Velocity = Vector3.Zero; + AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target + } // else the autopilot will get us close + } + else + { // its a scripted sit + m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. + I *am* using the part's position this time because we have no real idea how far away + the avatar is from the sit target. */ + RemoveFromPhysicalScene(); + Velocity = Vector3.Zero; + } + } + else return; // physactor is null! + + Vector3 offsetr; // = offset * partIRot; + // KF: In a linkset, offsetr needs to be relative to the group root! 091208 + // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); + // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. + // { // Single, or Root prim of linkset, target is ClickOffset * RootRot + //offsetr = offset * partIRot; +// + // else + // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) + // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + + // (offset * partRot); + // } + +//Console.WriteLine(" "); +//Console.WriteLine("link number ={0}", part.LinkNum); +//Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); +//Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); +//Console.WriteLine("Click offst ={0}", offset); +//Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); +//Console.WriteLine("offsetr ={0}", offsetr); +//Console.WriteLine("Camera At ={0}", cameraAtOffset); +//Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); + + //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child + ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); + + m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target + // This calls HandleAgentSit twice, once from here, and the client calls + // HandleAgentSit itself after it gets to the location + // It doesn't get to the location until we've moved them there though + // which happens in HandleAgentSit :P + m_autopilotMoving = autopilot; + m_autoPilotTarget = autopilotTarget; + m_sitAtAutoTarget = autopilot; + m_initialSitTarget = autopilotTarget; + if (!autopilot) + HandleAgentSit(remoteClient, UUID); + } + + public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) + { + if (m_parentID != 0) + { + StandUp(); + } + m_nextSitAnimation = "SIT"; + + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); + + if (part != null) + { + if (!String.IsNullOrEmpty(part.SitAnimation)) + { + m_nextSitAnimation = part.SitAnimation; + } + m_requestedSitTargetID = part.LocalId; + //m_requestedSitOffset = offset; + m_requestedSitTargetUUID = targetID; + + m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); + + if (m_scene.PhysicsScene.SupportsRayCast()) + { + //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); + //SitRayCastAvatarPosition(part); + //return; + } + } + else + { + + m_log.Warn("Sit requested on unknown object: " + targetID.ToString()); + } + + + + SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); + } + /* + public void SitRayCastAvatarPosition(SceneObjectPart part) + { + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = AbsolutePosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse); + } + + public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); + } + else + { + SitRayCastAvatarPositionCameraZ(part); + } + } + else + { + SitRayCastAvatarPositionCameraZ(part); + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) + { + // Next, try to raycast from the camera Z position + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse); + } + + public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal); + } + else + { + SitRayCastCameraPosition(part); + } + } + else + { + SitRayCastCameraPosition(part); + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + public void SitRayCastCameraPosition(SceneObjectPart part) + { + // Next, try to raycast from the camera position + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = CameraPosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse); + } + + public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); + } + else + { + SitRayHorizontal(part); + } + } + else + { + SitRayHorizontal(part); + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + public void SitRayHorizontal(SceneObjectPart part) + { + // Next, try to raycast from the avatar position to fwd + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = CameraPosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse); + } + + public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) + { + SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); + if (part != null) + { + if (hitYN) + { + if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f)) + { + SitRaycastFindEdge(collisionPoint, normal); + m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal); + // Next, try to raycast from the camera position + Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset; + Vector3 StartRayCastPosition = CameraPosition; + Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); + float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); + //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition); + } + else + { + ControllingClient.SendAlertMessage("Sit position not accessable."); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + } + else + { + ControllingClient.SendAlertMessage("Sit position not accessable."); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + } + else + { + ControllingClient.SendAlertMessage("Sit position no longer exists"); + m_requestedSitTargetUUID = UUID.Zero; + m_requestedSitTargetID = 0; + m_requestedSitOffset = Vector3.Zero; + } + + } + + private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) + { + int i = 0; + //throw new NotImplementedException(); + //m_requestedSitTargetUUID = UUID.Zero; + //m_requestedSitTargetID = 0; + //m_requestedSitOffset = Vector3.Zero; + + SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); + } + */ + public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset, string sitAnimation) + { + if (m_parentID != 0) + { + StandUp(); + } + if (!String.IsNullOrEmpty(sitAnimation)) + { + m_nextSitAnimation = sitAnimation; + } + else + { + m_nextSitAnimation = "SIT"; + } + + //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); + SceneObjectPart part = FindNextAvailableSitTarget(targetID); + if (part != null) + { + m_requestedSitTargetID = part.LocalId; + //m_requestedSitOffset = offset; + m_requestedSitTargetUUID = targetID; + + m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); + + if (m_scene.PhysicsScene.SupportsRayCast()) + { + //SitRayCastAvatarPosition(part); + //return; + } + } + else + { + m_log.Warn("Sit requested on unknown object: " + targetID); + } + + SendSitResponse(remoteClient, targetID, offset, Quaternion.Identity); + } + + public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) + { + if (!String.IsNullOrEmpty(m_nextSitAnimation)) + { + HandleAgentSit(remoteClient, agentID, m_nextSitAnimation); + } + else + { + HandleAgentSit(remoteClient, agentID, "SIT"); + } + } + + public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) + { + SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); + + if (m_sitAtAutoTarget || !m_autopilotMoving) + { + if (part != null) + { +//Console.WriteLine("Link #{0}, Rot {1}", part.LinkNum, part.GetWorldRotation()); + if (part.GetAvatarOnSitTarget() == UUID) + { +//Console.WriteLine("Scripted Sit"); + // Scripted sit + Vector3 sitTargetPos = part.SitTargetPosition; + Quaternion sitTargetOrient = part.SitTargetOrientation; + m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); + m_pos += SIT_TARGET_ADJUSTMENT; + if (!part.IsRoot) + { + m_pos *= part.RotationOffset; + } + m_bodyRot = sitTargetOrient; + m_parentPosition = part.AbsolutePosition; + part.IsOccupied = true; + part.ParentGroup.AddAvatar(agentID); + } + else + { + // if m_avUnscriptedSitPos is zero then Av sits above center + // Else Av sits at m_avUnscriptedSitPos + + // Non-scripted sit by Kitto Flora 21Nov09 + // Calculate angle of line from prim to Av + Quaternion partIRot; +// if (part.LinkNum == 1) +// { // Root prim of linkset +// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); +// } +// else +// { // single or child prim + partIRot = Quaternion.Inverse(part.GetWorldRotation()); +// } + Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; + float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); + float x_diff = ( m_avInitialPos.X - sitTargetPos.X); + if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 + if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 + float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); + // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. + // Av sits at world euler <0,0, z>, translated by part rotation + m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click + + m_parentPosition = part.AbsolutePosition; + part.IsOccupied = true; + part.ParentGroup.AddAvatar(agentID); + m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation + (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center + (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + + m_avUnscriptedSitPos; // adds click offset, if any + //Set up raytrace to find top surface of prim + Vector3 size = part.Scale; + float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); + Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); + Vector3 down = new Vector3(0f, 0f, -1f); +//Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); + m_scene.PhysicsScene.RaycastWorld( + start, // Vector3 position, + down, // Vector3 direction, + mag, // float length, + SitAltitudeCallback); // retMethod + } // end scripted/not + } + else // no Av + { + return; + } + } + + //We want our offsets to reference the root prim, not the child we may have sat on + if (!part.IsRoot) + { + m_parentID = part.ParentGroup.RootPart.LocalId; + m_pos += part.OffsetPosition; + } + else + { + m_parentID = m_requestedSitTargetID; + } + + m_linkedPrim = part.UUID; + if (part.GetAvatarOnSitTarget() != UUID) + { + m_offsetRotation = m_offsetRotation / part.RotationOffset; + } + Velocity = Vector3.Zero; + RemoveFromPhysicalScene(); + Animator.TrySetMovementAnimation(sitAnimation); + SendFullUpdateToAllClients(); + SendTerseUpdateToAllClients(); + } + + public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) + { + // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer + // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. + if(hitYN) + { + // m_pos = Av offset from prim center to make look like on center + // m_parentPosition = Actual center pos of prim + // collisionPoint = spot on prim where we want to sit + // collisionPoint.Z = global sit surface height + SceneObjectPart part = m_scene.GetSceneObjectPart(localid); + Quaternion partIRot; +// if (part.LinkNum == 1) +/// { // Root prim of linkset +// partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); +// } +// else +// { // single or child prim + partIRot = Quaternion.Inverse(part.GetWorldRotation()); +// } + if (m_initialSitTarget != null) + { + float offZ = collisionPoint.Z - m_initialSitTarget.Z; + Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction + //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); + m_pos += offset; + // ControllingClient.SendClearFollowCamProperties(part.UUID); + } + + } + } // End SitAltitudeCallback KF. + + /// + /// Event handler for the 'Always run' setting on the client + /// Tells the physics plugin to increase speed of movement. + /// + public void HandleSetAlwaysRun(IClientAPI remoteClient, bool pSetAlwaysRun) + { + m_setAlwaysRun = pSetAlwaysRun; + if (PhysicsActor != null) + { + PhysicsActor.SetAlwaysRun = pSetAlwaysRun; + } + } + + public void HandleStartAnim(IClientAPI remoteClient, UUID animID) + { + Animator.AddAnimation(animID, UUID.Zero); + } + + public void HandleStopAnim(IClientAPI remoteClient, UUID animID) + { + Animator.RemoveAnimation(animID); + } + + /// + /// Rotate the avatar to the given rotation and apply a movement in the given relative vector + /// + /// The vector in which to move. This is relative to the rotation argument + /// The direction in which this avatar should now face. + public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) + { + if (m_isChildAgent) + { + // WHAT??? + m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent, making root agent!"); + + // we have to reset the user's child agent connections. + // Likely, here they've lost the eventqueue for other regions so border + // crossings will fail at this point unless we reset them. + + List regions = new List(KnownChildRegionHandles); + regions.Remove(m_scene.RegionInfo.RegionHandle); + + MakeRootAgent(new Vector3(127f, 127f, 127f), true); + + // Async command + if (m_scene.SceneGridService != null) + { + m_scene.SceneGridService.SendCloseChildAgentConnections(UUID, regions); + + // Give the above command some time to try and close the connections. + // this is really an emergency.. so sleep, or we'll get all discombobulated. + System.Threading.Thread.Sleep(500); + } + + if (m_scene.SceneGridService != null) + { + IEntityTransferModule m_agentTransfer = m_scene.RequestModuleInterface(); + if (m_agentTransfer != null) + m_agentTransfer.EnableChildAgents(this); + } + + return; + } + + m_perfMonMS = Util.EnvironmentTickCount(); + + Rotation = rotation; + Vector3 direc = vec * rotation; + direc.Normalize(); + PhysicsActor actor = m_physicsActor; + if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. + + direc *= 0.03f * 128f * m_speedModifier; + + if (actor != null) + { + if (actor.Flying) + { + direc *= 4.0f; + //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); + //bool colliding = (m_physicsActor.IsColliding==true); + //if (controlland) + // m_log.Info("[AGENT]: landCommand"); + //if (colliding) + // m_log.Info("[AGENT]: colliding"); + //if (m_physicsActor.Flying && colliding && controlland) + //{ + // StopFlying(); + // m_log.Info("[AGENT]: Stop FLying"); + //} + } + else if (!actor.Flying && actor.IsColliding) + { + if (direc.Z > 2.0f) + { + if(m_animator.m_animTickJump == -1) + { + direc.Z *= 3.0f; // jump + } + else + { + direc.Z *= 0.1f; // prejump + } + /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs + Animator.TrySetMovementAnimation("PREJUMP"); + Animator.TrySetMovementAnimation("JUMP"); + */ + } + } + } + + // TODO: Add the force instead of only setting it to support multiple forces per frame? + m_forceToApply = direc; + m_isNudging = Nudging; + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + #endregion + + #region Overridden Methods + + public override void Update() + { + const float ROTATION_TOLERANCE = 0.01f; + const float VELOCITY_TOLERANCE = 0.001f; + const float POSITION_TOLERANCE = 0.05f; + //const int TIME_MS_TOLERANCE = 3000; + + + + if (m_isChildAgent == false) + { +// PhysicsActor actor = m_physicsActor; + + // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to + // grab the latest PhysicsActor velocity, whereas m_velocity is often + // storing a requested force instead of an actual traveling velocity + + // Throw away duplicate or insignificant updates + if (!m_bodyRot.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) || + !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || + !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) + //Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) + { + SendTerseUpdateToAllClients(); + + // Update the "last" values + m_lastPosition = m_pos; + m_lastRotation = m_bodyRot; + m_lastVelocity = Velocity; + //m_lastTerseSent = Environment.TickCount; + } + + // followed suggestion from mic bowman. reversed the two lines below. + if (m_parentID == 0 && m_physicsActor != null || m_parentID != 0) // Check that we have a physics actor or we're sitting on something + CheckForBorderCrossing(); + CheckForSignificantMovement(); // sends update to the modules. + } + + //Sending prim updates AFTER the avatar terse updates are sent + SendPrimUpdates(); + } + + #endregion + + #region Update Client(s) + + /// + /// Sends a location update to the client connected to this scenePresence + /// + /// + public void SendTerseUpdateToClient(IClientAPI remoteClient) + { + // If the client is inactive, it's getting its updates from another + // server. + if (remoteClient.IsActive) + { + m_perfMonMS = Util.EnvironmentTickCount(); + + PhysicsActor actor = m_physicsActor; + Vector3 velocity = (actor != null) ? actor.Velocity : Vector3.Zero; + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + //m_log.DebugFormat("[SCENEPRESENCE]: TerseUpdate: Pos={0} Rot={1} Vel={2}", m_pos, m_bodyRot, m_velocity); + + remoteClient.SendPrimUpdate(this, PrimUpdateFlags.Position | PrimUpdateFlags.Rotation | PrimUpdateFlags.Velocity | PrimUpdateFlags.Acceleration | PrimUpdateFlags.AngularVelocity); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + m_scene.StatsReporter.AddAgentUpdates(1); + } + } + + /// + /// Send a location/velocity/accelleration update to all agents in scene + /// + public void SendTerseUpdateToAllClients() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + m_scene.ForEachClient(SendTerseUpdateToClient); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + public void SendCoarseLocations(List coarseLocations, List avatarUUIDs) + { + SendCourseLocationsMethod d = m_sendCourseLocationsMethod; + if (d != null) + { + d.Invoke(m_scene.RegionInfo.originRegionID, this, coarseLocations, avatarUUIDs); + } + } + + public void SetSendCourseLocationMethod(SendCourseLocationsMethod d) + { + if (d != null) + m_sendCourseLocationsMethod = d; + } + + public void SendCoarseLocationsDefault(UUID sceneId, ScenePresence p, List coarseLocations, List avatarUUIDs) + { + m_perfMonMS = Util.EnvironmentTickCount(); + m_controllingClient.SendCoarseLocationUpdate(avatarUUIDs, coarseLocations); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) + /// + /// + public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) + { + // 2 stage check is needed. + if (remoteAvatar == null) + return; + IClientAPI cl=remoteAvatar.ControllingClient; + if (cl == null) + return; + if (m_appearance.Texture == null) + return; + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); + m_scene.StatsReporter.AddAgentUpdates(1); + } + + /// + /// Tell *ALL* agents about this agent + /// + public void SendInitialFullUpdateToAllClients() + { + m_perfMonMS = Util.EnvironmentTickCount(); + int avUpdates = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + ++avUpdates; + // only send if this is the root (children are only "listening posts" in a foreign region) + if (!IsChildAgent) + { + SendFullUpdateToOtherClient(avatar); + } + + if (avatar.LocalId != LocalId) + { + if (!avatar.IsChildAgent) + { + avatar.SendFullUpdateToOtherClient(this); + avatar.SendAppearanceToOtherAgent(this); + avatar.Animator.SendAnimPackToClient(ControllingClient); + } + } + }); + + m_scene.StatsReporter.AddAgentUpdates(avUpdates); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + + //Animator.SendAnimPack(); + } + + public void SendFullUpdateToAllClients() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + // only send update from root agents to other clients; children are only "listening posts" + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence sp) + { + if (sp.IsChildAgent) + return; + SendFullUpdateToOtherClient(sp); + ++count; + }); + m_scene.StatsReporter.AddAgentUpdates(count); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + + Animator.SendAnimPack(); + } + + /// + /// Do everything required once a client completes its movement into a region + /// + public void SendInitialData() + { + // Moved this into CompleteMovement to ensure that m_appearance is initialized before + // the inventory arrives + // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + m_controllingClient.SendAvatarDataImmediate(this); + + SendInitialFullUpdateToAllClients(); + SendAppearanceToAllOtherAgents(); + } + + /// + /// Tell the client for this scene presence what items it should be wearing now + /// + public void SendWearables() + { + m_log.DebugFormat("[SCENE]: Received request for wearables of {0}", Name); + + ControllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); + } + + /// + /// + /// + public void SendAppearanceToAllOtherAgents() + { + m_perfMonMS = Util.EnvironmentTickCount(); + + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + if (scenePresence.UUID != UUID) + { + SendAppearanceToOtherAgent(scenePresence); + } + }); + + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); + } + + /// + /// Send appearance data to an agent that isn't this one. + /// + /// + public void SendAppearanceToOtherAgent(ScenePresence avatar) + { + avatar.ControllingClient.SendAppearance( + m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); + } + + /// + /// Set appearance data (textureentry and slider settings) received from the client + /// + /// + /// + public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) + { + if (m_physicsActor != null) + { + if (!IsChildAgent) + { + // This may seem like it's redundant, remove the avatar from the physics scene + // just to add it back again, but it saves us from having to update + // 3 variables 10 times a second. + bool flyingTemp = m_physicsActor.Flying; + RemoveFromPhysicalScene(); + //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); + + //PhysicsActor = null; + + AddToPhysicalScene(flyingTemp); + } + } + + #region Bake Cache Check + + if (textureEntry != null) + { + for (int i = 0; i < BAKE_INDICES.Length; i++) + { + int j = BAKE_INDICES[i]; + Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; + + if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + { + if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) + { + m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); + this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); + } + } + } + + } + + + #endregion Bake Cache Check + + m_appearance.SetAppearance(textureEntry, visualParams); + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); + + // This is not needed, because only the transient data changed + //AvatarData adata = new AvatarData(m_appearance); + //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); + + SendAppearanceToAllOtherAgents(); + if (!m_startAnimationSet) + { + Animator.UpdateMovementAnimations(); + m_startAnimationSet = true; + } + + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; + + m_controllingClient.SendAvatarDataImmediate(this); + } + + public void SetWearable(int wearableId, AvatarWearable wearable) + { + m_appearance.SetWearable(wearableId, wearable); + AvatarData adata = new AvatarData(m_appearance); + m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); + m_controllingClient.SendWearables(m_appearance.Wearables, m_appearance.Serial++); + } + + // Because appearance setting is in a module, we actually need + // to give it access to our appearance directly, otherwise we + // get a synchronization issue. + public AvatarAppearance Appearance + { + get { return m_appearance; } + set { m_appearance = value; } + } + + #endregion + + #region Significant Movement Method + + /// + /// This checks for a significant movement and sends a courselocationchange update + /// + protected void CheckForSignificantMovement() + { + // Movement updates for agents in neighboring regions are sent directly to clients. + // This value only affects how often agent positions are sent to neighbor regions + // for things such as distance-based update prioritization + const float SIGNIFICANT_MOVEMENT = 2.0f; + + if (Util.GetDistanceTo(AbsolutePosition, posLastSignificantMove) > SIGNIFICANT_MOVEMENT) + { + posLastSignificantMove = AbsolutePosition; + m_scene.EventManager.TriggerSignificantClientMovement(m_controllingClient); + } + + // Minimum Draw distance is 64 meters, the Radius of the draw distance sphere is 32m + if (Util.GetDistanceTo(AbsolutePosition, m_lastChildAgentUpdatePosition) >= Scene.ChildReprioritizationDistance || + Util.GetDistanceTo(CameraPosition, m_lastChildAgentUpdateCamPosition) >= Scene.ChildReprioritizationDistance) + { + m_lastChildAgentUpdatePosition = AbsolutePosition; + m_lastChildAgentUpdateCamPosition = CameraPosition; + + ChildAgentDataUpdate cadu = new ChildAgentDataUpdate(); + cadu.ActiveGroupID = UUID.Zero.Guid; + cadu.AgentID = UUID.Guid; + cadu.alwaysrun = m_setAlwaysRun; + cadu.AVHeight = m_avHeight; + Vector3 tempCameraCenter = m_CameraCenter; + cadu.cameraPosition = tempCameraCenter; + cadu.drawdistance = m_DrawDistance; + cadu.GroupAccess = 0; + cadu.Position = AbsolutePosition; + cadu.regionHandle = m_rootRegionHandle; + float multiplier = 1; + int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); + if (innacurateNeighbors != 0) + { + multiplier = 1f / (float)innacurateNeighbors; + } + if (multiplier <= 0f) + { + multiplier = 0.25f; + } + + //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); + cadu.throttles = ControllingClient.GetThrottlesPacked(multiplier); + cadu.Velocity = Velocity; + + AgentPosition agentpos = new AgentPosition(); + agentpos.CopyFrom(cadu); + + m_scene.SendOutChildAgentUpdates(agentpos, this); + } + } + + #endregion + + #region Border Crossing Methods + + /// + /// Checks to see if the avatar is in range of a border and calls CrossToNewRegion + /// + protected void CheckForBorderCrossing() + { + if (IsChildAgent) + return; + + Vector3 pos2 = AbsolutePosition; + Vector3 vel = Velocity; + int neighbor = 0; + int[] fix = new int[2]; + + float timeStep = 0.1f; + pos2.X = pos2.X + (vel.X*timeStep); + pos2.Y = pos2.Y + (vel.Y*timeStep); + pos2.Z = pos2.Z + (vel.Z*timeStep); + + if (!IsInTransit) + { + // Checks if where it's headed exists a region + + bool needsTransit = false; + if (m_scene.TestBorderCross(pos2, Cardinals.W)) + { + if (m_scene.TestBorderCross(pos2, Cardinals.S)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.SW, ref fix); + } + else if (m_scene.TestBorderCross(pos2, Cardinals.N)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.NW, ref fix); + } + else + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.W, ref fix); + } + } + else if (m_scene.TestBorderCross(pos2, Cardinals.E)) + { + if (m_scene.TestBorderCross(pos2, Cardinals.S)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.SE, ref fix); + } + else if (m_scene.TestBorderCross(pos2, Cardinals.N)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.NE, ref fix); + } + else + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.E, ref fix); + } + } + else if (m_scene.TestBorderCross(pos2, Cardinals.S)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.S, ref fix); + } + else if (m_scene.TestBorderCross(pos2, Cardinals.N)) + { + needsTransit = true; + neighbor = HaveNeighbor(Cardinals.N, ref fix); + } + + + // Makes sure avatar does not end up outside region + if (neighbor <= 0) + { + if (!needsTransit) + { + if (m_requestedSitTargetUUID == UUID.Zero) + { + Vector3 pos = AbsolutePosition; + if (AbsolutePosition.X < 0) + pos.X += Velocity.X; + else if (AbsolutePosition.X > Constants.RegionSize) + pos.X -= Velocity.X; + if (AbsolutePosition.Y < 0) + pos.Y += Velocity.Y; + else if (AbsolutePosition.Y > Constants.RegionSize) + pos.Y -= Velocity.Y; + AbsolutePosition = pos; + } + } + } + else if (neighbor > 0) + CrossToNewRegion(); + } + else + { + RemoveFromPhysicalScene(); + // This constant has been inferred from experimentation + // I'm not sure what this value should be, so I tried a few values. + timeStep = 0.04f; + pos2 = AbsolutePosition; + pos2.X = pos2.X + (vel.X * timeStep); + pos2.Y = pos2.Y + (vel.Y * timeStep); + pos2.Z = pos2.Z + (vel.Z * timeStep); + m_pos = pos2; + } + } + + protected int HaveNeighbor(Cardinals car, ref int[] fix) + { + uint neighbourx = m_regionInfo.RegionLocX; + uint neighboury = m_regionInfo.RegionLocY; + + int dir = (int)car; + + if (dir > 1 && dir < 5) //Heading East + neighbourx++; + else if (dir > 5) // Heading West + neighbourx--; + + if (dir < 3 || dir == 8) // Heading North + neighboury++; + else if (dir > 3 && dir < 7) // Heading Sout + neighboury--; + + int x = (int)(neighbourx * Constants.RegionSize); + int y = (int)(neighboury * Constants.RegionSize); + GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, x, y); + + if (neighbourRegion == null) + { + fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx); + fix[1] = (int)(m_regionInfo.RegionLocY - neighboury); + return dir * (-1); + } + else + return dir; + } + + /// + /// Moves the agent outside the region bounds + /// Tells neighbor region that we're crossing to it + /// If the neighbor accepts, remove the agent's viewable avatar from this scene + /// set them to a child agent. + /// + protected void CrossToNewRegion() + { + InTransit(); + try + { + m_scene.CrossAgentToNewRegion(this, m_physicsActor.Flying); + } + catch + { + m_scene.CrossAgentToNewRegion(this, false); + } + } + + public void InTransit() + { + m_inTransit = true; + + if ((m_physicsActor != null) && m_physicsActor.Flying) + m_AgentControlFlags |= AgentManager.ControlFlags.AGENT_CONTROL_FLY; + else if ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0) + m_AgentControlFlags &= ~AgentManager.ControlFlags.AGENT_CONTROL_FLY; + } + + public void NotInTransit() + { + m_inTransit = false; + } + + public void RestoreInCurrentScene() + { + AddToPhysicalScene(false); // not exactly false + } + + public void Reset() + { + // Put the child agent back at the center + AbsolutePosition + = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 70); + Animator.ResetAnimations(); + } + + /// + /// Computes which child agents to close when the scene presence moves to another region. + /// Removes those regions from m_knownRegions. + /// + /// The new region's x on the map + /// The new region's y on the map + /// + public void CloseChildAgents(uint newRegionX, uint newRegionY) + { + List byebyeRegions = new List(); + m_log.DebugFormat( + "[SCENE PRESENCE]: Closing child agents. Checking {0} regions in {1}", + m_knownChildRegions.Keys.Count, Scene.RegionInfo.RegionName); + //DumpKnownRegions(); + + lock (m_knownChildRegions) + { + foreach (ulong handle in m_knownChildRegions.Keys) + { + // Don't close the agent on this region yet + if (handle != Scene.RegionInfo.RegionHandle) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + + //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); + //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); + if (Util.IsOutsideView(x, newRegionX, y, newRegionY)) + { + byebyeRegions.Add(handle); + } + } + } + } + + if (byebyeRegions.Count > 0) + { + m_log.Debug("[SCENE PRESENCE]: Closing " + byebyeRegions.Count + " child agents"); + m_scene.SceneGridService.SendCloseChildAgentConnections(m_controllingClient.AgentId, byebyeRegions); + } + + foreach (ulong handle in byebyeRegions) + { + RemoveNeighbourRegion(handle); + } + } + + #endregion + + /// + /// This allows the Sim owner the abiility to kick users from their sim currently. + /// It tells the client that the agent has permission to do so. + /// + public void GrantGodlikePowers(UUID agentID, UUID sessionID, UUID token, bool godStatus) + { + if (godStatus) + { + // For now, assign god level 200 to anyone + // who is granted god powers, but has no god level set. + // + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, agentID); + if (account != null) + { + if (account.UserLevel > 0) + m_godLevel = account.UserLevel; + else + m_godLevel = 200; + } + } + else + { + m_godLevel = 0; + } + + ControllingClient.SendAdminResponse(token, (uint)m_godLevel); + } + + #region Child Agent Updates + + public void ChildAgentDataUpdate(AgentData cAgentData) + { + //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); + if (!IsChildAgent) + return; + + CopyFrom(cAgentData); + } + + /// + /// This updates important decision making data about a child agent + /// The main purpose is to figure out what objects to send to a child agent that's in a neighboring region + /// + public void ChildAgentDataUpdate(AgentPosition cAgentData, uint tRegionX, uint tRegionY, uint rRegionX, uint rRegionY) + { + if (!IsChildAgent) + return; + + //m_log.Debug(" >>> ChildAgentPositionUpdate <<< " + rRegionX + "-" + rRegionY); + int shiftx = ((int)rRegionX - (int)tRegionX) * (int)Constants.RegionSize; + int shifty = ((int)rRegionY - (int)tRegionY) * (int)Constants.RegionSize; + + Vector3 offset = new Vector3(shiftx, shifty, 0f); + + m_DrawDistance = cAgentData.Far; + if (cAgentData.Position != new Vector3(-1f, -1f, -1f)) // UGH!! + m_pos = cAgentData.Position + offset; + + if (Vector3.Distance(AbsolutePosition, posLastSignificantMove) >= Scene.ChildReprioritizationDistance) + { + posLastSignificantMove = AbsolutePosition; + ReprioritizeUpdates(); + } + + m_CameraCenter = cAgentData.Center + offset; + + m_avHeight = cAgentData.Size.Z; + //SetHeight(cAgentData.AVHeight); + + if ((cAgentData.Throttles != null) && cAgentData.Throttles.Length > 0) + ControllingClient.SetChildAgentThrottle(cAgentData.Throttles); + + // Sends out the objects in the user's draw distance if m_sendTasksToChild is true. + if (m_scene.m_seeIntoRegionFromNeighbor) + m_sceneViewer.Reset(); + + //cAgentData.AVHeight; + m_rootRegionHandle = cAgentData.RegionHandle; + //m_velocity = cAgentData.Velocity; + } + + public void CopyTo(AgentData cAgent) + { + cAgent.AgentID = UUID; + cAgent.RegionID = Scene.RegionInfo.RegionID; + + cAgent.Position = AbsolutePosition; + cAgent.Velocity = m_velocity; + cAgent.Center = m_CameraCenter; + // Don't copy the size; it is inferred from apearance parameters + //cAgent.Size = new Vector3(0, 0, m_avHeight); + cAgent.AtAxis = m_CameraAtAxis; + cAgent.LeftAxis = m_CameraLeftAxis; + cAgent.UpAxis = m_CameraUpAxis; + + cAgent.Far = m_DrawDistance; + + // Throttles + float multiplier = 1; + int innacurateNeighbors = m_scene.GetInaccurateNeighborCount(); + if (innacurateNeighbors != 0) + { + multiplier = 1f / innacurateNeighbors; + } + if (multiplier <= 0f) + { + multiplier = 0.25f; + } + //m_log.Info("[NeighborThrottle]: " + m_scene.GetInaccurateNeighborCount().ToString() + " - m: " + multiplier.ToString()); + cAgent.Throttles = ControllingClient.GetThrottlesPacked(multiplier); + + cAgent.HeadRotation = m_headrotation; + cAgent.BodyRotation = m_bodyRot; + cAgent.ControlFlags = (uint)m_AgentControlFlags; + + if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) + cAgent.GodLevel = (byte)m_godLevel; + else + cAgent.GodLevel = (byte) 0; + + cAgent.AlwaysRun = m_setAlwaysRun; + + try + { + // We might not pass the Wearables in all cases... + // They're only needed so that persistent changes to the appearance + // are preserved in the new region where the user is moving to. + // But in Hypergrid we might not let this happen. + int i = 0; + UUID[] wears = new UUID[m_appearance.Wearables.Length * 2]; + foreach (AvatarWearable aw in m_appearance.Wearables) + { + if (aw != null) + { + wears[i++] = aw.ItemID; + wears[i++] = aw.AssetID; + } + else + { + wears[i++] = UUID.Zero; + wears[i++] = UUID.Zero; + } + } + cAgent.Wearables = wears; + + cAgent.VisualParams = m_appearance.VisualParams; + + if (m_appearance.Texture != null) + cAgent.AgentTextures = m_appearance.Texture.GetBytes(); + } + catch (Exception e) + { + m_log.Warn("[SCENE PRESENCE]: exception in CopyTo " + e.Message); + } + + //Attachments + List attPoints = m_appearance.GetAttachedPoints(); + if (attPoints != null) + { + //m_log.DebugFormat("[SCENE PRESENCE]: attachments {0}", attPoints.Count); + int i = 0; + AttachmentData[] attachs = new AttachmentData[attPoints.Count]; + foreach (int point in attPoints) + { + attachs[i++] = new AttachmentData(point, m_appearance.GetAttachedItem(point), m_appearance.GetAttachedAsset(point)); + } + cAgent.Attachments = attachs; + } + + lock (scriptedcontrols) + { + ControllerData[] controls = new ControllerData[scriptedcontrols.Count]; + int i = 0; + + foreach (ScriptControllers c in scriptedcontrols.Values) + { + controls[i++] = new ControllerData(c.itemID, (uint)c.ignoreControls, (uint)c.eventControls); + } + cAgent.Controllers = controls; + } + + // Animations + try + { + cAgent.Anims = Animator.Animations.ToArray(); + } + catch { } + + // cAgent.GroupID = ?? + // Groups??? + + } + + public void CopyFrom(AgentData cAgent) + { + m_originRegionID = cAgent.RegionID; + + m_callbackURI = cAgent.CallbackURI; + + m_pos = cAgent.Position; + + m_velocity = cAgent.Velocity; + m_CameraCenter = cAgent.Center; + //m_avHeight = cAgent.Size.Z; + m_CameraAtAxis = cAgent.AtAxis; + m_CameraLeftAxis = cAgent.LeftAxis; + m_CameraUpAxis = cAgent.UpAxis; + + m_DrawDistance = cAgent.Far; + + if ((cAgent.Throttles != null) && cAgent.Throttles.Length > 0) + ControllingClient.SetChildAgentThrottle(cAgent.Throttles); + + m_headrotation = cAgent.HeadRotation; + m_bodyRot = cAgent.BodyRotation; + m_AgentControlFlags = (AgentManager.ControlFlags)cAgent.ControlFlags; + + if (m_scene.Permissions.IsGod(new UUID(cAgent.AgentID))) + m_godLevel = cAgent.GodLevel; + m_setAlwaysRun = cAgent.AlwaysRun; + + uint i = 0; + try + { + if (cAgent.Wearables == null) + cAgent.Wearables = new UUID[0]; + AvatarWearable[] wears = new AvatarWearable[cAgent.Wearables.Length / 2]; + for (uint n = 0; n < cAgent.Wearables.Length; n += 2) + { + UUID itemId = cAgent.Wearables[n]; + UUID assetId = cAgent.Wearables[n + 1]; + wears[i++] = new AvatarWearable(itemId, assetId); + } + m_appearance.Wearables = wears; + Primitive.TextureEntry te; + if (cAgent.AgentTextures != null && cAgent.AgentTextures.Length > 1) + te = new Primitive.TextureEntry(cAgent.AgentTextures, 0, cAgent.AgentTextures.Length); + else + te = AvatarAppearance.GetDefaultTexture(); + if ((cAgent.VisualParams == null) || (cAgent.VisualParams.Length < AvatarAppearance.VISUALPARAM_COUNT)) + cAgent.VisualParams = AvatarAppearance.GetDefaultVisualParams(); + m_appearance.SetAppearance(te, (byte[])cAgent.VisualParams.Clone()); + } + catch (Exception e) + { + m_log.Warn("[SCENE PRESENCE]: exception in CopyFrom " + e.Message); + } + + // Attachments + try + { + if (cAgent.Attachments != null) + { + m_appearance.ClearAttachments(); + foreach (AttachmentData att in cAgent.Attachments) + { + m_appearance.SetAttachment(att.AttachPoint, att.ItemID, att.AssetID); + } + } + } + catch { } + + try + { + lock (scriptedcontrols) + { + if (cAgent.Controllers != null) + { + scriptedcontrols.Clear(); + + foreach (ControllerData c in cAgent.Controllers) + { + ScriptControllers sc = new ScriptControllers(); + sc.itemID = c.ItemID; + sc.ignoreControls = (ScriptControlled)c.IgnoreControls; + sc.eventControls = (ScriptControlled)c.EventControls; + + scriptedcontrols[sc.itemID] = sc; + } + } + } + } + catch { } + // Animations + try + { + Animator.ResetAnimations(); + Animator.Animations.FromArray(cAgent.Anims); + } + catch { } + + //cAgent.GroupID = ?? + //Groups??? + } + + public bool CopyAgent(out IAgentData agent) + { + agent = new CompleteAgentData(); + CopyTo((AgentData)agent); + return true; + } + + #endregion Child Agent Updates + + /// + /// Handles part of the PID controller function for moving an avatar. + /// + public override void UpdateMovement() + { + if (m_forceToApply.HasValue) + { + + Vector3 force = m_forceToApply.Value; + m_updateflag = true; + Velocity = force; + + m_forceToApply = null; + } + else + { + if (m_isNudging) + { + Vector3 force = Vector3.Zero; + + m_updateflag = true; + Velocity = force; + m_isNudging = false; + m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" + } + } + } + + public override void SetText(string text, Vector3 color, double alpha) + { + throw new Exception("Can't set Text on avatar."); + } + + /// + /// Adds a physical representation of the avatar to the Physics plugin + /// + public void AddToPhysicalScene(bool isFlying) + { + PhysicsScene scene = m_scene.PhysicsScene; + + Vector3 pVec = AbsolutePosition; + + // Old bug where the height was in centimeters instead of meters + if (m_avHeight == 127.0f) + { + m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, new Vector3(0f, 0f, 1.56f), + isFlying); + } + else + { + m_physicsActor = scene.AddAvatar(Firstname + "." + Lastname, pVec, + new Vector3(0f, 0f, m_avHeight), isFlying); + } + scene.AddPhysicsActorTaint(m_physicsActor); + //m_physicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; + m_physicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; + m_physicsActor.OnOutOfBounds += OutOfBoundsCall; // Called for PhysicsActors when there's something wrong + m_physicsActor.SubscribeEvents(500); + m_physicsActor.LocalID = LocalId; + } + + private void OutOfBoundsCall(Vector3 pos) + { + //bool flying = m_physicsActor.Flying; + //RemoveFromPhysicalScene(); + + //AddToPhysicalScene(flying); + if (ControllingClient != null) + ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); + } + + // Event called by the physics plugin to tell the avatar about a collision. + private void PhysicsCollisionUpdate(EventArgs e) + { + if (e == null) + return; + + // The Physics Scene will send (spam!) updates every 500 ms grep: m_physicsActor.SubscribeEvents( + // as of this comment the interval is set in AddToPhysicalScene + if (Animator!=null) + { + if (m_updateCount > 0) //KF: DO NOT call UpdateMovementAnimations outside of the m_updateCount wrapper, + { // else its will lock out other animation changes, like ground sit. + Animator.UpdateMovementAnimations(); + m_updateCount--; + } + } + + CollisionEventUpdate collisionData = (CollisionEventUpdate)e; + Dictionary coldata = collisionData.m_objCollisionList; + + CollisionPlane = Vector4.UnitW; + + if (m_lastColCount != coldata.Count) + { + m_updateCount = UPDATE_COUNT; + m_lastColCount = coldata.Count; + } + + if (coldata.Count != 0 && Animator != null) + { + switch (Animator.CurrentMovementAnimation) + { + case "STAND": + case "WALK": + case "RUN": + case "CROUCH": + case "CROUCHWALK": + { + ContactPoint lowest; + lowest.SurfaceNormal = Vector3.Zero; + lowest.Position = Vector3.Zero; + lowest.Position.Z = Single.NaN; + + foreach (ContactPoint contact in coldata.Values) + { + if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z) + { + lowest = contact; + } + } + + CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); + } + break; + } + } + + List thisHitColliders = new List(); + List endedColliders = new List(); + List startedColliders = new List(); + + foreach (uint localid in coldata.Keys) + { + thisHitColliders.Add(localid); + if (!m_lastColliders.Contains(localid)) + { + startedColliders.Add(localid); + } + //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); + } + + // calculate things that ended colliding + foreach (uint localID in m_lastColliders) + { + if (!thisHitColliders.Contains(localID)) + { + endedColliders.Add(localID); + } + } + //add the items that started colliding this time to the last colliders list. + foreach (uint localID in startedColliders) + { + m_lastColliders.Add(localID); + } + // remove things that ended colliding from the last colliders list + foreach (uint localID in endedColliders) + { + m_lastColliders.Remove(localID); + } + + // do event notification + if (startedColliders.Count > 0) + { + ColliderArgs StartCollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in startedColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + StartCollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); + } + } + + if (endedColliders.Count > 0) + { + ColliderArgs EndCollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in endedColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + EndCollidingMessage.Colliders = colliding; + + foreach (SceneObjectGroup att in Attachments) + Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); + } + } + + if (thisHitColliders.Count > 0) + { + ColliderArgs CollidingMessage = new ColliderArgs(); + List colliding = new List(); + foreach (uint localId in thisHitColliders) + { + if (localId == 0) + continue; + + SceneObjectPart obj = Scene.GetSceneObjectPart(localId); + string data = ""; + if (obj != null) + { + DetectedObject detobj = new DetectedObject(); + detobj.keyUUID = obj.UUID; + detobj.nameStr = obj.Name; + detobj.ownerUUID = obj.OwnerID; + detobj.posVector = obj.AbsolutePosition; + detobj.rotQuat = obj.GetWorldRotation(); + detobj.velVector = obj.Velocity; + detobj.colliderType = 0; + detobj.groupUUID = obj.GroupID; + colliding.Add(detobj); + } + } + + if (colliding.Count > 0) + { + CollidingMessage.Colliders = colliding; + + lock (m_attachments) + { + foreach (SceneObjectGroup att in m_attachments) + Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); + } + } + } + + if (m_invulnerable) + return; + + float starthealth = Health; + uint killerObj = 0; + foreach (uint localid in coldata.Keys) + { + SceneObjectPart part = Scene.GetSceneObjectPart(localid); + + if (part != null && part.ParentGroup.Damage != -1.0f) + Health -= part.ParentGroup.Damage; + else + { + if (coldata[localid].PenetrationDepth >= 0.10f) + Health -= coldata[localid].PenetrationDepth * 5.0f; + } + + if (Health <= 0.0f) + { + if (localid != 0) + killerObj = localid; + } + //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString()); + } + //Health = 100; + if (!m_invulnerable) + { + if (starthealth != Health) + { + ControllingClient.SendHealth(Health); + } + if (m_health <= 0) + m_scene.EventManager.TriggerAvatarKill(killerObj, this); + } + } + + public void setHealthWithUpdate(float health) + { + Health = health; + ControllingClient.SendHealth(Health); + } + + public void Close() + { + lock (m_attachments) + { + // Delete attachments from scene + // Don't try to save, as this thread won't live long + // enough to complete the save. This would cause no copy + // attachments to poof! + // + foreach (SceneObjectGroup grp in m_attachments) + { + m_scene.DeleteSceneObject(grp, false); + } + m_attachments.Clear(); + } + + lock (m_knownChildRegions) + { + m_knownChildRegions.Clear(); + } + + lock (m_reprioritization_timer) + { + m_reprioritization_timer.Enabled = false; + m_reprioritization_timer.Elapsed -= new ElapsedEventHandler(Reprioritize); + } + + // I don't get it but mono crashes when you try to dispose of this timer, + // unsetting the elapsed callback should be enough to allow for cleanup however. + // m_reprioritizationTimer.Dispose(); + + m_sceneViewer.Close(); + + RemoveFromPhysicalScene(); + m_animator.Close(); + m_animator = null; + } + + public void AddAttachment(SceneObjectGroup gobj) + { + lock (m_attachments) + { + m_attachments.Add(gobj); + } + } + + public bool HasAttachments() + { + return m_attachments.Count > 0; + } + + public bool HasScriptedAttachments() + { + lock (m_attachments) + { + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj != null) + { + if (gobj.RootPart.Inventory.ContainsScripts()) + return true; + } + } + } + return false; + } + + public void RemoveAttachment(SceneObjectGroup gobj) + { + lock (m_attachments) + { + if (m_attachments.Contains(gobj)) + { + m_attachments.Remove(gobj); + } + } + } + + public bool ValidateAttachments() + { + lock (m_attachments) + { + // Validate + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj == null) + return false; + + if (gobj.IsDeleted) + return false; + } + } + return true; + } + + /// + /// Send a script event to this scene presence's attachments + /// + /// The name of the event + /// The arguments for the event + public void SendScriptEventToAttachments(string eventName, Object[] args) + { + if (m_scriptEngines != null) + { + lock (m_attachments) + { + foreach (SceneObjectGroup grp in m_attachments) + { + // 16384 is CHANGED_ANIMATION + // + // Send this to all attachment root prims + // + foreach (IScriptModule m in m_scriptEngines) + { + if (m == null) // No script engine loaded + continue; + + m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); + } + } + } + } + } + + + public void initializeScenePresence(IClientAPI client, RegionInfo region, Scene scene) + { + m_controllingClient = client; + m_regionInfo = region; + m_scene = scene; + + RegisterToEvents(); + if (m_controllingClient != null) + { + m_controllingClient.ProcessPendingPackets(); + } + /* + AbsolutePosition = client.StartPos; + + Animations = new AvatarAnimations(); + Animations.LoadAnims(); + + m_animations = new List(); + m_animations.Add(Animations.AnimsUUID["STAND"]); + m_animationSeqs.Add(m_controllingClient.NextAnimationSequenceNumber); + + SetDirectionVectors(); + */ + } + + internal void PushForce(Vector3 impulse) + { + if (PhysicsActor != null) + { + PhysicsActor.AddForce(impulse,true); + } + } + + public void RegisterControlEventsToScript(int controls, int accept, int pass_on, uint Obj_localID, UUID Script_item_UUID) + { + ScriptControllers obj = new ScriptControllers(); + obj.ignoreControls = ScriptControlled.CONTROL_ZERO; + obj.eventControls = ScriptControlled.CONTROL_ZERO; + + obj.itemID = Script_item_UUID; + if (pass_on == 0 && accept == 0) + { + IgnoredControls |= (ScriptControlled)controls; + obj.ignoreControls = (ScriptControlled)controls; + } + + if (pass_on == 0 && accept == 1) + { + IgnoredControls |= (ScriptControlled)controls; + obj.ignoreControls = (ScriptControlled)controls; + obj.eventControls = (ScriptControlled)controls; + } + if (pass_on == 1 && accept == 1) + { + IgnoredControls = ScriptControlled.CONTROL_ZERO; + obj.eventControls = (ScriptControlled)controls; + obj.ignoreControls = ScriptControlled.CONTROL_ZERO; + } + + lock (scriptedcontrols) + { + if (pass_on == 1 && accept == 0) + { + IgnoredControls &= ~(ScriptControlled)controls; + if (scriptedcontrols.ContainsKey(Script_item_UUID)) + scriptedcontrols.Remove(Script_item_UUID); + } + else + { + scriptedcontrols[Script_item_UUID] = obj; + } + } + ControllingClient.SendTakeControls(controls, pass_on == 1 ? true : false, true); + } + + public void HandleForceReleaseControls(IClientAPI remoteClient, UUID agentID) + { + IgnoredControls = ScriptControlled.CONTROL_ZERO; + lock (scriptedcontrols) + { + scriptedcontrols.Clear(); + } + ControllingClient.SendTakeControls(int.MaxValue, false, false); + } + + public void UnRegisterControlEventsToScript(uint Obj_localID, UUID Script_item_UUID) + { + ScriptControllers takecontrols; + + lock (scriptedcontrols) + { + if (scriptedcontrols.TryGetValue(Script_item_UUID, out takecontrols)) + { + ScriptControlled sctc = takecontrols.eventControls; + + ControllingClient.SendTakeControls((int)sctc, false, false); + ControllingClient.SendTakeControls((int)sctc, true, false); + + scriptedcontrols.Remove(Script_item_UUID); + IgnoredControls = ScriptControlled.CONTROL_ZERO; + foreach (ScriptControllers scData in scriptedcontrols.Values) + { + IgnoredControls |= scData.ignoreControls; + } + } + } + } + + internal void SendControlToScripts(uint flags) + { + ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; + + if (MouseDown) + { + allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) + { + allflags = ScriptControlled.CONTROL_ZERO; + MouseDown = true; + } + } + + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) + { + allflags |= ScriptControlled.CONTROL_ML_LBUTTON; + MouseDown = true; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) + { + allflags |= ScriptControlled.CONTROL_LBUTTON; + MouseDown = true; + } + + // find all activated controls, whether the scripts are interested in them or not + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_FWD; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_BACK; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_UP; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_DOWN; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_LEFT; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_RIGHT; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) + { + allflags |= ScriptControlled.CONTROL_ROT_RIGHT; + } + if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) + { + allflags |= ScriptControlled.CONTROL_ROT_LEFT; + } + // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that + if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) + { + lock (scriptedcontrols) + { + foreach (KeyValuePair kvp in scriptedcontrols) + { + UUID scriptUUID = kvp.Key; + ScriptControllers scriptControlData = kvp.Value; + + ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us + ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle + ScriptControlled localChange = localHeld ^ localLast; // the changed bits + if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) + { + // only send if still pressed or just changed + m_scene.EventManager.TriggerControlEvent(scriptUUID, UUID, (uint)localHeld, (uint)localChange); + } + } + } + } + + LastCommands = allflags; + } + + internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) + { + if (ignored == ScriptControlled.CONTROL_ZERO) + return flags; + + if ((ignored & ScriptControlled.CONTROL_BACK) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG); + if ((ignored & ScriptControlled.CONTROL_FWD) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS | AgentManager.ControlFlags.AGENT_CONTROL_AT_POS); + if ((ignored & ScriptControlled.CONTROL_DOWN) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG); + if ((ignored & ScriptControlled.CONTROL_UP) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS | AgentManager.ControlFlags.AGENT_CONTROL_UP_POS); + if ((ignored & ScriptControlled.CONTROL_LEFT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS | AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS); + if ((ignored & ScriptControlled.CONTROL_RIGHT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG | AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG); + if ((ignored & ScriptControlled.CONTROL_ROT_LEFT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG); + if ((ignored & ScriptControlled.CONTROL_ROT_RIGHT) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS); + if ((ignored & ScriptControlled.CONTROL_ML_LBUTTON) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN); + if ((ignored & ScriptControlled.CONTROL_LBUTTON) != 0) + flags &= ~(AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP | AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN); + + //DIR_CONTROL_FLAG_FORWARD = AgentManager.ControlFlags.AGENT_CONTROL_AT_POS, + //DIR_CONTROL_FLAG_BACK = AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG, + //DIR_CONTROL_FLAG_LEFT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS, + //DIR_CONTROL_FLAG_RIGHT = AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG, + //DIR_CONTROL_FLAG_UP = AgentManager.ControlFlags.AGENT_CONTROL_UP_POS, + //DIR_CONTROL_FLAG_DOWN = AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG, + //DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG + + return flags; + } + + /// + /// RezAttachments. This should only be called upon login on the first region. + /// Attachment rezzings on crossings and TPs are done in a different way. + /// + public void RezAttachments() + { + if (null == m_appearance) + { + m_log.WarnFormat("[ATTACHMENT]: Appearance has not been initialized for agent {0}", UUID); + return; + } + + XmlDocument doc = new XmlDocument(); + string stateData = String.Empty; + + IAttachmentsService attServ = m_scene.RequestModuleInterface(); + if (attServ != null) + { + m_log.DebugFormat("[ATTACHMENT]: Loading attachment data from attachment service"); + stateData = attServ.Get(ControllingClient.AgentId.ToString()); + if (stateData != String.Empty) + { + try + { + doc.LoadXml(stateData); + } + catch { } + } + } + + Dictionary itemData = new Dictionary(); + + XmlNodeList nodes = doc.GetElementsByTagName("Attachment"); + if (nodes.Count > 0) + { + foreach (XmlNode n in nodes) + { + XmlElement elem = (XmlElement)n; + string itemID = elem.GetAttribute("ItemID"); + string xml = elem.InnerXml; + + itemData[new UUID(itemID)] = xml; + } + } + + List attPoints = m_appearance.GetAttachedPoints(); + foreach (int p in attPoints) + { + if (m_isDeleted) + return; + + UUID itemID = m_appearance.GetAttachedItem(p); + UUID assetID = m_appearance.GetAttachedAsset(p); + + // For some reason assetIDs are being written as Zero's in the DB -- need to track tat down + // But they're not used anyway, the item is being looked up for now, so let's proceed. + //if (UUID.Zero == assetID) + //{ + // m_log.DebugFormat("[ATTACHMENT]: Cannot rez attachment in point {0} with itemID {1}", p, itemID); + // continue; + //} + + try + { + string xmlData; + XmlDocument d = new XmlDocument(); + UUID asset; + if (itemData.TryGetValue(itemID, out xmlData)) + { + d.LoadXml(xmlData); + m_log.InfoFormat("[ATTACHMENT]: Found saved state for item {0}, loading it", itemID); + + // Rez from inventory + asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, d); + + } + else + { + // Rez from inventory (with a null doc to let + // CHANGED_OWNER happen) + asset + = m_scene.AttachmentsModule.RezSingleAttachmentFromInventory(ControllingClient, itemID, (uint)p, true, null); + } + + m_log.InfoFormat( + "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", + p, itemID, assetID, asset); + } + catch (Exception e) + { + m_log.ErrorFormat("[ATTACHMENT]: Unable to rez attachment: {0}", e.ToString()); + } + } + } + + private void ReprioritizeUpdates() + { + if (Scene.IsReprioritizationEnabled && Scene.UpdatePrioritizationScheme != UpdatePrioritizationSchemes.Time) + { + lock (m_reprioritization_timer) + { + if (!m_reprioritizing) + m_reprioritization_timer.Enabled = m_reprioritizing = true; + else + m_reprioritization_called = true; + } + } + } + + private void Reprioritize(object sender, ElapsedEventArgs e) + { + m_controllingClient.ReprioritizeUpdates(); + + lock (m_reprioritization_timer) + { + m_reprioritization_timer.Enabled = m_reprioritizing = m_reprioritization_called; + m_reprioritization_called = false; + } + } + + private Vector3 Quat2Euler(Quaternion rot){ + float x = Utils.RAD_TO_DEG * (float)Math.Atan2((double)((2.0f * rot.X * rot.W) - (2.0f * rot.Y * rot.Z)) , + (double)(1 - (2.0f * rot.X * rot.X) - (2.0f * rot.Z * rot.Z))); + float y = Utils.RAD_TO_DEG * (float)Math.Asin ((double)((2.0f * rot.X * rot.Y) + (2.0f * rot.Z * rot.W))); + float z = Utils.RAD_TO_DEG * (float)Math.Atan2(((double)(2.0f * rot.Y * rot.W) - (2.0f * rot.X * rot.Z)) , + (double)(1 - (2.0f * rot.Y * rot.Y) - (2.0f * rot.Z * rot.Z))); + return(new Vector3(x,y,z)); + } + + + } +} -- cgit v1.1 From 24b9a2885f1204d32cd032aa8ea9905fa9ce19b1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 10 Aug 2010 20:11:55 +0100 Subject: Resolve merge issues --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 68 +++++++++++++++------- 1 file changed, 46 insertions(+), 22 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a0f267c..b179646 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1838,6 +1838,26 @@ namespace OpenSim.Region.Framework.Scenes dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; + if (userExposed) + dupe.m_rootPart.TrimPermissions(); + + /// may need to create a new Physics actor. + if (dupe.RootPart.PhysActor != null && userExposed) + { + PrimitiveBaseShape pbs = dupe.RootPart.Shape; + + dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( + dupe.RootPart.Name, + pbs, + dupe.RootPart.AbsolutePosition, + dupe.RootPart.Scale, + dupe.RootPart.RotationOffset, + dupe.RootPart.PhysActor.IsPhysical); + + dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; + dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); + } + lockPartsForRead(true); List partList; @@ -1860,34 +1880,37 @@ namespace OpenSim.Region.Framework.Scenes newPart.LinkNum = part.LinkNum; } - } + // Need to duplicate the physics actor as well + if (part.PhysActor != null && userExposed) + { + PrimitiveBaseShape pbs = part.Shape; + + part.PhysActor + = m_scene.PhysicsScene.AddPrimShape( + part.Name, + pbs, + part.AbsolutePosition, + part.Scale, + part.RotationOffset, + part.PhysActor.IsPhysical); + + part.PhysActor.LocalID = part.LocalId; + part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); + } + + } if (userExposed) { - SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); - newPart.LinkNum = part.LinkNum; + dupe.UpdateParentIDs(); + dupe.HasGroupChanged = true; + dupe.AttachToBackup(); + + ScheduleGroupForFullUpdate(); } - // Need to duplicate the physics actor as well - if (part.PhysActor != null && userExposed) - { - PrimitiveBaseShape pbs = part.Shape; - - part.PhysActor - = m_scene.PhysicsScene.AddPrimShape( - part.Name, - pbs, - part.AbsolutePosition, - part.Scale, - part.RotationOffset, - part.PhysActor.IsPhysical); - - part.PhysActor.LocalID = part.LocalId; - part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); - } } - - if (userExposed) + finally { m_dupeInProgress = false; } @@ -1905,6 +1928,7 @@ namespace OpenSim.Region.Framework.Scenes SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, m_parts.Count, userExposed)); } + public void ScriptSetPhysicsStatus(bool UsePhysics) { bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); -- cgit v1.1 From d0a22fb359b8c911bff5a892d35e67ae9bb777a6 Mon Sep 17 00:00:00 2001 From: sacha Date: Tue, 10 Aug 2010 19:35:17 +0000 Subject: fixed ground texture issues ( it seems ) --- .../Region/CoreModules/World/Estate/EstateManagementModule.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index ee151da..849daea 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -148,6 +148,7 @@ namespace OpenSim.Region.CoreModules.World.Estate public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture) { + m_log.DebugFormat("[ESTATE]: sacha setting terrain texture change {0}, corner {1}",texture,corner); if (texture == UUID.Zero) return; @@ -166,8 +167,11 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.RegionSettings.TerrainTexture4 = texture; break; } + m_log.DebugFormat("[ESTATE]: sacha step 2 {0}",texture); m_scene.RegionInfo.RegionSettings.Save(); + m_log.DebugFormat("[ESTATE]: sacha step 3 {0}",texture); TriggerRegionInfoChange(); + m_log.DebugFormat("[ESTATE]: sacha step 4 {0}",texture); sendRegionInfoPacketToAll(); } @@ -199,6 +203,7 @@ namespace OpenSim.Region.CoreModules.World.Estate private void handleCommitEstateTerrainTextureRequest(IClientAPI remoteClient) { + m_log.Debug("[ESTATE]: sacha Commit terrain texture change"); sendRegionHandshakeToAll(); } @@ -949,7 +954,8 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); - TriggerRegionInfoChange(); + //TriggerRegionInfoChange(); + TriggerEstateInfoChange(); sendRegionInfoPacketToAll(); } @@ -995,7 +1001,8 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); - TriggerRegionInfoChange(); + //TriggerRegionInfoChange(); + TriggerEstateInfoChange(); sendRegionHandshakeToAll(); } } -- cgit v1.1 From 7fead01786a6bc406081d026c5909f8277b77aa5 Mon Sep 17 00:00:00 2001 From: sacha Date: Tue, 10 Aug 2010 19:43:32 +0000 Subject: remoning debug messages --- OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 849daea..c6a1614 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -148,7 +148,6 @@ namespace OpenSim.Region.CoreModules.World.Estate public void setEstateTerrainBaseTexture(IClientAPI remoteClient, int corner, UUID texture) { - m_log.DebugFormat("[ESTATE]: sacha setting terrain texture change {0}, corner {1}",texture,corner); if (texture == UUID.Zero) return; @@ -167,11 +166,8 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegionInfo.RegionSettings.TerrainTexture4 = texture; break; } - m_log.DebugFormat("[ESTATE]: sacha step 2 {0}",texture); m_scene.RegionInfo.RegionSettings.Save(); - m_log.DebugFormat("[ESTATE]: sacha step 3 {0}",texture); TriggerRegionInfoChange(); - m_log.DebugFormat("[ESTATE]: sacha step 4 {0}",texture); sendRegionInfoPacketToAll(); } @@ -203,7 +199,6 @@ namespace OpenSim.Region.CoreModules.World.Estate private void handleCommitEstateTerrainTextureRequest(IClientAPI remoteClient) { - m_log.Debug("[ESTATE]: sacha Commit terrain texture change"); sendRegionHandshakeToAll(); } -- cgit v1.1 From fb14390fb0446e225bca08ec2dc25960d1441728 Mon Sep 17 00:00:00 2001 From: meta7 Date: Tue, 10 Aug 2010 09:17:30 -0700 Subject: Note to self: don't break the build --- OpenSim/Framework/TaskInventoryDictionary.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 6b65fba..a8a53f2 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -99,7 +99,7 @@ namespace OpenSim.Framework // write call stack method names foreach (StackFrame stackFrame in stackFrames) { - m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name); // write method name + m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name } } catch diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ffe2094..20a2abc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -145,7 +145,7 @@ namespace OpenSim.Region.Framework.Scenes // write call stack method names foreach (StackFrame stackFrame in stackFrames) { - m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name); // write method name + m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name } m_partsLock.ExitReadLock(); -- cgit v1.1 From 48c52d6e4868640ac87fc748ac9ac533051a1e62 Mon Sep 17 00:00:00 2001 From: meta7 Date: Tue, 10 Aug 2010 09:50:18 -0700 Subject: Fix a dangling lock issue in llRemoveInventory --- .../Shared/Api/Implementation/LSL_Api.cs | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 71d63bb..1486e2a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4200,21 +4200,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); - m_host.TaskInventory.LockItemsForRead(true); - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + try { - if (item.Name == name) + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) { - if (item.ItemID == m_itemID) - throw new ScriptDeleteException(); - else - m_host.Inventory.RemoveInventoryItem(item.ItemID); - - m_host.TaskInventory.LockItemsForRead(false); - return; + if (item.Name == name) + { + if (item.ItemID == m_itemID) + throw new ScriptDeleteException(); + else + m_host.Inventory.RemoveInventoryItem(item.ItemID); + return; + } } } - m_host.TaskInventory.LockItemsForRead(false); + finally + { + m_host.TaskInventory.LockItemsForRead(false); + } } public void llSetText(string text, LSL_Vector color, double alpha) -- cgit v1.1 From 1582e05ac78ac46708de84f5d35f79c935febd5b Mon Sep 17 00:00:00 2001 From: meta7 Date: Tue, 10 Aug 2010 09:55:40 -0700 Subject: Fix a nullref issue in the AgentSetAppearance packet handler when removing the physactor from the scene --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3154872..4064339 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1090,12 +1090,17 @@ namespace OpenSim.Region.Framework.Scenes { if (PhysicsActor != null) { - m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; - m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; - m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); - m_physicsActor.UnSubscribeEvents(); - m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; - PhysicsActor = null; + try + { + m_physicsActor.OnRequestTerseUpdate -= SendTerseUpdateToAllClients; + m_physicsActor.OnOutOfBounds -= OutOfBoundsCall; + m_physicsActor.OnCollisionUpdate -= PhysicsCollisionUpdate; + m_scene.PhysicsScene.RemoveAvatar(PhysicsActor); + m_physicsActor.UnSubscribeEvents(); + PhysicsActor = null; + } + catch + { } } } -- cgit v1.1 From af60b8ac16361f7b60318a93bf51f094375d0c26 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 10 Aug 2010 22:52:51 +0200 Subject: Set triggering the texture and height update on a two second timer. This fixes the texture rubberbanding. --- .../CoreModules/World/Estate/EstateManagementModule.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index c6a1614..27e492b 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; using System.Security; +using System.Timers; using log4net; using Nini.Config; using OpenMetaverse; @@ -45,6 +46,7 @@ namespace OpenSim.Region.CoreModules.World.Estate private delegate void LookupUUIDS(List uuidLst); private Scene m_scene; + private Timer m_regionChangeTimer = new Timer(); private EstateTerrainXferHandler TerrainUploader; @@ -898,6 +900,9 @@ namespace OpenSim.Region.CoreModules.World.Estate m_scene.RegisterModuleInterface(this); m_scene.EventManager.OnNewClient += EventManager_OnNewClient; m_scene.EventManager.OnRequestChangeWaterHeight += changeWaterHeight; + m_regionChangeTimer.AutoReset = false; + m_regionChangeTimer.Interval = 2000; + m_regionChangeTimer.Elapsed += RaiseRegionInfoChange; m_scene.AddCommand(this, "set terrain texture", "set terrain texture [] []", @@ -949,8 +954,7 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); - //TriggerRegionInfoChange(); - TriggerEstateInfoChange(); + TriggerRegionInfoChange(); sendRegionInfoPacketToAll(); } @@ -996,8 +1000,7 @@ namespace OpenSim.Region.CoreModules.World.Estate break; } m_scene.RegionInfo.RegionSettings.Save(); - //TriggerRegionInfoChange(); - TriggerEstateInfoChange(); + TriggerRegionInfoChange(); sendRegionHandshakeToAll(); } } @@ -1170,6 +1173,12 @@ namespace OpenSim.Region.CoreModules.World.Estate protected void TriggerRegionInfoChange() { + m_regionChangeTimer.Stop(); + m_regionChangeTimer.Start(); + } + + protected void RaiseRegionInfoChange(object sender, ElapsedEventArgs e) + { ChangeDelegate change = OnRegionInfoChange; if (change != null) -- cgit v1.1 From a5a60df6879acfb5efc1f1f4a8c2cb257a4ef89d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 11 Aug 2010 02:52:52 +0200 Subject: Change chat packets to bypass the throttles. This should alleviate chat lag --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 800de8a..48465d9 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -787,7 +787,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP reply.ChatData.OwnerID = fromAgentID; reply.ChatData.SourceID = fromAgentID; - OutPacket(reply, ThrottleOutPacketType.Task); + OutPacket(reply, ThrottleOutPacketType.Unknown); } /// -- cgit v1.1 From d00a954d35c21581dfb7d06122ae329891bc7103 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 11 Aug 2010 03:09:56 +0200 Subject: Log the state of the prejump flag --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7e83634..7a97669 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -728,6 +728,8 @@ namespace OpenSim.Region.Framework.Scenes // TODO: Change default to true once the feature is supported m_usePreJump = startupConfig.GetBoolean("enableprejump", true); m_maxNonphys = startupConfig.GetFloat("NonPhysicalPrimMax", m_maxNonphys); + + m_log.DebugFormat("[SCENE]: prejump is {0}", m_usePreJump ? "ON" : "OFF"); if (RegionInfo.NonphysPrimMax > 0) { m_maxNonphys = RegionInfo.NonphysPrimMax; -- cgit v1.1 From fa393cb13a6008ed82c13d9f2bcec96dd8e21cae Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 11 Aug 2010 13:39:36 -0700 Subject: Fix Omega getting overwritten on startup. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index fbe1da9..dd780b7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1827,7 +1827,7 @@ namespace OpenSim.Region.Framework.Scenes // which stops client-side interpolation of deactivated joint proxy objects. } - if (!UsePhysics) + if (!UsePhysics && !isNew) { // reset velocity to 0 on physics switch-off. Without that, the client thinks the // prim still has velocity and continues to interpolate its position along the old -- cgit v1.1 From 24577876be9affa844f0361058bd9f93e244bdc0 Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 11 Aug 2010 14:10:47 -0700 Subject: Add some console debug to help fix a threadlock issue. --- OpenSim/Region/Framework/Scenes/Scene.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7a97669..7c89e65 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3335,7 +3335,9 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); } + m_log.Debug("[Scene] Beginning ClientClosed"); m_eventManager.TriggerClientClosed(agentID, this); + m_log.Debug("[Scene] Finished ClientClosed"); } catch (NullReferenceException) { @@ -3343,7 +3345,9 @@ namespace OpenSim.Region.Framework.Scenes // Avatar is already disposed :/ } + m_log.Debug("[Scene] Beginning OnRemovePresence"); m_eventManager.TriggerOnRemovePresence(agentID); + m_log.Debug("[Scene] Finished OnRemovePresence"); ForEachClient( delegate(IClientAPI client) { @@ -3359,8 +3363,11 @@ namespace OpenSim.Region.Framework.Scenes } // Remove the avatar from the scene + m_log.Debug("[Scene] Begin RemoveScenePresence"); m_sceneGraph.RemoveScenePresence(agentID); + m_log.Debug("[Scene] Finished RemoveScenePresence. Removing the client manager"); m_clientManager.Remove(agentID); + m_log.Debug("[Scene] Removed the client manager. Firing avatar.close"); try { @@ -3374,9 +3381,9 @@ namespace OpenSim.Region.Framework.Scenes { m_log.Error("[SCENE] Scene.cs:RemoveClient exception: " + e.ToString()); } - + m_log.Debug("[Scene] Done. Firing RemoveCircuit"); m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); - + m_log.Debug("[Scene] The avatar has left the building"); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); } -- cgit v1.1 From 7aac4d650f1e9d8b5ac071872f28b39e83143ccf Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 11 Aug 2010 14:30:09 -0700 Subject: Fix the llRemoveInventory recursive lock error (again) --- .../Shared/Api/Implementation/LSL_Api.cs | 24 ++++++++++++---------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1486e2a..9bece31 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4200,25 +4200,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); + List inv; try { m_host.TaskInventory.LockItemsForRead(true); - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Name == name) - { - if (item.ItemID == m_itemID) - throw new ScriptDeleteException(); - else - m_host.Inventory.RemoveInventoryItem(item.ItemID); - return; - } - } + inv = new List(m_host.TaskInventory.Values); } finally { m_host.TaskInventory.LockItemsForRead(false); } + foreach (TaskInventoryItem item in inv) + { + if (item.Name == name) + { + if (item.ItemID == m_itemID) + throw new ScriptDeleteException(); + else + m_host.Inventory.RemoveInventoryItem(item.ItemID); + return; + } + } } public void llSetText(string text, LSL_Vector color, double alpha) -- cgit v1.1 From b43a731beb24dccf273aefc0e601841ea59b6fd4 Mon Sep 17 00:00:00 2001 From: meta7 Date: Thu, 12 Aug 2010 05:40:41 -0700 Subject: Fix a nullref exception in the prioritizer --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 8cd0160..c6db7af 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -134,6 +134,7 @@ namespace OpenSim.Region.Framework.Scenes private double GetPriorityByFrontBack(IClientAPI client, ISceneEntity entity) { + if (entity == null) return double.NaN; ScenePresence presence = m_scene.GetScenePresence(client.AgentId); if (presence != null) { @@ -144,7 +145,17 @@ namespace OpenSim.Region.Framework.Scenes // Use group position for child prims Vector3 entityPos = entity.AbsolutePosition; if (entity is SceneObjectPart) - entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + { + SceneObjectGroup group = m_scene.GetGroupByPrim(entity.LocalId); + if (group == null) + { + entityPos = entity.AbsolutePosition; + } + else + { + entityPos = group.AbsolutePosition; + } + } else entityPos = entity.AbsolutePosition; -- cgit v1.1 From 042eb80a62c4a4d74e00a59b6aeed679e35d519e Mon Sep 17 00:00:00 2001 From: sacha Date: Sat, 14 Aug 2010 08:59:57 +0000 Subject: clearing some debugmessages --- .../CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs | 2 +- OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs index e1bc243..fb2edb9 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts if (account != null) m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, DateTime.Now + TimeSpan.FromMinutes(2.0d)); - m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); + // m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); } public UserAccount Get(UUID userID, out bool inCache) diff --git a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs index 38c191a..67c482b 100644 --- a/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/UserAccounts/UserAccountServiceConnector.cs @@ -113,7 +113,7 @@ namespace OpenSim.Services.Connectors public virtual UserAccount GetUserAccount(UUID scopeID, UUID userID) { - m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccount {0}", userID); + // m_log.DebugFormat("[ACCOUNTS CONNECTOR]: GetUserAccount {0}", userID); Dictionary sendData = new Dictionary(); //sendData["SCOPEID"] = scopeID.ToString(); sendData["VERSIONMIN"] = ProtocolVersions.ClientProtocolVersionMin.ToString(); -- cgit v1.1 From a32b0ce0ae28ff42d30e25530dc286401188b89c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 14 Aug 2010 13:59:36 +0200 Subject: Fix a possible nullref in BestAvatarResponsiveness policy --- OpenSim/Region/Framework/Scenes/Prioritizer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Prioritizer.cs b/OpenSim/Region/Framework/Scenes/Prioritizer.cs index 8cd0160..7c3746b 100644 --- a/OpenSim/Region/Framework/Scenes/Prioritizer.cs +++ b/OpenSim/Region/Framework/Scenes/Prioritizer.cs @@ -186,9 +186,9 @@ namespace OpenSim.Region.Framework.Scenes return 0.0; // Use group position for child prims - Vector3 entityPos = entity.AbsolutePosition; + Vector3 entityPos; if (entity is SceneObjectPart) - entityPos = m_scene.GetGroupByPrim(entity.LocalId).AbsolutePosition; + entityPos = ((SceneObjectPart)entity).ParentGroup.AbsolutePosition; else entityPos = entity.AbsolutePosition; -- cgit v1.1 From 810840b8624886a615f303baf74f7b72fb1ca66a Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 18 Aug 2010 04:23:56 -0700 Subject: Fix a typecasting issue in llList2Float. This addresses mantis #262 --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e3a69a8..76ade1f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5108,7 +5108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else if (src.Data[index] is LSL_Float) return Convert.ToDouble(((LSL_Float) src.Data[index]).value); else if (src.Data[index] is LSL_String) - return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); + return Convert.ToDouble(Regex.Replace(((LSL_String)src.Data[index]).m_string, "[^0-9]", "")); return Convert.ToDouble(src.Data[index]); } catch (FormatException) -- cgit v1.1 From fb2deb0d452c67c9c0b30c32223ef91b844e5e68 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 18 Aug 2010 20:17:20 +0200 Subject: Prevent a bad cast in llCreateLink(). --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 76ade1f..97dd2e1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3780,6 +3780,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); UUID invItemID = InventorySelf(); + UUID targetID; + + if (!UUID.TryParse(target, out targetID)) + return; TaskInventoryItem item; m_host.TaskInventory.LockItemsForRead(true); @@ -3798,7 +3802,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (sp != null) client = sp.ControllingClient; - SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)target); + SceneObjectPart targetPart = World.GetSceneObjectPart((UUID)targetID); if (targetPart.ParentGroup.RootPart.AttachmentPoint != 0) return; // Fail silently if attached -- cgit v1.1 From 7c673c79d4c52fa14ed803754a18d56bcf54ad87 Mon Sep 17 00:00:00 2001 From: sacha Date: Thu, 19 Aug 2010 08:31:51 +0000 Subject: Adding Group managment to the offline system Sending a group invite is offlined now --- OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index feeb9e6..d3db5b7 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -215,6 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && im.dialog != (byte)InstantMessageDialog.MessageFromAgent && im.dialog != (byte)InstantMessageDialog.GroupNotice && + im.dialog != (byte)InstantMessageDialog.GroupInvitation && im.dialog != (byte)InstantMessageDialog.InventoryOffered) { return; -- cgit v1.1 From 0344395776c22cbef6392129cd11feaf34ad4218 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 19 Aug 2010 12:01:40 +0200 Subject: Skip conversion if fields that are null in the database. This may uncover errors elsewhere. --- OpenSim/Data/MySQL/MySQLGenericTableHandler.cs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs index 6cbb2ee..7c23a47 100644 --- a/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs +++ b/OpenSim/Data/MySQL/MySQLGenericTableHandler.cs @@ -148,6 +148,10 @@ namespace OpenSim.Data.MySQL foreach (string name in m_Fields.Keys) { + if (reader[name] is DBNull) + { + continue; + } if (m_Fields[name].FieldType == typeof(bool)) { int v = Convert.ToInt32(reader[name]); -- cgit v1.1 From 1a8a11140cd5e0dee12f5145986fd090fa829d2b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 19 Aug 2010 12:04:46 +0200 Subject: Revert "Adding Group managment to the offline system" This reverts commit 7c673c79d4c52fa14ed803754a18d56bcf54ad87. That module only handles text IM --- OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index d3db5b7..feeb9e6 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -215,7 +215,6 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && im.dialog != (byte)InstantMessageDialog.MessageFromAgent && im.dialog != (byte)InstantMessageDialog.GroupNotice && - im.dialog != (byte)InstantMessageDialog.GroupInvitation && im.dialog != (byte)InstantMessageDialog.InventoryOffered) { return; -- cgit v1.1 From a1074cad5c6da38a67f79e3498574c5a7e0d3dbb Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 19 Aug 2010 20:41:55 +0200 Subject: Short-circuit the grid server lookup for RequestSimulatorData if the region info is requested for is the local region --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 97dd2e1..22a81ac 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9147,7 +9147,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api string reply = String.Empty; - GridRegion info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); + GridRegion info; + + if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) + info = new GridRegion(m_ScriptEngine.World.RegionInfo); + else + info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); switch (data) { -- cgit v1.1 From 47838e5fb39596effd4d0f7e1021ab68e69cd9d8 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 20 Aug 2010 08:46:46 +0200 Subject: Add some maptile options, change maptile generation from OpenSimBase to Scene to make it more configurable. --- OpenSim/Region/Application/OpenSimBase.cs | 13 ------- OpenSim/Region/Framework/Scenes/Scene.cs | 61 +++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 21 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index c08da18..4ef0b1b 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -390,19 +390,6 @@ namespace OpenSim // Prims have to be loaded after module configuration since some modules may be invoked during the load scene.LoadPrimsFromStorage(regionInfo.originRegionID); - if (scene.SnmpService != null) - { - scene.SnmpService.BootInfo("Creating region texture", scene); - } - - // moved these here as the map texture has to be created after the modules are initialized - // and has to happen before the region is registered with the grid. - IWorldMapModule mapModule = scene.RequestModuleInterface(); - if (mapModule != null) - mapModule.GenerateMaptile(); - else - m_log.WarnFormat("[STARTUP]: No map module available to generate map tile"); - // TODO : Try setting resource for region xstats here on scene MainServer.Instance.AddStreamHandler(new Region.Framework.Scenes.RegionStatsHandler(regionInfo)); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 73472a9..98c46bd 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -411,6 +411,9 @@ namespace OpenSim.Region.Framework.Scenes private double m_rootReprioritizationDistance = 10.0; private double m_childReprioritizationDistance = 20.0; + private Timer m_mapGenerationTimer = new Timer(); + bool m_generateMaptiles = false; + #endregion #region Properties @@ -665,6 +668,29 @@ namespace OpenSim.Region.Framework.Scenes m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); + + m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); + if (m_generateMaptiles) + { + int maptileRefresh = startupConfig.GetInt("MaptileRefresh", 0); + if (maptileRefresh != 0) + { + m_mapGenerationTimer.Interval = maptileRefresh * 1000; + m_mapGenerationTimer.Elapsed += RegenerateMaptile; + m_mapGenerationTimer.AutoReset = true; + m_mapGenerationTimer.Start(); + } + } + else + { + string tile = startupConfig.GetString("MaptileStaticUUID", UUID.Zero.ToString()); + UUID tileID; + + if (UUID.TryParse(tile, out tileID)) + { + RegionInfo.RegionSettings.TerrainImageID = tileID; + } + } } catch { @@ -1694,16 +1720,21 @@ namespace OpenSim.Region.Framework.Scenes m_sceneGridService.SetScene(this); - // These two 'commands' *must be* next to each other or sim rebooting fails. - //m_sceneGridService.RegisterRegion(m_interregionCommsOut, RegionInfo); - - GridRegion region = new GridRegion(RegionInfo); - string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); - if (error != String.Empty) + // If we generate maptiles internally at all, the maptile generator + // will register the region. If not, do it here + if (m_generateMaptiles) { - throw new Exception(error); + RegenerateMaptile(null, null); + } + else + { + GridRegion region = new GridRegion(RegionInfo); + string error = GridService.RegisterRegion(RegionInfo.ScopeID, region); + if (error != String.Empty) + { + throw new Exception(error); + } } - } #endregion @@ -4995,5 +5026,19 @@ namespace OpenSim.Region.Framework.Scenes return offsets.ToArray(); } + + public void RegenerateMaptile(object sender, ElapsedEventArgs e) + { + IWorldMapModule mapModule = RequestModuleInterface(); + if (mapModule != null) + { + mapModule.GenerateMaptile(); + + string error = GridService.RegisterRegion(RegionInfo.ScopeID, new GridRegion(RegionInfo)); + + if (error != String.Empty) + throw new Exception(error); + } + } } } -- cgit v1.1 From cc8864b0e3ae0ee594813eb0a1115eeb5765291e Mon Sep 17 00:00:00 2001 From: meta7 Date: Fri, 20 Aug 2010 11:00:14 -0700 Subject: Get maturity level from access number. This addresses mantis #269 --- OpenSim/Services/Interfaces/IGridService.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index ac234dc..cce8f2c 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -324,6 +324,12 @@ namespace OpenSim.Services.Interfaces if (kvp.ContainsKey("regionName")) RegionName = (string)kvp["regionName"]; + if (kvp.ContainsKey("access")) + { + byte access = Convert.ToByte((string)kvp["access"]); + Maturity = (int)Util.ConvertAccessLevelToMaturity(access); + } + if (kvp.ContainsKey("serverIP")) { //int port = 0; -- cgit v1.1 From b1790ba56ec4ee61a2df6747b1fa42ae0c37da15 Mon Sep 17 00:00:00 2001 From: meta7 Date: Fri, 20 Aug 2010 11:25:31 -0700 Subject: Delete items as well as folders in XInventoryService.PurgeFolder - this should make emptying the trash work properly. --- OpenSim/Services/InventoryService/XInventoryService.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 26c5b33..e3f0a19 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -342,6 +342,17 @@ namespace OpenSim.Services.InventoryService m_Database.DeleteFolders("folderID", x.folderID.ToString()); } + XInventoryItem[] items = m_Database.GetItems( + new string[] { "parentFolderID" }, + new string[] { folder.ID.ToString() }); + + List itemlist = new List(); + foreach (XInventoryItem i in items) + { + itemlist.Add(i.inventoryID); + } + + DeleteItems(folder.Owner, itemlist); return true; } -- cgit v1.1 From 47080834346b2528a65e5b4d5e59130206b0cb83 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 20 Aug 2010 18:53:33 +0200 Subject: Use the database mthod directly to delete items in a single sql swoop --- OpenSim/Services/InventoryService/XInventoryService.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index e3f0a19..3efdce4 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -342,17 +342,7 @@ namespace OpenSim.Services.InventoryService m_Database.DeleteFolders("folderID", x.folderID.ToString()); } - XInventoryItem[] items = m_Database.GetItems( - new string[] { "parentFolderID" }, - new string[] { folder.ID.ToString() }); - - List itemlist = new List(); - foreach (XInventoryItem i in items) - { - itemlist.Add(i.inventoryID); - } - - DeleteItems(folder.Owner, itemlist); + m_Database.DeleteItems("parentFolderID", folder.id.ToString()); return true; } -- cgit v1.1 From c448151f6b8f30bd0361db0b0f8f8075f7192618 Mon Sep 17 00:00:00 2001 From: meta7 Date: Fri, 20 Aug 2010 11:38:59 -0700 Subject: Someone from germany broke the build :P mentioning no names --- OpenSim/Services/InventoryService/XInventoryService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/InventoryService/XInventoryService.cs b/OpenSim/Services/InventoryService/XInventoryService.cs index 3efdce4..f63ab16 100644 --- a/OpenSim/Services/InventoryService/XInventoryService.cs +++ b/OpenSim/Services/InventoryService/XInventoryService.cs @@ -342,7 +342,7 @@ namespace OpenSim.Services.InventoryService m_Database.DeleteFolders("folderID", x.folderID.ToString()); } - m_Database.DeleteItems("parentFolderID", folder.id.ToString()); + m_Database.DeleteItems("parentFolderID", folder.ID.ToString()); return true; } -- cgit v1.1 From f7c4be1fa194323554128b6aee82dfa68448a5ef Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 21 Aug 2010 00:46:16 +0200 Subject: Forward-port a small improvement to the land out connector --- .../ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs index 2386060..252d9e7 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Land/RemoteLandServiceConnector.cs @@ -102,7 +102,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Land public void RegionLoaded(Scene scene) { - m_GridService = scene.GridService; + if (m_Enabled) + m_GridService = scene.GridService; } -- cgit v1.1 From 839b08c32be1dcfee9c89f31a2dd5358e2ab6e88 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 21 Aug 2010 06:30:53 -0700 Subject: Removed the NotImplementedException from llSetSoundQueueing, because the function not working won't actually stop the script from working, firing an exception will. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 22a81ac..37f2433 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5797,7 +5797,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public void llSetSoundQueueing(int queue) { m_host.AddScriptLPS(1); - NotImplemented("llSetSoundQueueing"); } public void llSetSoundRadius(double radius) -- cgit v1.1 From 3ffdadef7014334666d0d42ff8bd9bd83b3c6505 Mon Sep 17 00:00:00 2001 From: meta7 Date: Sat, 21 Aug 2010 07:22:41 -0700 Subject: Add support for attached avatars in llGetLinkKey() --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 37f2433..9615d08 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3985,6 +3985,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } else { + if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1)) + { + linknum -= (m_host.ParentGroup.PrimCount) + 1; + if (linknum > 0) linknum--; //for linksets + + List avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET); + if (avatars.Count > linknum) + { + return avatars[linknum].UUID.ToString(); + } + } return UUID.Zero.ToString(); } } -- cgit v1.1 From 8613336674141c223eee464575f1df239056c338 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sat, 21 Aug 2010 17:48:49 +0200 Subject: Don't allow oversized search reply packets --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 59 +++++++++++++++------- 1 file changed, 42 insertions(+), 17 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index d41df3d..fa72410 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2734,32 +2734,57 @@ namespace OpenSim.Region.ClientStack.LindenUDP packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); - packet.QueryReplies = - new DirPlacesReplyPacket.QueryRepliesBlock[data.Length]; - - packet.StatusData = new DirPlacesReplyPacket.StatusDataBlock[ - data.Length]; - packet.AgentData.AgentID = AgentId; packet.QueryData[0].QueryID = queryID; + DirPlacesReplyPacket.QueryRepliesBlock[] replies = + new DirPlacesReplyPacket.QueryRepliesBlock[0]; + DirPlacesReplyPacket.StatusDataBlock[] status = + new DirPlacesReplyPacket.StatusDataBlock[0]; + int i = 0; foreach (DirPlacesReplyData d in data) { - packet.QueryReplies[i] = - new DirPlacesReplyPacket.QueryRepliesBlock(); - packet.StatusData[i] = new DirPlacesReplyPacket.StatusDataBlock(); - packet.QueryReplies[i].ParcelID = d.parcelID; - packet.QueryReplies[i].Name = Utils.StringToBytes(d.name); - packet.QueryReplies[i].ForSale = d.forSale; - packet.QueryReplies[i].Auction = d.auction; - packet.QueryReplies[i].Dwell = d.dwell; - packet.StatusData[i].Status = d.Status; - i++; + int idx = replies.Length; + Array.Resize(ref replies, idx + 1); + Array.Resize(ref status, idx + 1); + + replies[idx] = new DirPlacesReplyPacket.QueryRepliesBlock(); + status[idx] = new DirPlacesReplyPacket.StatusDataBlock(); + replies[idx].ParcelID = d.parcelID; + replies[idx].Name = Utils.StringToBytes(d.name); + replies[idx].ForSale = d.forSale; + replies[idx].Auction = d.auction; + replies[idx].Dwell = d.dwell; + status[idx].Status = d.Status; + + packet.QueryReplies = replies; + packet.StatusData = status; + + if (packet.Length >= 1000) + { + OutPacket(packet, ThrottleOutPacketType.Task); + + packet = (DirPlacesReplyPacket)PacketPool.Instance.GetPacket(PacketType.DirPlacesReply); + + packet.AgentData = new DirPlacesReplyPacket.AgentDataBlock(); + + packet.QueryData = new DirPlacesReplyPacket.QueryDataBlock[1]; + packet.QueryData[0] = new DirPlacesReplyPacket.QueryDataBlock(); + + packet.AgentData.AgentID = AgentId; + + packet.QueryData[0].QueryID = queryID; + + replies = new DirPlacesReplyPacket.QueryRepliesBlock[0]; + status = new DirPlacesReplyPacket.StatusDataBlock[0]; + + } } - OutPacket(packet, ThrottleOutPacketType.Task); + if (replies.Length > 0) + OutPacket(packet, ThrottleOutPacketType.Task); } public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data) -- cgit v1.1 From a0a25bb8ca846c87b3e8e0de74d4fbcc985ae456 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 22 Aug 2010 13:42:29 +0200 Subject: A stab at making a better bounding box calculation --- .../Shared/Api/Implementation/LSL_Api.cs | 105 +++++++++++++++------ 1 file changed, 74 insertions(+), 31 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9615d08..d856464 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7829,55 +7829,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); UUID objID = UUID.Zero; LSL_List result = new LSL_List(); + + // If the ID is not valid, return null result if (!UUID.TryParse(obj, out objID)) { result.Add(new LSL_Vector()); result.Add(new LSL_Vector()); return result; } + + // Check if this is an attached prim. If so, replace + // the UUID with the avatar UUID and report it's bounding box + SceneObjectPart part = World.GetSceneObjectPart(objID); + if (part != null && part.ParentGroup.IsAttachment) + objID = part.ParentGroup.RootPart.AttachedAvatar; + + // Find out if this is an avatar ID. If so, return it's box ScenePresence presence = World.GetScenePresence(objID); if (presence != null) { - if (presence.ParentID == 0) // not sat on an object + // As per LSL Wiki, there is no difference between sitting + // and standing avatar since server 1.36 + LSL_Vector lower; + LSL_Vector upper; + if (presence.Animator.Animations.DefaultAnimation.AnimID + == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) { - LSL_Vector lower; - LSL_Vector upper; - if (presence.Animator.Animations.DefaultAnimation.AnimID - == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) - { - // This is for ground sitting avatars - float height = presence.Appearance.AvatarHeight / 2.66666667f; - lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); - upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); - } - else - { - // This is for standing/flying avatars - float height = presence.Appearance.AvatarHeight / 2.0f; - lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); - upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); - } - result.Add(lower); - result.Add(upper); - return result; + // This is for ground sitting avatars + float height = presence.Appearance.AvatarHeight / 2.66666667f; + lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); + upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); } else { - // sitting on an object so we need the bounding box of that - // which should include the avatar so set the UUID to the - // UUID of the object the avatar is sat on and allow it to fall through - // to processing an object - SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); - objID = p.UUID; + // This is for standing/flying avatars + float height = presence.Appearance.AvatarHeight / 2.0f; + lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); + upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); } + + // Adjust to the documented error offsets (see LSL Wiki) + lower += new LSL_Vector(0.05f, 0.05f, 0.05f); + upper -= new LSL_Vector(0.05f, 0.05f, 0.05f); + + if (lower.x > upper.x) + lower.x = upper.x; + if (lower.y > upper.y) + lower.y = upper.y; + if (lower.z > upper.z) + lower.z = upper.z; + + result.Add(lower); + result.Add(upper); + return result; } - SceneObjectPart part = World.GetSceneObjectPart(objID); + + part = World.GetSceneObjectPart(objID); // Currently only works for single prims without a sitting avatar if (part != null) { - Vector3 halfSize = part.Scale / 2.0f; - LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); - LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); + float minX; + float maxX; + float minY; + float maxY; + float minZ; + float maxZ; + + // This BBox is in sim coordinates, with the offset being + // a contained point. + Vector3[] offsets = World.GetCombinedBoundingBox(new List { part.ParentGroup }, + out minX, out maxX, out minY, out maxY, out minZ, out maxZ); + + minX -= offsets[0].X; + maxX -= offsets[0].X; + minY -= offsets[0].Y; + maxY -= offsets[0].Y; + minZ -= offsets[0].Z; + maxZ -= offsets[0].Z; + + LSL_Vector lower; + LSL_Vector upper; + + // Adjust to the documented error offsets (see LSL Wiki) + lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f); + upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f); + + if (lower.x > upper.x) + lower.x = upper.x; + if (lower.y > upper.y) + lower.y = upper.y; + if (lower.z > upper.z) + lower.z = upper.z; + result.Add(lower); result.Add(upper); return result; -- cgit v1.1 From 071edaff491c318ba4164b4c4783e425222dc570 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 22 Aug 2010 13:51:15 +0200 Subject: Suppress error messages about scripts not foind if they're in fact disabled --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index abb4de6..a7003c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -422,6 +422,9 @@ namespace OpenSim.Region.Framework.Scenes public void ResumeScripts() { + if (m_scene.RegionInfo.RegionSettings.DisableScripts) + return; + foreach (SceneObjectPart part in m_parts.Values) { part.Inventory.ResumeScripts(); -- cgit v1.1 From 32ddeab5e37b6ba11eaa8322ad6473b52f21d55b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 22 Aug 2010 14:26:58 +0200 Subject: Add printing the default script engine name. Report real exceptions when there is an issue with the config file, as a typo could cause configuration to silently fail. --- OpenSim/Region/Framework/Scenes/Scene.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 32211c4..957c4e8 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -658,6 +658,7 @@ namespace OpenSim.Region.Framework.Scenes m_persistAfter *= 10000000; m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "XEngine"); + m_log.InfoFormat("[SCENE]: Default script engine {0}", m_defaultScriptEngine); IConfig packetConfig = m_config.Configs["PacketPool"]; if (packetConfig != null) @@ -692,9 +693,9 @@ namespace OpenSim.Region.Framework.Scenes } } } - catch + catch (Exception e) { - m_log.Warn("[SCENE]: Failed to load StartupConfig"); + m_log.Error("[SCENE]: Failed to load StartupConfig: " + e.ToString()); } #endregion Region Config -- cgit v1.1 From 98b2d3a7f2f95ee26de76147d0d43468d8c5ad71 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 22 Aug 2010 15:55:23 +0200 Subject: Revert "Fix a typecasting issue in llList2Float. This addresses mantis #262" This reverts commit 810840b8624886a615f303baf74f7b72fb1ca66a. This breaks llList2Float in horrible ways. 12 hours 14 minutes becomes 1214.0 and 023.145 becomes 23145.0 Could just add the dot to fix the latter issue but that would not help the first part. Another solution is needed. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d856464..5caade6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5123,7 +5123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else if (src.Data[index] is LSL_Float) return Convert.ToDouble(((LSL_Float) src.Data[index]).value); else if (src.Data[index] is LSL_String) - return Convert.ToDouble(Regex.Replace(((LSL_String)src.Data[index]).m_string, "[^0-9]", "")); + return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); return Convert.ToDouble(src.Data[index]); } catch (FormatException) -- cgit v1.1 From 0ca771c1850780d0be87b5f16f282b46f9bd4936 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 22 Aug 2010 16:23:36 +0200 Subject: Provide a better implementation of llList2Float --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5caade6..ca09705 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5123,7 +5123,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else if (src.Data[index] is LSL_Float) return Convert.ToDouble(((LSL_Float) src.Data[index]).value); else if (src.Data[index] is LSL_String) - return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); + { + string str = ((LSL_String) src.Data[index]).m_string; + Match m = Regex.Match(str, "^\\s*(-?+?[0-9,]+\\.?[0-9]*)"); + if (m != Match.Empty) + { + str = m.Value; + double d = 0.0; + if (!Double.TryParse(str, out d)) + return 0.0; + + return d; + } + return 0.0; + } return Convert.ToDouble(src.Data[index]); } catch (FormatException) -- cgit v1.1 From 5c368c8d380e623185f74d32505b841f8496e510 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 22 Aug 2010 16:44:22 +0200 Subject: Refix the fix --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ca09705..5717086 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5125,7 +5125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api else if (src.Data[index] is LSL_String) { string str = ((LSL_String) src.Data[index]).m_string; - Match m = Regex.Match(str, "^\\s*(-?+?[0-9,]+\\.?[0-9]*)"); + Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)"); if (m != Match.Empty) { str = m.Value; -- cgit v1.1 From 46412f49313472f1665f864e3b631fcdeeff70da Mon Sep 17 00:00:00 2001 From: meta7 Date: Sun, 22 Aug 2010 09:32:40 -0700 Subject: Fix llGetLinkKey and llGetNumberOfPrims to play nice with avatars in the linkset (emulated) --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9615d08..b4134a4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3988,7 +3988,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1)) { linknum -= (m_host.ParentGroup.PrimCount) + 1; - if (linknum > 0) linknum--; //for linksets List avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET); if (avatars.Count > linknum) @@ -7807,13 +7806,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_Integer llGetNumberOfPrims() { m_host.AddScriptLPS(1); - int avatarCount = 0; - World.ForEachScenePresence(delegate(ScenePresence presence) - { - if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID)) - avatarCount++; - }); - + int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count; + return m_host.ParentGroup.PrimCount + avatarCount; } -- cgit v1.1 From b9e12ed3b7e6f33a824129ce6e79519140a34aa2 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 18:20:24 +0200 Subject: Add a method to delete left over / dropped attachments --- OpenSim/Region/Framework/Scenes/Scene.cs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 957c4e8..d0619d7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5040,5 +5040,37 @@ namespace OpenSim.Region.Framework.Scenes throw new Exception(error); } } + + public void CleanDroppedAttachments() + { + List objectsToDelete = + new List(); + + ForEachSOG(delegate (SceneObjectGroup grp) + { + if (grp.RootPart.Shape.State != 0) + { + UUID agentID = grp.OwnerID; + if (agentID == UUID.Zero) + { + objectsToDelete.Add(grp); + return; + } + + ScenePresence sp = GetScenePresence(agentID); + if (sp == null) + { + objectsToDelete.Add(grp); + return; + } + } + }); + + foreach (SceneObjectGroup grp in objectsToDelete) + { + m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); + DeleteSceneObject(grp, true); + } + } } } -- cgit v1.1 From 5a05de0eec5cba9500fd4803e2bf2ffb54d92265 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 18:38:54 +0200 Subject: Call attachment cleanup when an agent crosses out --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 0ba67d3..ee07f30 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -446,6 +446,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Now let's make it officially a child agent sp.MakeChildAgent(); + sp.Scene.CleanDroppedAttachments(); + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) -- cgit v1.1 From 512a13dbe7a8dfa36a662f64caf573f467173b95 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 18:52:00 +0200 Subject: Call the Cleanup when an agent logs out, when an agent leaves and just before an agent logs in directly. Intentionally not calling this from MakeRoot as that would mess up attachment transfer in teleport --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d0619d7..6452dfe 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3199,6 +3199,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[Scene] Beginning ClientClosed"); m_eventManager.TriggerClientClosed(agentID, this); m_log.Debug("[Scene] Finished ClientClosed"); + CleanDroppedAttachments(); } catch (NullReferenceException) { @@ -3442,6 +3443,8 @@ namespace OpenSim.Region.Framework.Scenes if (vialogin) { + CleanDroppedAttachments(); + if (TestBorderCross(agent.startpos, Cardinals.E)) { Border crossedBorder = GetCrossedBorder(agent.startpos, Cardinals.E); -- cgit v1.1 From 4e324ae3cbf5c4ce16900bd5e57d8671c1de0cfc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 24 Aug 2010 19:07:42 +0200 Subject: Call the cleanup after saving attachment states, so that the attachments don't get killed before they can be saved --- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6452dfe..37d797e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3199,7 +3199,6 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[Scene] Beginning ClientClosed"); m_eventManager.TriggerClientClosed(agentID, this); m_log.Debug("[Scene] Finished ClientClosed"); - CleanDroppedAttachments(); } catch (NullReferenceException) { @@ -3210,6 +3209,9 @@ namespace OpenSim.Region.Framework.Scenes m_log.Debug("[Scene] Beginning OnRemovePresence"); m_eventManager.TriggerOnRemovePresence(agentID); m_log.Debug("[Scene] Finished OnRemovePresence"); + + CleanDroppedAttachments(); + ForEachClient( delegate(IClientAPI client) { -- cgit v1.1 From 314d1171efd6d45686ad54944e9bf53ec8cd0b7f Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 16:06:06 +0200 Subject: Lock the attachment cleanup so it doesn't go into an endless deletion frenzy --- OpenSim/Region/Framework/Scenes/Scene.cs | 36 ++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 37d797e..2324f7a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -399,6 +399,7 @@ namespace OpenSim.Region.Framework.Scenes private bool m_firstHeartbeat = true; private object m_deleting_scene_object = new object(); + private object m_cleaningAttachments = new object(); // the minimum time that must elapse before a changed object will be considered for persisted public long m_dontPersistBefore = DEFAULT_MIN_TIME_FOR_PERSISTENCE * 10000000L; @@ -5051,26 +5052,29 @@ namespace OpenSim.Region.Framework.Scenes List objectsToDelete = new List(); - ForEachSOG(delegate (SceneObjectGroup grp) - { - if (grp.RootPart.Shape.State != 0) + lock (m_cleaningAttachments) + { + ForEachSOG(delegate (SceneObjectGroup grp) { - UUID agentID = grp.OwnerID; - if (agentID == UUID.Zero) + if (grp.RootPart.Shape.State != 0 || objectsToDelete.Contains(grp)) { - objectsToDelete.Add(grp); - return; + UUID agentID = grp.OwnerID; + if (agentID == UUID.Zero) + { + objectsToDelete.Add(grp); + return; + } + + ScenePresence sp = GetScenePresence(agentID); + if (sp == null) + { + objectsToDelete.Add(grp); + return; + } } + }); + } - ScenePresence sp = GetScenePresence(agentID); - if (sp == null) - { - objectsToDelete.Add(grp); - return; - } - } - }); - foreach (SceneObjectGroup grp in objectsToDelete) { m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); -- cgit v1.1 From c13045b25e6424c90642613d400ab6ebf2744064 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 20:11:47 +0200 Subject: Correct a logic error in attachment cleanup --- OpenSim/Region/Framework/Scenes/Scene.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 2324f7a..c7b38a1 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5056,7 +5056,7 @@ namespace OpenSim.Region.Framework.Scenes { ForEachSOG(delegate (SceneObjectGroup grp) { - if (grp.RootPart.Shape.State != 0 || objectsToDelete.Contains(grp)) + if (grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) { UUID agentID = grp.OwnerID; if (agentID == UUID.Zero) @@ -5075,10 +5075,15 @@ namespace OpenSim.Region.Framework.Scenes }); } - foreach (SceneObjectGroup grp in objectsToDelete) + if (objectsToDelete.Count > 0) { - m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); - DeleteSceneObject(grp, true); + m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count); + foreach (SceneObjectGroup grp in objectsToDelete) + { + m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); + DeleteSceneObject(grp, true); + } + m_log.Debug("[SCENE]: Finished dropped attachment deletion"); } } } -- cgit v1.1 From 1bcb2e788fd895a7d8165797c29e6f2a652eff8b Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:04:12 +0200 Subject: Change some e.Message to e.ToString. Don't use e.Message, it doesn't carry any useful information. Error messages are useless without location information. It looks more elegant, but is totally pointless. --- OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index 92a6caa..e9ae3a3 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -81,7 +81,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: {1}", requestUrl, e.Message); + m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); } finally { @@ -112,7 +112,7 @@ namespace OpenSim.Framework.Servers.HttpServer } catch (Exception e) { - m_log.DebugFormat("[FORMS]: exception occured on receiving reply {0}", e.Message); + m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); } finally { -- cgit v1.1 From dc1baf802545329fc78d5fa36174e27025629527 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:11:00 +0200 Subject: Change object cleanup again. Make scene object directories more robust and prevent deleted SOP's from sticking around --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 46 +++++++++++++++++---------- 2 files changed, 30 insertions(+), 19 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index c7b38a1..eb5c3cb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3211,8 +3211,6 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnRemovePresence(agentID); m_log.Debug("[Scene] Finished OnRemovePresence"); - CleanDroppedAttachments(); - ForEachClient( delegate(IClientAPI client) { @@ -3248,6 +3246,7 @@ namespace OpenSim.Region.Framework.Scenes } m_log.Debug("[Scene] Done. Firing RemoveCircuit"); m_authenticateHandler.RemoveCircuit(avatar.ControllingClient.CircuitCode); + CleanDroppedAttachments(); m_log.Debug("[Scene] The avatar has left the building"); //m_log.InfoFormat("[SCENE] Memory pre GC {0}", System.GC.GetTotalMemory(false)); //m_log.InfoFormat("[SCENE] Memory post GC {0}", System.GC.GetTotalMemory(true)); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 94ec534..1268259 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Scenes protected internal Dictionary SceneObjectGroupsByLocalID = new Dictionary(); protected internal Dictionary SceneObjectGroupsByFullID = new Dictionary(); - private readonly Object m_dictionary_lock = new Object(); private Object m_updateLock = new Object(); @@ -150,11 +149,10 @@ namespace OpenSim.Region.Framework.Scenes m_scenePresencesLock.ExitWriteLock(); } - lock (m_dictionary_lock) - { + lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID.Clear(); + lock (SceneObjectGroupsByLocalID) SceneObjectGroupsByLocalID.Clear(); - } Entities.Clear(); } @@ -385,15 +383,17 @@ namespace OpenSim.Region.Framework.Scenes OnObjectCreate(sceneObject); } - lock (m_dictionary_lock) + lock (SceneObjectGroupsByFullID) { SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; - SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; foreach (SceneObjectPart part in sceneObject.Children.Values) - { SceneObjectGroupsByFullID[part.UUID] = sceneObject; + } + lock (SceneObjectGroupsByLocalID) + { + SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; + foreach (SceneObjectPart part in sceneObject.Children.Values) SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; - } } } @@ -408,24 +408,32 @@ namespace OpenSim.Region.Framework.Scenes { if (Entities.ContainsKey(uuid)) { + SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; + if (!resultOfObjectLinked) { m_numPrim -= ((SceneObjectGroup) Entities[uuid]).Children.Count; - if ((((SceneObjectGroup)Entities[uuid]).RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) - { - RemovePhysicalPrim(((SceneObjectGroup)Entities[uuid]).Children.Count); - } + if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) + RemovePhysicalPrim(grp.Children.Count); } if (OnObjectRemove != null) OnObjectRemove(Entities[uuid]); - lock (m_dictionary_lock) + lock (SceneObjectGroupsByFullID) { - SceneObjectGroupsByFullID.Remove(uuid); - SceneObjectGroupsByLocalID.Remove(((SceneObjectGroup)Entities[uuid]).LocalId); + foreach (SceneObjectPart part in grp.Children.Values) + SceneObjectGroupsByFullID.Remove(part.UUID); + SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID); } + lock (SceneObjectGroupsByLocalID) + { + foreach (SceneObjectPart part in grp.Children.Values) + SceneObjectGroupsByLocalID.Remove(part.LocalId); + SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId); + } + Entities.Remove(uuid); //SceneObjectGroup part; //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) @@ -884,7 +892,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SceneObjectGroupsByLocalID.TryGetValue(localID, out sog)) { - return sog; + if (sog.HasChildPrim(localID)) + return sog; + SceneObjectGroupsByLocalID.Remove(localID); } } @@ -920,7 +930,9 @@ namespace OpenSim.Region.Framework.Scenes { if (SceneObjectGroupsByFullID.TryGetValue(fullID, out sog)) { - return sog; + if (sog.Children.ContainsKey(fullID)) + return sog; + SceneObjectGroupsByFullID.Remove(fullID); } } -- cgit v1.1 From 1096f43f0d3db628b463d4494c98ad496cf1f039 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 25 Aug 2010 23:34:39 +0200 Subject: Prevent an object disposed exception that made forms comms unreliable. After starting an asynchronous write, one should not close the channel it will be written to synchrnously, that leads to grief. --- .../Servers/HttpServer/SynchronousRestFormsRequester.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index e9ae3a3..f955df7 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -85,8 +85,13 @@ namespace OpenSim.Framework.Servers.HttpServer } finally { - if (requestStream != null) - requestStream.Close(); + // If this is closed, it will be disposed internally, + // but the above write is asynchronous and may hit after + // we're through here. So the thread handling that will + // throw and put us back into the catch above. Isn't + // .NET great? + //if (requestStream != null) + // requestStream.Close(); // Let's not close this //buffer.Close(); -- cgit v1.1 From 4b47008d30a42bd836ab3efeb399beb672a2446d Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 26 Aug 2010 00:37:54 +0200 Subject: Correct whitespace --- .../Shared/Api/Implementation/LS_Api.cs | 510 --------------------- 1 file changed, 510 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs index 91e2c3b..665b39f 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs @@ -1,512 +1,3 @@ -<<<<<<< HEAD:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Reflection; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.Remoting.Lifetime; -using OpenMetaverse; -using Nini.Config; -using OpenSim; -using OpenSim.Framework; -using OpenSim.Region.CoreModules.World.LightShare; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.ScriptEngine.Shared; -using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; -using OpenSim.Region.ScriptEngine.Shared.ScriptBase; -using OpenSim.Region.ScriptEngine.Interfaces; -using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; - -using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; -using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; -using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; -using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; -using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; -using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; - -namespace OpenSim.Region.ScriptEngine.Shared.Api -{ - [Serializable] - public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi - { - internal IScriptEngine m_ScriptEngine; - internal SceneObjectPart m_host; - internal uint m_localID; - internal UUID m_itemID; - internal bool m_LSFunctionsEnabled = false; - internal IScriptModuleComms m_comms = null; - - public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) - { - m_ScriptEngine = ScriptEngine; - m_host = host; - m_localID = localID; - m_itemID = itemID; - - if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) - m_LSFunctionsEnabled = true; - - if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false)) - m_LSFunctionsEnabled = true; - - m_comms = m_ScriptEngine.World.RequestModuleInterface(); - if (m_comms == null) - m_LSFunctionsEnabled = false; - } - - public override Object InitializeLifetimeService() - { - ILease lease = (ILease)base.InitializeLifetimeService(); - - if (lease.CurrentState == LeaseState.Initial) - { - lease.InitialLeaseTime = TimeSpan.FromMinutes(0); - // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); - // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); - } - return lease; - } - - public Scene World - { - get { return m_ScriptEngine.World; } - } - - // - //Dumps an error message on the debug console. - // - - internal void LSShoutError(string message) - { - if (message.Length > 1023) - message = message.Substring(0, 1023); - - World.SimChat(Utils.StringToBytes(message), - ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); - - IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface(); - wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); - } - - /// - /// Get the current Windlight scene - /// - /// List of windlight parameters - public LSL_List lsGetWindlightScene(LSL_List rules) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return new LSL_List(); - } - m_host.AddScriptLPS(1); - RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_List toadd = new LSL_List(); - - switch (rule) - { - case (int)ScriptBaseClass.WL_AMBIENT: - toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - toadd.Add(new LSL_Float(wl.blurMultiplier)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - toadd.Add(new LSL_Float(wl.cloudCoverage)); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - toadd.Add(new LSL_Float(wl.cloudScale)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - toadd.Add(new LSL_Float(wl.cloudScrollX)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - toadd.Add(new LSL_Float(wl.cloudScrollY)); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - toadd.Add(new LSL_Float(wl.densityMultiplier)); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - toadd.Add(new LSL_Float(wl.distanceMultiplier)); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - toadd.Add(new LSL_Float(wl.eastAngle)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - toadd.Add(new LSL_Float(wl.fresnelOffset)); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - toadd.Add(new LSL_Float(wl.fresnelScale)); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - toadd.Add(new LSL_Float(wl.hazeDensity)); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - toadd.Add(new LSL_Float(wl.hazeHorizon)); - break; - case (int)ScriptBaseClass.WL_HORIZON: - toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - toadd.Add(new LSL_Integer(wl.maxAltitude)); - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - toadd.Add(new LSL_Float(wl.refractScaleAbove)); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - toadd.Add(new LSL_Float(wl.refractScaleBelow)); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - toadd.Add(new LSL_Float(wl.sceneGamma)); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - toadd.Add(new LSL_Float(wl.starBrightness)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - toadd.Add(new LSL_Float(wl.sunGlowFocus)); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - toadd.Add(new LSL_Float(wl.sunGlowSize)); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - toadd.Add(new LSL_Float(wl.underwaterFogModifier)); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); - break; - } - - if (toadd.Length > 0) - { - values.Add(new LSL_Integer(rule)); - values.Add(toadd.Data[0]); - } - idx++; - } - - - return values; - - } - - private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) - { - RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); - - LSL_List values = new LSL_List(); - int idx = 0; - while (idx < rules.Length) - { - uint rule = (uint)rules.GetLSLIntegerItem(idx); - LSL_Types.Quaternion iQ; - LSL_Types.Vector3 iV; - switch (rule) - { - case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: - idx++; - wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_AMBIENT: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_BLUE_DENSITY: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: - idx++; - wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: - idx++; - wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCALE: - idx++; - wl.cloudScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: - idx++; - wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: - idx++; - wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: - idx++; - wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: - idx++; - wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: - idx++; - iV = rules.GetVector3Item(idx); - wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: - idx++; - wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: - idx++; - wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: - idx++; - wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; - break; - case (int)ScriptBaseClass.WL_EAST_ANGLE: - idx++; - wl.eastAngle = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: - idx++; - wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_FRESNEL_SCALE: - idx++; - wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_DENSITY: - idx++; - wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HAZE_HORIZON: - idx++; - wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_HORIZON: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: - idx++; - iV = rules.GetVector3Item(idx); - wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); - break; - case (int)ScriptBaseClass.WL_MAX_ALTITUDE: - idx++; - wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; - break; - case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: - idx++; - wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); - break; - case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: - idx++; - iV = rules.GetVector3Item(idx); - wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: - idx++; - wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: - idx++; - wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SCENE_GAMMA: - idx++; - wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: - idx++; - wl.starBrightness = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: - idx++; - wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: - idx++; - wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: - idx++; - iQ = rules.GetQuaternionItem(idx); - wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); - break; - case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: - idx++; - wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); - break; - case (int)ScriptBaseClass.WL_WATER_COLOR: - idx++; - iV = rules.GetVector3Item(idx); - wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); - break; - case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: - idx++; - wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); - break; - } - idx++; - } - return wl; - } - /// - /// Set the current Windlight scene - /// - /// - /// success: true or false - public int lsSetWindlightScene(LSL_List rules) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - m_host.ParentGroup.Scene.StoreWindlightProfile(wl); - success = 1; - } - else - { - LSShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - /// - /// Set the current Windlight scene to a target avatar - /// - /// - /// success: true or false - public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) - { - if (!m_LSFunctionsEnabled) - { - LSShoutError("LightShare functions are not enabled."); - return 0; - } - if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) - { - LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); - return 0; - } - int success = 0; - m_host.AddScriptLPS(1); - if (LightShareModule.EnableWindlight) - { - RegionLightShareData wl = getWindlightProfileFromRules(rules); - World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); - success = 1; - } - else - { - LSShoutError("Windlight module is disabled"); - return 0; - } - return success; - } - - } -} -======= /* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. @@ -1009,4 +500,3 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } ->>>>>>> master:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs -- cgit v1.1 From 47818a2db303eefaf59f7c98d03112bfb1371379 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 26 Aug 2010 01:06:50 +0200 Subject: Fix a horrible bug in SG, where iteration of scene objects is carried out in a fashion that causes the delegate to be invoked once per child prim for a given group. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9c5ee60..1d952c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1140,9 +1140,11 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal void ForEachSOG(Action action) { - List objlist = new List(SceneObjectGroupsByFullID.Values); - foreach (SceneObjectGroup obj in objlist) + List objlist = Entities.GetAllByType(); + foreach (EntityBase ent in objlist) { + SceneObjectGroup obj = (SceneObjectGroup)ent; + try { action(obj); -- cgit v1.1 From 8ee31d97a84632e4b6144cf81c4fdcd1e764df7c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 30 Aug 2010 02:19:21 +0100 Subject: Remove CRLF endings --- .../Region/CoreModules/World/Land/LandObject.cs | 2090 ++++++++++---------- 1 file changed, 1045 insertions(+), 1045 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index fcd993c..9e9934e 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -1,1045 +1,1045 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Reflection; -using log4net; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -namespace OpenSim.Region.CoreModules.World.Land -{ - /// - /// Keeps track of a specific piece of land's information - /// - public class LandObject : ILandObject - { - #region Member Variables - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - #pragma warning disable 0429 - private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; - #pragma warning restore 0429 - private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; - - private int m_lastSeqId = 0; - - protected LandData m_landData = new LandData(); - protected Scene m_scene; - protected List primsOverMe = new List(); - - public bool[,] LandBitmap - { - get { return m_landBitmap; } - set { m_landBitmap = value; } - } - - #endregion - - #region ILandObject Members - - public LandData LandData - { - get { return m_landData; } - - set { m_landData = value; } - } - - public UUID RegionUUID - { - get { return m_scene.RegionInfo.RegionID; } - } - - #region Constructors - - public LandObject(UUID owner_id, bool is_group_owned, Scene scene) - { - m_scene = scene; - LandData.OwnerID = owner_id; - if (is_group_owned) - LandData.GroupID = owner_id; - else - LandData.GroupID = UUID.Zero; - LandData.IsGroupOwned = is_group_owned; - } - - #endregion - - #region Member Functions - - #region General Functions - - /// - /// Checks to see if this land object contains a point - /// - /// - /// - /// Returns true if the piece of land contains the specified point - public bool ContainsPoint(int x, int y) - { - if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) - { - return (LandBitmap[x / 4, y / 4] == true); - } - else - { - return false; - } - } - - public ILandObject Copy() - { - ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); - - //Place all new variables here! - newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); - newLand.LandData = LandData.Copy(); - - return newLand; - } - - static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; - static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; - - public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) - { - overrideParcelMaxPrimCount = overrideDel; - } - public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) - { - overrideSimulatorMaxPrimCount = overrideDel; - } - - public int GetParcelMaxPrimCount(ILandObject thisObject) - { - if (overrideParcelMaxPrimCount != null) - { - return overrideParcelMaxPrimCount(thisObject); - } - else - { - // Normal Calculations - return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); - } - } - public int GetSimulatorMaxPrimCount(ILandObject thisObject) - { - if (overrideSimulatorMaxPrimCount != null) - { - return overrideSimulatorMaxPrimCount(thisObject); - } - else - { - //Normal Calculations - return m_scene.RegionInfo.ObjectCapacity; - } - } - #endregion - - #region Packet Request Handling - - public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) - { - IEstateModule estateModule = m_scene.RequestModuleInterface(); - uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); - if (estateModule != null) - regionFlags = estateModule.GetRegionFlags(); - - // In a perfect world, this would have worked. - // -// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) -// regionFlags |= (uint)RegionFlags.AllowLandmark; -// if (landData.OwnerID == remote_client.AgentId) -// regionFlags |= (uint)RegionFlags.AllowSetHome; - - int seq_id; - if (snap_selection && (sequence_id == 0)) - { - seq_id = m_lastSeqId; - } - else - { - seq_id = sequence_id; - m_lastSeqId = seq_id; - } - - remote_client.SendLandProperties(seq_id, - snap_selection, request_result, LandData, - (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, - GetParcelMaxPrimCount(this), - GetSimulatorMaxPrimCount(this), regionFlags); - } - - public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) - { - //Needs later group support - bool snap_selection = false; - LandData newData = LandData.Copy(); - - if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) - { - if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) - { - newData.AuthBuyerID = args.AuthBuyerID; - newData.SalePrice = args.SalePrice; - snap_selection = true; - } - } - newData.Category = args.Category; - newData.Description = args.Desc; - newData.GroupID = args.GroupID; - newData.LandingType = args.LandingType; - newData.MediaAutoScale = args.MediaAutoScale; - newData.MediaID = args.MediaID; - newData.MediaURL = args.MediaURL; - newData.MusicURL = args.MusicURL; - newData.Name = args.Name; - newData.Flags = args.ParcelFlags; - newData.PassHours = args.PassHours; - newData.PassPrice = args.PassPrice; - newData.SnapshotID = args.SnapshotID; - newData.UserLocation = args.UserLocation; - newData.UserLookAt = args.UserLookAt; - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(snap_selection); - } - } - - public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) - { - LandData newData = LandData.Copy(); - newData.OwnerID = avatarID; - newData.GroupID = groupID; - newData.IsGroupOwned = groupOwned; - //newData.auctionID = AuctionID; - newData.ClaimDate = Util.UnixTimeSinceEpoch(); - newData.ClaimPrice = claimprice; - newData.SalePrice = 0; - newData.AuthBuyerID = UUID.Zero; - newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(true); - } - - public void DeedToGroup(UUID groupID) - { - LandData newData = LandData.Copy(); - newData.OwnerID = groupID; - newData.GroupID = groupID; - newData.IsGroupOwned = true; - - // Reset show in directory flag on deed - newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - - SendLandUpdateToAvatarsOverMe(true); - } - - public bool IsEitherBannedOrRestricted(UUID avatar) - { - if (IsBannedFromLand(avatar)) - { - return true; - } - else if (IsRestrictedFromLand(avatar)) - { - return true; - } - return false; - } - - public bool HasGroupAccess(UUID avatar) - { - if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) - { - IGroupsModule groupsModule = - m_scene.RequestModuleInterface(); - - List agentGroups = new List(); - if (groupsModule != null) - { - GroupMembershipData[] GroupMembership = - groupsModule.GetMembershipData(avatar); - - if (GroupMembership != null) - { - for (int i = 0; i < GroupMembership.Length; i++) - { - if (LandData.GroupID == GroupMembership[i].GroupID) - { - return true; - } - } - } - } - } - return false; - } - - public bool IsBannedFromLand(UUID avatar) - { - if (m_scene.Permissions.IsAdministrator(avatar)) - return false; - - if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Ban; - entry.Time = new DateTime(); - //See if they are on the list, but make sure the owner isn't banned - if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) - { - //They are banned, so lets send them a notice about this parcel - return true; - } - } - return false; - } - - public bool IsRestrictedFromLand(UUID avatar) - { - if (m_scene.Permissions.IsAdministrator(avatar)) - return false; - - if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) - { - ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); - entry.AgentID = avatar; - entry.Flags = AccessList.Access; - entry.Time = new DateTime(); - - //If they are not on the access list and are not the owner - if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) - { - if (!HasGroupAccess(avatar)) - { - //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel - return true; - } - } - } - - return false; - } - - public void SendLandUpdateToClient(IClientAPI remote_client) - { - SendLandProperties(0, false, 0, remote_client); - } - - public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) - { - SendLandProperties(0, snap_selection, 0, remote_client); - } - - public void SendLandUpdateToAvatarsOverMe() - { - SendLandUpdateToAvatarsOverMe(false); - } - - public void SendLandUpdateToAvatarsOverMe(bool snap_selection) - { - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) - { - if (avatar.IsChildAgent) - return; - - ILandObject over = null; - try - { - over = - m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), - Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); - } - catch (Exception) - { - m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + - Math.Round(avatar.AbsolutePosition.Y)); - } - - if (over != null) - { - if (over.LandData.LocalID == LandData.LocalID) - { - if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && - m_scene.RegionInfo.RegionSettings.AllowDamage) - avatar.Invulnerable = false; - else - avatar.Invulnerable = true; - - SendLandUpdateToClient(snap_selection, avatar.ControllingClient); - } - } - }); - } - - #endregion - - #region AccessList Functions - - public List CreateAccessListArrayByFlag(AccessList flag) - { - List list = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) - { - if (entry.Flags == flag) - { - list.Add(entry.AgentID); - } - } - if (list.Count == 0) - { - list.Add(UUID.Zero); - } - - return list; - } - - public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, - IClientAPI remote_client) - { - - if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) - { - List avatars = CreateAccessListArrayByFlag(AccessList.Access); - remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); - } - - if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) - { - List avatars = CreateAccessListArrayByFlag(AccessList.Ban); - remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); - } - } - - public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) - { - LandData newData = LandData.Copy(); - - if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) - { - entries.Clear(); - } - - List toRemove = new List(); - foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) - { - if (entry.Flags == (AccessList)flags) - { - toRemove.Add(entry); - } - } - - foreach (ParcelManager.ParcelAccessEntry entry in toRemove) - { - newData.ParcelAccessList.Remove(entry); - } - foreach (ParcelManager.ParcelAccessEntry entry in entries) - { - ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); - temp.AgentID = entry.AgentID; - temp.Time = new DateTime(); //Pointless? Yes. - temp.Flags = (AccessList)flags; - - if (!newData.ParcelAccessList.Contains(temp)) - { - newData.ParcelAccessList.Add(temp); - } - } - - m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); - } - - #endregion - - #region Update Functions - - public void UpdateLandBitmapByteArray() - { - LandData.Bitmap = ConvertLandBitmapToBytes(); - } - - /// - /// Update all settings in land such as area, bitmap byte array, etc - /// - public void ForceUpdateLandInfo() - { - UpdateAABBAndAreaValues(); - UpdateLandBitmapByteArray(); - } - - public void SetLandBitmapFromByteArray() - { - LandBitmap = ConvertBytesToLandBitmap(); - } - - /// - /// Updates the AABBMin and AABBMax values after area/shape modification of the land object - /// - private void UpdateAABBAndAreaValues() - { - int min_x = 64; - int min_y = 64; - int max_x = 0; - int max_y = 0; - int tempArea = 0; - int x, y; - for (x = 0; x < 64; x++) - { - for (y = 0; y < 64; y++) - { - if (LandBitmap[x, y] == true) - { - if (min_x > x) min_x = x; - if (min_y > y) min_y = y; - if (max_x < x) max_x = x; - if (max_y < y) max_y = y; - tempArea += 16; //16sqm peice of land - } - } - } - int tx = min_x * 4; - if (tx > ((int)Constants.RegionSize - 1)) - tx = ((int)Constants.RegionSize - 1); - int ty = min_y * 4; - if (ty > ((int)Constants.RegionSize - 1)) - ty = ((int)Constants.RegionSize - 1); - LandData.AABBMin = - new Vector3((float) (min_x * 4), (float) (min_y * 4), - (float) m_scene.Heightmap[tx, ty]); - - tx = max_x * 4; - if (tx > ((int)Constants.RegionSize - 1)) - tx = ((int)Constants.RegionSize - 1); - ty = max_y * 4; - if (ty > ((int)Constants.RegionSize - 1)) - ty = ((int)Constants.RegionSize - 1); - LandData.AABBMax = - new Vector3((float) (max_x * 4), (float) (max_y * 4), - (float) m_scene.Heightmap[tx, ty]); - LandData.Area = tempArea; - } - - #endregion - - #region Land Bitmap Functions - - /// - /// Sets the land's bitmap manually - /// - /// 64x64 block representing where this land is on a map - public void SetLandBitmap(bool[,] bitmap) - { - if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - //throw new Exception("Error: Invalid Parcel Bitmap"); - } - else - { - //Valid: Lets set it - LandBitmap = bitmap; - ForceUpdateLandInfo(); - } - } - - /// - /// Gets the land's bitmap manually - /// - /// - public bool[,] GetLandBitmap() - { - return LandBitmap; - } - - /// - /// Full sim land object creation - /// - /// - public bool[,] BasicFullRegionLandBitmap() - { - return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); - } - - /// - /// Used to modify the bitmap between the x and y points. Points use 64 scale - /// - /// - /// - /// - /// - /// - public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) - { - bool[,] tempBitmap = new bool[64,64]; - tempBitmap.Initialize(); - - tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); - return tempBitmap; - } - - /// - /// Change a land bitmap at within a square and set those points to a specific value - /// - /// - /// - /// - /// - /// - /// - /// - public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, - bool set_value) - { - if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); - } - - int x, y; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - if (x >= start_x / 4 && x < end_x / 4 - && y >= start_y / 4 && y < end_y / 4) - { - land_bitmap[x, y] = set_value; - } - } - } - return land_bitmap; - } - - /// - /// Join the true values of 2 bitmaps together - /// - /// - /// - /// - public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) - { - if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); - } - if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) - { - //Throw an exception - The bitmap is not 64x64 - throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); - } - - int x, y; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - if (bitmap_add[x, y]) - { - bitmap_base[x, y] = true; - } - } - } - return bitmap_base; - } - - /// - /// Converts the land bitmap to a packet friendly byte array - /// - /// - private byte[] ConvertLandBitmapToBytes() - { - byte[] tempConvertArr = new byte[512]; - byte tempByte = 0; - int x, y, i, byteNum = 0; - i = 0; - for (y = 0; y < 64; y++) - { - for (x = 0; x < 64; x++) - { - tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); - if (i % 8 == 0) - { - tempConvertArr[byteNum] = tempByte; - tempByte = (byte) 0; - i = 0; - byteNum++; - } - } - } - return tempConvertArr; - } - - private bool[,] ConvertBytesToLandBitmap() - { - bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; - tempConvertMap.Initialize(); - byte tempByte = 0; - int x = 0, y = 0, i = 0, bitNum = 0; - for (i = 0; i < 512; i++) - { - tempByte = LandData.Bitmap[i]; - for (bitNum = 0; bitNum < 8; bitNum++) - { - bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); - tempConvertMap[x, y] = bit; - x++; - if (x > 63) - { - x = 0; - y++; - } - } - } - return tempConvertMap; - } - - #endregion - - #region Object Select and Object Owner Listing - - public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) - { - List resultLocalIDs = new List(); - try - { - lock (primsOverMe) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.LocalId > 0) - { - if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && - obj.OwnerID != remote_client.AgentId) - { - resultLocalIDs.Add(obj.LocalId); - } - else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) - { - resultLocalIDs.Add(obj.LocalId); - } - } - } - } - } catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); - } - - remote_client.SendForceClientSelectObjects(resultLocalIDs); - } - } - - /// - /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes - /// aggreagete details such as the number of prims. - /// - /// - /// - /// A - /// - public void SendLandObjectOwners(IClientAPI remote_client) - { - if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) - { - Dictionary primCount = new Dictionary(); - List groups = new List(); - - lock (primsOverMe) - { - try - { - - foreach (SceneObjectGroup obj in primsOverMe) - { - try - { - if (!primCount.ContainsKey(obj.OwnerID)) - { - primCount.Add(obj.OwnerID, 0); - } - } - catch (NullReferenceException) - { - m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); - } - try - { - primCount[obj.OwnerID] += obj.PrimCount; - } - catch (KeyNotFoundException) - { - m_log.Error("[LAND]: Unable to match a prim with it's owner."); - } - if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) - groups.Add(obj.OwnerID); - } - } - catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to Enumerate Land object arr."); - } - } - - remote_client.SendLandObjectOwners(LandData, groups, primCount); - } - } - - public Dictionary GetLandObjectOwners() - { - Dictionary ownersAndCount = new Dictionary(); - lock (primsOverMe) - { - try - { - - foreach (SceneObjectGroup obj in primsOverMe) - { - if (!ownersAndCount.ContainsKey(obj.OwnerID)) - { - ownersAndCount.Add(obj.OwnerID, 0); - } - ownersAndCount[obj.OwnerID] += obj.PrimCount; - } - } - catch (InvalidOperationException) - { - m_log.Error("[LAND]: Unable to enumerate land owners. arr."); - } - - } - return ownersAndCount; - } - - #endregion - - #region Object Returning - - public void ReturnObject(SceneObjectGroup obj) - { - SceneObjectGroup[] objs = new SceneObjectGroup[1]; - objs[0] = obj; - m_scene.returnObjects(objs, obj.OwnerID); - } - - public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) - { - Dictionary> returns = - new Dictionary>(); - - lock (primsOverMe) - { - if (type == (uint)ObjectReturnType.Owner) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.OwnerID == m_landData.OwnerID) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.GroupID == m_landData.GroupID) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.Other) - { - foreach (SceneObjectGroup obj in primsOverMe) - { - if (obj.OwnerID != m_landData.OwnerID && - (obj.GroupID != m_landData.GroupID || - m_landData.GroupID == UUID.Zero)) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - else if (type == (uint)ObjectReturnType.List) - { - List ownerlist = new List(owners); - - foreach (SceneObjectGroup obj in primsOverMe) - { - if (ownerlist.Contains(obj.OwnerID)) - { - if (!returns.ContainsKey(obj.OwnerID)) - returns[obj.OwnerID] = - new List(); - returns[obj.OwnerID].Add(obj); - } - } - } - } - - foreach (List ol in returns.Values) - { - if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) - m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); - } - } - - #endregion - - #region Object Adding/Removing from Parcel - - public void ResetLandPrimCounts() - { - LandData.GroupPrims = 0; - LandData.OwnerPrims = 0; - LandData.OtherPrims = 0; - LandData.SelectedPrims = 0; - - - lock (primsOverMe) - primsOverMe.Clear(); - } - - public void AddPrimToCount(SceneObjectGroup obj) - { - - UUID prim_owner = obj.OwnerID; - int prim_count = obj.PrimCount; - - if (obj.IsSelected) - { - LandData.SelectedPrims += prim_count; - } - else - { - if (prim_owner == LandData.OwnerID) - { - LandData.OwnerPrims += prim_count; - } - else if ((obj.GroupID == LandData.GroupID || - prim_owner == LandData.GroupID) && - LandData.GroupID != UUID.Zero) - { - LandData.GroupPrims += prim_count; - } - else - { - LandData.OtherPrims += prim_count; - } - } - - lock (primsOverMe) - primsOverMe.Add(obj); - } - - public void RemovePrimFromCount(SceneObjectGroup obj) - { - lock (primsOverMe) - { - if (primsOverMe.Contains(obj)) - { - UUID prim_owner = obj.OwnerID; - int prim_count = obj.PrimCount; - - if (prim_owner == LandData.OwnerID) - { - LandData.OwnerPrims -= prim_count; - } - else if (obj.GroupID == LandData.GroupID || - prim_owner == LandData.GroupID) - { - LandData.GroupPrims -= prim_count; - } - else - { - LandData.OtherPrims -= prim_count; - } - - primsOverMe.Remove(obj); - } - } - } - - #endregion - - #endregion - - #endregion - - /// - /// Set the media url for this land parcel - /// - /// - public void SetMediaUrl(string url) - { - LandData.MediaURL = url; - SendLandUpdateToAvatarsOverMe(); - } - - /// - /// Set the music url for this land parcel - /// - /// - public void SetMusicUrl(string url) - { - LandData.MusicURL = url; - SendLandUpdateToAvatarsOverMe(); - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Reflection; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.World.Land +{ + /// + /// Keeps track of a specific piece of land's information + /// + public class LandObject : ILandObject + { + #region Member Variables + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + #pragma warning disable 0429 + private const int landArrayMax = ((int)((int)Constants.RegionSize / 4) >= 64) ? (int)((int)Constants.RegionSize / 4) : 64; + #pragma warning restore 0429 + private bool[,] m_landBitmap = new bool[landArrayMax,landArrayMax]; + + private int m_lastSeqId = 0; + + protected LandData m_landData = new LandData(); + protected Scene m_scene; + protected List primsOverMe = new List(); + + public bool[,] LandBitmap + { + get { return m_landBitmap; } + set { m_landBitmap = value; } + } + + #endregion + + #region ILandObject Members + + public LandData LandData + { + get { return m_landData; } + + set { m_landData = value; } + } + + public UUID RegionUUID + { + get { return m_scene.RegionInfo.RegionID; } + } + + #region Constructors + + public LandObject(UUID owner_id, bool is_group_owned, Scene scene) + { + m_scene = scene; + LandData.OwnerID = owner_id; + if (is_group_owned) + LandData.GroupID = owner_id; + else + LandData.GroupID = UUID.Zero; + LandData.IsGroupOwned = is_group_owned; + } + + #endregion + + #region Member Functions + + #region General Functions + + /// + /// Checks to see if this land object contains a point + /// + /// + /// + /// Returns true if the piece of land contains the specified point + public bool ContainsPoint(int x, int y) + { + if (x >= 0 && y >= 0 && x <= Constants.RegionSize && y <= Constants.RegionSize) + { + return (LandBitmap[x / 4, y / 4] == true); + } + else + { + return false; + } + } + + public ILandObject Copy() + { + ILandObject newLand = new LandObject(LandData.OwnerID, LandData.IsGroupOwned, m_scene); + + //Place all new variables here! + newLand.LandBitmap = (bool[,]) (LandBitmap.Clone()); + newLand.LandData = LandData.Copy(); + + return newLand; + } + + static overrideParcelMaxPrimCountDelegate overrideParcelMaxPrimCount; + static overrideSimulatorMaxPrimCountDelegate overrideSimulatorMaxPrimCount; + + public void SetParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) + { + overrideParcelMaxPrimCount = overrideDel; + } + public void SetSimulatorObjectMaxOverride(overrideSimulatorMaxPrimCountDelegate overrideDel) + { + overrideSimulatorMaxPrimCount = overrideDel; + } + + public int GetParcelMaxPrimCount(ILandObject thisObject) + { + if (overrideParcelMaxPrimCount != null) + { + return overrideParcelMaxPrimCount(thisObject); + } + else + { + // Normal Calculations + return (int)Math.Round(((float)LandData.Area / 65536.0f) * (float)m_scene.RegionInfo.ObjectCapacity * (float)m_scene.RegionInfo.RegionSettings.ObjectBonus); + } + } + public int GetSimulatorMaxPrimCount(ILandObject thisObject) + { + if (overrideSimulatorMaxPrimCount != null) + { + return overrideSimulatorMaxPrimCount(thisObject); + } + else + { + //Normal Calculations + return m_scene.RegionInfo.ObjectCapacity; + } + } + #endregion + + #region Packet Request Handling + + public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, IClientAPI remote_client) + { + IEstateModule estateModule = m_scene.RequestModuleInterface(); + uint regionFlags = 336723974 & ~((uint)(RegionFlags.AllowLandmark | RegionFlags.AllowSetHome)); + if (estateModule != null) + regionFlags = estateModule.GetRegionFlags(); + + // In a perfect world, this would have worked. + // +// if ((landData.Flags & (uint)ParcelFlags.AllowLandmark) != 0) +// regionFlags |= (uint)RegionFlags.AllowLandmark; +// if (landData.OwnerID == remote_client.AgentId) +// regionFlags |= (uint)RegionFlags.AllowSetHome; + + int seq_id; + if (snap_selection && (sequence_id == 0)) + { + seq_id = m_lastSeqId; + } + else + { + seq_id = sequence_id; + m_lastSeqId = seq_id; + } + + remote_client.SendLandProperties(seq_id, + snap_selection, request_result, LandData, + (float)m_scene.RegionInfo.RegionSettings.ObjectBonus, + GetParcelMaxPrimCount(this), + GetSimulatorMaxPrimCount(this), regionFlags); + } + + public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId,this)) + { + //Needs later group support + bool snap_selection = false; + LandData newData = LandData.Copy(); + + if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) + { + if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this)) + { + newData.AuthBuyerID = args.AuthBuyerID; + newData.SalePrice = args.SalePrice; + snap_selection = true; + } + } + newData.Category = args.Category; + newData.Description = args.Desc; + newData.GroupID = args.GroupID; + newData.LandingType = args.LandingType; + newData.MediaAutoScale = args.MediaAutoScale; + newData.MediaID = args.MediaID; + newData.MediaURL = args.MediaURL; + newData.MusicURL = args.MusicURL; + newData.Name = args.Name; + newData.Flags = args.ParcelFlags; + newData.PassHours = args.PassHours; + newData.PassPrice = args.PassPrice; + newData.SnapshotID = args.SnapshotID; + newData.UserLocation = args.UserLocation; + newData.UserLookAt = args.UserLookAt; + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(snap_selection); + } + } + + public void UpdateLandSold(UUID avatarID, UUID groupID, bool groupOwned, uint AuctionID, int claimprice, int area) + { + LandData newData = LandData.Copy(); + newData.OwnerID = avatarID; + newData.GroupID = groupID; + newData.IsGroupOwned = groupOwned; + //newData.auctionID = AuctionID; + newData.ClaimDate = Util.UnixTimeSinceEpoch(); + newData.ClaimPrice = claimprice; + newData.SalePrice = 0; + newData.AuthBuyerID = UUID.Zero; + newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(true); + } + + public void DeedToGroup(UUID groupID) + { + LandData newData = LandData.Copy(); + newData.OwnerID = groupID; + newData.GroupID = groupID; + newData.IsGroupOwned = true; + + // Reset show in directory flag on deed + newData.Flags &= ~(uint) (ParcelFlags.ForSale | ParcelFlags.ForSaleObjects | ParcelFlags.SellParcelObjects | ParcelFlags.ShowDirectory); + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + + SendLandUpdateToAvatarsOverMe(true); + } + + public bool IsEitherBannedOrRestricted(UUID avatar) + { + if (IsBannedFromLand(avatar)) + { + return true; + } + else if (IsRestrictedFromLand(avatar)) + { + return true; + } + return false; + } + + public bool HasGroupAccess(UUID avatar) + { + if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) + { + IGroupsModule groupsModule = + m_scene.RequestModuleInterface(); + + List agentGroups = new List(); + if (groupsModule != null) + { + GroupMembershipData[] GroupMembership = + groupsModule.GetMembershipData(avatar); + + if (GroupMembership != null) + { + for (int i = 0; i < GroupMembership.Length; i++) + { + if (LandData.GroupID == GroupMembership[i].GroupID) + { + return true; + } + } + } + } + } + return false; + } + + public bool IsBannedFromLand(UUID avatar) + { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + + if ((LandData.Flags & (uint) ParcelFlags.UseBanList) > 0) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = avatar; + entry.Flags = AccessList.Ban; + entry.Time = new DateTime(); + //See if they are on the list, but make sure the owner isn't banned + if (LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + { + //They are banned, so lets send them a notice about this parcel + return true; + } + } + return false; + } + + public bool IsRestrictedFromLand(UUID avatar) + { + if (m_scene.Permissions.IsAdministrator(avatar)) + return false; + + if ((LandData.Flags & (uint) ParcelFlags.UseAccessList) > 0) + { + ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry(); + entry.AgentID = avatar; + entry.Flags = AccessList.Access; + entry.Time = new DateTime(); + + //If they are not on the access list and are not the owner + if (!LandData.ParcelAccessList.Contains(entry) && LandData.OwnerID != avatar) + { + if (!HasGroupAccess(avatar)) + { + //They are not allowed in this parcel, but not banned, so lets send them a notice about this parcel + return true; + } + } + } + + return false; + } + + public void SendLandUpdateToClient(IClientAPI remote_client) + { + SendLandProperties(0, false, 0, remote_client); + } + + public void SendLandUpdateToClient(bool snap_selection, IClientAPI remote_client) + { + SendLandProperties(0, snap_selection, 0, remote_client); + } + + public void SendLandUpdateToAvatarsOverMe() + { + SendLandUpdateToAvatarsOverMe(false); + } + + public void SendLandUpdateToAvatarsOverMe(bool snap_selection) + { + m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + { + if (avatar.IsChildAgent) + return; + + ILandObject over = null; + try + { + over = + m_scene.LandChannel.GetLandObject(Util.Clamp((int)Math.Round(avatar.AbsolutePosition.X), 0, ((int)Constants.RegionSize - 1)), + Util.Clamp((int)Math.Round(avatar.AbsolutePosition.Y), 0, ((int)Constants.RegionSize - 1))); + } + catch (Exception) + { + m_log.Warn("[LAND]: " + "unable to get land at x: " + Math.Round(avatar.AbsolutePosition.X) + " y: " + + Math.Round(avatar.AbsolutePosition.Y)); + } + + if (over != null) + { + if (over.LandData.LocalID == LandData.LocalID) + { + if (((over.LandData.Flags & (uint)ParcelFlags.AllowDamage) != 0) && + m_scene.RegionInfo.RegionSettings.AllowDamage) + avatar.Invulnerable = false; + else + avatar.Invulnerable = true; + + SendLandUpdateToClient(snap_selection, avatar.ControllingClient); + } + } + }); + } + + #endregion + + #region AccessList Functions + + public List CreateAccessListArrayByFlag(AccessList flag) + { + List list = new List(); + foreach (ParcelManager.ParcelAccessEntry entry in LandData.ParcelAccessList) + { + if (entry.Flags == flag) + { + list.Add(entry.AgentID); + } + } + if (list.Count == 0) + { + list.Add(UUID.Zero); + } + + return list; + } + + public void SendAccessList(UUID agentID, UUID sessionID, uint flags, int sequenceID, + IClientAPI remote_client) + { + + if (flags == (uint) AccessList.Access || flags == (uint) AccessList.Both) + { + List avatars = CreateAccessListArrayByFlag(AccessList.Access); + remote_client.SendLandAccessListData(avatars,(uint) AccessList.Access,LandData.LocalID); + } + + if (flags == (uint) AccessList.Ban || flags == (uint) AccessList.Both) + { + List avatars = CreateAccessListArrayByFlag(AccessList.Ban); + remote_client.SendLandAccessListData(avatars, (uint)AccessList.Ban, LandData.LocalID); + } + } + + public void UpdateAccessList(uint flags, List entries, IClientAPI remote_client) + { + LandData newData = LandData.Copy(); + + if (entries.Count == 1 && entries[0].AgentID == UUID.Zero) + { + entries.Clear(); + } + + List toRemove = new List(); + foreach (ParcelManager.ParcelAccessEntry entry in newData.ParcelAccessList) + { + if (entry.Flags == (AccessList)flags) + { + toRemove.Add(entry); + } + } + + foreach (ParcelManager.ParcelAccessEntry entry in toRemove) + { + newData.ParcelAccessList.Remove(entry); + } + foreach (ParcelManager.ParcelAccessEntry entry in entries) + { + ParcelManager.ParcelAccessEntry temp = new ParcelManager.ParcelAccessEntry(); + temp.AgentID = entry.AgentID; + temp.Time = new DateTime(); //Pointless? Yes. + temp.Flags = (AccessList)flags; + + if (!newData.ParcelAccessList.Contains(temp)) + { + newData.ParcelAccessList.Add(temp); + } + } + + m_scene.LandChannel.UpdateLandObject(LandData.LocalID, newData); + } + + #endregion + + #region Update Functions + + public void UpdateLandBitmapByteArray() + { + LandData.Bitmap = ConvertLandBitmapToBytes(); + } + + /// + /// Update all settings in land such as area, bitmap byte array, etc + /// + public void ForceUpdateLandInfo() + { + UpdateAABBAndAreaValues(); + UpdateLandBitmapByteArray(); + } + + public void SetLandBitmapFromByteArray() + { + LandBitmap = ConvertBytesToLandBitmap(); + } + + /// + /// Updates the AABBMin and AABBMax values after area/shape modification of the land object + /// + private void UpdateAABBAndAreaValues() + { + int min_x = 64; + int min_y = 64; + int max_x = 0; + int max_y = 0; + int tempArea = 0; + int x, y; + for (x = 0; x < 64; x++) + { + for (y = 0; y < 64; y++) + { + if (LandBitmap[x, y] == true) + { + if (min_x > x) min_x = x; + if (min_y > y) min_y = y; + if (max_x < x) max_x = x; + if (max_y < y) max_y = y; + tempArea += 16; //16sqm peice of land + } + } + } + int tx = min_x * 4; + if (tx > ((int)Constants.RegionSize - 1)) + tx = ((int)Constants.RegionSize - 1); + int ty = min_y * 4; + if (ty > ((int)Constants.RegionSize - 1)) + ty = ((int)Constants.RegionSize - 1); + LandData.AABBMin = + new Vector3((float) (min_x * 4), (float) (min_y * 4), + (float) m_scene.Heightmap[tx, ty]); + + tx = max_x * 4; + if (tx > ((int)Constants.RegionSize - 1)) + tx = ((int)Constants.RegionSize - 1); + ty = max_y * 4; + if (ty > ((int)Constants.RegionSize - 1)) + ty = ((int)Constants.RegionSize - 1); + LandData.AABBMax = + new Vector3((float) (max_x * 4), (float) (max_y * 4), + (float) m_scene.Heightmap[tx, ty]); + LandData.Area = tempArea; + } + + #endregion + + #region Land Bitmap Functions + + /// + /// Sets the land's bitmap manually + /// + /// 64x64 block representing where this land is on a map + public void SetLandBitmap(bool[,] bitmap) + { + if (bitmap.GetLength(0) != 64 || bitmap.GetLength(1) != 64 || bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + //throw new Exception("Error: Invalid Parcel Bitmap"); + } + else + { + //Valid: Lets set it + LandBitmap = bitmap; + ForceUpdateLandInfo(); + } + } + + /// + /// Gets the land's bitmap manually + /// + /// + public bool[,] GetLandBitmap() + { + return LandBitmap; + } + + /// + /// Full sim land object creation + /// + /// + public bool[,] BasicFullRegionLandBitmap() + { + return GetSquareLandBitmap(0, 0, (int) Constants.RegionSize, (int) Constants.RegionSize); + } + + /// + /// Used to modify the bitmap between the x and y points. Points use 64 scale + /// + /// + /// + /// + /// + /// + public bool[,] GetSquareLandBitmap(int start_x, int start_y, int end_x, int end_y) + { + bool[,] tempBitmap = new bool[64,64]; + tempBitmap.Initialize(); + + tempBitmap = ModifyLandBitmapSquare(tempBitmap, start_x, start_y, end_x, end_y, true); + return tempBitmap; + } + + /// + /// Change a land bitmap at within a square and set those points to a specific value + /// + /// + /// + /// + /// + /// + /// + /// + public bool[,] ModifyLandBitmapSquare(bool[,] land_bitmap, int start_x, int start_y, int end_x, int end_y, + bool set_value) + { + if (land_bitmap.GetLength(0) != 64 || land_bitmap.GetLength(1) != 64 || land_bitmap.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + //throw new Exception("Error: Invalid Parcel Bitmap in modifyLandBitmapSquare()"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (x >= start_x / 4 && x < end_x / 4 + && y >= start_y / 4 && y < end_y / 4) + { + land_bitmap[x, y] = set_value; + } + } + } + return land_bitmap; + } + + /// + /// Join the true values of 2 bitmaps together + /// + /// + /// + /// + public bool[,] MergeLandBitmaps(bool[,] bitmap_base, bool[,] bitmap_add) + { + if (bitmap_base.GetLength(0) != 64 || bitmap_base.GetLength(1) != 64 || bitmap_base.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_base in mergeLandBitmaps"); + } + if (bitmap_add.GetLength(0) != 64 || bitmap_add.GetLength(1) != 64 || bitmap_add.Rank != 2) + { + //Throw an exception - The bitmap is not 64x64 + throw new Exception("Error: Invalid Parcel Bitmap - Bitmap_add in mergeLandBitmaps"); + } + + int x, y; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + if (bitmap_add[x, y]) + { + bitmap_base[x, y] = true; + } + } + } + return bitmap_base; + } + + /// + /// Converts the land bitmap to a packet friendly byte array + /// + /// + private byte[] ConvertLandBitmapToBytes() + { + byte[] tempConvertArr = new byte[512]; + byte tempByte = 0; + int x, y, i, byteNum = 0; + i = 0; + for (y = 0; y < 64; y++) + { + for (x = 0; x < 64; x++) + { + tempByte = Convert.ToByte(tempByte | Convert.ToByte(LandBitmap[x, y]) << (i++ % 8)); + if (i % 8 == 0) + { + tempConvertArr[byteNum] = tempByte; + tempByte = (byte) 0; + i = 0; + byteNum++; + } + } + } + return tempConvertArr; + } + + private bool[,] ConvertBytesToLandBitmap() + { + bool[,] tempConvertMap = new bool[landArrayMax, landArrayMax]; + tempConvertMap.Initialize(); + byte tempByte = 0; + int x = 0, y = 0, i = 0, bitNum = 0; + for (i = 0; i < 512; i++) + { + tempByte = LandData.Bitmap[i]; + for (bitNum = 0; bitNum < 8; bitNum++) + { + bool bit = Convert.ToBoolean(Convert.ToByte(tempByte >> bitNum) & (byte) 1); + tempConvertMap[x, y] = bit; + x++; + if (x > 63) + { + x = 0; + y++; + } + } + } + return tempConvertMap; + } + + #endregion + + #region Object Select and Object Owner Listing + + public void SendForceObjectSelect(int local_id, int request_type, List returnIDs, IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + { + List resultLocalIDs = new List(); + try + { + lock (primsOverMe) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.LocalId > 0) + { + if (request_type == LandChannel.LAND_SELECT_OBJECTS_OWNER && obj.OwnerID == LandData.OwnerID) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandChannel.LAND_SELECT_OBJECTS_GROUP && obj.GroupID == LandData.GroupID && LandData.GroupID != UUID.Zero) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == LandChannel.LAND_SELECT_OBJECTS_OTHER && + obj.OwnerID != remote_client.AgentId) + { + resultLocalIDs.Add(obj.LocalId); + } + else if (request_type == (int)ObjectReturnType.List && returnIDs.Contains(obj.OwnerID)) + { + resultLocalIDs.Add(obj.LocalId); + } + } + } + } + } catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to force select the parcel objects. Arr."); + } + + remote_client.SendForceClientSelectObjects(resultLocalIDs); + } + } + + /// + /// Notify the parcel owner each avatar that owns prims situated on their land. This notification includes + /// aggreagete details such as the number of prims. + /// + /// + /// + /// A + /// + public void SendLandObjectOwners(IClientAPI remote_client) + { + if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this)) + { + Dictionary primCount = new Dictionary(); + List groups = new List(); + + lock (primsOverMe) + { + try + { + + foreach (SceneObjectGroup obj in primsOverMe) + { + try + { + if (!primCount.ContainsKey(obj.OwnerID)) + { + primCount.Add(obj.OwnerID, 0); + } + } + catch (NullReferenceException) + { + m_log.Info("[LAND]: " + "Got Null Reference when searching land owners from the parcel panel"); + } + try + { + primCount[obj.OwnerID] += obj.PrimCount; + } + catch (KeyNotFoundException) + { + m_log.Error("[LAND]: Unable to match a prim with it's owner."); + } + if (obj.OwnerID == obj.GroupID && (!groups.Contains(obj.OwnerID))) + groups.Add(obj.OwnerID); + } + } + catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to Enumerate Land object arr."); + } + } + + remote_client.SendLandObjectOwners(LandData, groups, primCount); + } + } + + public Dictionary GetLandObjectOwners() + { + Dictionary ownersAndCount = new Dictionary(); + lock (primsOverMe) + { + try + { + + foreach (SceneObjectGroup obj in primsOverMe) + { + if (!ownersAndCount.ContainsKey(obj.OwnerID)) + { + ownersAndCount.Add(obj.OwnerID, 0); + } + ownersAndCount[obj.OwnerID] += obj.PrimCount; + } + } + catch (InvalidOperationException) + { + m_log.Error("[LAND]: Unable to enumerate land owners. arr."); + } + + } + return ownersAndCount; + } + + #endregion + + #region Object Returning + + public void ReturnObject(SceneObjectGroup obj) + { + SceneObjectGroup[] objs = new SceneObjectGroup[1]; + objs[0] = obj; + m_scene.returnObjects(objs, obj.OwnerID); + } + + public void ReturnLandObjects(uint type, UUID[] owners, UUID[] tasks, IClientAPI remote_client) + { + Dictionary> returns = + new Dictionary>(); + + lock (primsOverMe) + { + if (type == (uint)ObjectReturnType.Owner) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.OwnerID == m_landData.OwnerID) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.Group && m_landData.GroupID != UUID.Zero) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.GroupID == m_landData.GroupID) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.Other) + { + foreach (SceneObjectGroup obj in primsOverMe) + { + if (obj.OwnerID != m_landData.OwnerID && + (obj.GroupID != m_landData.GroupID || + m_landData.GroupID == UUID.Zero)) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + else if (type == (uint)ObjectReturnType.List) + { + List ownerlist = new List(owners); + + foreach (SceneObjectGroup obj in primsOverMe) + { + if (ownerlist.Contains(obj.OwnerID)) + { + if (!returns.ContainsKey(obj.OwnerID)) + returns[obj.OwnerID] = + new List(); + returns[obj.OwnerID].Add(obj); + } + } + } + } + + foreach (List ol in returns.Values) + { + if (m_scene.Permissions.CanReturnObjects(this, remote_client.AgentId, ol)) + m_scene.returnObjects(ol.ToArray(), remote_client.AgentId); + } + } + + #endregion + + #region Object Adding/Removing from Parcel + + public void ResetLandPrimCounts() + { + LandData.GroupPrims = 0; + LandData.OwnerPrims = 0; + LandData.OtherPrims = 0; + LandData.SelectedPrims = 0; + + + lock (primsOverMe) + primsOverMe.Clear(); + } + + public void AddPrimToCount(SceneObjectGroup obj) + { + + UUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (obj.IsSelected) + { + LandData.SelectedPrims += prim_count; + } + else + { + if (prim_owner == LandData.OwnerID) + { + LandData.OwnerPrims += prim_count; + } + else if ((obj.GroupID == LandData.GroupID || + prim_owner == LandData.GroupID) && + LandData.GroupID != UUID.Zero) + { + LandData.GroupPrims += prim_count; + } + else + { + LandData.OtherPrims += prim_count; + } + } + + lock (primsOverMe) + primsOverMe.Add(obj); + } + + public void RemovePrimFromCount(SceneObjectGroup obj) + { + lock (primsOverMe) + { + if (primsOverMe.Contains(obj)) + { + UUID prim_owner = obj.OwnerID; + int prim_count = obj.PrimCount; + + if (prim_owner == LandData.OwnerID) + { + LandData.OwnerPrims -= prim_count; + } + else if (obj.GroupID == LandData.GroupID || + prim_owner == LandData.GroupID) + { + LandData.GroupPrims -= prim_count; + } + else + { + LandData.OtherPrims -= prim_count; + } + + primsOverMe.Remove(obj); + } + } + } + + #endregion + + #endregion + + #endregion + + /// + /// Set the media url for this land parcel + /// + /// + public void SetMediaUrl(string url) + { + LandData.MediaURL = url; + SendLandUpdateToAvatarsOverMe(); + } + + /// + /// Set the music url for this land parcel + /// + /// + public void SetMusicUrl(string url) + { + LandData.MusicURL = url; + SendLandUpdateToAvatarsOverMe(); + } + } +} -- cgit v1.1 From 4cf5ef3cd4c6712f74615385a03217f5d4cecb80 Mon Sep 17 00:00:00 2001 From: meta7 Date: Mon, 30 Aug 2010 11:41:20 -0700 Subject: Kick the user from the region in the circumstance that the TP home failed - ONLY if it was triggered by an estate ban. This makes baby jesus cry, and should be fixed to search for alternative regions if the home region is unavailable. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 16 +++++++++++----- .../EntityTransfer/HGEntityTransferModule.cs | 19 ++++++++++++------- .../World/Estate/EstateManagementModule.cs | 18 +++++++++++++++--- .../Framework/Interfaces/IEntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 5 +++-- 5 files changed, 42 insertions(+), 18 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 0ba67d3..d6f37ae 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -99,7 +99,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual void OnNewClient(IClientAPI client) { - client.OnTeleportHomeRequest += TeleportHome; + client.OnTeleportHomeRequest += TeleportHomeFired; } public virtual void Close() @@ -552,7 +552,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Teleport Home - public virtual void TeleportHome(UUID id, IClientAPI client) + public void TeleportHomeFired(UUID id, IClientAPI client) + { + TeleportHome(id, client); + } + + public virtual bool TeleportHome(UUID id, IClientAPI client) { m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); @@ -565,14 +570,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // can't find the Home region: Tell viewer and abort client.SendTeleportFailed("You don't have a home position set."); - return; + return false; } GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); if (regionInfo == null) { // can't find the Home region: Tell viewer and abort client.SendTeleportFailed("Your home region could not be found."); - return; + return false; } m_log.DebugFormat("[ENTITY TRANSFER MODULE]: User's home region is {0} {1} ({2}-{3})", regionInfo.RegionName, regionInfo.RegionID, regionInfo.RegionLocX / Constants.RegionSize, regionInfo.RegionLocY / Constants.RegionSize); @@ -586,8 +591,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // can't find the Home region: Tell viewer and abort client.SendTeleportFailed("Your home region could not be found."); - return; + return false; } + return true; } #endregion diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 1ac7508..47898cc 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -86,7 +86,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override void OnNewClient(IClientAPI client) { - client.OnTeleportHomeRequest += TeleportHome; + client.OnTeleportHomeRequest += TeleportHomeFired; client.OnConnectionClosed += new Action(OnConnectionClosed); } @@ -174,7 +174,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); } - public override void TeleportHome(UUID id, IClientAPI client) + public void TeleportHomeFired(UUID id, IClientAPI client) + { + TeleportHome(id, client); + } + + public override bool TeleportHome(UUID id, IClientAPI client) { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); @@ -184,8 +189,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // local grid user m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); - base.TeleportHome(id, client); - return; + return base.TeleportHome(id, client); } // Foreign user wants to go home @@ -195,7 +199,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { client.SendTeleportFailed("Your information has been lost"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); - return; + return false; } IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); @@ -205,7 +209,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { client.SendTeleportFailed("Your home region could not be found"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); - return; + return false; } ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); @@ -213,7 +217,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { client.SendTeleportFailed("Internal error"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); - return; + return false; } IEventQueue eq = sp.Scene.RequestModuleInterface(); @@ -223,6 +227,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ExternalHostName, homeGatekeeper.HttpPort, homeGatekeeper.RegionName); DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); + return true; } #endregion diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 171e0b9..8411d04 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -345,7 +345,11 @@ namespace OpenSim.Region.CoreModules.World.Estate { if (!s.IsChildAgent) { - m_scene.TeleportClientHome(user, s.ControllingClient); + if (!m_scene.TeleportClientHome(user, s.ControllingClient)) + { + s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); + s.ControllingClient.Close(); + } } } @@ -479,7 +483,11 @@ namespace OpenSim.Region.CoreModules.World.Estate ScenePresence s = m_scene.GetScenePresence(prey); if (s != null) { - m_scene.TeleportClientHome(prey, s.ControllingClient); + if (!m_scene.TeleportClientHome(prey, s.ControllingClient)) + { + s.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); + s.ControllingClient.Close(); + } } } } @@ -498,7 +506,11 @@ namespace OpenSim.Region.CoreModules.World.Estate // Also make sure they are actually in the region if (p != null && !p.IsChildAgent) { - m_scene.TeleportClientHome(p.UUID, p.ControllingClient); + if (!m_scene.TeleportClientHome(p.UUID, p.ControllingClient)) + { + p.ControllingClient.Kick("You were teleported home by the region owner, but the TP failed - you have been logged out."); + p.ControllingClient.Close(); + } } } }); diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index e8738c4..45ca5c5 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -40,7 +40,7 @@ namespace OpenSim.Region.Framework.Interfaces void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags); - void TeleportHome(UUID id, IClientAPI client); + bool TeleportHome(UUID id, IClientAPI client); void Cross(ScenePresence agent, bool isFlying); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 957c4e8..736b696 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2985,15 +2985,16 @@ namespace OpenSim.Region.Framework.Scenes /// /// The avatar's Unique ID /// The IClientAPI for the client - public virtual void TeleportClientHome(UUID agentId, IClientAPI client) + public virtual bool TeleportClientHome(UUID agentId, IClientAPI client) { if (m_teleportModule != null) - m_teleportModule.TeleportHome(agentId, client); + return m_teleportModule.TeleportHome(agentId, client); else { m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); client.SendTeleportFailed("Unable to perform teleports on this simulator."); } + return false; } /// -- cgit v1.1 From b973fe52976c909197c360d6afdd62952e3d37ae Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 31 Aug 2010 22:24:11 +0200 Subject: Adjust the "Magic numbers" we use because we can't reference the actual script state enum to reflect recent changes. --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 2a36362..4159610 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -689,7 +689,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } // Fire on_rez - group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); + group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); rootPart.ParentGroup.ResumeScripts(); rootPart.ScheduleFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8760c84..ffbf7bf 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1993,7 +1993,7 @@ namespace OpenSim.Region.Framework.Scenes // We can only call this after adding the scene object, since the scene object references the scene // to find out if scripts should be activated at all. - group.CreateScriptInstances(param, true, DefaultScriptEngine, 2); + group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); group.ScheduleGroupForFullUpdate(); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6a742c1..767d370 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2442,7 +2442,7 @@ namespace OpenSim.Region.Framework.Scenes return false; } - newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 1); + newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, 2); newObject.ResumeScripts(); diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b86a564..8823df1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1928,7 +1928,7 @@ namespace OpenSim.Region.Framework.Scenes copy.UpdateGroupRotationR(rot); } - copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 0); + copy.CreateScriptInstances(0, false, m_parentScene.DefaultScriptEngine, 1); copy.HasGroupChanged = true; copy.ScheduleGroupForFullUpdate(); copy.ResumeScripts(); -- cgit v1.1 From 2232e6f27300032188a7a1eeb77c56e84cd51d66 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 1 Sep 2010 14:08:52 +0200 Subject: Improve sim health reporting. Output error message if heartbeat thread is restarted by scene. This may help to find out why this recovery mechanism isn't working. --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b950dbd..a9e6647 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1160,6 +1160,7 @@ namespace OpenSim.Region.Framework.Scenes //m_heartbeatTimer.Elapsed += new ElapsedEventHandler(Heartbeat); if (HeartbeatThread != null) { + m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName); HeartbeatThread.Abort(); HeartbeatThread = null; } @@ -4555,7 +4556,7 @@ namespace OpenSim.Region.Framework.Scenes // int health=1; // Start at 1, means we're up - if ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000) + if (m_firstHeartbeat || ((Util.EnvironmentTickCountSubtract(m_lastUpdate)) < 1000)) health+=1; else return health; -- cgit v1.1 From 09fba1609493b5ad60ab95fb6db4b368a1833fc3 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 1 Sep 2010 20:10:44 +0200 Subject: Prevent Meta7 plants from being treated like dropped attachments and removed from the sim. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a9e6647..400f4c0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5068,7 +5068,7 @@ namespace OpenSim.Region.Framework.Scenes { ForEachSOG(delegate (SceneObjectGroup grp) { - if (grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) + if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) { UUID agentID = grp.OwnerID; if (agentID == UUID.Zero) -- cgit v1.1 From db015963a9905b1af5d4d1d42a6384b5644a3617 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 2 Sep 2010 14:17:33 +0200 Subject: Remove the annoying "Script saved" popups when saving scripts in task inventory. They cause spam when using recompile scripts in selection and are redundant because that message is also shown in the script window message pane. These popups were a legacy from when we couldn't drive the message pane and their finest hour has now come. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index ffbf7bf..0d9682e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -218,8 +218,7 @@ namespace OpenSim.Region.Framework.Scenes // Update item with new asset item.AssetID = asset.FullID; - if (group.UpdateInventoryItem(item)) - remoteClient.SendAgentAlertMessage("Script saved", false); + group.UpdateInventoryItem(item); part.GetProperties(remoteClient); @@ -232,10 +231,6 @@ namespace OpenSim.Region.Framework.Scenes // errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 0); } - else - { - remoteClient.SendAgentAlertMessage("Script saved", false); - } part.ParentGroup.ResumeScripts(); return errors; } @@ -1401,13 +1396,6 @@ namespace OpenSim.Region.Framework.Scenes { agentTransactions.HandleTaskItemUpdateFromTransaction( remoteClient, part, transactionID, currentItem); - - if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) - remoteClient.SendAgentAlertMessage("Notecard saved", false); - else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) - remoteClient.SendAgentAlertMessage("Script saved", false); - else - remoteClient.SendAgentAlertMessage("Item saved", false); } // Base ALWAYS has move -- cgit v1.1 From 0f40ec5c65f1698d2bb32cc28960b3651c1f7dac Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 2 Sep 2010 16:10:44 +0200 Subject: Implement UploadBakedTexture cap --- OpenSim/Framework/Capabilities/Caps.cs | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 0db7bb9..8a339fe 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -44,6 +44,8 @@ namespace OpenSim.Framework.Capabilities string assetName, string description, UUID assetID, UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, string assetType); + public delegate void UploadedBakedTexture(UUID assetID, byte[] data); + public delegate UUID UpdateItem(UUID itemID, byte[] data); public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors); @@ -97,6 +99,7 @@ namespace OpenSim.Framework.Capabilities // private static readonly string m_provisionVoiceAccountRequestPath = "0008/";// This is in a module. // private static readonly string m_remoteParcelRequestPath = "0009/";// This is in the LandManagementModule. + private static readonly string m_uploadBakedTexturePath = "0010/";// This is in the LandManagementModule. //private string eventQueue = "0100/"; private IScene m_Scene; @@ -185,6 +188,8 @@ namespace OpenSim.Framework.Capabilities m_capsHandlers["UpdateScriptTaskInventory"] = new RestStreamHandler("POST", capsBase + m_notecardTaskUpdatePath, ScriptTaskInventory); m_capsHandlers["UpdateScriptTask"] = m_capsHandlers["UpdateScriptTaskInventory"]; + m_capsHandlers["UploadBakedTexture"] = + new RestStreamHandler("POST", capsBase + m_uploadBakedTexturePath, UploadBakedTexture); } catch (Exception e) @@ -742,6 +747,50 @@ namespace OpenSim.Framework.Capabilities return null; } + public string UploadBakedTexture(string request, string path, + string param, OSHttpRequest httpRequest, + OSHttpResponse httpResponse) + { + try + { + m_log.Debug("[CAPS]: UploadBakedTexture Request in region: " + + m_regionName); + + string capsBase = "/CAPS/" + m_capsObjectPath; + string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000"); + + BakedTextureUploader uploader = + new BakedTextureUploader( capsBase + uploaderPath, + m_httpListener); + uploader.OnUpLoad += BakedTextureUploaded; + + m_httpListener.AddStreamHandler( + new BinaryStreamHandler("POST", capsBase + uploaderPath, + uploader.uploaderCaps)); + + string protocol = "http://"; + + if (m_httpListener.UseSSL) + protocol = "https://"; + + string uploaderURL = protocol + m_httpListenerHostName + ":" + + m_httpListenPort.ToString() + capsBase + uploaderPath; + + LLSDAssetUploadResponse uploadResponse = + new LLSDAssetUploadResponse(); + uploadResponse.uploader = uploaderURL; + uploadResponse.state = "upload"; + + return LLSDHelpers.SerialiseLLSDReply(uploadResponse); + } + catch (Exception e) + { + m_log.Error("[CAPS]: " + e.ToString()); + } + + return null; + } + /// /// Called by the notecard update handler. Provides a URL to which the client can upload a new asset. /// @@ -925,6 +974,17 @@ namespace OpenSim.Framework.Capabilities } } + public void BakedTextureUploaded(UUID assetID, byte[] data) + { + m_log.DebugFormat("[CAPS]: Received baked texture {0}", assetID.ToString()); + AssetBase asset; + asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_agentID.ToString()); + asset.Data = data; + asset.Temporary = true; + asset.Local = true; + m_assetCache.Store(asset); + } + /// /// Called when new asset data for an agent inventory item update has been uploaded. /// @@ -1243,5 +1303,50 @@ namespace OpenSim.Framework.Capabilities fs.Close(); } } + + public class BakedTextureUploader + { + public event UploadedBakedTexture OnUpLoad; + private UploadedBakedTexture handlerUpLoad = null; + + private string uploaderPath = String.Empty; + private UUID newAssetID; + private IHttpServer httpListener; + + public BakedTextureUploader(string path, IHttpServer httpServer) + { + newAssetID = UUID.Random(); + uploaderPath = path; + httpListener = httpServer; + } + + /// + /// + /// + /// + /// + /// + /// + public string uploaderCaps(byte[] data, string path, string param) + { + string res = String.Empty; + LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); + uploadComplete.new_asset = newAssetID.ToString(); + uploadComplete.new_inventory_item = UUID.Zero; + uploadComplete.state = "complete"; + + res = LLSDHelpers.SerialiseLLSDReply(uploadComplete); + + httpListener.RemoveStreamHandler("POST", uploaderPath); + + handlerUpLoad = OnUpLoad; + if (handlerUpLoad != null) + { + handlerUpLoad(newAssetID, data); + } + + return res; + } + } } } -- cgit v1.1 From 713c6668273ebd853db7f3f69185c9b4f119f702 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 2 Sep 2010 19:49:42 +0200 Subject: Show when appearance is sent to an avatar to help track down failure \to display avatars --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 105501f..aa7de05 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3427,6 +3427,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP avp.Sender.IsTrial = false; avp.Sender.ID = agentID; + m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); OutPacket(avp, ThrottleOutPacketType.Task); } -- cgit v1.1 From eea5d8368acb9a7934e55b6e4b6ccddb40bc5611 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 2 Sep 2010 20:08:39 +0200 Subject: Experimentally comment the sending of unbaked avatars --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cd80eb0..2acf8ff 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2806,7 +2806,9 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.SendAvatarDataImmediate(this); SendInitialFullUpdateToAllClients(); - SendAppearanceToAllOtherAgents(); + // Experimentally commenting this. We don't have bakes at this time + // and 1.23 will not display an avatar without bakes. + //SendAppearanceToAllOtherAgents(); } /// -- cgit v1.1 From 5ea979d51517b11895a4c5431e3c3c02767a23ac Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Thu, 2 Sep 2010 20:51:27 +0200 Subject: Remove commented code and the comment, as the change has proven out --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 3 --- 1 file changed, 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2acf8ff..604ffad 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2806,9 +2806,6 @@ namespace OpenSim.Region.Framework.Scenes m_controllingClient.SendAvatarDataImmediate(this); SendInitialFullUpdateToAllClients(); - // Experimentally commenting this. We don't have bakes at this time - // and 1.23 will not display an avatar without bakes. - //SendAppearanceToAllOtherAgents(); } /// -- cgit v1.1 From 16814dd8f18b51f5dd8841ae341847e117bb83b3 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 2 Sep 2010 21:51:19 +0000 Subject: Fixes to JUMP system. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 151 ++++++++++++++++----- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 66 ++++++--- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 7 +- 3 files changed, 168 insertions(+), 56 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index b847d87..99d9564 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -58,7 +58,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation private int m_animTickFall; // private int m_animTickJump; public int m_animTickJump; // ScenePresence has to see this to control +Z force - + public bool m_jumping = false; // Add for jumping + public float m_jumpVelocity = 0f; // Add for jumping + private int m_landing = 0; // Add for jumping + /// /// The scene presence that this animator applies to /// @@ -141,9 +144,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation /// public string GetMovementAnimation() { +//Console.WriteLine("GMA-------"); //## const float FALL_DELAY = 0.33f; - const float PREJUMP_DELAY = 0.25f; - +//rm for jumping const float PREJUMP_DELAY = 0.25f; + const float PREJUMP_DELAY = 200f; // mS add for jumping + const float JUMP_PERIOD = 800f; // mS add for jumping #region Inputs AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags; @@ -177,8 +182,7 @@ namespace OpenSim.Region.Framework.Scenes.Animation // Is the avatar trying to move? // bool moving = (move != Vector3.Zero); - bool jumping = m_animTickJump != 0; - +// rm for jumping bool jumping = m_animTickJump != 0; #endregion Inputs #region Flying @@ -187,6 +191,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation { m_animTickFall = 0; m_animTickJump = 0; + m_jumping = false; //add for jumping flag + m_jumpVelocity = 0f; //add for jumping flag + actor.Selected = false; //add for jumping flag if (move.X != 0f || move.Y != 0f) { @@ -213,8 +220,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation #region Falling/Floating/Landing - if (actor == null || !actor.IsColliding) +// rm for jumping if (actor == null || !actor.IsColliding) + if ((actor == null || !actor.IsColliding) && !m_jumping) // add for jumping { +//Console.WriteLine("FFL"); //## float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; @@ -223,7 +232,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation // Just started falling m_animTickFall = Environment.TickCount; } - else if (!jumping && fallElapsed > FALL_DELAY) +// else if (!jumping && fallElapsed > FALL_DELAY) + else if (!m_jumping && fallElapsed > FALL_DELAY) // add for jumping { // Falling long enough to trigger the animation return "FALLDOWN"; @@ -234,6 +244,67 @@ namespace OpenSim.Region.Framework.Scenes.Animation #endregion Falling/Floating/Landing + + #region Jumping // section added for jumping... + + Vector3 vj = Vector3.Zero; + int jumptime; + jumptime = Environment.TickCount - m_animTickJump; + + + if ((move.Z > 0f) && (!m_jumping)) + { +//Console.WriteLine("PJ {0}", jumptime); //## + // Start jumping, prejump + m_animTickFall = 0; + m_jumping = true; + actor.Selected = true; // borrowed for jmping flag + m_animTickJump = Environment.TickCount; + vj.Z = 0.35f; +m_jumpVelocity = 0.35f; + vj += actor.Velocity; +// #@ actor.Velocity = vj; + return "PREJUMP"; + } + + if(m_jumping) + { + if ( (jumptime > (JUMP_PERIOD * 1.5f)) && actor.IsColliding) + { +//Console.WriteLine("LA {0}", jumptime); //## + // end jumping + m_jumping = false; + actor.Selected = false; // borrowed for jumping flag +m_jumpVelocity = 0f; + m_animTickFall = Environment.TickCount; + return "LAND"; + } + else if (jumptime > JUMP_PERIOD) + { +//Console.WriteLine("JD {0}", jumptime); //## + // jump down + vj = actor.Velocity; + vj.Z = 0f; +m_jumpVelocity = 0f; +// #@ actor.Velocity = vj; + return "JUMP"; + } + else if (jumptime > PREJUMP_DELAY) + { +//Console.WriteLine("JU {0}", jumptime); //## + // jump up + m_jumping = true; + vj.Z = 10f; +m_jumpVelocity = 10f; + vj.X = actor.Velocity.X; + vj.Y = actor.Velocity.Y; +// #@ actor.Velocity = vj; + return "JUMP"; + } + } + + #endregion Jumping // end added section + #region Ground Movement if (m_movementAnimation == "FALLDOWN") @@ -245,11 +316,26 @@ namespace OpenSim.Region.Framework.Scenes.Animation } else if (m_movementAnimation == "LAND") { - float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; - if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY)) +// rm jumping float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; + int landElapsed = Environment.TickCount - m_animTickFall; // add for jumping +// rm jumping if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY)) +/* Try change ## + if ((m_animTickFall != 0) && (landElapsed <= 500)) // add for jumping + return "LAND"; + */ + // NB if this is set too long a weird anim reset from some place prevents STAND from being sent to client + if ((m_animTickFall != 0) && (landElapsed <= 300)) // add for jumping + { +//Console.WriteLine("LAND"); //## return "LAND"; + } + else + { +//Console.WriteLine("STAND"); //## + return "STAND"; + } } - +/* This section removed, replaced by jumping section m_animTickFall = 0; if (move.Z > 0f) @@ -279,27 +365,28 @@ namespace OpenSim.Region.Framework.Scenes.Animation { // Not jumping m_animTickJump = 0; - - if (move.X != 0f || move.Y != 0f) - { - // Walking / crouchwalking / running - if (move.Z < 0f) - return "CROUCHWALK"; - else if (m_scenePresence.SetAlwaysRun) - return "RUN"; - else - return "WALK"; - } + */ + // next section moved outside paren. and realigned for jumping + if (move.X != 0f || move.Y != 0f) + { + // Walking / crouchwalking / running + if (move.Z < 0f) + return "CROUCHWALK"; + else if (m_scenePresence.SetAlwaysRun) + return "RUN"; else - { - // Not walking - if (move.Z < 0f) - return "CROUCH"; - else - return "STAND"; - } + return "WALK"; } - +// rm for jumping else + else if (!m_jumping) // add for jumping + { + // Not walking + if (move.Z < 0f) + return "CROUCH"; + else + return "STAND"; + } + // end section realign for jumping #endregion Ground Movement return m_movementAnimation; @@ -311,15 +398,15 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void UpdateMovementAnimations() { m_movementAnimation = GetMovementAnimation(); - if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) +/* if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump) { // This was the previous behavior before PREJUMP TrySetMovementAnimation("JUMP"); } else - { + { removed for jumping */ TrySetMovementAnimation(m_movementAnimation); - } +// rm for jumping } } public UUID[] GetAnimationArray() diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cd80eb0..f682ee5 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1471,6 +1471,9 @@ namespace OpenSim.Region.Framework.Scenes if (actor.Flying != oldflying) update_movementflag = true; + if (m_animator.m_jumping) // add for jumping + update_movementflag = true; + if (q != m_bodyRot) { m_bodyRot = q; @@ -2580,6 +2583,7 @@ namespace OpenSim.Region.Framework.Scenes // m_log.Info("[AGENT]: Stop FLying"); //} } + /* This jumping section removed to SPA else if (!actor.Flying && actor.IsColliding) { if (direc.Z > 2.0f) @@ -2592,12 +2596,12 @@ namespace OpenSim.Region.Framework.Scenes { direc.Z *= 0.1f; // prejump } - /* Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs + / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs Animator.TrySetMovementAnimation("PREJUMP"); Animator.TrySetMovementAnimation("JUMP"); - */ + * / } - } + } */ } // TODO: Add the force instead of only setting it to support multiple forces per frame? @@ -3543,28 +3547,46 @@ namespace OpenSim.Region.Framework.Scenes /// public override void UpdateMovement() { - if (m_forceToApply.HasValue) - { + if (Animator!=null) // add for jumping + { // add for jumping + // if (!m_animator.m_jumping) // add for jumping + // { // add for jumping - Vector3 force = m_forceToApply.Value; - m_updateflag = true; - Velocity = force; + if (m_forceToApply.HasValue) // this section realigned + { - m_forceToApply = null; - } - else - { - if (m_isNudging) - { - Vector3 force = Vector3.Zero; + Vector3 force = m_forceToApply.Value; + m_updateflag = true; +if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping + Velocity = force; +//Console.WriteLine("UM1 {0}", Velocity); + m_forceToApply = null; + } + else + { + if (m_isNudging) + { + Vector3 force = Vector3.Zero; + + m_updateflag = true; +if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping + Velocity = force; +//Console.WriteLine("UM2 {0}", Velocity); + m_isNudging = false; + m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" + } + else // add for jumping + { // add for jumping + Vector3 force = Vector3.Zero; // add for jumping +if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for jumping +//Console.WriteLine("UM3 {0}", Velocity); + Velocity = force; // add for jumping + } - m_updateflag = true; - Velocity = force; - m_isNudging = false; - m_updateCount = UPDATE_COUNT; //KF: Update anims to pickup "STAND" - } - } - } + } + // } // end realign + } // add for jumping + } // add for jumping /// /// Adds a physical representation of the avatar to the Physics plugin diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 61c16b8..0c79aa6 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -90,6 +90,7 @@ namespace OpenSim.Region.Physics.OdePlugin public float walkDivisor = 1.3f; public float runDivisor = 0.8f; private bool flying = false; + private bool jumping = false; // add for jumping private bool m_iscolliding = false; private bool m_iscollidingGround = false; private bool m_wascolliding = false; @@ -229,7 +230,8 @@ namespace OpenSim.Region.Physics.OdePlugin public override bool Selected { - set { return; } +// set { return; } + set { jumping = value; } // add for jumping flag } public override float Buoyancy @@ -1018,7 +1020,8 @@ namespace OpenSim.Region.Physics.OdePlugin { // close, jump to lateral destination d.BodySetPosition(Body, _zeroPosition.X, _zeroPosition.Y, pos.Z); } - if (flying) +// if (flying) + if (flying || jumping) // add for jumping { vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P; } -- cgit v1.1 From 457160afc3cc0878b068486a7cbb8a41a5f18520 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Fri, 3 Sep 2010 03:16:08 +0200 Subject: Fix an issue with rezzing scripted objects. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index c5994b2..1959427 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -278,7 +278,7 @@ namespace OpenSim.Region.Framework.Scenes if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { - if (stateSource == 1 && // Prim crossing + if (stateSource == 2 && // Prim crossing m_part.ParentGroup.Scene.m_trustBinaries) { m_items.LockItemsForWrite(true); @@ -1263,4 +1263,4 @@ namespace OpenSim.Region.Framework.Scenes Items.LockItemsForRead(false); } } -} \ No newline at end of file +} -- cgit v1.1 From e5936071711e35f9edf44d8393b8ad28ef4023db Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Sun, 5 Sep 2010 14:16:42 +0200 Subject: Remove "Dwell" support from core and replace it with calls to methods on IDwellModule --- OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs | 6 +- OpenSim/Data/MySQL/MySQLLegacyRegionData.cs | 6 +- OpenSim/Data/SQLite/SQLiteRegionData.cs | 3 - OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs | 3 - OpenSim/Framework/LandData.cs | 14 --- .../Serialization/External/LandDataSerializer.cs | 5 +- .../HttpServer/SynchronousRestFormsRequester.cs | 109 ++++++++++----------- .../Region/ClientStack/LindenUDP/LLClientView.cs | 6 +- .../CoreModules/World/Land/LandManagementModule.cs | 13 --- OpenSim/Region/DataSnapshot/LandSnapshot.cs | 7 +- 10 files changed, 69 insertions(+), 103 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs index 7ff8737..77b8a10 100644 --- a/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs +++ b/OpenSim/Data/MSSQL/MSSQLLegacyRegionData.cs @@ -638,9 +638,9 @@ ELSE //Insert new values string sql = @"INSERT INTO [land] -([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID],[OtherCleanTime],[Dwell]) +([UUID],[RegionUUID],[LocalLandID],[Bitmap],[Name],[Description],[OwnerUUID],[IsGroupOwned],[Area],[AuctionID],[Category],[ClaimDate],[ClaimPrice],[GroupUUID],[SalePrice],[LandStatus],[LandFlags],[LandingType],[MediaAutoScale],[MediaTextureUUID],[MediaURL],[MusicURL],[PassHours],[PassPrice],[SnapshotUUID],[UserLocationX],[UserLocationY],[UserLocationZ],[UserLookAtX],[UserLookAtY],[UserLookAtZ],[AuthbuyerID],[OtherCleanTime]) VALUES -(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime,@Dwell)"; +(@UUID,@RegionUUID,@LocalLandID,@Bitmap,@Name,@Description,@OwnerUUID,@IsGroupOwned,@Area,@AuctionID,@Category,@ClaimDate,@ClaimPrice,@GroupUUID,@SalePrice,@LandStatus,@LandFlags,@LandingType,@MediaAutoScale,@MediaTextureUUID,@MediaURL,@MusicURL,@PassHours,@PassPrice,@SnapshotUUID,@UserLocationX,@UserLocationY,@UserLocationZ,@UserLookAtX,@UserLookAtY,@UserLookAtZ,@AuthbuyerID,@OtherCleanTime)"; using (SqlConnection conn = new SqlConnection(m_connectionString)) using (SqlCommand cmd = new SqlCommand(sql, conn)) @@ -954,7 +954,6 @@ VALUES newData.SnapshotID = new UUID((Guid)row["SnapshotUUID"]); newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); try { @@ -1357,7 +1356,6 @@ VALUES parameters.Add(_Database.CreateParameter("UserLookAtZ", land.UserLookAt.Z)); parameters.Add(_Database.CreateParameter("AuthBuyerID", land.AuthBuyerID)); parameters.Add(_Database.CreateParameter("OtherCleanTime", land.OtherCleanTime)); - parameters.Add(_Database.CreateParameter("Dwell", land.Dwell)); return parameters.ToArray(); } diff --git a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs index 04446ce..30253c3 100644 --- a/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs +++ b/OpenSim/Data/MySQL/MySQLLegacyRegionData.cs @@ -677,7 +677,7 @@ namespace OpenSim.Data.MySQL "MusicURL, PassHours, PassPrice, SnapshotUUID, " + "UserLocationX, UserLocationY, UserLocationZ, " + "UserLookAtX, UserLookAtY, UserLookAtZ, " + - "AuthbuyerID, OtherCleanTime, Dwell, MediaType, MediaDescription, " + + "AuthbuyerID, OtherCleanTime, MediaType, MediaDescription, " + "MediaSize, MediaLoop, ObscureMusic, ObscureMedia) values (" + "?UUID, ?RegionUUID, " + "?LocalLandID, ?Bitmap, ?Name, ?Description, " + @@ -688,7 +688,7 @@ namespace OpenSim.Data.MySQL "?MusicURL, ?PassHours, ?PassPrice, ?SnapshotUUID, " + "?UserLocationX, ?UserLocationY, ?UserLocationZ, " + "?UserLookAtX, ?UserLookAtY, ?UserLookAtZ, " + - "?AuthbuyerID, ?OtherCleanTime, ?Dwell, ?MediaType, ?MediaDescription, "+ + "?AuthbuyerID, ?OtherCleanTime, ?MediaType, ?MediaDescription, "+ "CONCAT(?MediaWidth, ',', ?MediaHeight), ?MediaLoop, ?ObscureMusic, ?ObscureMedia)"; FillLandCommand(cmd, parcel.LandData, parcel.RegionUUID); @@ -1329,7 +1329,6 @@ namespace OpenSim.Data.MySQL UUID.TryParse((string)row["AuthBuyerID"], out authedbuyer); UUID.TryParse((string)row["SnapshotUUID"], out snapshotID); newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); newData.AuthBuyerID = authedbuyer; newData.SnapshotID = snapshotID; @@ -1660,7 +1659,6 @@ namespace OpenSim.Data.MySQL cmd.Parameters.AddWithValue("UserLookAtZ", land.UserLookAt.Z); cmd.Parameters.AddWithValue("AuthBuyerID", land.AuthBuyerID); cmd.Parameters.AddWithValue("OtherCleanTime", land.OtherCleanTime); - cmd.Parameters.AddWithValue("Dwell", land.Dwell); cmd.Parameters.AddWithValue("MediaDescription", land.MediaDescription); cmd.Parameters.AddWithValue("MediaType", land.MediaType); cmd.Parameters.AddWithValue("MediaWidth", land.MediaWidth); diff --git a/OpenSim/Data/SQLite/SQLiteRegionData.cs b/OpenSim/Data/SQLite/SQLiteRegionData.cs index 8432e74..88699a7 100644 --- a/OpenSim/Data/SQLite/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLite/SQLiteRegionData.cs @@ -1111,7 +1111,6 @@ namespace OpenSim.Data.SQLite createCol(land, "UserLookAtZ", typeof (Double)); createCol(land, "AuthbuyerID", typeof(String)); createCol(land, "OtherCleanTime", typeof(Int32)); - createCol(land, "Dwell", typeof(Int32)); land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]}; @@ -1449,7 +1448,6 @@ namespace OpenSim.Data.SQLite UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID); newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); return newData; } @@ -1761,7 +1759,6 @@ namespace OpenSim.Data.SQLite row["UserLookAtZ"] = land.UserLookAt.Z; row["AuthbuyerID"] = land.AuthBuyerID.ToString(); row["OtherCleanTime"] = land.OtherCleanTime; - row["Dwell"] = land.Dwell; row["MediaType"] = land.MediaType; row["MediaDescription"] = land.MediaDescription; row["MediaSize"] = land.MediaWidth.ToString() + "," + land.MediaHeight.ToString(); diff --git a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs index 289fd94..b5ce4c0 100644 --- a/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs +++ b/OpenSim/Data/SQLiteLegacy/SQLiteRegionData.cs @@ -1069,7 +1069,6 @@ namespace OpenSim.Data.SQLiteLegacy createCol(land, "UserLookAtZ", typeof (Double)); createCol(land, "AuthbuyerID", typeof(String)); createCol(land, "OtherCleanTime", typeof(Int32)); - createCol(land, "Dwell", typeof(Int32)); land.PrimaryKey = new DataColumn[] {land.Columns["UUID"]}; @@ -1400,7 +1399,6 @@ namespace OpenSim.Data.SQLiteLegacy UUID.TryParse((string)row["AuthbuyerID"], out authBuyerID); newData.OtherCleanTime = Convert.ToInt32(row["OtherCleanTime"]); - newData.Dwell = Convert.ToInt32(row["Dwell"]); return newData; } @@ -1711,7 +1709,6 @@ namespace OpenSim.Data.SQLiteLegacy row["UserLookAtZ"] = land.UserLookAt.Z; row["AuthbuyerID"] = land.AuthBuyerID.ToString(); row["OtherCleanTime"] = land.OtherCleanTime; - row["Dwell"] = land.Dwell; } /// diff --git a/OpenSim/Framework/LandData.cs b/OpenSim/Framework/LandData.cs index 4440c94..5bb0413 100644 --- a/OpenSim/Framework/LandData.cs +++ b/OpenSim/Framework/LandData.cs @@ -88,7 +88,6 @@ namespace OpenSim.Framework private UUID _snapshotID = UUID.Zero; private Vector3 _userLocation = new Vector3(); private Vector3 _userLookAt = new Vector3(); - private int _dwell = 0; private int _otherCleanTime = 0; private string _mediaType = "none/none"; private string _mediaDescription = ""; @@ -620,18 +619,6 @@ namespace OpenSim.Framework } /// - /// Deprecated idea. Number of visitors ~= free money - /// - public int Dwell { - get { - return _dwell; - } - set { - _dwell = value; - } - } - - /// /// Number of minutes to return SceneObjectGroup that are owned by someone who doesn't own /// the parcel and isn't set to the same 'group' as the parcel. /// @@ -703,7 +690,6 @@ namespace OpenSim.Framework landData._userLocation = _userLocation; landData._userLookAt = _userLookAt; landData._otherCleanTime = _otherCleanTime; - landData._dwell = _dwell; landData._mediaType = _mediaType; landData._mediaDescription = _mediaDescription; landData._mediaWidth = _mediaWidth; diff --git a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs index ff0afc8..fc0387b 100644 --- a/OpenSim/Framework/Serialization/External/LandDataSerializer.cs +++ b/OpenSim/Framework/Serialization/External/LandDataSerializer.cs @@ -118,7 +118,8 @@ namespace OpenSim.Framework.Serialization.External landData.SnapshotID = UUID.Parse( xtr.ReadElementString("SnapshotID")); landData.UserLocation = Vector3.Parse( xtr.ReadElementString("UserLocation")); landData.UserLookAt = Vector3.Parse( xtr.ReadElementString("UserLookAt")); - landData.Dwell = Convert.ToInt32( xtr.ReadElementString("Dwell")); + // No longer used here + xtr.ReadElementString("Dwell"); landData.OtherCleanTime = Convert.ToInt32( xtr.ReadElementString("OtherCleanTime")); xtr.ReadEndElement(); @@ -177,7 +178,7 @@ namespace OpenSim.Framework.Serialization.External xtw.WriteElementString("SnapshotID", landData.SnapshotID.ToString()); xtw.WriteElementString("UserLocation", landData.UserLocation.ToString()); xtw.WriteElementString("UserLookAt", landData.UserLookAt.ToString()); - xtw.WriteElementString("Dwell", Convert.ToString(landData.Dwell)); + xtw.WriteElementString("Dwell", "0"); xtw.WriteElementString("OtherCleanTime", Convert.ToString(landData.OtherCleanTime)); xtw.WriteEndElement(); diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index f955df7..41ece86 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -57,80 +57,73 @@ namespace OpenSim.Framework.Servers.HttpServer { WebRequest request = WebRequest.Create(requestUrl); request.Method = verb; + string respstring = String.Empty; - if ((verb == "POST") || (verb == "PUT")) + using (MemoryStream buffer = new MemoryStream()) { - request.ContentType = "text/www-form-urlencoded"; - - MemoryStream buffer = new MemoryStream(); - int length = 0; - using (StreamWriter writer = new StreamWriter(buffer)) + if ((verb == "POST") || (verb == "PUT")) { - writer.Write(obj); - writer.Flush(); - } + request.ContentType = "text/www-form-urlencoded"; - length = (int)obj.Length; - request.ContentLength = length; + int length = 0; + using (StreamWriter writer = new StreamWriter(buffer)) + { + writer.Write(obj); + writer.Flush(); + } - Stream requestStream = null; - try - { - requestStream = request.GetRequestStream(); - requestStream.Write(buffer.ToArray(), 0, length); - } - catch (Exception e) - { - m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); - } - finally - { - // If this is closed, it will be disposed internally, - // but the above write is asynchronous and may hit after - // we're through here. So the thread handling that will - // throw and put us back into the catch above. Isn't - // .NET great? - //if (requestStream != null) - // requestStream.Close(); - // Let's not close this - //buffer.Close(); + length = (int)obj.Length; + request.ContentLength = length; + Stream requestStream = null; + try + { + requestStream = request.GetRequestStream(); + requestStream.Write(buffer.ToArray(), 0, length); + } + catch (Exception e) + { + m_log.DebugFormat("[FORMS]: exception occured on sending request to {0}: " + e.ToString(), requestUrl); + } + finally + { + if (requestStream != null) + requestStream.Close(); + } } - } - - string respstring = String.Empty; - try - { - using (WebResponse resp = request.GetResponse()) + try { - if (resp.ContentLength != 0) + using (WebResponse resp = request.GetResponse()) { - Stream respStream = null; - try + if (resp.ContentLength != 0) { - respStream = resp.GetResponseStream(); - using (StreamReader reader = new StreamReader(respStream)) + Stream respStream = null; + try { - respstring = reader.ReadToEnd(); + respStream = resp.GetResponseStream(); + using (StreamReader reader = new StreamReader(respStream)) + { + respstring = reader.ReadToEnd(); + } + } + catch (Exception e) + { + m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); + } + finally + { + if (respStream != null) + respStream.Close(); } - } - catch (Exception e) - { - m_log.DebugFormat("[FORMS]: exception occured on receiving reply " + e.ToString()); - } - finally - { - if (respStream != null) - respStream.Close(); } } } - } - catch (System.InvalidOperationException) - { - // This is what happens when there is invalid XML - m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); + catch (System.InvalidOperationException) + { + // This is what happens when there is invalid XML + m_log.DebugFormat("[FORMS]: InvalidOperationException on receiving request"); + } } return respstring; } diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index a1cd30a..3dea40c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2687,6 +2687,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y) { + float dwell = 0.0f; + IDwellModule dwellModule = m_scene.RequestModuleInterface(); + if (dwellModule != null) + dwell = dwellModule.GetDwell(land.GlobalID); ParcelInfoReplyPacket reply = (ParcelInfoReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelInfoReply); reply.AgentData.AgentID = m_agentId; reply.Data.ParcelID = parcelID; @@ -2711,7 +2715,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP reply.Data.GlobalZ = pos.Z; reply.Data.SimName = Utils.StringToBytes(info.RegionName); reply.Data.SnapshotID = land.SnapshotID; - reply.Data.Dwell = land.Dwell; + reply.Data.Dwell = dwell; reply.Data.SalePrice = land.SalePrice; reply.Data.AuctionID = (int)land.AuctionID; diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 776fe30..040dc8c 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -171,7 +171,6 @@ namespace OpenSim.Region.CoreModules.World.Land client.OnParcelGodForceOwner += ClientOnParcelGodForceOwner; client.OnParcelReclaim += ClientOnParcelReclaim; client.OnParcelInfoRequest += ClientOnParcelInfoRequest; -// client.OnParcelDwellRequest += ClientOnParcelDwellRequest; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; client.OnPreAgentUpdate += ClientOnPreAgentUpdate; @@ -1512,18 +1511,6 @@ namespace OpenSim.Region.CoreModules.World.Land #endregion - private void ClientOnParcelDwellRequest(int localID, IClientAPI remoteClient) - { - ILandObject selectedParcel = null; - lock (m_landList) - { - if (!m_landList.TryGetValue(localID, out selectedParcel)) - return; - } - - remoteClient.SendParcelDwellReply(localID, selectedParcel.LandData.GlobalID, selectedParcel.LandData.Dwell); - } - private void ClientOnParcelInfoRequest(IClientAPI remoteClient, UUID parcelID) { if (parcelID == UUID.Zero) diff --git a/OpenSim/Region/DataSnapshot/LandSnapshot.cs b/OpenSim/Region/DataSnapshot/LandSnapshot.cs index 64d29f2..b8c90cd 100644 --- a/OpenSim/Region/DataSnapshot/LandSnapshot.cs +++ b/OpenSim/Region/DataSnapshot/LandSnapshot.cs @@ -123,6 +123,8 @@ namespace OpenSim.Region.DataSnapshot.Providers ILandChannel landChannel = m_scene.LandChannel; List parcels = landChannel.AllParcels(); + IDwellModule dwellModule = m_scene.RequestModuleInterface(); + XmlNode parent = nodeFactory.CreateNode(XmlNodeType.Element, "parceldata", ""); if (parcels != null) { @@ -208,7 +210,10 @@ namespace OpenSim.Region.DataSnapshot.Providers xmlparcel.AppendChild(infouuid); XmlNode dwell = nodeFactory.CreateNode(XmlNodeType.Element, "dwell", ""); - dwell.InnerText = parcel.Dwell.ToString(); + if (dwellModule != null) + dwell.InnerText = dwellModule.GetDwell(parcel.GlobalID).ToString(); + else + dwell.InnerText = "0"; xmlparcel.AppendChild(dwell); //TODO: figure how to figure out teleport system landData.landingType -- cgit v1.1 From 00a23eea0ec5d3607cf9cd021a3a182da258686e Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 6 Sep 2010 03:59:48 +0200 Subject: Reflect the ParcelPropertiesUpdateRequest into Scene.EventManager, because modules need to see it (Search!) even if it comes in via CAPS --- .../CoreModules/World/Land/LandManagementModule.cs | 14 +++++++++--- OpenSim/Region/Framework/Scenes/EventManager.cs | 26 +++++++++++++++++++++- 2 files changed, 36 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 040dc8c..f62ec1b 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1115,7 +1115,11 @@ namespace OpenSim.Region.CoreModules.World.Land m_landList.TryGetValue(localID, out land); } - if (land != null) land.UpdateLandProperties(args, remote_client); + if (land != null) + { + land.UpdateLandProperties(args, remote_client); + m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(args, localID, remote_client); + } } public void ClientOnParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) @@ -1433,9 +1437,13 @@ namespace OpenSim.Region.CoreModules.World.Land m_landList.TryGetValue(parcelID, out land); } - if (land != null) { + if (land != null) + { land.UpdateLandProperties(land_update, client); - } else { + m_scene.EventManager.TriggerOnParcelPropertiesUpdateRequest(land_update, parcelID, client); + } + else + { m_log.WarnFormat("[LAND] unable to find parcelID {0}", parcelID); } return LLSDHelpers.SerialiseLLSDReply(new LLSDEmpty()); diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 52e6e92..d4e2736 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs @@ -113,6 +113,8 @@ namespace OpenSim.Region.Framework.Scenes public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; + public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest; + /// /// Fired when an object is touched/grabbed. /// @@ -2128,5 +2130,27 @@ namespace OpenSim.Region.Framework.Scenes } } } + + public void TriggerOnParcelPropertiesUpdateRequest(LandUpdateArgs args, + int local_id, IClientAPI remote_client) + { + ParcelPropertiesUpdateRequest handler = OnParcelPropertiesUpdateRequest; + if (handler != null) + { + foreach (ParcelPropertiesUpdateRequest d in handler.GetInvocationList()) + { + try + { + d(args, local_id, remote_client); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[EVENT MANAGER]: Delegate for TriggerOnSceneObjectPartCopy failed - continuing. {0} {1}", + e.Message, e.StackTrace); + } + } + } + } } -} \ No newline at end of file +} -- cgit v1.1 From f2e343d53081dbd6956d39b1e172e171101a4900 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 6 Sep 2010 14:09:46 +0200 Subject: Workaround for mono bug #312968 --- OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index 41ece86..e481b2b 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -64,6 +64,7 @@ namespace OpenSim.Framework.Servers.HttpServer if ((verb == "POST") || (verb == "PUT")) { request.ContentType = "text/www-form-urlencoded"; + request.KeepAlive = true; int length = 0; using (StreamWriter writer = new StreamWriter(buffer)) -- cgit v1.1 From 06adbc13242c16d40f9e9a02652067131f2eb9b7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 6 Sep 2010 17:24:10 +0200 Subject: Revert "Workaround for mono bug #312968" This reverts commit f2e343d53081dbd6956d39b1e172e171101a4900. Doesn't compile with our version of Mono. Patched Mono instead. --- OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs index e481b2b..41ece86 100644 --- a/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs +++ b/OpenSim/Framework/Servers/HttpServer/SynchronousRestFormsRequester.cs @@ -64,7 +64,6 @@ namespace OpenSim.Framework.Servers.HttpServer if ((verb == "POST") || (verb == "PUT")) { request.ContentType = "text/www-form-urlencoded"; - request.KeepAlive = true; int length = 0; using (StreamWriter writer = new StreamWriter(buffer)) -- cgit v1.1 From f4f9a2cb4590fe56e672242b4c5697078785e793 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 6 Sep 2010 18:14:24 +0200 Subject: Don't turn off the sale settings on child prims when linking, and on copy of prims anymore. The behavior now matches SL and can be used to link vendor prims for transport --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 8 -------- 1 file changed, 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 8823df1..86842b3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1619,11 +1619,6 @@ namespace OpenSim.Region.Framework.Scenes if (child != null) { - // Make sure no child prim is set for sale - // So that, on delink, no prims are unwittingly - // left for sale and sold off - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; childGroups.Add(child); } } @@ -1907,9 +1902,6 @@ namespace OpenSim.Region.Framework.Scenes child.ApplyNextOwnerPermissions(); } } - - copy.RootPart.ObjectSaleType = 0; - copy.RootPart.SalePrice = 10; } Entities.Add(copy); -- cgit v1.1 From 8886afd31961e1a838cb15df863ff9155885e0c6 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 6 Sep 2010 21:59:52 +0200 Subject: Fix yet another cause of "Ghost attachments" --- .../CoreModules/Avatar/Attachments/AttachmentsModule.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index bd9e621..100b55c 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -271,8 +271,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; - AttachObject(remoteClient, objatt, AttachmentPt, false); - //objatt.ScheduleGroupForFullUpdate(); + // This will throw if the attachment fails + try + { + AttachObject(remoteClient, objatt, AttachmentPt, false); + } + catch + { + // Make sure the object doesn't stick around and bail + m_scene.DeleteSceneObject(objatt, false); + return null; + } if (tainted) objatt.HasGroupChanged = true; @@ -616,4 +625,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.HasGroupChanged = false; } } -} \ No newline at end of file +} -- cgit v1.1 From c719e016ed9bfbb56fd8c571b9b7b9622bcef566 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Mon, 6 Sep 2010 21:45:07 +0000 Subject: Falling animation fix, comment out instrumentation. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 95 +++++++++++++--------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 6 +- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 21 +++-- OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs | 18 +++- 4 files changed, 90 insertions(+), 50 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 99d9564..9658e11 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -61,6 +61,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation public bool m_jumping = false; // Add for jumping public float m_jumpVelocity = 0f; // Add for jumping private int m_landing = 0; // Add for jumping + public bool m_falling = false; // Add for falling + private float m_fallHeight; // Add for falling /// /// The scene presence that this animator applies to @@ -118,7 +120,9 @@ namespace OpenSim.Region.Framework.Scenes.Animation public void ResetAnimations() { +Console.WriteLine("ResetA............."); m_animations.Clear(); +TrySetMovementAnimation("STAND"); } /// @@ -145,7 +149,8 @@ namespace OpenSim.Region.Framework.Scenes.Animation public string GetMovementAnimation() { //Console.WriteLine("GMA-------"); //## - const float FALL_DELAY = 0.33f; +//#@ const float FALL_DELAY = 0.33f; + const float FALL_DELAY = 800f; //## mS //rm for jumping const float PREJUMP_DELAY = 0.25f; const float PREJUMP_DELAY = 200f; // mS add for jumping const float JUMP_PERIOD = 800f; // mS add for jumping @@ -191,9 +196,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation { m_animTickFall = 0; m_animTickJump = 0; - m_jumping = false; //add for jumping flag - m_jumpVelocity = 0f; //add for jumping flag + m_jumping = false; //add for jumping + m_falling = true; //add for falling + m_jumpVelocity = 0f; //add for jumping actor.Selected = false; //add for jumping flag + m_fallHeight = actor.Position.Z; // save latest flying height if (move.X != 0f || move.Y != 0f) { @@ -205,8 +212,11 @@ namespace OpenSim.Region.Framework.Scenes.Animation } else if (move.Z < 0f) { - if (actor != null && actor.IsColliding) + if (actor != null && actor.IsColliding) + { //## +//Console.WriteLine("LAND FLYING"); // ## return "LAND"; + } //# else return "HOVER_DOWN"; } @@ -223,19 +233,25 @@ namespace OpenSim.Region.Framework.Scenes.Animation // rm for jumping if (actor == null || !actor.IsColliding) if ((actor == null || !actor.IsColliding) && !m_jumping) // add for jumping { -//Console.WriteLine("FFL"); //## - float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; +// rm float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; + float fallElapsed = (float)(Environment.TickCount - m_animTickFall); // add, in mS float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f; +//Console.WriteLine("falling t={0} v={1}", fallElapsed, fallVelocity); //## - if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f)) +// rm for fall if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f)) + if (!m_jumping && (fallVelocity < -3.0f) ) m_falling = true; // add for falling and jumping + + if (m_animTickFall == 0 || (fallVelocity >= 0.0f)) // add for jumping + // not falling yet or going up { - // Just started falling + // reset start of fall time m_animTickFall = Environment.TickCount; } // else if (!jumping && fallElapsed > FALL_DELAY) - else if (!m_jumping && fallElapsed > FALL_DELAY) // add for jumping + else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) ) // add for falling and jumping { // Falling long enough to trigger the animation +//Console.WriteLine("FALLDOWN"); //## return "FALLDOWN"; } @@ -247,7 +263,6 @@ namespace OpenSim.Region.Framework.Scenes.Animation #region Jumping // section added for jumping... - Vector3 vj = Vector3.Zero; int jumptime; jumptime = Environment.TickCount - m_animTickJump; @@ -258,12 +273,10 @@ namespace OpenSim.Region.Framework.Scenes.Animation // Start jumping, prejump m_animTickFall = 0; m_jumping = true; + m_falling = false; actor.Selected = true; // borrowed for jmping flag m_animTickJump = Environment.TickCount; - vj.Z = 0.35f; -m_jumpVelocity = 0.35f; - vj += actor.Velocity; -// #@ actor.Velocity = vj; + m_jumpVelocity = 0.35f; return "PREJUMP"; } @@ -274,8 +287,9 @@ m_jumpVelocity = 0.35f; //Console.WriteLine("LA {0}", jumptime); //## // end jumping m_jumping = false; + m_falling = false; actor.Selected = false; // borrowed for jumping flag -m_jumpVelocity = 0f; + m_jumpVelocity = 0f; m_animTickFall = Environment.TickCount; return "LAND"; } @@ -283,10 +297,7 @@ m_jumpVelocity = 0f; { //Console.WriteLine("JD {0}", jumptime); //## // jump down - vj = actor.Velocity; - vj.Z = 0f; -m_jumpVelocity = 0f; -// #@ actor.Velocity = vj; + m_jumpVelocity = 0f; return "JUMP"; } else if (jumptime > PREJUMP_DELAY) @@ -294,11 +305,7 @@ m_jumpVelocity = 0f; //Console.WriteLine("JU {0}", jumptime); //## // jump up m_jumping = true; - vj.Z = 10f; -m_jumpVelocity = 10f; - vj.X = actor.Velocity.X; - vj.Y = actor.Velocity.Y; -// #@ actor.Velocity = vj; + m_jumpVelocity = 10f; return "JUMP"; } } @@ -309,29 +316,37 @@ m_jumpVelocity = 10f; if (m_movementAnimation == "FALLDOWN") { + m_falling = false; m_animTickFall = Environment.TickCount; - // TODO: SOFT_LAND support - return "LAND"; + float fallHeight = m_fallHeight - actor.Position.Z; +//Console.WriteLine("Hit from {0}", fallHeight); //## + if (fallHeight > 15.0f) // add for falling + return "STANDUP"; + else if (fallHeight > 8.0f) // add for falling + return "SOFT_LAND"; // add for falling + else // add for falling + return "LAND"; // add for falling } - else if (m_movementAnimation == "LAND") - { // rm jumping float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f; - int landElapsed = Environment.TickCount - m_animTickFall; // add for jumping // rm jumping if ((m_animTickFall != 0) && (landElapsed <= FALL_DELAY)) -/* Try change ## - if ((m_animTickFall != 0) && (landElapsed <= 500)) // add for jumping - return "LAND"; - */ - // NB if this is set too long a weird anim reset from some place prevents STAND from being sent to client - if ((m_animTickFall != 0) && (landElapsed <= 300)) // add for jumping +// rm for landing return "LAND"; + else if ((m_movementAnimation == "LAND") || (m_movementAnimation == "SOFT_LAND") || (m_movementAnimation == "STANDUP")) + { + int landElapsed = Environment.TickCount - m_animTickFall; // add for jumping + int limit = 1000; // add for jumping + if(m_movementAnimation == "LAND") limit = 350; // add for jumping + // NB if the above is set too long a weird anim reset from some place prevents STAND from being sent to client + + if ((m_animTickFall != 0) && (landElapsed <= limit)) // add for jumping { -//Console.WriteLine("LAND"); //## - return "LAND"; +//Console.WriteLine("Lelapse {0}", m_movementAnimation); //## + return m_movementAnimation; } else { -//Console.WriteLine("STAND"); //## +//Console.WriteLine("end/STAND"); //## + m_fallHeight = actor.Position.Z; // save latest flying height return "STAND"; } } @@ -369,6 +384,8 @@ m_jumpVelocity = 10f; // next section moved outside paren. and realigned for jumping if (move.X != 0f || move.Y != 0f) { + m_fallHeight = actor.Position.Z; // save latest flying height + m_falling = false; // Add for falling // Walking / crouchwalking / running if (move.Z < 0f) return "CROUCHWALK"; @@ -380,6 +397,7 @@ m_jumpVelocity = 10f; // rm for jumping else else if (!m_jumping) // add for jumping { + m_falling = false; // Add for falling // Not walking if (move.Z < 0f) return "CROUCH"; @@ -389,6 +407,7 @@ m_jumpVelocity = 10f; // end section realign for jumping #endregion Ground Movement + m_falling = false; // Add for falling return m_movementAnimation; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 2ed00a0..faf6354 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2568,9 +2568,11 @@ namespace OpenSim.Region.Framework.Scenes if (actor != null) { - if (actor.Flying) +// rm falling if (actor.Flying) + if ((actor.Flying) || Animator.m_falling) // add for falling lateral speed { - direc *= 4.0f; +// rm speed mod direc *= 4.0f; + direc *= 5.2f; // for speed mod //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); //bool colliding = (m_physicsActor.IsColliding==true); //if (controlland) diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index 0c79aa6..ae63cfa 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -269,7 +269,10 @@ namespace OpenSim.Region.Physics.OdePlugin /// public override bool IsColliding { - get { return m_iscolliding; } +//#@ get { return m_iscolliding; } + get { //## +//Console.WriteLine(">>>>>>>>>>>> IC get = {0}", m_iscolliding); //## + return m_iscolliding; } //## set { int i; @@ -307,6 +310,7 @@ namespace OpenSim.Region.Physics.OdePlugin { m_iscolliding = true; } +// ## Console.WriteLine("IC SET = {0} t{1} f{2} i {3}", value, truecount, falsecount, m_iscolliding); if (m_wascolliding != m_iscolliding) { //base.SendCollisionUpdate(new CollisionEventUpdate()); @@ -589,7 +593,7 @@ namespace OpenSim.Region.Physics.OdePlugin Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); _parent_scene.geom_name_map[Shell] = m_name; _parent_scene.actor_name_map[Shell] = (PhysicsActor)this; -//Console.WriteLine("**** Create {2} Dicts: actor={0} name={1}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name); +Console.WriteLine("**** Create {2} Dicts: actor={0} name={1} height={3} rad={4}", _parent_scene.actor_name_map.Count, _parent_scene.geom_name_map.Count, m_name, CAPSULE_LENGTH, CAPSULE_RADIUS); d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); d.GeomSetCollideBits(Shell, (int)m_collisionFlags); @@ -857,7 +861,9 @@ namespace OpenSim.Region.Physics.OdePlugin { m_pidControllerActive = false; force *= 100f; - doForce(force); +//Console.WriteLine("DF 1"); // ## + if (!force.ApproxEquals(Vector3.Zero, 0.01f)) + doForce(force); // If uncommented, things get pushed off world // // m_log.Debug("Push!"); @@ -896,7 +902,8 @@ namespace OpenSim.Region.Physics.OdePlugin d.BodyAddForce(Body, force.X, force.Y, force.Z); //d.BodySetRotation(Body, ref m_StandUpRotation); //standupStraight(); - + d.Vector3 vel = d.BodyGetLinearVel(Body); //## +//Console.WriteLine("AvVel <{0},{1},{2}>", vel.X, vel.Y, vel.Z); //## } } @@ -1103,12 +1110,14 @@ namespace OpenSim.Region.Physics.OdePlugin } if (vec.IsFinite()) { - if (!vec.ApproxEquals(Vector3.Zero, 0.01f)) + if (!vec.ApproxEquals(Vector3.Zero, 0.02f)) // 0.01 allows 0.002 !! { +//Console.WriteLine("DF 2"); // ## + doForce(vec); if (!_zeroFlag) { - AlignAvatarTiltWithCurrentDirectionOfMovement(vec); +// AlignAvatarTiltWithCurrentDirectionOfMovement(vec); } } } diff --git a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs index ab084fd..86f9893 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/OdePlugin.cs @@ -713,7 +713,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Test if we're colliding a geom with a space. // If so we have to drill down into the space recursively - +//Console.WriteLine("near -----------"); //## if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2)) { if (g1 == IntPtr.Zero || g2 == IntPtr.Zero) @@ -844,11 +844,21 @@ namespace OpenSim.Region.Physics.OdePlugin // Testing if the collision is at the feet of the avatar //m_log.DebugFormat("[PHYSICS]: {0} - {1} - {2} - {3}", curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); - if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)) - p2.IsColliding = true; - } +//#@ if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)) +//#@ p2.IsColliding = true; + if ((p2.Position.Z - curContact.pos.Z) > (p2.Size.Z * 0.6f)){ //## +//Console.WriteLine("AvColl 1 {0} - {1} - {2} - {3}", //## +// curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); //## + p2.IsColliding = true; //## + }else{ +//Console.WriteLine("AvColl 2 {0} - {1} - {2} - {3}", //## +// curContact.pos.Z, p2.Position.Z, (p2.Position.Z - curContact.pos.Z), (p2.Size.Z * 0.6f)); //## + + } //## + } else { +//Console.WriteLine("AvColl 3 {0}", p2.PhysicsActorType); //## p2.IsColliding = true; } -- cgit v1.1 From 8ab4b277c1e1d5470a0322ec49dde665f3cceadc Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 7 Sep 2010 17:12:28 +0200 Subject: Fix some issues with unlinking --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 109 +++++++++++++------------- 1 file changed, 53 insertions(+), 56 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 905c683..a39f27a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1678,28 +1678,23 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup group = part.ParentGroup; if (!affectedGroups.Contains(group)) + { + group.areUpdatesSuspended = true; affectedGroups.Add(group); + } } } } if (childParts.Count > 0) { - try + foreach (SceneObjectPart child in childParts) { - childParts[0].ParentGroup.areUpdatesSuspended = true; - foreach (SceneObjectPart child in childParts) - { - // Unlink all child parts from their groups - // - child.ParentGroup.DelinkFromGroup(child, true); - child.ParentGroup.HasGroupChanged = true; - child.ParentGroup.ScheduleGroupForFullUpdate(); - } - } - finally - { - childParts[0].ParentGroup.areUpdatesSuspended = false; + // Unlink all child parts from their groups + // + child.ParentGroup.DelinkFromGroup(child, true); + child.ParentGroup.HasGroupChanged = true; + child.ParentGroup.ScheduleGroupForFullUpdate(); } } @@ -1710,9 +1705,10 @@ namespace OpenSim.Region.Framework.Scenes // However, editing linked parts and unlinking may be different // SceneObjectGroup group = root.ParentGroup; + group.areUpdatesSuspended = true; List newSet = null; - int numChildren = -1; + int numChildren; lock (group.Children) { @@ -1720,63 +1716,63 @@ namespace OpenSim.Region.Framework.Scenes numChildren = group.PrimCount; } + if (numChildren == 1) + break; + // If there are prims left in a link set, but the root is // slated for unlink, we need to do this + // Unlink the remaining set // - if (numChildren != 1) - { - // Unlink the remaining set - // - bool sendEventsToRemainder = true; - if (numChildren > 1) - sendEventsToRemainder = false; + bool sendEventsToRemainder = true; + if (numChildren > 1) + sendEventsToRemainder = false; - if (newSet.Count > 0) + foreach (SceneObjectPart p in newSet) + { + if (p != group.RootPart) { - try + group.DelinkFromGroup(p, sendEventsToRemainder); + if (numChildren > 2) { - newSet[0].ParentGroup.areUpdatesSuspended = true; - foreach (SceneObjectPart p in newSet) - { - if (p != group.RootPart) - group.DelinkFromGroup(p, sendEventsToRemainder); - } + p.ParentGroup.areUpdatesSuspended = true; } - finally + else { - newSet[0].ParentGroup.areUpdatesSuspended = false; + p.ParentGroup.HasGroupChanged = true; + p.ParentGroup.ScheduleGroupForFullUpdate(); } } + } + + // If there is more than one prim remaining, we + // need to re-link + // + if (numChildren > 2) + { + // Remove old root + // + if (newSet.Contains(root)) + newSet.Remove(root); - // If there is more than one prim remaining, we - // need to re-link + // Preserve link ordering // - if (numChildren > 2) + newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) { - // Remove old root - // - if (newSet.Contains(root)) - newSet.Remove(root); - - // Preserve link ordering - // - newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b) - { - return a.LinkNum.CompareTo(b.LinkNum); - }); + return a.LinkNum.CompareTo(b.LinkNum); + }); - // Determine new root - // - SceneObjectPart newRoot = newSet[0]; - newSet.RemoveAt(0); + // Determine new root + // + SceneObjectPart newRoot = newSet[0]; + newSet.RemoveAt(0); - foreach (SceneObjectPart newChild in newSet) - newChild.UpdateFlag = 0; + foreach (SceneObjectPart newChild in newSet) + newChild.UpdateFlag = 0; - LinkObjects(newRoot, newSet); - if (!affectedGroups.Contains(newRoot.ParentGroup)) - affectedGroups.Add(newRoot.ParentGroup); - } + newRoot.ParentGroup.areUpdatesSuspended = true; + LinkObjects(newRoot, newSet); + if (!affectedGroups.Contains(newRoot.ParentGroup)) + affectedGroups.Add(newRoot.ParentGroup); } } @@ -1786,6 +1782,7 @@ namespace OpenSim.Region.Framework.Scenes { g.TriggerScriptChangedEvent(Changed.LINK); g.HasGroupChanged = true; // Persist + g.areUpdatesSuspended = false; g.ScheduleGroupForFullUpdate(); } } -- cgit v1.1 From 50cc22c9e68aa62a529bf62553dc2f0739f3d0a2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 7 Sep 2010 20:19:52 +0100 Subject: Fix Simian regression --- .../SimianGrid/SimianAssetServiceConnector.cs | 37 +++++++++-------- .../SimianAuthenticationServiceConnector.cs | 35 ++++++++-------- .../SimianGrid/SimianAvatarServiceConnector.cs | 35 ++++++++-------- .../SimianGrid/SimianGridServiceConnector.cs | 35 ++++++++-------- .../SimianGrid/SimianInventoryServiceConnector.cs | 47 ++++++++++++---------- .../SimianGrid/SimianPresenceServiceConnector.cs | 35 ++++++++-------- .../SimianUserAccountServiceConnector.cs | 35 ++++++++-------- 7 files changed, 140 insertions(+), 119 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs index 99e6983..6d5b30e 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAssetServiceConnector.cs @@ -81,7 +81,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianAssetServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -91,25 +91,28 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("AssetServices", ""); if (name == Name) - { - IConfig gridConfig = source.Configs["AssetService"]; - if (gridConfig != null) - { - string serviceUrl = gridConfig.GetString("AssetServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - } - } + CommonInit(source); + } + } - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN ASSET CONNECTOR]: No AssetServerURI specified, disabling connector"); - else - m_Enabled = true; + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["AssetService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("AssetServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) + { + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN ASSET CONNECTOR]: No AssetServerURI specified, disabling connector"); + else + m_Enabled = true; } #region IAssetService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs index 68f73ee..51a09f8 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAuthenticationServiceConnector.cs @@ -69,7 +69,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianAuthenticationServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -79,24 +79,27 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("AuthenticationServices", ""); if (name == Name) - { - IConfig gridConfig = source.Configs["AuthenticationService"]; - if (gridConfig != null) - { - string serviceUrl = gridConfig.GetString("AuthenticationServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - m_Enabled = true; - } - } + CommonInit(source); + } + } - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN AUTH CONNECTOR]: No AuthenticationServerURI specified, disabling connector"); + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["AuthenticationService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("AuthenticationServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) + { + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; + m_Enabled = true; } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN AUTH CONNECTOR]: No AuthenticationServerURI specified, disabling connector"); } public string Authenticate(UUID principalID, string password, int lifetime) diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs index 7e56bd1..3505c64 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianAvatarServiceConnector.cs @@ -74,7 +74,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianAvatarServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -84,24 +84,27 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("AvatarServices", ""); if (name == Name) - { - IConfig gridConfig = source.Configs["AvatarService"]; - if (gridConfig != null) - { - string serviceUrl = gridConfig.GetString("AvatarServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - m_Enabled = true; - } - } + CommonInit(source); + } + } - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN AVATAR CONNECTOR]: No AvatarServerURI specified, disabling connector"); + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["AvatarService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("AvatarServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) + { + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; + m_Enabled = true; } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN AVATAR CONNECTOR]: No AvatarServerURI specified, disabling connector"); } #region IAvatarService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs index 4fceef6..c2c7168 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianGridServiceConnector.cs @@ -98,7 +98,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianGridServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -108,24 +108,27 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("GridServices", ""); if (name == Name) - { - IConfig gridConfig = source.Configs["GridService"]; - if (gridConfig != null) - { - string serviceUrl = gridConfig.GetString("GridServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - m_Enabled = true; - } - } + CommonInit(source); + } + } - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN GRID CONNECTOR]: No GridServerURI specified, disabling connector"); + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["GridService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("GridServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) + { + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; + m_Enabled = true; } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN GRID CONNECTOR]: No GridServerURI specified, disabling connector"); } #region IGridService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs index eb118ae..470eccd 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianInventoryServiceConnector.cs @@ -88,7 +88,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianInventoryServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -98,36 +98,39 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("InventoryServices", ""); if (name == Name) + CommonInit(source); + } + } + + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["InventoryService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("InventoryServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) { - IConfig gridConfig = source.Configs["InventoryService"]; + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; + + gridConfig = source.Configs["UserAccountService"]; if (gridConfig != null) { - string serviceUrl = gridConfig.GetString("InventoryServerURI"); + serviceUrl = gridConfig.GetString("UserAccountServerURI"); if (!String.IsNullOrEmpty(serviceUrl)) { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - - gridConfig = source.Configs["UserAccountService"]; - if (gridConfig != null) - { - serviceUrl = gridConfig.GetString("UserAccountServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - m_userServerUrl = serviceUrl; - m_Enabled = true; - } - } + m_userServerUrl = serviceUrl; + m_Enabled = true; } } - - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No InventoryServerURI specified, disabling connector"); - else if (String.IsNullOrEmpty(m_userServerUrl)) - m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No UserAccountServerURI specified, disabling connector"); } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No InventoryServerURI specified, disabling connector"); + else if (String.IsNullOrEmpty(m_userServerUrl)) + m_log.Info("[SIMIAN INVENTORY CONNECTOR]: No UserAccountServerURI specified, disabling connector"); } /// diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs index 074c80f..077be3c 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianPresenceServiceConnector.cs @@ -99,7 +99,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianPresenceServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -109,24 +109,27 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("PresenceServices", ""); if (name == Name) + CommonInit(source); + } + } + + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["PresenceService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("PresenceServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) { - IConfig gridConfig = source.Configs["PresenceService"]; - if (gridConfig != null) - { - string serviceUrl = gridConfig.GetString("PresenceServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - m_Enabled = true; - } - } - - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN PRESENCE CONNECTOR]: No PresenceServerURI specified, disabling connector"); + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; + m_Enabled = true; } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN PRESENCE CONNECTOR]: No PresenceServerURI specified, disabling connector"); } #region IPresenceService diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index deb8695..694aa72 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -73,7 +73,7 @@ namespace OpenSim.Services.Connectors.SimianGrid public SimianUserAccountServiceConnector(IConfigSource source) { - Initialise(source); + CommonInit(source); } public void Initialise(IConfigSource source) @@ -83,24 +83,27 @@ namespace OpenSim.Services.Connectors.SimianGrid { string name = moduleConfig.GetString("UserAccountServices", ""); if (name == Name) - { - IConfig gridConfig = source.Configs["UserAccountService"]; - if (gridConfig != null) - { - string serviceUrl = gridConfig.GetString("UserAccountServerURI"); - if (!String.IsNullOrEmpty(serviceUrl)) - { - if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) - serviceUrl = serviceUrl + '/'; - m_serverUrl = serviceUrl; - m_Enabled = true; - } - } + CommonInit(source); + } + } - if (String.IsNullOrEmpty(m_serverUrl)) - m_log.Info("[SIMIAN ACCOUNT CONNECTOR]: No UserAccountServerURI specified, disabling connector"); + private void CommonInit(IConfigSource source) + { + IConfig gridConfig = source.Configs["UserAccountService"]; + if (gridConfig != null) + { + string serviceUrl = gridConfig.GetString("UserAccountServerURI"); + if (!String.IsNullOrEmpty(serviceUrl)) + { + if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) + serviceUrl = serviceUrl + '/'; + m_serverUrl = serviceUrl; + m_Enabled = true; } } + + if (String.IsNullOrEmpty(m_serverUrl)) + m_log.Info("[SIMIAN ACCOUNT CONNECTOR]: No UserAccountServerURI specified, disabling connector"); } public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) -- cgit v1.1 From 7a1b1dd419d458cbf46ecdf48872497186e67355 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Wed, 8 Sep 2010 00:49:32 +0200 Subject: Make AddRestoredSceneObject reset the IsDeleted flag so we can take an object out of the scene and then put it back in. --- OpenSim/Region/Framework/Scenes/Scene.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 6b71426..be342ab 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2003,7 +2003,10 @@ namespace OpenSim.Region.Framework.Scenes public bool AddRestoredSceneObject( SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates) { - return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); + bool result = m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates); + if (result) + sceneObject.IsDeleted = false; + return result; } /// -- cgit v1.1 From 5e5260ad1b677f5ee85e065e0011ceb71d1c299a Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 11 Sep 2010 20:22:10 +0100 Subject: Prevent child agents from being blacklisted in the kill record. --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 3dea40c..8a96389 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -1529,10 +1529,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP kill.Header.Reliable = true; kill.Header.Zerocoded = true; - lock (m_entityUpdates.SyncRoot) + if (m_scene.GetScenePresence(localID) == null) { - m_killRecord.Add(localID); - OutPacket(kill, ThrottleOutPacketType.State); + lock (m_entityUpdates.SyncRoot) + { + m_killRecord.Add(localID); + OutPacket(kill, ThrottleOutPacketType.State); + } } } -- cgit v1.1 From 5e1aab92f588e776bb6ff6c532c0099e87908c4f Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 13 Sep 2010 23:12:48 +0100 Subject: Make the inimaster option default to OpenSimDefaults.ini. --- OpenSim/Region/Application/ConfigurationLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index e2e0640..31ce500 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -83,7 +83,7 @@ namespace OpenSim List sources = new List(); string masterFileName = - startupConfig.GetString("inimaster", String.Empty); + startupConfig.GetString("inimaster", "OpenSimDefaults.ini"); if (IsUri(masterFileName)) { -- cgit v1.1 From 8e51ca3a7ba51ae1b38ba66ae24a958ccb405a21 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 13 Sep 2010 23:17:42 +0100 Subject: Output an error and quit if the master file is missing. Also rename OpenSim.ini.example to bin/OpenSimDefaults.ini.example --- OpenSim/Region/Application/ConfigurationLoader.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index 31ce500..9d6fef7 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -85,6 +85,9 @@ namespace OpenSim string masterFileName = startupConfig.GetString("inimaster", "OpenSimDefaults.ini"); + if (masterFileName == "none") + masterFileName = String.Empty; + if (IsUri(masterFileName)) { if (!sources.Contains(masterFileName)) @@ -95,10 +98,19 @@ namespace OpenSim string masterFilePath = Path.GetFullPath( Path.Combine(Util.configDir(), masterFileName)); - if (masterFileName != String.Empty && - File.Exists(masterFilePath) && - (!sources.Contains(masterFilePath))) - sources.Add(masterFilePath); + if (masterFileName != String.Empty) + { + if (File.Exists(masterFilePath) + { + if (!sources.Contains(masterFilePath)) + sources.Add(masterFilePath); + } + else + { + m_log.ErrorFormat("Master ini file {0} not found", masterFilePath); + Environment.Exit(1); + } + } } -- cgit v1.1 From 656e64b3ed4cf294b371739b315d7f603421788b Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 13 Sep 2010 23:22:25 +0100 Subject: Change the help message to point to copying OpenSimDefaults.ini.example. Provide a mostly empty OpenSim.ini.example --- OpenSim/Region/Application/ConfigurationLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index 9d6fef7..b76e85d 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -172,7 +172,7 @@ namespace OpenSim if (sources.Count == 0) { m_log.FatalFormat("[CONFIG]: Could not load any configuration"); - m_log.FatalFormat("[CONFIG]: Did you copy the OpenSim.ini.example file to OpenSim.ini?"); + m_log.FatalFormat("[CONFIG]: Did you copy the OpenSimDefaults.ini.example file to OpenSimDefaults.ini?"); Environment.Exit(1); } -- cgit v1.1 From ec305a48252b01e35a3ef4c2908fd229ccc7077d Mon Sep 17 00:00:00 2001 From: meta7 Date: Mon, 13 Sep 2010 17:43:45 -0700 Subject: LSL compatibility: Don't throw an exception if an invalid key is passed to llInstantMessage, instead shout about it and apply the usual delay. This now matches SL. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a5b3cd0..e299f96 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3249,10 +3249,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID result; if (!UUID.TryParse(user, out result)) { - if (!m_debuggerSafe) - { - throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user)); - } + ShoutError("An invalid key was passed to llInstantMessage"); + ScriptSleep(2000); return; } -- cgit v1.1 From d299f8b55cb0e3848dbcbb941a5789d52459bc44 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 14 Sep 2010 19:41:53 +0200 Subject: Fix a small left over buglet and also add checking of the physics actor position on backup. This way, ant object that has been moved will be checked for ghost prims as soon as it is persisted. --- OpenSim/Region/Application/ConfigurationLoader.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Application/ConfigurationLoader.cs b/OpenSim/Region/Application/ConfigurationLoader.cs index b76e85d..6e3d6af 100644 --- a/OpenSim/Region/Application/ConfigurationLoader.cs +++ b/OpenSim/Region/Application/ConfigurationLoader.cs @@ -100,7 +100,7 @@ namespace OpenSim if (masterFileName != String.Empty) { - if (File.Exists(masterFilePath) + if (File.Exists(masterFilePath)) { if (!sources.Contains(masterFilePath)) sources.Add(masterFilePath); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a952508..37630e0 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1786,6 +1786,16 @@ namespace OpenSim.Region.Framework.Scenes // don't backup while it's selected or you're asking for changes mid stream. if (isTimeToPersist() || forcedBackup) { + if (m_rootPart.PhysActor != null && + (!m_rootPart.PhysActor.IsPhysical)) + { + if (m_rootPart.PhysActor.Position != m_rootPart.GroupPosition) + { + m_rootPart.PhysActor.Position = m_rootPart.GroupPosition; + m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; + m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + } + } // m_log.DebugFormat( // "[SCENE]: Storing {0}, {1} in {2}", // Name, UUID, m_scene.RegionInfo.RegionName); -- cgit v1.1 From cc290abf7a2bd651205e8978a095cb83ffeddcf7 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 14 Sep 2010 22:13:44 +0200 Subject: Adjust the code for ghost prim removal to new information from Kitto --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 37630e0..e933e77 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1789,11 +1789,15 @@ namespace OpenSim.Region.Framework.Scenes if (m_rootPart.PhysActor != null && (!m_rootPart.PhysActor.IsPhysical)) { + // Possible ghost prim if (m_rootPart.PhysActor.Position != m_rootPart.GroupPosition) { - m_rootPart.PhysActor.Position = m_rootPart.GroupPosition; - m_rootPart.PhysActor.Orientation = m_rootPart.RotationOffset; - m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); + foreach (SceneObjectPart part in Children.Values) + { + // Re-set physics actor positions and + // orientations + part.GroupPosition = m_rootPart.GroupPosition; + } } } // m_log.DebugFormat( -- cgit v1.1 From 2f41bc4ca738cd27730639c8cd49a154404c6a82 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Sep 2010 22:14:08 +0100 Subject: Fix merge issues --- OpenSim/Region/Framework/Scenes/Scene.cs | 3 --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index abec699..12c7fea 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1348,15 +1348,12 @@ namespace OpenSim.Region.Framework.Scenes if (m_frame % m_update_presences == 0) m_sceneGraph.UpdatePresences(); -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/Scene.cs // Update SceneObjectGroups that have scheduled themselves for updates // Objects queue their updates onto all scene presences if (m_frame % m_update_objects == 0) m_sceneGraph.UpdateObjectGroups(); -======= // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) ->>>>>>> master:OpenSim/Region/Framework/Scenes/Scene.cs if (m_frame % m_update_coarse_locations == 0) { List coarseLocations; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index caf376b..ed92d86 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4330,8 +4330,8 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju } m_log.InfoFormat( - "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2} ({3})", - p, itemID, assetID, asset); + "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {3}", + p, itemID, asset); } catch (Exception e) { -- cgit v1.1 From e27f59cf422e4afef1b76af29d49f2c2770e3281 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Sep 2010 22:15:16 +0100 Subject: reorder some code to avoid merge issues in the future --- OpenSim/Region/Framework/Scenes/Scene.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 12c7fea..ac2246c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1343,16 +1343,16 @@ namespace OpenSim.Region.Framework.Scenes // Check if any objects have reached their targets CheckAtTargets(); - // Run through all ScenePresences looking for updates - // Presence updates and queued object updates for each presence are sent to clients - if (m_frame % m_update_presences == 0) - m_sceneGraph.UpdatePresences(); - // Update SceneObjectGroups that have scheduled themselves for updates // Objects queue their updates onto all scene presences if (m_frame % m_update_objects == 0) m_sceneGraph.UpdateObjectGroups(); + // Run through all ScenePresences looking for updates + // Presence updates and queued object updates for each presence are sent to clients + if (m_frame % m_update_presences == 0) + m_sceneGraph.UpdatePresences(); + // Coarse locations relate to positions of green dots on the mini-map (on a SecondLife client) if (m_frame % m_update_coarse_locations == 0) { -- cgit v1.1 From 7f7bbbb84a42d7fd984b637eaf7f1ce115d5fe19 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 14 Sep 2010 23:05:42 +0100 Subject: Fix the above --- OpenSim/Services/Connectors/Simulation/EstateDataService.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Simulation/EstateDataService.cs b/OpenSim/Services/Connectors/Simulation/EstateDataService.cs index 2eedebb..8a8b46d 100644 --- a/OpenSim/Services/Connectors/Simulation/EstateDataService.cs +++ b/OpenSim/Services/Connectors/Simulation/EstateDataService.cs @@ -60,9 +60,8 @@ namespace OpenSim.Services.Connectors if (dbConfig != null) { dllName = dbConfig.GetString("StorageProvider", String.Empty); - connString = dbConfig.GetString("EstateConnectionString", String.Empty); - if (String.IsNullOrEmpty(connString)) - connString = dbConfig.GetString("ConnectionString", String.Empty); + connString = dbConfig.GetString("ConnectionString", String.Empty); + connString = dbConfig.GetString("EstateConnectionString", connString); } // Try reading the [EstateDataStore] section, if it exists @@ -70,7 +69,7 @@ namespace OpenSim.Services.Connectors if (estConfig != null) { dllName = estConfig.GetString("StorageProvider", dllName); - connString = dbConfig.GetString("ConnectionString", connString); + connString = estConfig.GetString("ConnectionString", connString); } // We tried, but this doesn't exist. We can't proceed -- cgit v1.1 From 1f74f013b23a8bbcc94d79aa57d35e1929b662d6 Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 15 Sep 2010 07:59:28 -0700 Subject: Don't fart when deserializing a prim with no ParentGroup set yet --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 2de439b..a9a5c8a 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -132,7 +132,11 @@ namespace OpenSim.Region.Framework.Scenes } HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; + if (m_part.ParentGroup != null) + { + m_part.ParentGroup.HasGroupChanged = true; + } + IList items = new List(Items.Values); Items.Clear(); -- cgit v1.1 From 77eb8ade8c030fd174bc24306e8c4adfd415b769 Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 15 Sep 2010 08:08:29 -0700 Subject: Don't throw an exception if the authorizationservice is missing a serviceuri config entry. Not every authorization service will need a URI. --- .../Services/Connectors/Authorization/AuthorizationServiceConnector.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs index 4eb4bd2..8ae12ad 100644 --- a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs @@ -77,7 +77,6 @@ namespace OpenSim.Services.Connectors if (serviceURI == String.Empty) { m_log.Error("[AUTHORIZATION CONNECTOR]: No Server URI named in section AuthorizationService"); - throw new Exception("Authorization connector init error"); } m_ServerURI = serviceURI; -- cgit v1.1 From 571693d7b6d9d7e138dbaf1e4dd958e453b8bd32 Mon Sep 17 00:00:00 2001 From: meta7 Date: Wed, 15 Sep 2010 08:16:38 -0700 Subject: Revert last commit --- .../Services/Connectors/Authorization/AuthorizationServiceConnector.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs index 8ae12ad..4eb4bd2 100644 --- a/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Authorization/AuthorizationServiceConnector.cs @@ -77,6 +77,7 @@ namespace OpenSim.Services.Connectors if (serviceURI == String.Empty) { m_log.Error("[AUTHORIZATION CONNECTOR]: No Server URI named in section AuthorizationService"); + throw new Exception("Authorization connector init error"); } m_ServerURI = serviceURI; -- cgit v1.1 From ec89dc99b705f86fb4ed2f984125c2196d8c6288 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Sep 2010 18:58:25 +0200 Subject: Some small bug fixes --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3411d18..142f5d8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Diagnostics; using System.Linq; using System.Threading; using System.Xml; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ed92d86..8da9bdc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4330,7 +4330,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju } m_log.InfoFormat( - "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {3}", + "[ATTACHMENT]: Rezzed attachment in point {0} from item {1} and asset {2}", p, itemID, asset); } catch (Exception e) -- cgit v1.1 From d50a072336f584f8e484160ba50042020f35d112 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Sep 2010 20:21:30 +0200 Subject: Suppress the strange "Result not Dictionary" messages that happen when a region queries for a nonexistent presence. --- OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs index 9f86078..f1c99ce 100644 --- a/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs +++ b/OpenSim/Services/Connectors/Presence/PresenceServiceConnector.cs @@ -302,6 +302,9 @@ namespace OpenSim.Services.Connectors } else { + if (replyData["result"].ToString() == "null") + return null; + m_log.DebugFormat("[PRESENCE CONNECTOR]: Invalid reply (result not dictionary) received from presence server when querying for sessionID {0}", sessionID.ToString()); } } -- cgit v1.1 From 512ded6eb57019aed8aaa73d64b62d29450023cf Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Sep 2010 21:07:09 +0200 Subject: Catch a nullref --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 5378930..7c95658 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -334,7 +334,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (m_scene.InventoryService != null) item = m_scene.InventoryService.GetItem(item); - presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); + if (presence.Appearance != null) + presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/); } return att.UUID; -- cgit v1.1 From a0c87b5af6bba104fe50de3006b5dd515a8eb833 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Sep 2010 23:12:32 +0200 Subject: JustinCC is evil. f7b28dd3 broke script persistence. This fixes it. --- .../Framework/Interfaces/IEntityInventory.cs | 9 +++++++ .../Region/Framework/Scenes/SceneObjectGroup.cs | 1 + OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 3 ++- .../Framework/Scenes/SceneObjectPartInventory.cs | 28 ++++++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 6289f7a..59ce090 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -58,6 +58,15 @@ namespace OpenSim.Region.Framework.Interfaces void ResetInventoryIDs(); /// + /// Reset parent object UUID for all the items in the prim's inventory. + /// + /// + /// If this method is called and there are inventory items, then we regard the inventory as having changed. + /// + /// Link number for the part + void ResetObjectID(); + + /// /// Change every item in this inventory to a new owner. /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 142f5d8..ab9cbd7 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -696,6 +696,7 @@ namespace OpenSim.Region.Framework.Scenes if (node.Attributes["UUID"] != null) { UUID itemid = new UUID(node.Attributes["UUID"].Value); + m_log.DebugFormat("[SCRIPT STATE]: Adding state for oldID {0}", itemid); m_savedScriptState.Add(itemid, node.InnerXml); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5c4a2a3..40112c9 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -514,7 +514,7 @@ namespace OpenSim.Region.Framework.Scenes // This is necessary so that TaskInventoryItem parent ids correctly reference the new uuid of this part if (Inventory != null) - Inventory.ResetInventoryIDs(); + Inventory.ResetObjectID(); } } @@ -2800,6 +2800,7 @@ namespace OpenSim.Region.Framework.Scenes UUID = UUID.Random(); LinkNum = linkNum; LocalId = 0; + Inventory.ResetInventoryIDs(); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index a9a5c8a..b205503 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -148,6 +148,34 @@ namespace OpenSim.Region.Framework.Scenes m_items.LockItemsForWrite(false); } + public void ResetObjectID() + { + m_items.LockItemsForWrite(true); + + if (Items.Count == 0) + { + m_items.LockItemsForWrite(false); + return; + } + + HasInventoryChanged = true; + if (m_part.ParentGroup != null) + { + m_part.ParentGroup.HasGroupChanged = true; + } + + IList items = new List(Items.Values); + Items.Clear(); + + foreach (TaskInventoryItem item in items) + { + item.ParentPartID = m_part.UUID; + item.ParentID = m_part.UUID; + Items.Add(item.ItemID, item); + } + m_items.LockItemsForWrite(false); + } + /// /// Change every item in this inventory to a new owner. /// -- cgit v1.1 From 1e4e978f7ff798292211c58ef07eee37cd76ef8e Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Sep 2010 23:26:53 +0200 Subject: Removing debug --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index ab9cbd7..142f5d8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -696,7 +696,6 @@ namespace OpenSim.Region.Framework.Scenes if (node.Attributes["UUID"] != null) { UUID itemid = new UUID(node.Attributes["UUID"].Value); - m_log.DebugFormat("[SCRIPT STATE]: Adding state for oldID {0}", itemid); m_savedScriptState.Add(itemid, node.InnerXml); } } -- cgit v1.1 From 251f2444d049ed525ef41c4c4792ec446c53b973 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 17 Sep 2010 01:50:48 +0200 Subject: Revert "* Changed 11 calls for session info to the more optimized API method" This reverts commit 5dc9ea2f2487804d788b4b80d40d91bd792de4c2. Also makes online indicators and IM more robust --- .../CoreModules/Avatar/Friends/FriendsModule.cs | 103 ++++++++++++++------- .../Avatar/InstantMessage/MessageTransferModule.cs | 13 ++- .../Shared/Api/Implementation/LSL_Api.cs | 26 +++++- .../Connectors/SimianGrid/SimianProfiles.cs | 4 +- 4 files changed, 109 insertions(+), 37 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs index a49e71e..21ed9dc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsModule.cs @@ -317,7 +317,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends continue; UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID); - PresenceInfo presence = PresenceService.GetAgent(fromAgentID); + + PresenceInfo presence = null; + PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid }); + if (presences != null && presences.Length > 0) + presence = presences[0]; + if (presence != null) + im.offline = 0; im.fromAgentID = fromAgentID.Guid; im.fromAgentName = account.FirstName + " " + account.LastName; @@ -430,13 +436,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return; // The friend is not here [as root]. Let's forward. - PresenceInfo friendSession = PresenceService.GetAgent(friendID); - if (friendSession != null && friendSession.RegionID != UUID.Zero) // let's guard against sessions-gone-bad with the RegionID check + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); - m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); + PresenceInfo friendSession = null; + foreach (PresenceInfo pinfo in friendSessions) + if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad + { + friendSession = pinfo; + break; + } + + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName); + m_FriendsSimConnector.StatusNotify(region, userID, friendID, online); + } } + + // Friend is not online. Ignore. } else { @@ -477,11 +496,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends return; // The prospective friend is not here [as root]. Let's forward. - PresenceInfo friendSession = PresenceService.GetAgent(friendID); - if (friendSession != null) + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); + PresenceInfo friendSession = friendSessions[0]; + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.FriendshipOffered(region, agentID, friendID, im.message); + } } // If the prospective friend is not online, he'll get the message upon login. } @@ -508,12 +531,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends } // The friend is not here - PresenceInfo friendSession = PresenceService.GetAgent(friendID); - if (friendSession != null) + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - m_FriendsSimConnector.FriendshipApproved(region, agentID, client.Name, friendID); - client.SendAgentOnline(new UUID[] { friendID }); + PresenceInfo friendSession = friendSessions[0]; + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.FriendshipApproved(region, agentID, client.Name, friendID); + client.SendAgentOnline(new UUID[] { friendID }); + } } } @@ -532,14 +559,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (LocalFriendshipDenied(agentID, client.Name, friendID)) return; - PresenceInfo friendSession = PresenceService.GetAgent(friendID); - if (friendSession != null) + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - if (region != null) - m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID); - else - m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID); + PresenceInfo friendSession = friendSessions[0]; + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + if (region != null) + m_FriendsSimConnector.FriendshipDenied(region, agentID, client.Name, friendID); + else + m_log.WarnFormat("[FRIENDS]: Could not find region {0} in locating {1}", friendSession.RegionID, friendID); + } } } @@ -561,11 +592,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (LocalFriendshipTerminated(exfriendID)) return; - PresenceInfo friendSession = PresenceService.GetAgent(exfriendID); - if (friendSession != null) + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { exfriendID.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID); + PresenceInfo friendSession = friendSessions[0]; + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + m_FriendsSimConnector.FriendshipTerminated(region, agentID, exfriendID); + } } } @@ -604,13 +639,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends if (LocalGrantRights(requester, target, myFlags, rights)) return; - PresenceInfo friendSession = PresenceService.GetAgent(target); - if (friendSession != null) + PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() }); + if (friendSessions != null && friendSessions.Length > 0) { - GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); - // TODO: You might want to send the delta to save the lookup - // on the other end!! - m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); + PresenceInfo friendSession = friendSessions[0]; + if (friendSession != null) + { + GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); + // TODO: You might want to send the delta to save the lookup + // on the other end!! + m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights); + } } } } diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index a6894ff..2a405ac 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -497,7 +497,18 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (lookupAgent) { // Non-cached user agent lookup. - upd = PresenceService.GetAgent(toAgentID); + PresenceInfo[] presences = PresenceService.GetAgents(new string[] { toAgentID.ToString() }); + if (presences != null && presences.Length > 0) + { + foreach (PresenceInfo p in presences) + { + if (p.RegionID != UUID.Zero) + { + upd = p; + break; + } + } + } if (upd != null) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e299f96..0dd1787 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4296,7 +4296,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } - pinfo = World.PresenceService.GetAgent(uuid); + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + { + foreach (PresenceInfo p in pinfos) + { + if (p.RegionID != UUID.Zero) + { + pinfo = p; + } + } + } ce = new UserInfoCacheEntry(); ce.time = Util.EnvironmentTickCount(); @@ -4315,7 +4325,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) { - pinfo = World.PresenceService.GetAgent(uuid); + PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); + if (pinfos != null && pinfos.Length > 0) + { + foreach (PresenceInfo p in pinfos) + { + if (p.RegionID != UUID.Zero) + { + pinfo = p; + } + } + } + else + pinfo = null; ce.time = Util.EnvironmentTickCount(); ce.pinfo = pinfo; diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs index b7e8538..0ef4974 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianProfiles.cs @@ -291,8 +291,8 @@ namespace OpenSim.Services.Connectors.SimianGrid // Check if the user is online if (client.Scene is Scene) { - OpenSim.Services.Interfaces.PresenceInfo presence = ((Scene)client.Scene).PresenceService.GetAgent(avatarID); - if (presence != null) + OpenSim.Services.Interfaces.PresenceInfo[] presences = ((Scene)client.Scene).PresenceService.GetAgents(new string[] { avatarID.ToString() }); + if (presences != null && presences.Length > 0) flags |= ProfileFlags.Online; } -- cgit v1.1 From 87a1e00f058f737628d50732ffbe46d5d6638779 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 17 Sep 2010 04:00:00 +0200 Subject: Remove the now unused partslock --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 3bc7834..f9bfffd 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -112,7 +112,6 @@ namespace OpenSim.Region.Framework.Scenes private long m_minPersistTime = 0; private Random m_rand; private bool m_suspendUpdates; - private System.Threading.ReaderWriterLockSlim m_partsLock = new System.Threading.ReaderWriterLockSlim(); private List m_linkedAvatars = new List(); public bool areUpdatesSuspended -- cgit v1.1 From 3a760ad12bbb8fa3e48dde533744a1f2dd1c7871 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 17 Sep 2010 22:20:20 +0100 Subject: Overwrite the core version of the string parsing method with ours --- .../Shared/Api/Implementation/LSL_Api.cs | 97 +++++++++------------- 1 file changed, 37 insertions(+), 60 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index cd8353f..caa39ba 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -5949,6 +5949,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(5000); } + public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) + { + return ParseString2List(str, separators, in_spacers, false); + } + public LSL_Integer llOverMyLand(string id) { m_host.AddScriptLPS(1); @@ -8931,7 +8936,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api // garbage generation. // - private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) + public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) { return ParseString2List(src, separators, spacers, true); } @@ -8952,19 +8957,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int i, j; string d; - // All entries are initially valid - - for (int i = 0; i < mlen; i++) - active[i] = true; - - offset[mlen] = srclen; - - while (beginning < srclen) - { - - best = mlen; // as bad as it gets + m_host.AddScriptLPS(1); - // Scan for separators + /* + * Convert separator and spacer lists to C# strings. + * Also filter out null strings so we don't hang. + */ + for (i = 0; i < seplen; i ++) { + d = separray[i].ToString(); + if (d.Length > 0) { + delarray[dellen++] = d; + } + } + seplen = dellen; for (i = 0; i < spclen; i ++) { d = spcarray[i].ToString(); @@ -8999,45 +9004,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } - // This is the normal exit from the scanning loop - - if (best == mlen) - { - // no markers were found on this pass - // so we're pretty much done - if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0)) - tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning))); - break; + /* + * Output source string starting at i through start of earliest delimeter. + */ + if (keepNulls || (earliestSrc > i)) { + outarray[outlen++] = src.Substring(i, earliestSrc - i); } - // Otherwise we just add the newly delimited token - // and recalculate where the search should continue. - if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) - tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); + /* + * If no delimeter found at or after i, we're done scanning. + */ + if (earliestDel < 0) break; - if (best < seplen) - { - beginning = offset[best] + (separray[best].ToString()).Length; - } - else - { - beginning = offset[best] + (spcarray[best - seplen].ToString()).Length; - string str = spcarray[best - seplen].ToString(); - if ((keepNulls) || ((!keepNulls) && (str.Length > 0))) - tokens.Add(new LSL_String(str)); + /* + * If delimeter was a spacer, output the spacer. + */ + if (earliestDel >= seplen) { + outarray[outlen++] = earliestStr; } - } - - // This an awkward an not very intuitive boundary case. If the - // last substring is a tokenizer, then there is an implied trailing - // null list entry. Hopefully the single comparison will not be too - // arduous. Alternatively the 'break' could be replced with a return - // but that's shabby programming. - if ((beginning == srclen) && (keepNulls)) - { - if (srclen != 0) - tokens.Add(new LSL_String("")); + /* + * Look at rest of src string following delimeter. + */ + i = earliestSrc + earliestStr.Length; } /* @@ -9049,19 +9038,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } return new LSL_List(outlist); } - - public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers) - { - m_host.AddScriptLPS(1); - return this.ParseString(src, separators, spacers, false); - } - - public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) - { - m_host.AddScriptLPS(1); - return this.ParseString(src, separators, spacers, true); - } - + public LSL_Integer llGetObjectPermMask(int mask) { m_host.AddScriptLPS(1); -- cgit v1.1 From 9cf8795ecf1a2f34f803babf318d9c1f394ee18b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 19 Sep 2010 22:53:05 +0200 Subject: Fix a merge artefact that broke script state persistence in XAttachments --- OpenSim/Framework/TaskInventoryItem.cs | 8 +++----- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index df5b936..883f61a 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -120,7 +120,7 @@ namespace OpenSim.Framework private UUID _permsGranter; private int _permsMask; private int _type = 0; - private UUID _oldID; + private UUID _oldID = UUID.Zero; private bool _ownerChanged = false; @@ -227,9 +227,6 @@ namespace OpenSim.Framework get { return _oldID; } - set { - _oldID = value; - } } public UUID LastOwnerID { @@ -348,7 +345,8 @@ namespace OpenSim.Framework /// The new part ID to which this item belongs public void ResetIDs(UUID partID) { - OldItemID = ItemID; + if (_oldID == UUID.Zero) + _oldID = ItemID; ItemID = UUID.Random(); ParentPartID = partID; ParentID = partID; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f9bfffd..41b0a42 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1029,7 +1029,7 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = m_parts.GetArray(); for (int i = 0; i < parts.Length; i++) { - Dictionary pstates = parts[i].Inventory.GetScriptStates(); + Dictionary pstates = parts[i].Inventory.GetScriptStates(oldIDs); foreach (KeyValuePair kvp in pstates) states.Add(kvp.Key, kvp.Value); } -- cgit v1.1 From 7229bc4fbda804d41525356027269ca9a665b0bf Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Sep 2010 02:08:55 +0200 Subject: Refactor script create permission into the perms module --- .../World/Permissions/PermissionsModule.cs | 28 ++++++++++++++++++---- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 10 -------- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index ecfd211..e46fb1c 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -1780,10 +1780,28 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - if ((int)InventoryType.LSL == invType) - if (m_allowedScriptCreators == UserSet.Administrators && !IsAdministrator(userID)) - return false; - + SceneObjectPart part = scene.GetSceneObjectPart(objectID); + ScenePresence p = scene.GetScenePresence(userID); + + if (part == null || p == null) + return false; + + if (!IsAdministrator(userID)) + { + if (part.OwnerID != userID) + { + // Group permissions + if ((part.GroupID == UUID.Zero) || (p.ControllingClient.GetGroupPowers(part.GroupID) == 0) || ((part.GroupMask & (uint)PermissionMask.Modify) == 0)) + return false; + } else { + if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) + return false; + } + if ((int)InventoryType.LSL == invType) + if (m_allowedScriptCreators == UserSet.Administrators) + return false; + } + return true; } @@ -1980,4 +1998,4 @@ namespace OpenSim.Region.CoreModules.World.Permissions return false; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index ac82fda..18cfcbc 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1532,16 +1532,6 @@ namespace OpenSim.Region.Framework.Scenes if (part == null) return; - if (part.OwnerID != remoteClient.AgentId) - { - // Group permissions - if ((part.GroupID == UUID.Zero) || (remoteClient.GetGroupPowers(part.GroupID) == 0) || ((part.GroupMask & (uint)PermissionMask.Modify) == 0)) - return; - } else { - if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0) - return; - } - if (!Permissions.CanCreateObjectInventory( itemBase.InvType, part.UUID, remoteClient.AgentId)) return; -- cgit v1.1 From 12f9b1df8c10f25b80f7cda7cccd7e3866653f49 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Sep 2010 03:57:09 +0200 Subject: Fix a typo --- OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs index e46fb1c..289741f 100644 --- a/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs +++ b/OpenSim/Region/CoreModules/World/Permissions/PermissionsModule.cs @@ -238,7 +238,7 @@ namespace OpenSim.Region.CoreModules.World.Permissions m_scene.Permissions.OnEditNotecard += CanEditNotecard; //NOT YET IMPLEMENTED m_scene.Permissions.OnEditScript += CanEditScript; //NOT YET IMPLEMENTED - m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; //NOT IMPLEMENTED HERE + m_scene.Permissions.OnCreateObjectInventory += CanCreateObjectInventory; m_scene.Permissions.OnEditObjectInventory += CanEditObjectInventory;//MAYBE FULLY IMPLEMENTED m_scene.Permissions.OnCopyObjectInventory += CanCopyObjectInventory; //NOT YET IMPLEMENTED m_scene.Permissions.OnDeleteObjectInventory += CanDeleteObjectInventory; //NOT YET IMPLEMENTED @@ -1780,8 +1780,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions DebugPermissionInformation(MethodInfo.GetCurrentMethod().Name); if (m_bypassPermissions) return m_bypassPermissionsValue; - SceneObjectPart part = scene.GetSceneObjectPart(objectID); - ScenePresence p = scene.GetScenePresence(userID); + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); + ScenePresence p = m_scene.GetScenePresence(userID); if (part == null || p == null) return false; -- cgit v1.1 From 33bd4fe789529e339db8954b29cf49ca7f7a0268 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 24 Sep 2010 22:00:51 +0200 Subject: When clearing the addin registry, respect a custom path --- OpenSim/Framework/PluginLoader.cs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs index 819cb7b..cc80943 100644 --- a/OpenSim/Framework/PluginLoader.cs +++ b/OpenSim/Framework/PluginLoader.cs @@ -244,13 +244,22 @@ namespace OpenSim.Framework // The Mono addin manager (in Mono.Addins.dll version 0.2.0.0) // occasionally seems to corrupt its addin cache // Hence, as a temporary solution we'll remove it before each startup + + string customDir = Environment.GetEnvironmentVariable ("MONO_ADDINS_REGISTRY"); + string v0 = "addin-db-000"; + string v1 = "addin-db-001"; + if (customDir != null && customDir != String.Empty) + { + v0 = Path.Combine(customDir, v0); + v1 = Path.Combine(customDir, v1); + } try { - if (Directory.Exists("addin-db-000")) - Directory.Delete("addin-db-000", true); + if (Directory.Exists(v0)) + Directory.Delete(v0, true); - if (Directory.Exists("addin-db-001")) - Directory.Delete("addin-db-001", true); + if (Directory.Exists(v1)) + Directory.Delete(v1, true); } catch (IOException) { -- cgit v1.1 From 1c1f3080526ed3e4845b4e98488d1d0c327dabb3 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 24 Sep 2010 23:48:52 +0200 Subject: if you can't edit a prim's inventory, you don't need to see the asset ids. Prevents stealing IDs of animations, sounds and textures from prim inventories. Prevents copybot from gathering the wearable UUIDs needed for pirating things from vendors. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8aa17a1..9359aea 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -975,6 +975,10 @@ namespace OpenSim.Region.Framework.Scenes // isn't available (such as drag from prim inventory to agent inventory) InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); + bool includeAssets = false; + if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) + includeAssets = true; + m_items.LockItemsForRead(true); foreach (TaskInventoryItem item in m_items.Values) @@ -1005,7 +1009,10 @@ namespace OpenSim.Region.Framework.Scenes invString.AddNameValueLine("group_id", item.GroupID.ToString()); invString.AddSectionEnd(); - invString.AddNameValueLine("asset_id", item.AssetID.ToString()); + if (includeAssets) + invString.AddNameValueLine("asset_id", item.AssetID.ToString()); + else + invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); -- cgit v1.1 From 83b16612ce13ee89f139df8fdc78ded14cb6a69e Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 25 Sep 2010 05:57:08 +0200 Subject: Experimental locking of taint processing --- OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs | 156 +++++++++++---------- 1 file changed, 80 insertions(+), 76 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs index ae63cfa..505d455 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODECharacter.cs @@ -143,6 +143,7 @@ namespace OpenSim.Region.Physics.OdePlugin // unique UUID of this character object public UUID m_uuid; public bool bad = false; + private Object m_syncRoot = new Object(); public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, CollisionLocker dode, Vector3 size, float pid_d, float pid_p, float capsule_radius, float tensor, float density, float height_fudge_factor, float walk_divisor, float rundivisor) { @@ -1323,103 +1324,106 @@ Console.WriteLine("**** Create {2} Dicts: actor={0} name={1} height={3} ra public void ProcessTaints(float timestep) { - - if (m_tainted_isPhysical != m_isPhysical) + lock (m_syncRoot) { - if (m_tainted_isPhysical) - { - // Create avatar capsule and related ODE data - if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) - { - m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " - + (Shell!=IntPtr.Zero ? "Shell ":"") - + (Body!=IntPtr.Zero ? "Body ":"") - + (Amotor!=IntPtr.Zero ? "Amotor ":"")); - } - AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); - _parent_scene.AddCharacter(this); - } - else - { - _parent_scene.RemoveCharacter(this); - // destroy avatar capsule and related ODE data - if (Amotor != IntPtr.Zero) - { - // Kill the Amotor - d.JointDestroy(Amotor); - Amotor = IntPtr.Zero; - } - //kill the Geometry - _parent_scene.waitForSpaceUnlock(_parent_scene.space); - if (Body != IntPtr.Zero) + if (m_tainted_isPhysical != m_isPhysical) + { + if (m_tainted_isPhysical) { - //kill the body - d.BodyDestroy(Body); - Body = IntPtr.Zero; + // Create avatar capsule and related ODE data + if (!(Shell == IntPtr.Zero && Body == IntPtr.Zero && Amotor == IntPtr.Zero)) + { + m_log.Warn("[PHYSICS]: re-creating the following avatar ODE data, even though it already exists - " + + (Shell!=IntPtr.Zero ? "Shell ":"") + + (Body!=IntPtr.Zero ? "Body ":"") + + (Amotor!=IntPtr.Zero ? "Amotor ":"")); + } + AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z, m_tensor); + _parent_scene.AddCharacter(this); } - - if(Shell != IntPtr.Zero) + else { - try + _parent_scene.RemoveCharacter(this); + // destroy avatar capsule and related ODE data + if (Amotor != IntPtr.Zero) { - d.GeomDestroy(Shell); + // Kill the Amotor + d.JointDestroy(Amotor); + Amotor = IntPtr.Zero; } - catch (System.AccessViolationException) + //kill the Geometry + _parent_scene.waitForSpaceUnlock(_parent_scene.space); + + if (Body != IntPtr.Zero) { - m_log.Error("[PHYSICS]: PrimGeom dead"); + //kill the body + d.BodyDestroy(Body); + Body = IntPtr.Zero; } - // Remove any old entries -//string tShell; -//_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); -//Console.WriteLine("**** Remove {0}", tShell); - if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); - if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); - Shell = IntPtr.Zero; + if(Shell != IntPtr.Zero) + { + try + { + d.GeomDestroy(Shell); + } + catch (System.AccessViolationException) + { + m_log.Error("[PHYSICS]: PrimGeom dead"); + } + // Remove any old entries + //string tShell; + //_parent_scene.geom_name_map.TryGetValue(Shell, out tShell); + //Console.WriteLine("**** Remove {0}", tShell); + + if(_parent_scene.geom_name_map.ContainsKey(Shell)) _parent_scene.geom_name_map.Remove(Shell); + if(_parent_scene.actor_name_map.ContainsKey(Shell)) _parent_scene.actor_name_map.Remove(Shell); + Shell = IntPtr.Zero; + } } - } - m_isPhysical = m_tainted_isPhysical; - } + m_isPhysical = m_tainted_isPhysical; + } - if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) - { - if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) + if (m_tainted_CAPSULE_LENGTH != CAPSULE_LENGTH) { + if (Shell != IntPtr.Zero && Body != IntPtr.Zero && Amotor != IntPtr.Zero) + { - m_pidControllerActive = true; - // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() - d.JointDestroy(Amotor); - float prevCapsule = CAPSULE_LENGTH; - CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; - //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); - d.BodyDestroy(Body); - AvatarGeomAndBodyCreation(_position.X, _position.Y, - _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); - Velocity = Vector3.Zero; - } - else - { - m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " - + (Shell==IntPtr.Zero ? "Shell ":"") - + (Body==IntPtr.Zero ? "Body ":"") - + (Amotor==IntPtr.Zero ? "Amotor ":"")); + m_pidControllerActive = true; + // no lock needed on _parent_scene.OdeLock because we are called from within the thread lock in OdePlugin's simulate() + d.JointDestroy(Amotor); + float prevCapsule = CAPSULE_LENGTH; + CAPSULE_LENGTH = m_tainted_CAPSULE_LENGTH; + //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString()); + d.BodyDestroy(Body); + AvatarGeomAndBodyCreation(_position.X, _position.Y, + _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor); + Velocity = Vector3.Zero; + } + else + { + m_log.Warn("[PHYSICS]: trying to change capsule size, but the following ODE data is missing - " + + (Shell==IntPtr.Zero ? "Shell ":"") + + (Body==IntPtr.Zero ? "Body ":"") + + (Amotor==IntPtr.Zero ? "Amotor ":"")); + } } - } - if (!m_taintPosition.ApproxEquals(_position, 0.05f)) - { - if (Body != IntPtr.Zero) + if (!m_taintPosition.ApproxEquals(_position, 0.05f)) { - d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); + if (Body != IntPtr.Zero) + { + d.BodySetPosition(Body, m_taintPosition.X, m_taintPosition.Y, m_taintPosition.Z); - _position.X = m_taintPosition.X; - _position.Y = m_taintPosition.Y; - _position.Z = m_taintPosition.Z; + _position.X = m_taintPosition.X; + _position.Y = m_taintPosition.Y; + _position.Z = m_taintPosition.Z; + } } - } + } } internal void AddCollisionFrameTime(int p) -- cgit v1.1 From 6f689f591a295195cf8db3c37bcd382502d468d7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 26 Sep 2010 17:56:31 +0100 Subject: Merge Master --- .../Region/Physics/Manager/PhysicsPluginManager.cs | 4 ++-- OpenSim/Region/Physics/Manager/ZeroMesher.cs | 3 ++- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 13 +++++++++---- .../Region/Physics/OdePlugin/Tests/ODETestClass.cs | 6 +++++- .../Region/ScriptEngine/Interfaces/IScriptEngine.cs | 1 + .../Region/ScriptEngine/Shared/AssemblyResolver.cs | 7 ++++--- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 5 +++-- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 21 ++++++++++++++------- 8 files changed, 40 insertions(+), 20 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs index 7130a3e..3763696 100644 --- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs +++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs @@ -81,7 +81,7 @@ namespace OpenSim.Region.Physics.Manager if (_MeshPlugins.ContainsKey(meshEngineName)) { m_log.Info("[PHYSICS]: creating meshing engine " + meshEngineName); - meshEngine = _MeshPlugins[meshEngineName].GetMesher(); + meshEngine = _MeshPlugins[meshEngineName].GetMesher(config); } else { @@ -234,6 +234,6 @@ namespace OpenSim.Region.Physics.Manager public interface IMeshingPlugin { string GetName(); - IMesher GetMesher(); + IMesher GetMesher(IConfigSource config); } } diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs index e6e75f9..ba19db6 100644 --- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs +++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs @@ -28,6 +28,7 @@ using System; using OpenSim.Framework; using OpenMetaverse; +using Nini.Config; /* * This is the zero mesher. @@ -53,7 +54,7 @@ namespace OpenSim.Region.Physics.Manager return "ZeroMesher"; } - public IMesher GetMesher() + public IMesher GetMesher(IConfigSource config) { return new ZeroMesher(); } diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index fded95e..62f947c 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -35,6 +35,7 @@ using System.Drawing; using System.Drawing.Imaging; using PrimMesher; using log4net; +using Nini.Config; using System.Reflection; using System.IO; @@ -51,9 +52,9 @@ namespace OpenSim.Region.Physics.Meshing return "Meshmerizer"; } - public IMesher GetMesher() + public IMesher GetMesher(IConfigSource config) { - return new Meshmerizer(); + return new Meshmerizer(config); } } @@ -70,14 +71,18 @@ namespace OpenSim.Region.Physics.Meshing #endif private bool cacheSculptMaps = true; - private string decodedScultMapPath = "j2kDecodeCache"; + private string decodedScultMapPath = null; private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh private Dictionary m_uniqueMeshes = new Dictionary(); - public Meshmerizer() + public Meshmerizer(IConfigSource config) { + IConfig start_config = config.Configs["Startup"]; + + decodedScultMapPath = start_config.GetString("DecodedSculpMapPath","j2kDecodeCache"); + try { if (!Directory.Exists(decodedScultMapPath)) diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index 69e2d03..ab8f8bf 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs @@ -48,6 +48,10 @@ namespace OpenSim.Region.Physics.OdePlugin [SetUp] public void Initialize() { + IConfigSource TopConfig = new IniConfigSource(); + IConfig config = TopConfig.AddConfig("Startup"); + config.Set("DecodedSculpMapPath","j2kDecodeCache"); + // Loading ODEPlugin cbt = new OdePlugin(); // Loading Zero Mesher @@ -55,7 +59,7 @@ namespace OpenSim.Region.Physics.OdePlugin // Getting Physics Scene ps = cbt.GetScene("test"); // Initializing Physics Scene. - ps.Initialise(imp.GetMesher(),null); + ps.Initialise(imp.GetMesher(TopConfig),null); float[] _heightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize]; for (int i = 0; i < ((int)Constants.RegionSize * (int)Constants.RegionSize); i++) { diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs index 02d1511..581a9a9 100644 --- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs +++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptEngine.cs @@ -82,6 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces IConfig Config { get; } IConfigSource ConfigSource { get; } string ScriptEngineName { get; } + string ScriptEnginePath { get; } IScriptApi GetApi(UUID itemID, string name); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs b/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs index ade1924..130e197 100644 --- a/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs +++ b/OpenSim/Region/ScriptEngine/Shared/AssemblyResolver.cs @@ -32,7 +32,7 @@ using System.Reflection; namespace OpenSim.Region.ScriptEngine.Shared { [Serializable] - public class AssemblyResolver + public class AssemblyResolver : MarshalByRefObject { public static Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) @@ -42,9 +42,10 @@ namespace OpenSim.Region.ScriptEngine.Shared AppDomain myDomain = (AppDomain)sender; string dirName = myDomain.FriendlyName; + string ScriptEnginesPath = myDomain.SetupInformation.PrivateBinPath; - string[] pathList = new string[] {"bin", "ScriptEngines", - Path.Combine("ScriptEngines", dirName)}; + string[] pathList = new string[] {"bin", ScriptEnginesPath, + Path.Combine(ScriptEnginesPath, dirName)}; string assemblyName = args.Name; if (assemblyName.IndexOf(",") != -1) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index cd8c67e..49d6abe 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -72,7 +72,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools private Dictionary LanguageMapping = new Dictionary(StringComparer.CurrentCultureIgnoreCase); private string FilePrefix; - private string ScriptEnginesPath = "ScriptEngines"; + private string ScriptEnginesPath = null; // mapping between LSL and C# line/column numbers private ICodeConverter LSL_Converter; @@ -95,7 +95,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools public Compiler(IScriptEngine scriptEngine) { - m_scriptEngine = scriptEngine; + m_scriptEngine = scriptEngine;; + ScriptEnginesPath = scriptEngine.ScriptEnginePath; ReadConfig(); } diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index e82d297..c0ec0e8 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -89,6 +89,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine private IXmlRpcRouter m_XmlRpcRouter; private int m_EventLimit; private bool m_KillTimedOutScripts; + private string m_ScriptEnginesPath = null; private static List m_ScriptEngines = new List(); @@ -224,6 +225,11 @@ namespace OpenSim.Region.ScriptEngine.XEngine get { return m_ScriptConfig; } } + public string ScriptEnginePath + { + get { return m_ScriptEnginesPath; } + } + public IConfigSource ConfigSource { get { return m_ConfigSource; } @@ -281,6 +287,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine m_EventLimit = m_ScriptConfig.GetInt("EventLimit", 30); m_KillTimedOutScripts = m_ScriptConfig.GetBoolean("KillTimedOutScripts", false); m_SaveTime = m_ScriptConfig.GetInt("SaveInterval", 120) * 1000; + m_ScriptEnginesPath = m_ScriptConfig.GetString("ScriptEnginesPath", "ScriptEngines"); m_Prio = ThreadPriority.BelowNormal; switch (priority) @@ -478,7 +485,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine return 0; } - public Type ReplaceableInterface + public Type ReplaceableInterface { get { return null; } } @@ -1040,7 +1047,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine startInfo.IdleTimeout = idleTimeout*1000; // convert to seconds as stated in .ini startInfo.MaxWorkerThreads = maxThreads; startInfo.MinWorkerThreads = minThreads; - startInfo.ThreadPriority = threadPriority; + startInfo.ThreadPriority = threadPriority;; startInfo.StackSize = stackSize; startInfo.StartSuspended = true; @@ -1186,8 +1193,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine if (!(sender is System.AppDomain)) return null; - string[] pathList = new string[] {"bin", "ScriptEngines", - Path.Combine("ScriptEngines", + string[] pathList = new string[] {"bin", m_ScriptEnginesPath, + Path.Combine(m_ScriptEnginesPath, m_Scene.RegionInfo.RegionID.ToString())}; string assemblyName = args.Name; @@ -1564,7 +1571,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine string fn = assemE.GetAttribute("Filename"); string base64 = assemE.InnerText; - string path = Path.Combine("ScriptEngines", World.RegionInfo.RegionID.ToString()); + string path = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString()); path = Path.Combine(path, fn); if (!File.Exists(path)) @@ -1604,7 +1611,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine } } - string statepath = Path.Combine("ScriptEngines", World.RegionInfo.RegionID.ToString()); + string statepath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString()); statepath = Path.Combine(statepath, itemID.ToString() + ".state"); try @@ -1630,7 +1637,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine { XmlElement mapE = (XmlElement)mapL[0]; - string mappath = Path.Combine("ScriptEngines", World.RegionInfo.RegionID.ToString()); + string mappath = Path.Combine(m_ScriptEnginesPath, World.RegionInfo.RegionID.ToString()); mappath = Path.Combine(mappath, mapE.GetAttribute("Filename")); try -- cgit v1.1 From aecac9bba9b89682f53ebde1e182ad04f5b2dc99 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 26 Sep 2010 18:05:55 +0100 Subject: Typo fixes --- OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 12 ++++++------ OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 62f947c..20a5bb4 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs @@ -71,7 +71,7 @@ namespace OpenSim.Region.Physics.Meshing #endif private bool cacheSculptMaps = true; - private string decodedScultMapPath = null; + private string decodedSculptMapPath = null; private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh @@ -81,16 +81,16 @@ namespace OpenSim.Region.Physics.Meshing { IConfig start_config = config.Configs["Startup"]; - decodedScultMapPath = start_config.GetString("DecodedSculpMapPath","j2kDecodeCache"); + decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache"); try { - if (!Directory.Exists(decodedScultMapPath)) - Directory.CreateDirectory(decodedScultMapPath); + if (!Directory.Exists(decodedSculptMapPath)) + Directory.CreateDirectory(decodedSculptMapPath); } catch (Exception e) { - m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedScultMapPath, e.Message); + m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message); } } @@ -265,7 +265,7 @@ namespace OpenSim.Region.Physics.Meshing { if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero) { - decodedSculptFileName = System.IO.Path.Combine(decodedScultMapPath, "smap_" + primShape.SculptTexture.ToString()); + decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString()); try { if (File.Exists(decodedSculptFileName)) diff --git a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs index ab8f8bf..a7f8baa 100644 --- a/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs +++ b/OpenSim/Region/Physics/OdePlugin/Tests/ODETestClass.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.Physics.OdePlugin { IConfigSource TopConfig = new IniConfigSource(); IConfig config = TopConfig.AddConfig("Startup"); - config.Set("DecodedSculpMapPath","j2kDecodeCache"); + config.Set("DecodedSculptMapPath","j2kDecodeCache"); // Loading ODEPlugin cbt = new OdePlugin(); -- cgit v1.1 From 34e8bf45b6f44c7e9c1e8fb824215214f6e9244c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 27 Sep 2010 00:29:27 +0100 Subject: Restrict inventory items added in a transaction to folder belonging to the connected client. --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 18cfcbc..9a33993 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -834,6 +834,12 @@ namespace OpenSim.Region.Framework.Scenes if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; + InventoryFolderBase f = new InventoryFolderBase(folderID, remoteClient.AgentId); + InventoryFolderBase folder = InventoryService.GetFolder(f); + + if (folder == null || folder.Owner != remoteClient.AgentId) + return; + if (transactionID == UUID.Zero) { ScenePresence presence; -- cgit v1.1 From 41051b3cc68f1b7cf92538bd2affbf4c838f1a1d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 27 Sep 2010 02:11:55 +0100 Subject: Prevent setting arbitrary groups on your objects. --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 5ef14bf..b61aed5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -590,6 +590,9 @@ namespace OpenSim.Region.Framework.Scenes protected internal void HandleObjectGroupUpdate( IClientAPI remoteClient, UUID GroupID, uint objectLocalID, UUID Garbage) { + if (!remoteClient.IsGroupMember(GroupID)) + return; + SceneObjectGroup group = GetGroupByPrim(objectLocalID); if (group != null) { -- cgit v1.1 From 841c84831fedcfa40e0b0fa9c99990f6754591fa Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 27 Sep 2010 19:34:16 +0200 Subject: Try to prevent threading issues in SP.SetAppearance by locking it --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 85 +++++++++++++----------- 1 file changed, 45 insertions(+), 40 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b3df1ea..ec3f004 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -229,6 +229,8 @@ namespace OpenSim.Region.Framework.Scenes private const int NumMovementsBetweenRayCast = 5; private List m_lastColliders = new List(); + private object m_syncRoot = new Object(); + private bool CameraConstraintActive; //private int m_moveToPositionStateStatus; //***************************************************** @@ -2861,66 +2863,69 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) { - if (m_physicsActor != null) + lock (m_syncRoot) { - if (!IsChildAgent) + if (m_physicsActor != null) { - // This may seem like it's redundant, remove the avatar from the physics scene - // just to add it back again, but it saves us from having to update - // 3 variables 10 times a second. - bool flyingTemp = m_physicsActor.Flying; - RemoveFromPhysicalScene(); - //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); + if (!IsChildAgent) + { + // This may seem like it's redundant, remove the avatar from the physics scene + // just to add it back again, but it saves us from having to update + // 3 variables 10 times a second. + bool flyingTemp = m_physicsActor.Flying; + RemoveFromPhysicalScene(); + //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); - //PhysicsActor = null; + //PhysicsActor = null; - AddToPhysicalScene(flyingTemp); + AddToPhysicalScene(flyingTemp); + } } - } - #region Bake Cache Check + #region Bake Cache Check - if (textureEntry != null) - { - for (int i = 0; i < BAKE_INDICES.Length; i++) + if (textureEntry != null) { - int j = BAKE_INDICES[i]; - Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; - - if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) + for (int i = 0; i < BAKE_INDICES.Length; i++) { - if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) + int j = BAKE_INDICES[i]; + Primitive.TextureEntryFace face = textureEntry.FaceTextures[j]; + + if (face != null && face.TextureID != AppearanceManager.DEFAULT_AVATAR_TEXTURE) { - m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); - this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); + if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) + { + m_log.Warn("[APPEARANCE]: Missing baked texture " + face.TextureID + " (" + j + ") for avatar " + this.Name); + this.ControllingClient.SendRebakeAvatarTextures(face.TextureID); + } } } - } - } + } - #endregion Bake Cache Check + #endregion Bake Cache Check - m_appearance.SetAppearance(textureEntry, visualParams); - if (m_appearance.AvatarHeight > 0) - SetHeight(m_appearance.AvatarHeight); + m_appearance.SetAppearance(textureEntry, visualParams); + if (m_appearance.AvatarHeight > 0) + SetHeight(m_appearance.AvatarHeight); - // This is not needed, because only the transient data changed - //AvatarData adata = new AvatarData(m_appearance); - //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); + // This is not needed, because only the transient data changed + //AvatarData adata = new AvatarData(m_appearance); + //m_scene.AvatarService.SetAvatar(m_controllingClient.AgentId, adata); - SendAppearanceToAllOtherAgents(); - if (!m_startAnimationSet) - { - Animator.UpdateMovementAnimations(); - m_startAnimationSet = true; - } + SendAppearanceToAllOtherAgents(); + if (!m_startAnimationSet) + { + Animator.UpdateMovementAnimations(); + m_startAnimationSet = true; + } - Vector3 pos = m_pos; - pos.Z += m_appearance.HipOffset; + Vector3 pos = m_pos; + pos.Z += m_appearance.HipOffset; - m_controllingClient.SendAvatarDataImmediate(this); + m_controllingClient.SendAvatarDataImmediate(this); + } } public void SetWearable(int wearableId, AvatarWearable wearable) -- cgit v1.1 From 3d75e9addd50b9416a221282d7e24fc44ebda3a8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 28 Sep 2010 02:22:32 +0200 Subject: Lock the iteration over the inventory items when saving script states --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index c88dda6..522f75e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1241,6 +1241,7 @@ namespace OpenSim.Region.Framework.Scenes if (engines == null) // No engine at all return ret; + Items.LockItemsForRead(true); foreach (TaskInventoryItem item in m_items.Values) { if (item.InvType == (int)InventoryType.LSL) @@ -1268,6 +1269,7 @@ namespace OpenSim.Region.Framework.Scenes } } } + Items.LockItemsForRead(false); return ret; } -- cgit v1.1 From 9522881404e9496cb68d97fae537d60bbfa5233b Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 30 Sep 2010 02:46:47 +0200 Subject: Fix a potential key collision --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a9502ed..a00a7c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1035,7 +1035,7 @@ namespace OpenSim.Region.Framework.Scenes { Dictionary pstates = parts[i].Inventory.GetScriptStates(oldIDs); foreach (KeyValuePair kvp in pstates) - states.Add(kvp.Key, kvp.Value); + states[kvp.Key] = kvp.Value; } if (states.Count > 0) -- cgit v1.1 From ac7a4a7d38454c9c2263b54f847b28a5a7567b83 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 30 Sep 2010 02:47:07 +0200 Subject: Fix an inventory fetch issue --- OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 4d97db7..21c36d3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs @@ -515,6 +515,9 @@ namespace OpenSim.Region.Framework.Scenes public void HandleFetchInventoryDescendents(IClientAPI remoteClient, UUID folderID, UUID ownerID, bool fetchFolders, bool fetchItems, int sortOrder) { + if (folderID == UUID.Zero) + return; + // FIXME MAYBE: We're not handling sortOrder! // TODO: This code for looking in the folder for the library should be folded somewhere else -- cgit v1.1 From 7ad1b60ecaa64ae693be48df9a32cb93bb22e76f Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 30 Sep 2010 20:01:55 +0200 Subject: Enforce region agent limit as set in estate tools --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++++++ OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 +++++ 2 files changed, 13 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 240d33c..e835281 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3856,6 +3856,14 @@ namespace OpenSim.Region.Framework.Scenes // We have to wait until the viewer contacts this region after receiving EAC. // That calls AddNewClient, which finally creates the ScenePresence + int num = m_sceneGraph.GetNumberOfScenePresences(); + + if (num >= RegionInfo.RegionSettings.AgentLimit) + { + if (!Permissions.IsAdministrator(cAgentData.AgentID)) + return false; + } + ScenePresence childAgentUpdate = WaitGetScenePresence(cAgentData.AgentID); if (childAgentUpdate != null) { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b61aed5..1163ebf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -826,6 +826,11 @@ namespace OpenSim.Region.Framework.Scenes return m_scenePresenceArray; } + public int GetNumberOfScenePresences() + { + return m_scenePresenceArray.Count; + } + /// /// Request a scene presence by UUID. Fast, indexed lookup. /// -- cgit v1.1 From 9f7f266f583cfd47f3c66aa56b0ba26e634e8d91 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 2 Oct 2010 00:18:52 +0200 Subject: Replace CalculateMass with a better, contributed version --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 471 +++++++++++++------------- 1 file changed, 228 insertions(+), 243 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 2105be1..793774a 100644 --- a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs @@ -884,300 +884,285 @@ namespace OpenSim.Region.Physics.OdePlugin private float CalculateMass() { - float volume = 0; - - // No material is passed to the physics engines yet.. soo.. - // we're using the m_density constant in the class definition + float volume = _size.X * _size.Y * _size.Z; // default + float tmp; float returnMass = 0; - + float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; + float hollowVolume = hollowAmount * hollowAmount; + switch (_pbs.ProfileShape) { case ProfileShape.Square: - // Profile Volume + // default box + + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + if (hollowAmount > 0.0) + { + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; - volume = _size.X*_size.Y*_size.Z; + case HollowShape.Circle: - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage + hollowVolume *= 0.78539816339f; + break; - if (((float) _pbs.ProfileHollow/50000f) > 0.0) - { - float hollowAmount = (float) _pbs.ProfileHollow/50000f; + case HollowShape.Triangle: + + hollowVolume *= (0.5f * .5f); + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - case HollowShape.Square: - case HollowShape.Same: - // Cube Hollow volume calculation - float hollowsizex = _size.X*hollowAmount; - float hollowsizey = _size.Y*hollowAmount; - float hollowsizez = _size.Z*hollowAmount; - hollowVolume = hollowsizex*hollowsizey*hollowsizez; - break; - - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X/2; - float hLength = _size.Z; - - // pi * r2 * h - hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount); - break; - - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y - - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); - break; - - default: - hollowVolume = 0; - break; + //a tube + + volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); + tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY); + volume -= volume*tmp*tmp; + + if (hollowAmount > 0.0) + { + hollowVolume *= hollowAmount; + + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; + + case HollowShape.Circle: + hollowVolume *= 0.78539816339f;; + break; + + case HollowShape.Triangle: + hollowVolume *= 0.5f * 0.5f; + break; + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } } - volume = volume - hollowVolume; - } break; + case ProfileShape.Circle: - if (_pbs.PathCurve == (byte)Extrusion.Straight) - { - // Cylinder - float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z); - float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z); - // Approximating the cylinder's irregularity. - if (volume1 > volume2) - { - volume = (float)volume1 - (volume1 - volume2); - } - else if (volume2 > volume1) + if (_pbs.PathCurve == (byte)Extrusion.Straight) { - volume = (float)volume2 - (volume2 - volume1); + volume *= 0.78539816339f; // elipse base + + if (hollowAmount > 0.0) + { + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; + + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } } - else + + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - // Regular cylinder - volume = volume1; - } - } - else - { - // We don't know what the shape is yet, so use default - volume = _size.X * _size.Y * _size.Z; - } - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage + volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); + volume *= (1.0f - tmp * tmp); + + if (hollowAmount > 0.0) + { - if (((float)_pbs.ProfileHollow / 50000f) > 0.0) - { - float hollowAmount = (float)_pbs.ProfileHollow / 50000f; + // calculate the hollow volume by it's shape compared to the prim shape + hollowVolume *= hollowAmount; - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) - { - case HollowShape.Same: - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X / 2; - float hLength = _size.Z; - - // pi * r2 * h - hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); - break; - - case HollowShape.Square: - // Cube Hollow volume calculation - float hollowsizex = _size.X * hollowAmount; - float hollowsizey = _size.Y * hollowAmount; - float hollowsizez = _size.Z * hollowAmount; - hollowVolume = hollowsizex * hollowsizey * hollowsizez; - break; - - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y - - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); - break; - - default: - hollowVolume = 0; - break; + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; + + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } } - volume = volume - hollowVolume; - } break; case ProfileShape.HalfCircle: if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - if (_size.X == _size.Y && _size.Y == _size.Z) - { - // regular sphere - // v = 4/3 * pi * r^3 - float sradius3 = (float)Math.Pow((_size.X / 2), 3); - volume = (float)((4f / 3f) * Math.PI * sradius3); - } - else - { - // we treat this as a box currently - volume = _size.X * _size.Y * _size.Z; - } - } - else - { - // We don't know what the shape is yet, so use default - volume = _size.X * _size.Y * _size.Z; + volume *= 0.52359877559829887307710723054658f; } break; case ProfileShape.EquilateralTriangle: - /* - v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h - // seed mesh - Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); - Vertex PM = new Vertex(+0.5f, 0f, 0.0f); - Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f); - */ - float xA = -0.25f * _size.X; - float yA = -0.45f * _size.Y; + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + volume *= 0.32475953f; - float xB = 0.5f * _size.X; - float yB = 0; + if (hollowAmount > 0.0) + { - float xC = -0.25f * _size.X; - float yC = 0.45f * _size.Y; + // calculate the hollow volume by it's shape compared to the prim shape + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; - volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage - float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f); - if (((float)fhollowFactor / 50000f) > 0.0) - { - float hollowAmount = (float)fhollowFactor / 50000f; + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) - { - case HollowShape.Same: - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y - - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); - break; - - case HollowShape.Square: - // Cube Hollow volume calculation - float hollowsizex = _size.X * hollowAmount; - float hollowsizey = _size.Y * hollowAmount; - float hollowsizez = _size.Z * hollowAmount; - hollowVolume = hollowsizex * hollowsizey * hollowsizez; - break; - - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X / 2; - float hLength = _size.Z; - - // pi * r2 * h - hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); - break; - - default: - hollowVolume = 0; - break; + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } } - volume = volume - hollowVolume; - } - break; + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + volume *= 0.32475953f; + volume *= 0.01f * (float)(200 - _pbs.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); + volume *= (1.0f - tmp * tmp); - default: - // we don't have all of the volume formulas yet so - // use the common volume formula for all - volume = _size.X*_size.Y*_size.Z; - break; - } + if (hollowAmount > 0.0) + { - // Calculate Path cut effect on volume - // Not exact, in the triangle hollow example - // They should never be zero or less then zero.. - // we'll ignore it if it's less then zero + hollowVolume *= hollowAmount; - // ProfileEnd and ProfileBegin are values - // from 0 to 50000 + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; - // Turning them back into percentages so that I can cut that percentage off the volume + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; - float PathCutEndAmount = _pbs.ProfileEnd; - float PathCutStartAmount = _pbs.ProfileBegin; - if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f) - { - float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f); + case HollowShape.Circle: - // Check the return amount for sanity - if (pathCutAmount >= 0.99f) - pathCutAmount = 0.99f; + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; - volume = volume - (volume*pathCutAmount); - } - UInt16 taperX = _pbs.PathScaleX; - UInt16 taperY = _pbs.PathScaleY; - float taperFactorX = 0; - float taperFactorY = 0; + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + break; - // Mass = density * volume - if (taperX != 100) - { - if (taperX > 100) - { - taperFactorX = 1.0f - ((float)taperX / 200); - //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString()); - } - else - { - taperFactorX = 1.0f - ((100 - (float)taperX) / 100); - //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString()); + default: + break; } - volume = (float)volume * ((taperFactorX / 3f) + 0.001f); - } - if (taperY != 100) - { - if (taperY > 100) + + + float taperX1; + float taperY1; + float taperX; + float taperY; + float pathBegin; + float pathEnd; + float profileBegin; + float profileEnd; + + if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) { - taperFactorY = 1.0f - ((float)taperY / 200); - //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString()); + taperX1 = _pbs.PathScaleX * 0.01f; + if (taperX1 > 1.0f) + taperX1 = 2.0f - taperX1; + taperX = 1.0f - taperX1; + + taperY1 = _pbs.PathScaleY * 0.01f; + if (taperY1 > 1.0f) + taperY1 = 2.0f - taperY1; + taperY = 1.0f - taperY1; } - else + else { - taperFactorY = 1.0f - ((100 - (float)taperY) / 100); - //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString()); + taperX = _pbs.PathTaperX * 0.01f; + if (taperX < 0.0f) + taperX = -taperX; + taperX1 = 1.0f - taperX; + + taperY = _pbs.PathTaperY * 0.01f; + if (taperY < 0.0f) + taperY = -taperY; + taperY1 = 1.0f - taperY; + } - volume = (float)volume * ((taperFactorY / 3f) + 0.001f); - } - returnMass = m_density*volume; - if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. + + + volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); + + pathBegin = (float)_pbs.PathBegin * 2.0e-5f; + pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; + volume *= (pathEnd - pathBegin); + +// this is crude aproximation + profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; + profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; + volume *= (profileEnd - profileBegin); + + returnMass = m_density * volume; + + if (returnMass <= 0) + returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. +// else if (returnMass > _parent_scene.maximumMassObject) +// returnMass = _parent_scene.maximumMassObject; + -- cgit v1.1 From b40c91777cf272b485da0cdfba2ffec868cfc7cf Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 2 Oct 2010 00:19:30 +0200 Subject: Replace CalculateMass with a more accurate version, contributed by Ubit. Thank you. --- OpenSim/Region/Physics/OdePlugin/ODEPrim.cs | 453 ++++++++++++++-------------- 1 file changed, 219 insertions(+), 234 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs index daf7fb0..319a951 100644 --- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs +++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs @@ -403,300 +403,285 @@ namespace OpenSim.Region.Physics.OdePlugin private float CalculateMass() { - float volume = 0; - - // No material is passed to the physics engines yet.. soo.. - // we're using the m_density constant in the class definition + float volume = _size.X * _size.Y * _size.Z; // default + float tmp; float returnMass = 0; - + float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; + float hollowVolume = hollowAmount * hollowAmount; + switch (_pbs.ProfileShape) { case ProfileShape.Square: - // Profile Volume + // default box - volume = _size.X*_size.Y*_size.Z; + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + if (hollowAmount > 0.0) + { + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage + case HollowShape.Circle: - if (((float) _pbs.ProfileHollow/50000f) > 0.0) - { - float hollowAmount = (float) _pbs.ProfileHollow/50000f; + hollowVolume *= 0.78539816339f; + break; - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) - { - case HollowShape.Square: - case HollowShape.Same: - // Cube Hollow volume calculation - float hollowsizex = _size.X*hollowAmount; - float hollowsizey = _size.Y*hollowAmount; - float hollowsizez = _size.Z*hollowAmount; - hollowVolume = hollowsizex*hollowsizey*hollowsizez; - break; + case HollowShape.Triangle: - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X/2; - float hLength = _size.Z; - - // pi * r2 * h - hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount); - break; + hollowVolume *= (0.5f * .5f); + break; - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount); - break; + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) + { + //a tube - default: - hollowVolume = 0; - break; + volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); + tmp= 1.0f -2.0e-2f * (float)(200 - _pbs.PathScaleY); + volume -= volume*tmp*tmp; + + if (hollowAmount > 0.0) + { + hollowVolume *= hollowAmount; + + switch (_pbs.HollowShape) + { + case HollowShape.Square: + case HollowShape.Same: + break; + + case HollowShape.Circle: + hollowVolume *= 0.78539816339f;; + break; + + case HollowShape.Triangle: + hollowVolume *= 0.5f * 0.5f; + break; + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } } - volume = volume - hollowVolume; - } break; + case ProfileShape.Circle: - if (_pbs.PathCurve == (byte)Extrusion.Straight) - { - // Cylinder - float volume1 = (float)(Math.PI * Math.Pow(_size.X/2, 2) * _size.Z); - float volume2 = (float)(Math.PI * Math.Pow(_size.Y/2, 2) * _size.Z); - // Approximating the cylinder's irregularity. - if (volume1 > volume2) - { - volume = (float)volume1 - (volume1 - volume2); - } - else if (volume2 > volume1) - { - volume = (float)volume2 - (volume2 - volume1); - } - else + if (_pbs.PathCurve == (byte)Extrusion.Straight) { - // Regular cylinder - volume = volume1; - } - } - else - { - // We don't know what the shape is yet, so use default - volume = _size.X * _size.Y * _size.Z; - } - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage + volume *= 0.78539816339f; // elipse base - if (((float)_pbs.ProfileHollow / 50000f) > 0.0) - { - float hollowAmount = (float)_pbs.ProfileHollow / 50000f; + if (hollowAmount > 0.0) + { + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; + + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - case HollowShape.Same: - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X / 2; - float hLength = _size.Z; - - // pi * r2 * h - hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount); - break; + volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); + volume *= (1.0f - tmp * tmp); + + if (hollowAmount > 0.0) + { - case HollowShape.Square: - // Cube Hollow volume calculation - float hollowsizex = _size.X * hollowAmount; - float hollowsizey = _size.Y * hollowAmount; - float hollowsizez = _size.Z * hollowAmount; - hollowVolume = hollowsizex * hollowsizey * hollowsizez; - break; + // calculate the hollow volume by it's shape compared to the prim shape + hollowVolume *= hollowAmount; - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Circle: + break; - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); - break; + case HollowShape.Square: + hollowVolume *= 0.5f * 2.5984480504799f; + break; - default: - hollowVolume = 0; - break; + case HollowShape.Triangle: + hollowVolume *= .5f * 1.27323954473516f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } } - volume = volume - hollowVolume; - } break; case ProfileShape.HalfCircle: if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - if (_size.X == _size.Y && _size.Y == _size.Z) - { - // regular sphere - // v = 4/3 * pi * r^3 - float sradius3 = (float)Math.Pow((_size.X / 2), 3); - volume = (float)((4f / 3f) * Math.PI * sradius3); - } - else - { - // we treat this as a box currently - volume = _size.X * _size.Y * _size.Z; - } - } - else - { - // We don't know what the shape is yet, so use default - volume = _size.X * _size.Y * _size.Z; + volume *= 0.52359877559829887307710723054658f; } break; case ProfileShape.EquilateralTriangle: - /* - v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h - // seed mesh - Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f); - Vertex PM = new Vertex(+0.5f, 0f, 0.0f); - Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f); - */ - float xA = -0.25f * _size.X; - float yA = -0.45f * _size.Y; + if (_pbs.PathCurve == (byte)Extrusion.Straight) + { + volume *= 0.32475953f; - float xB = 0.5f * _size.X; - float yB = 0; + if (hollowAmount > 0.0) + { - float xC = -0.25f * _size.X; - float yC = 0.45f * _size.Y; + // calculate the hollow volume by it's shape compared to the prim shape + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; - volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z); + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; - // If the user has 'hollowed out' - // ProfileHollow is one of those 0 to 50000 values :P - // we like percentages better.. so turning into a percentage - float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f); - if (((float)fhollowFactor / 50000f) > 0.0) - { - float hollowAmount = (float)fhollowFactor / 50000f; + case HollowShape.Circle: + // Hollow shape is a perfect cyllinder in respect to the cube's scale + // Cyllinder hollow volume calculation - // calculate the hollow volume by it's shape compared to the prim shape - float hollowVolume = 0; - switch (_pbs.HollowShape) + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; + + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { - case HollowShape.Same: - case HollowShape.Triangle: - // Equilateral Triangular Prism volume hollow calculation - // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y - - float aLength = _size.Y; - // 1/2 abh - hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount); - break; + volume *= 0.32475953f; + volume *= 0.01f * (float)(200 - _pbs.PathScaleX); + tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); + volume *= (1.0f - tmp * tmp); - case HollowShape.Square: - // Cube Hollow volume calculation - float hollowsizex = _size.X * hollowAmount; - float hollowsizey = _size.Y * hollowAmount; - float hollowsizez = _size.Z * hollowAmount; - hollowVolume = hollowsizex * hollowsizey * hollowsizez; - break; + if (hollowAmount > 0.0) + { - case HollowShape.Circle: - // Hollow shape is a perfect cyllinder in respect to the cube's scale - // Cyllinder hollow volume calculation - float hRadius = _size.X / 2; - float hLength = _size.Z; + hollowVolume *= hollowAmount; - // pi * r2 * h - hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount); - break; + switch (_pbs.HollowShape) + { + case HollowShape.Same: + case HollowShape.Triangle: + hollowVolume *= .25f; + break; - default: - hollowVolume = 0; - break; - } - volume = volume - hollowVolume; - } - break; + case HollowShape.Square: + hollowVolume *= 0.499849f * 3.07920140172638f; + break; - default: - // we don't have all of the volume formulas yet so - // use the common volume formula for all - volume = _size.X*_size.Y*_size.Z; - break; - } + case HollowShape.Circle: - // Calculate Path cut effect on volume - // Not exact, in the triangle hollow example - // They should never be zero or less then zero.. - // we'll ignore it if it's less then zero + hollowVolume *= 0.1963495f * 3.07920140172638f; + break; - // ProfileEnd and ProfileBegin are values - // from 0 to 50000 + default: + hollowVolume = 0; + break; + } + volume *= (1.0f - hollowVolume); + } + } + break; - // Turning them back into percentages so that I can cut that percentage off the volume + default: + break; + } - float PathCutEndAmount = _pbs.ProfileEnd; - float PathCutStartAmount = _pbs.ProfileBegin; - if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f) - { - float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f); - // Check the return amount for sanity - if (pathCutAmount >= 0.99f) - pathCutAmount = 0.99f; - volume = volume - (volume*pathCutAmount); - } - UInt16 taperX = _pbs.PathScaleX; - UInt16 taperY = _pbs.PathScaleY; - float taperFactorX = 0; - float taperFactorY = 0; + float taperX1; + float taperY1; + float taperX; + float taperY; + float pathBegin; + float pathEnd; + float profileBegin; + float profileEnd; - // Mass = density * volume - if (taperX != 100) - { - if (taperX > 100) + if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) { - taperFactorX = 1.0f - ((float)taperX / 200); - //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString()); - } - else - { - taperFactorX = 1.0f - ((100 - (float)taperX) / 100); - //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString()); - } - volume = (float)volume * ((taperFactorX / 3f) + 0.001f); - } + taperX1 = _pbs.PathScaleX * 0.01f; + if (taperX1 > 1.0f) + taperX1 = 2.0f - taperX1; + taperX = 1.0f - taperX1; - if (taperY != 100) - { - if (taperY > 100) - { - taperFactorY = 1.0f - ((float)taperY / 200); - //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString()); + taperY1 = _pbs.PathScaleY * 0.01f; + if (taperY1 > 1.0f) + taperY1 = 2.0f - taperY1; + taperY = 1.0f - taperY1; } - else + else { - taperFactorY = 1.0f - ((100 - (float)taperY) / 100); - //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString()); + taperX = _pbs.PathTaperX * 0.01f; + if (taperX < 0.0f) + taperX = -taperX; + taperX1 = 1.0f - taperX; + + taperY = _pbs.PathTaperY * 0.01f; + if (taperY < 0.0f) + taperY = -taperY; + taperY1 = 1.0f - taperY; + } - volume = (float)volume * ((taperFactorY / 3f) + 0.001f); - } - returnMass = m_density*volume; - if (returnMass <= 0) returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. + + + volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); + + pathBegin = (float)_pbs.PathBegin * 2.0e-5f; + pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; + volume *= (pathEnd - pathBegin); + +// this is crude aproximation + profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; + profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; + volume *= (profileEnd - profileBegin); + + returnMass = m_density * volume; + + if (returnMass <= 0) + returnMass = 0.0001f;//ckrinke: Mass must be greater then zero. +// else if (returnMass > _parent_scene.maximumMassObject) +// returnMass = _parent_scene.maximumMassObject; + -- cgit v1.1 From 50b03d08a8cdec9359adcece5b4645a6dc821d26 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 4 Oct 2010 00:04:42 +0200 Subject: Add linden prim renderer and update libOMV --- OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | 4 ++-- OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs | 4 ++-- .../ServiceConnectorsOut/UserAccounts/UserAccountCache.cs | 4 ++-- .../Connectors/SimianGrid/SimianUserAccountServiceConnector.cs | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index c120a12..043e7d3 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -143,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutgoingPacket pendingAdd; if (m_pendingAdds != null) { - while (m_pendingAdds.Dequeue(out pendingAdd)) + while (m_pendingAdds.TryDequeue(out pendingAdd)) { if (pendingAdd != null && m_packets != null) { @@ -157,7 +157,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutgoingPacket ackedPacket; if (m_pendingRemoves != null) { - while (m_pendingRemoves.Dequeue(out pendingRemove)) + while (m_pendingRemoves.TryDequeue(out pendingRemove)) { if (m_pendingRemoves != null && m_packets != null) { diff --git a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs index 9eaa758..6ed4867 100644 --- a/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs +++ b/OpenSim/Region/CoreModules/Asset/FlotsamAssetCache.cs @@ -252,7 +252,7 @@ namespace Flotsam.RegionModules.AssetCache } else { - m_MemoryCache.AddOrUpdate(key, asset, DateTime.MaxValue); + m_MemoryCache.AddOrUpdate(key, asset, Double.MaxValue); } } } @@ -863,4 +863,4 @@ namespace Flotsam.RegionModules.AssetCache #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs index 64788db..0da3f5f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/UserAccountCache.cs @@ -53,9 +53,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public void Cache(UUID userID, UserAccount account) { // Cache even null accounts - m_UUIDCache.AddOrUpdate(userID, account, DateTime.Now + TimeSpan.FromSeconds(CACHE_EXPIRATION_SECONDS)); + m_UUIDCache.AddOrUpdate(userID, account, CACHE_EXPIRATION_SECONDS); if (account != null) - m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, DateTime.Now + TimeSpan.FromSeconds(CACHE_EXPIRATION_SECONDS)); + m_NameCache.AddOrUpdate(account.Name, account.PrincipalID, CACHE_EXPIRATION_SECONDS); // m_log.DebugFormat("[USER CACHE]: cached user {0}", userID); } diff --git a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs index ddd2322..9c150ee 100644 --- a/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs +++ b/OpenSim/Services/Connectors/SimianGrid/SimianUserAccountServiceConnector.cs @@ -147,7 +147,7 @@ namespace OpenSim.Services.Connectors.SimianGrid if (account == null) { // Store null responses too, to avoid repeated lookups for missing accounts - m_accountCache.AddOrUpdate(userID, null, DateTime.Now + TimeSpan.FromSeconds(CACHE_EXPIRATION_SECONDS)); + m_accountCache.AddOrUpdate(userID, null, CACHE_EXPIRATION_SECONDS); } return account; @@ -225,7 +225,7 @@ namespace OpenSim.Services.Connectors.SimianGrid if (success) { // Cache the user account info - m_accountCache.AddOrUpdate(data.PrincipalID, data, DateTime.Now + TimeSpan.FromSeconds(CACHE_EXPIRATION_SECONDS)); + m_accountCache.AddOrUpdate(data.PrincipalID, data, CACHE_EXPIRATION_SECONDS); } else { @@ -290,7 +290,7 @@ namespace OpenSim.Services.Connectors.SimianGrid GetFirstLastName(response["Name"].AsString(), out account.FirstName, out account.LastName); // Cache the user account info - m_accountCache.AddOrUpdate(account.PrincipalID, account, DateTime.Now + TimeSpan.FromSeconds(CACHE_EXPIRATION_SECONDS)); + m_accountCache.AddOrUpdate(account.PrincipalID, account, CACHE_EXPIRATION_SECONDS); return account; } -- cgit v1.1 From 90f9b7b7c41927fed070cbe7a8f6cd2a258c2365 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 4 Oct 2010 00:37:18 +0200 Subject: Fix line endings --- .../LindenUDP/UnackedPacketCollection.cs | 368 ++++++++++----------- 1 file changed, 184 insertions(+), 184 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 043e7d3..4cb4aee 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs @@ -1,184 +1,184 @@ -/* - * Copyright (c) Contributors, http://opensimulator.org/ - * See CONTRIBUTORS.TXT for a full list of copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of the OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; -using System.Net; -using OpenMetaverse; - -namespace OpenSim.Region.ClientStack.LindenUDP -{ - /// - /// Special collection that is optimized for tracking unacknowledged packets - /// - public sealed class UnackedPacketCollection - { - /// - /// Holds information about a pending acknowledgement - /// - private struct PendingAck - { - /// Sequence number of the packet to remove - public uint SequenceNumber; - /// Environment.TickCount value when the remove was queued. - /// This is used to update round-trip times for packets - public int RemoveTime; - /// Whether or not this acknowledgement was attached to a - /// resent packet. If so, round-trip time will not be calculated - public bool FromResend; - - public PendingAck(uint sequenceNumber, int currentTime, bool fromResend) - { - SequenceNumber = sequenceNumber; - RemoveTime = currentTime; - FromResend = fromResend; - } - } - - /// Holds the actual unacked packet data, sorted by sequence number - private Dictionary m_packets = new Dictionary(); - /// Holds packets that need to be added to the unacknowledged list - private LocklessQueue m_pendingAdds = new LocklessQueue(); - /// Holds information about pending acknowledgements - private LocklessQueue m_pendingRemoves = new LocklessQueue(); - - /// - /// Add an unacked packet to the collection - /// - /// Packet that is awaiting acknowledgement - /// True if the packet was successfully added, false if the - /// packet already existed in the collection - /// This does not immediately add the ACK to the collection, - /// it only queues it so it can be added in a thread-safe way later - public void Add(OutgoingPacket packet) - { - m_pendingAdds.Enqueue(packet); - } - - /// - /// Marks a packet as acknowledged - /// - /// Sequence number of the packet to - /// acknowledge - /// Current value of Environment.TickCount - /// This does not immediately acknowledge the packet, it only - /// queues the ack so it can be handled in a thread-safe way later - public void Remove(uint sequenceNumber, int currentTime, bool fromResend) - { - m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); - } - - /// - /// Returns a list of all of the packets with a TickCount older than - /// the specified timeout - /// - /// Number of ticks (milliseconds) before a - /// packet is considered expired - /// A list of all expired packets according to the given - /// expiration timeout - /// This function is not thread safe, and cannot be called - /// multiple times concurrently - public List GetExpiredPackets(int timeoutMS) - { - ProcessQueues(); - - List expiredPackets = null; - - if (m_packets.Count > 0) - { - int now = Environment.TickCount & Int32.MaxValue; - - foreach (OutgoingPacket packet in m_packets.Values) - { - // TickCount of zero means a packet is in the resend queue - // but hasn't actually been sent over the wire yet - if (packet.TickCount == 0) - continue; - - if (now - packet.TickCount >= timeoutMS) - { - if (expiredPackets == null) - expiredPackets = new List(); - - // The TickCount will be set to the current time when the packet - // is actually sent out again - packet.TickCount = 0; - - expiredPackets.Add(packet); - } - } - } - - return expiredPackets; - } - - private void ProcessQueues() - { - // Process all the pending adds - - OutgoingPacket pendingAdd; - if (m_pendingAdds != null) - { - while (m_pendingAdds.TryDequeue(out pendingAdd)) - { - if (pendingAdd != null && m_packets != null) - { - m_packets[pendingAdd.SequenceNumber] = pendingAdd; - } - } - } - - // Process all the pending removes, including updating statistics and round-trip times - PendingAck pendingRemove; - OutgoingPacket ackedPacket; - if (m_pendingRemoves != null) - { - while (m_pendingRemoves.TryDequeue(out pendingRemove)) - { - if (m_pendingRemoves != null && m_packets != null) - { - if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) - { - m_packets.Remove(pendingRemove.SequenceNumber); - - // Update stats - System.Threading.Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); - - if (!pendingRemove.FromResend) - { - // Calculate the round-trip time for this packet and its ACK - int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; - if (rtt > 0) - ackedPacket.Client.UpdateRoundTrip(rtt); - } - } - } - } - } - } - } -} +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Net; +using OpenMetaverse; + +namespace OpenSim.Region.ClientStack.LindenUDP +{ + /// + /// Special collection that is optimized for tracking unacknowledged packets + /// + public sealed class UnackedPacketCollection + { + /// + /// Holds information about a pending acknowledgement + /// + private struct PendingAck + { + /// Sequence number of the packet to remove + public uint SequenceNumber; + /// Environment.TickCount value when the remove was queued. + /// This is used to update round-trip times for packets + public int RemoveTime; + /// Whether or not this acknowledgement was attached to a + /// resent packet. If so, round-trip time will not be calculated + public bool FromResend; + + public PendingAck(uint sequenceNumber, int currentTime, bool fromResend) + { + SequenceNumber = sequenceNumber; + RemoveTime = currentTime; + FromResend = fromResend; + } + } + + /// Holds the actual unacked packet data, sorted by sequence number + private Dictionary m_packets = new Dictionary(); + /// Holds packets that need to be added to the unacknowledged list + private LocklessQueue m_pendingAdds = new LocklessQueue(); + /// Holds information about pending acknowledgements + private LocklessQueue m_pendingRemoves = new LocklessQueue(); + + /// + /// Add an unacked packet to the collection + /// + /// Packet that is awaiting acknowledgement + /// True if the packet was successfully added, false if the + /// packet already existed in the collection + /// This does not immediately add the ACK to the collection, + /// it only queues it so it can be added in a thread-safe way later + public void Add(OutgoingPacket packet) + { + m_pendingAdds.Enqueue(packet); + } + + /// + /// Marks a packet as acknowledged + /// + /// Sequence number of the packet to + /// acknowledge + /// Current value of Environment.TickCount + /// This does not immediately acknowledge the packet, it only + /// queues the ack so it can be handled in a thread-safe way later + public void Remove(uint sequenceNumber, int currentTime, bool fromResend) + { + m_pendingRemoves.Enqueue(new PendingAck(sequenceNumber, currentTime, fromResend)); + } + + /// + /// Returns a list of all of the packets with a TickCount older than + /// the specified timeout + /// + /// Number of ticks (milliseconds) before a + /// packet is considered expired + /// A list of all expired packets according to the given + /// expiration timeout + /// This function is not thread safe, and cannot be called + /// multiple times concurrently + public List GetExpiredPackets(int timeoutMS) + { + ProcessQueues(); + + List expiredPackets = null; + + if (m_packets.Count > 0) + { + int now = Environment.TickCount & Int32.MaxValue; + + foreach (OutgoingPacket packet in m_packets.Values) + { + // TickCount of zero means a packet is in the resend queue + // but hasn't actually been sent over the wire yet + if (packet.TickCount == 0) + continue; + + if (now - packet.TickCount >= timeoutMS) + { + if (expiredPackets == null) + expiredPackets = new List(); + + // The TickCount will be set to the current time when the packet + // is actually sent out again + packet.TickCount = 0; + + expiredPackets.Add(packet); + } + } + } + + return expiredPackets; + } + + private void ProcessQueues() + { + // Process all the pending adds + + OutgoingPacket pendingAdd; + if (m_pendingAdds != null) + { + while (m_pendingAdds.TryDequeue(out pendingAdd)) + { + if (pendingAdd != null && m_packets != null) + { + m_packets[pendingAdd.SequenceNumber] = pendingAdd; + } + } + } + + // Process all the pending removes, including updating statistics and round-trip times + PendingAck pendingRemove; + OutgoingPacket ackedPacket; + if (m_pendingRemoves != null) + { + while (m_pendingRemoves.TryDequeue(out pendingRemove)) + { + if (m_pendingRemoves != null && m_packets != null) + { + if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) + { + m_packets.Remove(pendingRemove.SequenceNumber); + + // Update stats + System.Threading.Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); + + if (!pendingRemove.FromResend) + { + // Calculate the round-trip time for this packet and its ACK + int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; + if (rtt > 0) + ackedPacket.Client.UpdateRoundTrip(rtt); + } + } + } + } + } + } + } +} -- cgit v1.1 From e55e93c994befde561c467b40768a21dcf72892e Mon Sep 17 00:00:00 2001 From: Latif Khalifa Date: Mon, 4 Oct 2010 07:37:22 +0200 Subject: Avoid throwing errors when adding existing meshes to the render scene --- OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs index a99b20c..49b4364 100644 --- a/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs +++ b/OpenSim/Region/CoreModules/World/Warp3DMap/MapImageModule.cs @@ -352,6 +352,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap Face face = renderMesh.Faces[i]; string meshName = primID + "-Face-" + i.ToString(); + // Avoid adding duplicate meshes to the scene + if (renderer.Scene.objectData.ContainsKey(meshName)) + { + continue; + } + warp_Object faceObj = new warp_Object(face.Vertices.Count, face.Indices.Count / 3); for (int j = 0; j < face.Vertices.Count; j++) -- cgit v1.1 From 1a47ec082ed541a3af0b7e8bb7d18f564f64335d Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Oct 2010 05:15:47 +0200 Subject: Convert worldview to GET --- .../World/WorldView/WorldViewRequestHandler.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs index 5e744bf..bfdcdb4 100644 --- a/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs +++ b/OpenSim/Region/OptionalModules/World/WorldView/WorldViewRequestHandler.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.OptionalModules.World.WorldView protected Object m_RequestLock = new Object(); public WorldViewRequestHandler(WorldViewModule fmodule, string rid) - : base("POST", "/worldview/" + rid) + : base("GET", "/worldview/" + rid) { m_WorldViewModule = fmodule; } @@ -58,24 +58,28 @@ namespace OpenSim.Region.OptionalModules.World.WorldView public override byte[] Handle(string path, Stream requestData, OSHttpRequest httpRequest, OSHttpResponse httpResponse) { - StreamReader sr = new StreamReader(requestData); - string body = sr.ReadToEnd(); - sr.Close(); - body = body.Trim(); + httpResponse.ContentType = "image/jpeg"; + +// StreamReader sr = new StreamReader(requestData); +// string body = sr.ReadToEnd(); +// sr.Close(); +// body = body.Trim(); try { lock (m_RequestLock) { Dictionary request = - ServerUtils.ParseQueryString(body); + new Dictionary(); + foreach (string name in httpRequest.QueryString) + request[name] = httpRequest.QueryString[name]; return SendWorldView(request); } } catch (Exception e) { - m_log.Debug("[WORLDVIEW]: Exception {0}" + e.ToString()); + m_log.Debug("[WORLDVIEW]: Exception: " + e.ToString()); } return new Byte[0]; -- cgit v1.1 From 42f76773a15d83fd31f249cc4a21985184b0cdbf Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 6 Oct 2010 19:59:30 +0200 Subject: Plumb the path for multiple object deletes --- .../InventoryAccess/InventoryAccessModule.cs | 31 ++++++++++++--- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 44 +++++----------------- OpenSim/Region/Framework/Scenes/Scene.cs | 4 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 8 +++- .../Scenes/Tests/SceneObjectBasicTests.cs | 2 +- OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs | 2 +- 6 files changed, 45 insertions(+), 46 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 42e3359..9ccf5a0 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -196,13 +196,24 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // currently calls this with multiple items. UUID ret = UUID.Zero; + Dictionary> deletes = + new Dictionary>(); + foreach (SceneObjectGroup g in objectGroups) - ret = DeleteToInventory(action, folderID, g, remoteClient); + { + if (!deletes.ContainsKey(g.OwnerID)) + deletes[g.OwnerID] = new List(); + + deletes[g.OwnerID].Add(g); + } + + foreach (List objlist in deletes.Values) + ret = DeleteToInventory(action, folderID, objlist, remoteClient); return ret; } - public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, + private UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) { UUID assetID = UUID.Zero; @@ -320,10 +331,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } else { - // Catch all. Use lost & found - // + if (remoteClient == null || + objectGroup.OwnerID != remoteClient.AgentId) + { + // Taking copy of another person's item. Take to + // Objects folder. + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); + } + else + { + // Catch all. Use lost & found + // - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9a33993..8b5316a 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1688,37 +1688,6 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Called when one or more objects are removed from the environment into inventory. - /// - /// - /// - /// - /// - /// - public virtual void DeRezObject(IClientAPI remoteClient, List localIDs, - UUID groupID, DeRezAction action, UUID destinationID) - { - foreach (uint localID in localIDs) - { - DeRezObject(remoteClient, localID, groupID, action, destinationID); - } - } - - /// - /// Called when an object is removed from the environment into inventory. - /// - /// - /// - /// - /// - /// - public virtual void DeRezObject(IClientAPI remoteClient, uint localID, - UUID groupID, DeRezAction action, UUID destinationID) - { - DeRezObjects(remoteClient, new List() { localID }, groupID, action, destinationID); - } - public virtual void DeRezObjects(IClientAPI remoteClient, List localIDs, UUID groupID, DeRezAction action, UUID destinationID) { @@ -2003,14 +1972,19 @@ namespace OpenSim.Region.Framework.Scenes return group; } - public virtual bool returnObjects(SceneObjectGroup[] returnobjects, UUID AgentId) + public virtual bool returnObjects(SceneObjectGroup[] returnobjects, + UUID AgentId) { + List localIDs = new List(); + foreach (SceneObjectGroup grp in returnobjects) { - AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); - DeRezObject(null, grp.RootPart.LocalId, - grp.RootPart.GroupID, DeRezAction.Return, UUID.Zero); + AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, + "parcel owner return"); + localIDs.Add(grp.RootPart.LocalId); } + DeRezObjects(null, localIDs, UUID.Zero, DeRezAction.Return, + UUID.Zero); return true; } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index e835281..bcc439c 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2823,7 +2823,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnGrabUpdate += m_sceneGraph.MoveObject; client.OnSpinStart += m_sceneGraph.SpinStart; client.OnSpinUpdate += m_sceneGraph.SpinObject; - client.OnDeRezObject += DeRezObject; + client.OnDeRezObject += DeRezObjects; client.OnObjectName += m_sceneGraph.PrimName; client.OnObjectClickAction += m_sceneGraph.PrimClickAction; @@ -2953,7 +2953,7 @@ namespace OpenSim.Region.Framework.Scenes client.OnGrabUpdate -= m_sceneGraph.MoveObject; client.OnSpinStart -= m_sceneGraph.SpinStart; client.OnSpinUpdate -= m_sceneGraph.SpinObject; - client.OnDeRezObject -= DeRezObject; + client.OnDeRezObject -= DeRezObjects; client.OnObjectName -= m_sceneGraph.PrimName; client.OnObjectClickAction -= m_sceneGraph.PrimClickAction; client.OnObjectMaterial -= m_sceneGraph.PrimMaterial; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a00a7c4..a6d89cf 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1569,6 +1569,8 @@ namespace OpenSim.Region.Framework.Scenes ILandObject parcel = m_scene.LandChannel.GetLandObject( m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); + List returns = new List(); + if (parcel != null && parcel.LandData != null && parcel.LandData.OtherCleanTime != 0) { @@ -1582,13 +1584,15 @@ namespace OpenSim.Region.Framework.Scenes DetachFromBackup(); m_log.InfoFormat("[SCENE]: Returning object {0} due to parcel auto return", RootPart.UUID.ToString()); m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel auto return"); - m_scene.DeRezObject(null, RootPart.LocalId, - RootPart.GroupID, DeRezAction.Return, UUID.Zero); + returns.Add(RootPart.LocalId); return; } } } + + m_scene.DeRezObjects(null, returns, UUID.Zero, + DeRezAction.Return, UUID.Zero); } if (HasGroupChanged) diff --git a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs index 5616a4e..4969b09 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/SceneObjectBasicTests.cs @@ -142,7 +142,7 @@ namespace OpenSim.Region.Framework.Scenes.Tests SceneObjectPart part = SceneSetupHelpers.AddSceneObject(scene); IClientAPI client = SceneSetupHelpers.AddRootAgent(scene, agentId); - scene.DeRezObject(client, part.LocalId, UUID.Zero, DeRezAction.Delete, UUID.Zero); + scene.DeRezObjects(client, new System.Collections.Generic.List() { part.LocalId }, UUID.Zero, DeRezAction.Delete, UUID.Zero); SceneObjectPart retrievedPart = scene.GetSceneObjectPart(part.LocalId); diff --git a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs index fc9db03..9d7733e 100644 --- a/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs +++ b/OpenSim/Tests/Common/Setup/SceneSetupHelpers.cs @@ -556,7 +556,7 @@ namespace OpenSim.Tests.Common.Setup AsyncSceneObjectGroupDeleter sogd = scene.SceneObjectGroupDeleter; sogd.Enabled = false; - scene.DeRezObject(client, part.LocalId, UUID.Zero, action, destinationId); + scene.DeRezObjects(client, new List() { part.LocalId }, UUID.Zero, action, destinationId); sogd.InventoryDeQueueAndDelete(); } } -- cgit v1.1 From 2db0ac74c72f18d1bceb15b8a368777e42b366c0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Oct 2010 01:13:17 +0200 Subject: Implement taking of coalesced objects. WARNING!!!!! You can TAKE them, but you can't REZ them again. Only the first of the contained objects will rez, the rest is inaccessible until rezzing them is implemented. Also, rotations are not explicitly stored. This MAY work. Or not. --- .../InventoryAccess/InventoryAccessModule.cs | 463 ++++++++++++--------- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 4 +- OpenSim/Region/Framework/Scenes/Scene.cs | 9 + .../Region/Framework/Scenes/SceneObjectGroup.cs | 7 +- 4 files changed, 276 insertions(+), 207 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 9ccf5a0..753aada 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Xml; using System.Reflection; using System.Threading; @@ -191,11 +192,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient) { - // HACK: This is only working for lists containing a single item! - // It's just a hack to make this WIP compile and run. Nothing - // currently calls this with multiple items. UUID ret = UUID.Zero; + // The following code groups the SOG's by owner. No objects + // belonging to different people can be coalesced, for obvious + // reasons. Dictionary> deletes = new Dictionary>(); @@ -207,266 +208,328 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess deletes[g.OwnerID].Add(g); } - foreach (List objlist in deletes.Values) - ret = DeleteToInventory(action, folderID, objlist, remoteClient); + // This is pethod scoped and will be returned. It will be the + // last created asset id + UUID assetID = UUID.Zero; - return ret; - } + // Each iteration is really a separate asset being created, + // with distinct destinations as well. + foreach (List objlist in deletes.Values) + { + Dictionary xmlStrings = + new Dictionary(); - private UUID DeleteToInventory(DeRezAction action, UUID folderID, - SceneObjectGroup objectGroup, IClientAPI remoteClient) - { - UUID assetID = UUID.Zero; + foreach (SceneObjectGroup objectGroup in objlist) + { + Vector3 inventoryStoredPosition = new Vector3 + (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) + ? 250 + : objectGroup.AbsolutePosition.X) + , + (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) + ? 250 + : objectGroup.AbsolutePosition.X, + objectGroup.AbsolutePosition.Z); - Vector3 inventoryStoredPosition = new Vector3 - (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) - ? 250 - : objectGroup.AbsolutePosition.X) - , - (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) - ? 250 - : objectGroup.AbsolutePosition.X, - objectGroup.AbsolutePosition.Z); + Vector3 originalPosition = objectGroup.AbsolutePosition; - Vector3 originalPosition = objectGroup.AbsolutePosition; + // Restore attachment data after trip through the sim + if (objectGroup.RootPart.AttachPoint > 0) + inventoryStoredPosition = objectGroup.RootPart.AttachOffset; + objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; - // Restore attachment data after trip through the sim - if (objectGroup.RootPart.AttachPoint > 0) - inventoryStoredPosition = objectGroup.RootPart.AttachOffset; - objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; + objectGroup.AbsolutePosition = inventoryStoredPosition; - objectGroup.AbsolutePosition = inventoryStoredPosition; + // Make sure all bits but the ones we want are clear + // on take. + // This will be applied to the current perms, so + // it will do what we want. + objectGroup.RootPart.NextOwnerMask &= + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify); + objectGroup.RootPart.NextOwnerMask |= + (uint)PermissionMask.Move; - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); - objectGroup.AbsolutePosition = originalPosition; + objectGroup.AbsolutePosition = originalPosition; - // Get the user info of the item destination - // - UUID userID = UUID.Zero; + xmlStrings[objectGroup.UUID] = sceneObjectXml; + } - if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || - action == DeRezAction.SaveToExistingUserInventoryItem) - { - // Take or take copy require a taker - // Saving changes requires a local user - // - if (remoteClient == null) - return UUID.Zero; + string itemXml; - userID = remoteClient.AgentId; - } - else - { - // All returns / deletes go to the object owner - // + if (objlist.Count > 1) + { + float minX, minY, minZ; + float maxX, maxY, maxZ; - userID = objectGroup.RootPart.OwnerID; - } + Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist, + out minX, out maxX, out minY, out maxY, + out minZ, out maxZ); - if (userID == UUID.Zero) // Can't proceed - { - return UUID.Zero; - } + // CreateWrapper + XmlDocument itemDoc = new XmlDocument(); + XmlElement root = itemDoc.CreateElement("", "CoalescedObject", ""); + itemDoc.AppendChild(root); - // If we're returning someone's item, it goes back to the - // owner's Lost And Found folder. - // Delete is treated like return in this case - // Deleting your own items makes them go to trash - // + // Embed the offsets into the group XML + for ( int i = 0 ; i < objlist.Count ; i++ ) + { + XmlDocument doc = new XmlDocument(); + SceneObjectGroup g = objlist[i]; + doc.LoadXml(xmlStrings[g.UUID]); + XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); + e.SetAttribute("offsetx", offsets[i].X.ToString()); + e.SetAttribute("offsety", offsets[i].Y.ToString()); + e.SetAttribute("offsetz", offsets[i].Z.ToString()); - InventoryFolderBase folder = null; - InventoryItemBase item = null; + XmlNode objectNode = itemDoc.ImportNode(e, true); + root.AppendChild(objectNode); + } - if (DeRezAction.SaveToExistingUserInventoryItem == action) - { - item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); - item = m_Scene.InventoryService.GetItem(item); + float sizeX = maxX - minX; + float sizeY = maxY - minY; + float sizeZ = maxZ - minZ; - //item = userInfo.RootFolder.FindItem( - // objectGroup.RootPart.FromUserInventoryItemID); + root.SetAttribute("x", sizeX.ToString()); + root.SetAttribute("y", sizeY.ToString()); + root.SetAttribute("z", sizeZ.ToString()); - if (null == item) + itemXml = itemDoc.InnerXml; + } + else { - m_log.DebugFormat( - "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", - objectGroup.Name, objectGroup.UUID); - return UUID.Zero; + itemXml = xmlStrings[objlist[0].UUID]; } - } - else - { - // Folder magic + + // Get the user info of the item destination // - if (action == DeRezAction.Delete) + UUID userID = UUID.Zero; + + if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || + action == DeRezAction.SaveToExistingUserInventoryItem) { - // Deleting someone else's item + // Take or take copy require a taker + // Saving changes requires a local user // - if (remoteClient == null || - objectGroup.OwnerID != remoteClient.AgentId) - { + if (remoteClient == null) + return UUID.Zero; - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); - } - else - { - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); - } + userID = remoteClient.AgentId; } - else if (action == DeRezAction.Return) + else { - - // Dump to lost + found unconditionally + // All returns / deletes go to the object owner // - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + + userID = objlist[0].RootPart.OwnerID; } - if (folderID == UUID.Zero && folder == null) + if (userID == UUID.Zero) // Can't proceed { - if (action == DeRezAction.Delete) + return UUID.Zero; + } + + // If we're returning someone's item, it goes back to the + // owner's Lost And Found folder. + // Delete is treated like return in this case + // Deleting your own items makes them go to trash + // + + InventoryFolderBase folder = null; + InventoryItemBase item = null; + + if (DeRezAction.SaveToExistingUserInventoryItem == action) + { + item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); + item = m_Scene.InventoryService.GetItem(item); + + //item = userInfo.RootFolder.FindItem( + // objectGroup.RootPart.FromUserInventoryItemID); + + if (null == item) { - // Deletes go to trash by default - // - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); + m_log.DebugFormat( + "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", + objlist[0].Name, objlist[0].UUID); + return UUID.Zero; } - else + } + else + { + // Folder magic + // + if (action == DeRezAction.Delete) { + // Deleting someone else's item + // if (remoteClient == null || - objectGroup.OwnerID != remoteClient.AgentId) + objlist[0].OwnerID != remoteClient.AgentId) { - // Taking copy of another person's item. Take to - // Objects folder. - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); + + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } else { - // Catch all. Use lost & found + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); + } + } + else if (action == DeRezAction.Return) + { + + // Dump to lost + found unconditionally + // + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } + + if (folderID == UUID.Zero && folder == null) + { + if (action == DeRezAction.Delete) + { + // Deletes go to trash by default // + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); + } + else + { + if (remoteClient == null || + objlist[0].OwnerID != remoteClient.AgentId) + { + // Taking copy of another person's item. Take to + // Objects folder. + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); + } + else + { + // Catch all. Use lost & found + // - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } } } - } - // Override and put into where it came from, if it came - // from anywhere in inventory - // - if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) - { - if (objectGroup.RootPart.FromFolderID != UUID.Zero) + // Override and put into where it came from, if it came + // from anywhere in inventory + // + if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) { - InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID); - folder = m_Scene.InventoryService.GetFolder(f); + if (objlist[0].RootPart.FromFolderID != UUID.Zero) + { + InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); + folder = m_Scene.InventoryService.GetFolder(f); + } } - } - - if (folder == null) // None of the above - { - folder = new InventoryFolderBase(folderID); - if (folder == null) // Nowhere to put it + if (folder == null) // None of the above { - return UUID.Zero; - } - } + folder = new InventoryFolderBase(folderID); - item = new InventoryItemBase(); - item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); - item.ID = UUID.Random(); - item.InvType = (int)InventoryType.Object; - item.Folder = folder.ID; - item.Owner = userID; - } + if (folder == null) // Nowhere to put it + { + return UUID.Zero; + } + } - AssetBase asset = CreateAsset( - objectGroup.GetPartName(objectGroup.RootPart.LocalId), - objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), - (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml), - objectGroup.OwnerID.ToString()); - m_Scene.AssetService.Store(asset); - assetID = asset.FullID; + item = new InventoryItemBase(); + // Can't know creator is the same, so null it in inventory + if (objlist.Count > 1) + item.CreatorId = UUID.Zero.ToString(); + else + item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); + item.ID = UUID.Random(); + item.InvType = (int)InventoryType.Object; + item.Folder = folder.ID; + item.Owner = userID; + if (objlist.Count > 1) + item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; + } - if (DeRezAction.SaveToExistingUserInventoryItem == action) - { - item.AssetID = asset.FullID; - m_Scene.InventoryService.UpdateItem(item); - } - else - { - item.AssetID = asset.FullID; + AssetBase asset = CreateAsset( + objlist[0].GetPartName(objlist[0].RootPart.LocalId), + objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), + (sbyte)AssetType.Object, + Utils.StringToBytes(itemXml), + objlist[0].OwnerID.ToString()); + m_Scene.AssetService.Store(asset); + assetID = asset.FullID; - if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) + if (DeRezAction.SaveToExistingUserInventoryItem == action) { - uint perms = objectGroup.GetEffectivePermissions(); - uint nextPerms = (perms & 7) << 13; - if ((nextPerms & (uint)PermissionMask.Copy) == 0) - perms &= ~(uint)PermissionMask.Copy; - if ((nextPerms & (uint)PermissionMask.Transfer) == 0) - perms &= ~(uint)PermissionMask.Transfer; - if ((nextPerms & (uint)PermissionMask.Modify) == 0) - perms &= ~(uint)PermissionMask.Modify; - - // Make sure all bits but the ones we want are clear - // on take. - // This will be applied to the current perms, so - // it will do what we want. - objectGroup.RootPart.NextOwnerMask &= - ((uint)PermissionMask.Copy | - (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify); - objectGroup.RootPart.NextOwnerMask |= - (uint)PermissionMask.Move; - - item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask; - item.CurrentPermissions = item.BasePermissions; - item.NextPermissions = objectGroup.RootPart.NextOwnerMask; - item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask; - item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask; - - // Magic number badness. Maybe this deserves an enum. - // bit 4 (16) is the "Slam" bit, it means treat as passed - // and apply next owner perms on rez - item.CurrentPermissions |= 16; // Slam! + item.AssetID = asset.FullID; + m_Scene.InventoryService.UpdateItem(item); } else { - item.BasePermissions = objectGroup.GetEffectivePermissions(); - item.CurrentPermissions = objectGroup.GetEffectivePermissions(); - item.NextPermissions = objectGroup.RootPart.NextOwnerMask; - item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; - item.GroupPermissions = objectGroup.RootPart.GroupMask; + item.AssetID = asset.FullID; + + uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; + foreach (SceneObjectGroup grp in objlist) + effectivePerms &= grp.GetEffectivePermissions(); + effectivePerms |= (uint)PermissionMask.Move; + + if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) + { + uint perms = effectivePerms; + uint nextPerms = (perms & 7) << 13; + if ((nextPerms & (uint)PermissionMask.Copy) == 0) + perms &= ~(uint)PermissionMask.Copy; + if ((nextPerms & (uint)PermissionMask.Transfer) == 0) + perms &= ~(uint)PermissionMask.Transfer; + if ((nextPerms & (uint)PermissionMask.Modify) == 0) + perms &= ~(uint)PermissionMask.Modify; + + item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask; + item.CurrentPermissions = item.BasePermissions; + item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask; + item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask; + item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask; + + // Magic number badness. Maybe this deserves an enum. + // bit 4 (16) is the "Slam" bit, it means treat as passed + // and apply next owner perms on rez + item.CurrentPermissions |= 16; // Slam! + } + else + { + item.BasePermissions = effectivePerms; + item.CurrentPermissions = effectivePerms; + item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms; + item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms; + item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms; - item.CurrentPermissions &= - ((uint)PermissionMask.Copy | - (uint)PermissionMask.Transfer | - (uint)PermissionMask.Modify | - (uint)PermissionMask.Move | - 7); // Preserve folded permissions - } + item.CurrentPermissions &= + ((uint)PermissionMask.Copy | + (uint)PermissionMask.Transfer | + (uint)PermissionMask.Modify | + (uint)PermissionMask.Move | + 7); // Preserve folded permissions + } - // TODO: add the new fields (Flags, Sale info, etc) - item.CreationDate = Util.UnixTimeSinceEpoch(); - item.Description = asset.Description; - item.Name = asset.Name; - item.AssetType = asset.Type; + // TODO: add the new fields (Flags, Sale info, etc) + item.CreationDate = Util.UnixTimeSinceEpoch(); + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; - m_Scene.AddInventoryItem(item); + m_Scene.AddInventoryItem(item); - if (remoteClient != null && item.Owner == remoteClient.AgentId) - { - remoteClient.SendInventoryItemCreateUpdate(item, 0); - } - else - { - ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); - if (notifyUser != null) + if (remoteClient != null && item.Owner == remoteClient.AgentId) { - notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); + remoteClient.SendInventoryItemCreateUpdate(item, 0); + } + else + { + ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); + if (notifyUser != null) + { + notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); + } } } } - return assetID; } diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 64567db..8feb022 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes x = m_inventoryDeletes.Dequeue(); m_log.DebugFormat( - "[ASYNC DELETER]: Sending object to user's inventory, {0} item(s) remaining.", left); + "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count); try { @@ -177,4 +177,4 @@ namespace OpenSim.Region.Framework.Scenes return false; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index bcc439c..76e160d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5063,8 +5063,17 @@ namespace OpenSim.Region.Framework.Scenes { float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; + Vector3 vec = g.AbsolutePosition; + g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); + ominX += vec.X; + omaxX += vec.X; + ominY += vec.Y; + omaxY += vec.Y; + ominZ += vec.Z; + omaxZ += vec.Z; + if (minX > ominX) minX = ominX; if (minY > ominY) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a6d89cf..9a7d560 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1569,8 +1569,6 @@ namespace OpenSim.Region.Framework.Scenes ILandObject parcel = m_scene.LandChannel.GetLandObject( m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); - List returns = new List(); - if (parcel != null && parcel.LandData != null && parcel.LandData.OtherCleanTime != 0) { @@ -1584,15 +1582,14 @@ namespace OpenSim.Region.Framework.Scenes DetachFromBackup(); m_log.InfoFormat("[SCENE]: Returning object {0} due to parcel auto return", RootPart.UUID.ToString()); m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel auto return"); - returns.Add(RootPart.LocalId); + m_scene.DeRezObjects(null, new List() { RootPart.LocalId }, UUID.Zero, + DeRezAction.Return, UUID.Zero); return; } } } - m_scene.DeRezObjects(null, returns, UUID.Zero, - DeRezAction.Return, UUID.Zero); } if (HasGroupChanged) -- cgit v1.1 From ba0afa53d30566381d5757fb5a7b1ce55fe4521a Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 7 Oct 2010 05:12:39 +0200 Subject: Implement rezzing coalesced objects --- .../InventoryAccess/InventoryAccessModule.cs | 318 ++++++++++++--------- 1 file changed, 182 insertions(+), 136 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 753aada..d429979 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -444,7 +444,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess item.Folder = folder.ID; item.Owner = userID; if (objlist.Count > 1) + { item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; + } + else + { + item.SaleType = objlist[0].RootPart.ObjectSaleType; + item.SalePrice = objlist[0].RootPart.SalePrice; + } } AssetBase asset = CreateAsset( @@ -508,7 +515,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess 7); // Preserve folded permissions } - // TODO: add the new fields (Flags, Sale info, etc) item.CreationDate = Util.UnixTimeSinceEpoch(); item.Description = asset.Description; item.Name = asset.Name; @@ -587,6 +593,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); + SceneObjectGroup group = null; + if (rezAsset != null) { UUID itemId = UUID.Zero; @@ -595,16 +603,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { - if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { itemId = item.ID; } } else { - // Brave new fullperm world - // - itemId = item.ID; + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + // Brave new fullperm world + itemId = item.ID; + } } if (item.ID == UUID.Zero) @@ -613,27 +623,63 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } string xmlData = Utils.BytesToString(rezAsset.Data); - SceneObjectGroup group - = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); - Vector3 storedPosition = group.AbsolutePosition; - if (group.UUID == UUID.Zero) + List objlist = + new List(); + List veclist = new List(); + + XmlDocument doc = new XmlDocument(); + doc.LoadXml(xmlData); + XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); + if (e == null || attachment) // Single { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); - } - group.RootPart.FromFolderID = item.Folder; + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, xmlData); + objlist.Add(g); + veclist.Add(new Vector3(0, 0, 0)); - // If it's rezzed in world, select it. Much easier to - // find small items. - // - if (!attachment) + float offsetHeight = 0; + pos = m_Scene.GetNewRezLocation( + RayStart, RayEnd, RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); + pos.Z += offsetHeight; + } + else { - group.RootPart.CreateSelected = true; - foreach (SceneObjectPart child in group.Parts) - child.CreateSelected = true; + XmlElement coll = (XmlElement)e; + float bx = Convert.ToSingle(coll.GetAttribute("x")); + float by = Convert.ToSingle(coll.GetAttribute("y")); + float bz = Convert.ToSingle(coll.GetAttribute("z")); + Vector3 bbox = new Vector3(bx, by, bz); + + pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, + RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, + bbox, false); + + pos -= bbox / 2; + + XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); + foreach (XmlNode n in groups) + { + SceneObjectGroup g = + SceneObjectSerializer.FromOriginalXmlFormat( + itemId, n.OuterXml); + objlist.Add(g); + XmlElement el = (XmlElement)n; + float x = Convert.ToSingle(el.GetAttribute("offsetx")); + float y = Convert.ToSingle(el.GetAttribute("offsety")); + float z = Convert.ToSingle(el.GetAttribute("offsetz")); + veclist.Add(new Vector3(x, y, z)); + } } + int primcount = 0; + foreach (SceneObjectGroup g in objlist) + primcount += g.PrimCount; + if (!m_Scene.Permissions.CanRezObject( - group.PrimCount, remoteClient.AgentId, pos) + primcount, remoteClient.AgentId, pos) && !attachment) { // The client operates in no fail mode. It will @@ -645,135 +691,139 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess remoteClient.SendBulkUpdateInventory(item); return null; } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 4"); - } - group.ResetIDs(); - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 5"); - } - if (attachment) + + for (int i = 0 ; i < objlist.Count ; i++ ) { - group.RootPart.Flags |= PrimFlags.Phantom; - group.RootPart.IsAttachment = true; - } + group = objlist[i]; - // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since - // we'll be doing that later on. Scheduling more than one full update during the attachment - // process causes some clients to fail to display the attachment properly. - m_Scene.AddNewSceneObject(group, true, false); + Vector3 storedPosition = group.AbsolutePosition; + if (group.UUID == UUID.Zero) + { + m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 3"); + } + group.RootPart.FromFolderID = item.Folder; - // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); - // if attachment we set it's asset id so object updates can reflect that - // if not, we set it's position in world. - if (!attachment) - { - group.ScheduleGroupForFullUpdate(); - - float offsetHeight = 0; - pos = m_Scene.GetNewRezLocation( - RayStart, RayEnd, RayTargetID, Quaternion.Identity, - BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); - pos.Z += offsetHeight; - group.AbsolutePosition = pos; - // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); + // If it's rezzed in world, select it. Much easier to + // find small items. + // + if (!attachment) + { + group.RootPart.CreateSelected = true; + foreach (SceneObjectPart child in group.Parts) + child.CreateSelected = true; + } - } - else - { - group.SetFromItemID(itemID); - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 6"); - } - SceneObjectPart rootPart = null; - try - { - rootPart = group.GetChildPart(group.UUID); - } - catch (NullReferenceException) - { - string isAttachment = ""; + group.ResetIDs(); if (attachment) - isAttachment = " Object was an attachment"; + { + group.RootPart.Flags |= PrimFlags.Phantom; + group.RootPart.IsAttachment = true; + } - m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 7"); - } - // Since renaming the item in the inventory does not affect the name stored - // in the serialization, transfer the correct name from the inventory to the - // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - - group.SetGroup(remoteClient.ActiveGroupId, remoteClient); - if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) - { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; + // If we're rezzing an attachment then don't ask + // AddNewSceneObject() to update the client since + // we'll be doing that later on. Scheduling more than + // one full update during the attachment + // process causes some clients to fail to display the + // attachment properly. + m_Scene.AddNewSceneObject(group, true, false); + + // if attachment we set it's asset id so object updates + // can reflect that, if not, we set it's position in world. + if (!attachment) + { + group.ScheduleGroupForFullUpdate(); + + group.AbsolutePosition = pos + veclist[i]; + } + else + { + group.SetFromItemID(itemID); + } + + SceneObjectPart rootPart = null; + + try + { + rootPart = group.GetChildPart(group.UUID); + } + catch (NullReferenceException) + { + string isAttachment = ""; + + if (attachment) + isAttachment = " Object was an attachment"; + + m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); + } - if (m_Scene.Permissions.PropagatePermissions()) + // Since renaming the item in the inventory does not + // affect the name stored in the serialization, transfer + // the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; + + group.SetGroup(remoteClient.ActiveGroupId, remoteClient); + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) { - foreach (SceneObjectPart part in group.Parts) + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + + if (m_Scene.Permissions.PropagatePermissions()) { - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - part.GroupMask = 0; // DO NOT propagate here + foreach (SceneObjectPart part in group.Parts) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + } + part.GroupMask = 0; // DO NOT propagate here + } + + group.ApplyNextOwnerPermissions(); } - - group.ApplyNextOwnerPermissions(); } - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 8"); - } - foreach (SceneObjectPart part in group.Parts) - { - if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) + foreach (SceneObjectPart part in group.Parts) { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.Owner; - part.Inventory.ChangeInventoryOwner(item.Owner); - part.GroupMask = 0; // DO NOT propagate here + if ((part.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); + part.GroupMask = 0; // DO NOT propagate here + } + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; } - part.EveryoneMask = item.EveryOnePermissions; - part.NextOwnerMask = item.NextPermissions; - } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 9"); - } - rootPart.TrimPermissions(); - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 10"); - } - if (!attachment) - { - if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + + rootPart.TrimPermissions(); + + if (!attachment) { - // Save attachment data - group.RootPart.AttachPoint = group.RootPart.Shape.State; - group.RootPart.AttachOffset = storedPosition; + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + { + // Save attachment data + group.RootPart.AttachPoint = group.RootPart.Shape.State; + group.RootPart.AttachOffset = storedPosition; - group.ClearPartAttachmentData(); - } - - // Fire on_rez - group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); - rootPart.ParentGroup.ResumeScripts(); + group.ClearPartAttachmentData(); + } + + // Fire on_rez + group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 1); + rootPart.ParentGroup.ResumeScripts(); - rootPart.ScheduleFullUpdate(); + rootPart.ScheduleFullUpdate(); + } } if (!m_Scene.Permissions.BypassPermissions()) @@ -791,12 +841,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } } - if (group.UUID == UUID.Zero) - { - m_log.Debug("[InventoryAccessModule]: Inventory object has UUID.Zero! Position 11"); - } - return group; } + return group; } return null; -- cgit v1.1 From 52dd547863c0cdd22f53f0efcaef11ae096855a0 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 8 Oct 2010 11:31:52 +0200 Subject: Make SendKillObject send multiple localIDs in one packet. This avoids the halting visual behavior of large group deletes and eliminates the packet flood --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 8 ++++- .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 2 +- OpenSim/Framework/IClientAPI.cs | 2 +- .../Region/ClientStack/LindenUDP/LLClientView.cs | 41 ++++++++++++++-------- .../Avatar/Attachments/AttachmentsModule.cs | 2 +- .../EntityTransfer/EntityTransferModule.cs | 2 +- .../Region/Examples/SimpleModule/ComplexObject.cs | 5 +-- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 2 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 7 ++++ OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 8 +++-- OpenSim/Region/Framework/Scenes/Scene.cs | 26 ++++++++------ .../Framework/Scenes/SceneCommunicationService.cs | 4 --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 6 +--- .../Server/IRCClientView.cs | 2 +- .../ContentManagementSystem/CMModel.cs | 3 +- .../ContentManagementSystem/MetaEntity.cs | 4 +-- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 2 +- .../World/TreePopulator/TreePopulatorModule.cs | 4 +-- OpenSim/Tests/Common/Mock/TestClient.cs | 2 +- 19 files changed, 79 insertions(+), 53 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 87b99e0..df9d21b 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -897,7 +897,13 @@ namespace OpenSim.Client.MXP.ClientStack // Need to translate to MXP somehow } - public void SendKillObject(ulong regionHandle, uint localID) + public void SendKillObject(ulong regionHandle, List localIDs) + { + foreach (uint localID in localIDs) + SendKillObject(regionHandle, localID); + } + + private void SendKillObject(ulong regionHandle, uint localID) { DisappearanceEventMessage de = new DisappearanceEventMessage(); de.ObjectIndex = localID; diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 51c5c17..26be5d9 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -495,7 +495,7 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void SendKillObject(ulong regionHandle, uint localID) + public void SendKillObject(ulong regionHandle, List localID) { throw new System.NotImplementedException(); } diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 9025dda..51482a1 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -979,7 +979,7 @@ namespace OpenSim.Framework /// /// /// - void SendKillObject(ulong regionHandle, uint localID); + void SendKillObject(ulong regionHandle, List localID); void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs); void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 2b1bd97..fff4300 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -1516,35 +1516,46 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(pc, ThrottleOutPacketType.Unknown); } - public void SendKillObject(ulong regionHandle, uint localID) + public void SendKillObject(ulong regionHandle, List localIDs) { // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); // TODO: don't create new blocks if recycling an old packet - kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; - kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); - kill.ObjectData[0].ID = localID; + kill.ObjectData = new KillObjectPacket.ObjectDataBlock[localIDs.Count]; + for (int i = 0 ; i < localIDs.Count ; i++ ) + { + kill.ObjectData[i] = new KillObjectPacket.ObjectDataBlock(); + kill.ObjectData[i].ID = localIDs[i]; + } kill.Header.Reliable = true; kill.Header.Zerocoded = true; - if (m_scene.GetScenePresence(localID) == null) + if (localIDs.Count == 1) { - lock (m_entityUpdates.SyncRoot) + if (m_scene.GetScenePresence(localIDs[0]) != null) { - m_killRecord.Add(localID); - - // The throttle queue used here must match that being used for updates. Otherwise, there is a - // chance that a kill packet put on a separate queue will be sent to the client before an existing - // update packet on another queue. Receiving updates after kills results in unowned and undeletable - // scene objects in a viewer until that viewer is relogged in. - OutPacket(kill, ThrottleOutPacketType.Task); + OutPacket(kill, ThrottleOutPacketType.State); + return; } + m_killRecord.Add(localIDs[0]); } else { - OutPacket(kill, ThrottleOutPacketType.State); + lock (m_entityUpdates.SyncRoot) + { + foreach (uint localID in localIDs) + m_killRecord.Add(localID); + } } + + // The throttle queue used here must match that being used for + // updates. Otherwise, there is a chance that a kill packet put + // on a separate queue will be sent to the client before an + // existing update packet on another queue. Receiving updates + // after kills results in unowned and undeletable + // scene objects in a viewer until that viewer is relogged in. + OutPacket(kill, ThrottleOutPacketType.Task); } /// @@ -10969,7 +10980,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { // It's a ghost! tell the client to delete it from view. simClient.SendKillObject(Scene.RegionInfo.RegionHandle, - localId); + new List() { localId }); } else { diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 87c9100..6ff0ffc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -616,7 +616,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // if (so.IsSelected) { - m_scene.SendKillObject(so.RootPart.LocalId); + m_scene.SendKillObject(new List { so.RootPart.LocalId }); } so.IsSelected = false; // fudge.... diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index d506208..2921b0d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -529,7 +529,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected void KillEntity(Scene scene, uint localID) { - scene.SendKillObject(localID); + scene.SendKillObject(new List() { localID }); } protected virtual GridRegion GetFinalDestination(GridRegion region) diff --git a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs index e951bef..7a0ce51 100644 --- a/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs +++ b/OpenSim/Region/Examples/SimpleModule/ComplexObject.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System.Collections.Generic; using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Scenes; @@ -110,7 +111,7 @@ namespace OpenSim.Region.Examples.SimpleModule { m_parts.Remove(part.UUID); - remoteClient.SendKillObject(m_regionHandle, part.LocalId); + remoteClient.SendKillObject(m_regionHandle, new List() { part.LocalId} ); remoteClient.AddMoney(1); remoteClient.SendChatMessage("Poof!", 1, AbsolutePosition, "Party Party", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); } @@ -121,7 +122,7 @@ namespace OpenSim.Region.Examples.SimpleModule { m_parts.Remove(m_rootPart.UUID); m_scene.DeleteSceneObject(this, false); - remoteClient.SendKillObject(m_regionHandle, m_rootPart.LocalId); + remoteClient.SendKillObject(m_regionHandle, new List() { m_rootPart.LocalId }); remoteClient.AddMoney(50); remoteClient.SendChatMessage("KABLAM!!!", 1, AbsolutePosition, "Groupie Groupie", UUID.Zero, (byte)ChatSourceType.Object, (byte)ChatAudibleLevel.Fully); } diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 944ad94..db427b4 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -429,7 +429,7 @@ namespace OpenSim.Region.Examples.SimpleModule } - public virtual void SendKillObject(ulong regionHandle, uint localID) + public virtual void SendKillObject(ulong regionHandle, List localID) { } diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 8feb022..a8d24fd 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -104,8 +104,15 @@ namespace OpenSim.Region.Framework.Scenes // better than losing the object for now. if (permissionToDelete) { + List killIDs = new List(); + foreach (SceneObjectGroup g in objectGroups) + { + killIDs.Add(g.LocalId); g.DeleteGroupFromScene(false); + } + + m_scene.SendKillObject(killIDs); } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8b5316a..6d7f984 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1709,7 +1709,7 @@ namespace OpenSim.Region.Framework.Scenes if (part == null) { //Client still thinks the object exists, kill it - SendKillObject(localID); + deleteIDs.Add(localID); continue; } @@ -1717,7 +1717,7 @@ namespace OpenSim.Region.Framework.Scenes if (part.ParentGroup == null || part.ParentGroup.IsDeleted) { //Client still thinks the object exists, kill it - SendKillObject(localID); + deleteIDs.Add(localID); continue; } @@ -1727,8 +1727,8 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup grp = part.ParentGroup; - deleteIDs.Add(localID); deleteGroups.Add(grp); + deleteIDs.Add(grp.LocalId); if (remoteClient == null) { @@ -1811,6 +1811,8 @@ namespace OpenSim.Region.Framework.Scenes } } + SendKillObject(deleteIDs); + if (permissionToTake) { m_asyncSceneObjectDeleter.DeleteToInventory( diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 76e160d..48ae4ca 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2188,6 +2188,8 @@ namespace OpenSim.Region.Framework.Scenes } group.DeleteGroupFromScene(silent); + if (!silent) + SendKillObject(new List() { group.LocalId }); // m_log.DebugFormat("[SCENE]: Exit DeleteSceneObject() for {0} {1}", group.Name, group.UUID); } @@ -3273,7 +3275,7 @@ namespace OpenSim.Region.Framework.Scenes delegate(IClientAPI client) { //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway - try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } + try { client.SendKillObject(avatar.RegionHandle, new List() { avatar.LocalId}); } catch (NullReferenceException) { } }); @@ -3336,18 +3338,24 @@ namespace OpenSim.Region.Framework.Scenes #region Entities - public void SendKillObject(uint localID) + public void SendKillObject(List localIDs) { - SceneObjectPart part = GetSceneObjectPart(localID); - if (part != null) // It is a prim + List deleteIDs = new List(); + + foreach (uint localID in localIDs) { - if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid + SceneObjectPart part = GetSceneObjectPart(localID); + if (part != null) // It is a prim { - if (part.ParentGroup.RootPart != part) // Child part - return; + if (part.ParentGroup != null && !part.ParentGroup.IsDeleted) // Valid + { + if (part.ParentGroup.RootPart != part) // Child part + continue; + } } + deleteIDs.Add(localID); } - ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); + ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, deleteIDs); }); } #endregion @@ -3365,7 +3373,6 @@ namespace OpenSim.Region.Framework.Scenes //m_sceneGridService.OnChildAgentUpdate += IncomingChildAgentDataUpdate; //m_sceneGridService.OnRemoveKnownRegionFromAvatar += HandleRemoveKnownRegionsFromAvatar; m_sceneGridService.OnLogOffUser += HandleLogOffUserFromGrid; - m_sceneGridService.KiPrimitive += SendKillObject; m_sceneGridService.OnGetLandData += GetLandData; } @@ -3374,7 +3381,6 @@ namespace OpenSim.Region.Framework.Scenes /// public void UnRegisterRegionWithComms() { - m_sceneGridService.KiPrimitive -= SendKillObject; m_sceneGridService.OnLogOffUser -= HandleLogOffUserFromGrid; //m_sceneGridService.OnRemoveKnownRegionFromAvatar -= HandleRemoveKnownRegionsFromAvatar; //m_sceneGridService.OnChildAgentUpdate -= IncomingChildAgentDataUpdate; diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 1293d5d..632646d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -44,8 +44,6 @@ using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Region.Framework.Scenes { - public delegate void KiPrimitiveDelegate(uint localID); - public delegate void RemoveKnownRegionsFromAvatarList(UUID avatarID, List regionlst); /// @@ -113,8 +111,6 @@ namespace OpenSim.Region.Framework.Scenes // private LogOffUser handlerLogOffUser = null; // private GetLandData handlerGetLandData = null; // OnGetLandData - public KiPrimitiveDelegate KiPrimitive; - public SceneCommunicationService() { } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9a7d560..c870797 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1151,7 +1151,7 @@ namespace OpenSim.Region.Framework.Scenes // if (IsSelected) { - m_scene.SendKillObject(m_rootPart.LocalId); + m_scene.SendKillObject(new List { m_rootPart.LocalId }); } IsSelected = false; // fudge.... @@ -1415,11 +1415,7 @@ namespace OpenSim.Region.Framework.Scenes avatar.StandUp(); if (!silent) - { part.UpdateFlag = 0; - if (part == m_rootPart) - avatar.ControllingClient.SendKillObject(m_regionHandle, part.LocalId); - } }); } diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 4ab67aa..72e5ebd 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -947,7 +947,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void SendKillObject(ulong regionHandle, uint localID) + public void SendKillObject(ulong regionHandle, List localID) { } diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs index 3a6996e..84c7f29 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/CMModel.cs @@ -259,9 +259,10 @@ namespace OpenSim.Region.OptionalModules.ContentManagement // I thought that the DeleteGroup() function would handle all of this, but it doesn't. I'm not sure WHAT it handles. ((SceneObjectGroup)scene.Entities[uuid]).DetachFromBackup(); scene.PhysicsScene.RemovePrim(((SceneObjectGroup)scene.Entities[uuid]).RootPart.PhysActor); - scene.SendKillObject(scene.Entities[uuid].LocalId); + scene.SendKillObject(new List() { scene.Entities[uuid].LocalId }); scene.SceneGraph.DeleteSceneObject(uuid, false); ((SceneObjectGroup)scene.Entities[uuid]).DeleteGroupFromScene(false); + scene.SendKillObject(new List() { ((SceneObjectGroup)scene.Entities[uuid]).LocalId }); } catch(Exception e) { diff --git a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs index c7b1ed7..cd60f4b 100644 --- a/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs +++ b/OpenSim/Region/OptionalModules/ContentManagementSystem/MetaEntity.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement //This is important because we are not IN any database. //m_Entity.FakeDeleteGroup(); foreach (SceneObjectPart part in m_Entity.Parts) - client.SendKillObject(m_Entity.RegionHandle, part.LocalId); + client.SendKillObject(m_Entity.RegionHandle, new List() { part.LocalId }); } /// @@ -187,7 +187,7 @@ namespace OpenSim.Region.OptionalModules.ContentManagement { m_Entity.Scene.ForEachClient( delegate(IClientAPI controller) - { controller.SendKillObject(m_Entity.RegionHandle, part.LocalId); } + { controller.SendKillObject(m_Entity.RegionHandle, new List() { part.LocalId }); } ); } } diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 1653ecb..3cbe391 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -519,7 +519,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC } - public virtual void SendKillObject(ulong regionHandle, uint localID) + public virtual void SendKillObject(ulong regionHandle, List localID) { } diff --git a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs index 421da36..2563361 100644 --- a/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs +++ b/OpenSim/Region/OptionalModules/World/TreePopulator/TreePopulatorModule.cs @@ -386,7 +386,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator m_scene.ForEachClient(delegate(IClientAPI controller) { controller.SendKillObject(m_scene.RegionInfo.RegionHandle, - selectedTree.LocalId); + new List() { selectedTree.LocalId }); }); } else @@ -727,7 +727,7 @@ namespace OpenSim.Region.OptionalModules.World.TreePopulator m_scene.ForEachClient(delegate(IClientAPI controller) { controller.SendKillObject(m_scene.RegionInfo.RegionHandle, - selectedTree.LocalId); + new List() { selectedTree.LocalId }); }); break; diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 1c860a7..6324146 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -487,7 +487,7 @@ namespace OpenSim.Tests.Common.Mock } - public virtual void SendKillObject(ulong regionHandle, uint localID) + public virtual void SendKillObject(ulong regionHandle, List localID) { } -- cgit v1.1 From ff49a21eca5b084bf0df71f69bce98db0b2f0094 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 9 Oct 2010 01:02:57 +0200 Subject: Fix a security relevant issue with take / take copy --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 110 ++++++++++++--------- 1 file changed, 62 insertions(+), 48 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 6d7f984..9b5459d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1695,6 +1695,7 @@ namespace OpenSim.Region.Framework.Scenes // build a list of eligible objects List deleteIDs = new List(); List deleteGroups = new List(); + List takeGroups = new List(); // Start with true for both, then remove the flags if objects // that we can't derez are part of the selection @@ -1727,9 +1728,6 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectGroup grp = part.ParentGroup; - deleteGroups.Add(grp); - deleteIDs.Add(grp.LocalId); - if (remoteClient == null) { // Autoreturn has a null client. Nothing else does. So @@ -1756,73 +1754,89 @@ namespace OpenSim.Region.Framework.Scenes if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) permissionToDelete = false; } - } - // Handle god perms - if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) - { - permissionToTake = true; - permissionToTakeCopy = true; - permissionToDelete = true; - } + // Handle god perms + if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) + { + permissionToTake = true; + permissionToTakeCopy = true; + permissionToDelete = true; + } - // If we're re-saving, we don't even want to delete - if (action == DeRezAction.SaveToExistingUserInventoryItem) - permissionToDelete = false; + // If we're re-saving, we don't even want to delete + if (action == DeRezAction.SaveToExistingUserInventoryItem) + permissionToDelete = false; - // if we want to take a copy, we also don't want to delete - // Note: after this point, the permissionToTakeCopy flag - // becomes irrelevant. It already includes the permissionToTake - // permission and after excluding no copy items here, we can - // just use that. - if (action == DeRezAction.TakeCopy) - { - // If we don't have permission, stop right here - if (!permissionToTakeCopy) - return; + // if we want to take a copy, we also don't want to delete + // Note: after this point, the permissionToTakeCopy flag + // becomes irrelevant. It already includes the permissionToTake + // permission and after excluding no copy items here, we can + // just use that. + if (action == DeRezAction.TakeCopy) + { + // If we don't have permission, stop right here + if (!permissionToTakeCopy) + return; - permissionToTake = true; - // Don't delete - permissionToDelete = false; - } + permissionToTake = true; + // Don't delete + permissionToDelete = false; + } - if (action == DeRezAction.Return) - { - if (remoteClient != null) + if (action == DeRezAction.Return) { - if (Permissions.CanReturnObjects( - null, - remoteClient.AgentId, - deleteGroups)) + if (remoteClient != null) + { + if (Permissions.CanReturnObjects( + null, + remoteClient.AgentId, + deleteGroups)) + { + permissionToTake = true; + permissionToDelete = true; + + AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); + } + } + else // Auto return passes through here with null agent { permissionToTake = true; permissionToDelete = true; + } - foreach (SceneObjectGroup g in deleteGroups) - { - AddReturn(g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); - } + if (permissionToTake && (!permissionToDelete)) + takeGroups.Add(grp); + + if (permissionToDelete) + { + if (permissionToTake) + deleteGroups.Add(grp); + deleteIDs.Add(grp.LocalId); } } - else // Auto return passes through here with null agent - { - permissionToTake = true; - permissionToDelete = true; - } } SendKillObject(deleteIDs); - if (permissionToTake) + if (deleteGroups.Count > 0) { + foreach (SceneObjectGroup g in deleteGroups) + deleteIDs.Remove(g.LocalId); + m_asyncSceneObjectDeleter.DeleteToInventory( action, destinationID, deleteGroups, remoteClient, - permissionToDelete); + true); + } + if (takeGroups.Count > 0) + { + m_asyncSceneObjectDeleter.DeleteToInventory( + action, destinationID, takeGroups, remoteClient, + false); } - else if (permissionToDelete) + if (deleteIDs.Count > 0) { foreach (SceneObjectGroup g in deleteGroups) - DeleteSceneObject(g, false); + DeleteSceneObject(g, true); } } -- cgit v1.1 From c2971a6398f21cb3eb6c9cad46348a035eb2a0f5 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 10 Oct 2010 20:15:02 +0200 Subject: Add group invites to the list of messages that get offlined --- .../Avatar/InstantMessage/OfflineMessageModule.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 28 +++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index feeb9e6..d3db5b7 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -215,6 +215,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && im.dialog != (byte)InstantMessageDialog.MessageFromAgent && im.dialog != (byte)InstantMessageDialog.GroupNotice && + im.dialog != (byte)InstantMessageDialog.GroupInvitation && im.dialog != (byte)InstantMessageDialog.InventoryOffered) { return; diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 9b5459d..1d8b988 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -1697,14 +1697,14 @@ namespace OpenSim.Region.Framework.Scenes List deleteGroups = new List(); List takeGroups = new List(); - // Start with true for both, then remove the flags if objects - // that we can't derez are part of the selection - bool permissionToTake = true; - bool permissionToTakeCopy = true; - bool permissionToDelete = true; - foreach (uint localID in localIDs) { + // Start with true for both, then remove the flags if objects + // that we can't derez are part of the selection + bool permissionToTake = true; + bool permissionToTakeCopy = true; + bool permissionToDelete = true; + // Invalid id SceneObjectPart part = GetSceneObjectPart(localID); if (part == null) @@ -1803,16 +1803,16 @@ namespace OpenSim.Region.Framework.Scenes permissionToTake = true; permissionToDelete = true; } + } - if (permissionToTake && (!permissionToDelete)) - takeGroups.Add(grp); + if (permissionToTake && (!permissionToDelete)) + takeGroups.Add(grp); - if (permissionToDelete) - { - if (permissionToTake) - deleteGroups.Add(grp); - deleteIDs.Add(grp.LocalId); - } + if (permissionToDelete) + { + if (permissionToTake) + deleteGroups.Add(grp); + deleteIDs.Add(grp.LocalId); } } -- cgit v1.1 From 2804c97a39ece1352bc8ce8cf3672307798417df Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 10 Oct 2010 22:06:47 +0100 Subject: Change the part for sound playback to be the root part / object UUID instead of the child prim because using the child prim plain doesn't work. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index efdb94c..726bda1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2730,7 +2730,7 @@ namespace OpenSim.Region.Framework.Scenes public void PreloadSound(string sound) { // UUID ownerID = OwnerID; - UUID objectID = UUID; + UUID objectID = ParentGroup.RootPart.UUID; UUID soundID = UUID.Zero; if (!UUID.TryParse(sound, out soundID)) @@ -3112,7 +3112,7 @@ namespace OpenSim.Region.Framework.Scenes volume = 0; UUID ownerID = _ownerID; - UUID objectID = UUID; + UUID objectID = ParentGroup.RootPart.UUID; UUID parentID = GetRootPartUUID(); if (ParentGroup.IsAttachment && ParentGroup.RootPart.Shape.State > 30) @@ -3157,11 +3157,11 @@ namespace OpenSim.Region.Framework.Scenes else soundModule.PlayAttachedSound(soundID, ownerID, objectID, volume, position, flags, radius); ParentGroup.PlaySoundMasterPrim = this; - ownerID = this._ownerID; - objectID = this.UUID; - parentID = this.GetRootPartUUID(); - position = this.AbsolutePosition; // region local - regionHandle = this.ParentGroup.Scene.RegionInfo.RegionHandle; + ownerID = _ownerID; + objectID = ParentGroup.RootPart.UUID; + parentID = GetRootPartUUID(); + position = AbsolutePosition; // region local + regionHandle = ParentGroup.Scene.RegionInfo.RegionHandle; if (triggered) soundModule.TriggerSound(soundID, ownerID, objectID, parentID, volume, position, regionHandle, radius); else @@ -3169,7 +3169,7 @@ namespace OpenSim.Region.Framework.Scenes foreach (SceneObjectPart prim in ParentGroup.PlaySoundSlavePrims) { ownerID = prim._ownerID; - objectID = prim.UUID; + objectID = prim.ParentGroup.RootPart.UUID; parentID = prim.GetRootPartUUID(); position = prim.AbsolutePosition; // region local regionHandle = prim.ParentGroup.Scene.RegionInfo.RegionHandle; -- cgit v1.1 From 3eb68c319e1211bf0d4e251931f23d44ac88e63e Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 13 Oct 2010 08:24:18 +0200 Subject: change default next owner persm to mod/trans to match SL. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 726bda1..f0740f8 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -443,7 +443,7 @@ namespace OpenSim.Region.Framework.Scenes private uint _ownerMask = (uint)PermissionMask.All; private uint _groupMask = (uint)PermissionMask.None; private uint _everyoneMask = (uint)PermissionMask.None; - private uint _nextOwnerMask = (uint)PermissionMask.All; + private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer); private PrimFlags _flags = PrimFlags.None; private DateTime m_expires; private DateTime m_rezzed; @@ -1668,6 +1668,9 @@ namespace OpenSim.Region.Framework.Scenes // Move afterwards ResetIDs as it clears the localID dupe.LocalId = localID; + if(dupe.PhysActor != null) + dupe.PhysActor.LocalID = localID; + // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. dupe._lastOwnerID = OwnerID; -- cgit v1.1 From 537905d81b1d1d4c573eb56f41afdc39c1eec5ef Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 13 Oct 2010 19:45:55 +0100 Subject: Add a setter to OldItemID so it can be deserialized --- OpenSim/Framework/TaskInventoryItem.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Framework/TaskInventoryItem.cs b/OpenSim/Framework/TaskInventoryItem.cs index 883f61a..53237fc 100644 --- a/OpenSim/Framework/TaskInventoryItem.cs +++ b/OpenSim/Framework/TaskInventoryItem.cs @@ -227,6 +227,9 @@ namespace OpenSim.Framework get { return _oldID; } + set { + _oldID = value; + } } public UUID LastOwnerID { -- cgit v1.1 From efc555ca225f05d1adfa8ed75f5802637bd76a9f Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 16 Oct 2010 10:50:07 +0200 Subject: Actually set the PrivateBinPath in XEngine so relocating the scripts directory works --- OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs | 7 ++++--- OpenSim/Region/ScriptEngine/XEngine/XEngine.cs | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs index b4da246..623cb7d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs @@ -56,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance { public class ScriptInstance : MarshalByRefObject, IScriptInstance { - // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private IScriptEngine m_Engine; private IScriptWorkItem m_CurrentResult = null; @@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // lease.Register(this); } - catch (Exception) + catch (Exception e) { - // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); + m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); + throw; } try diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index c0ec0e8..35cc65b 100644 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -794,9 +794,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine try { AppDomainSetup appSetup = new AppDomainSetup(); - // appSetup.ApplicationBase = Path.Combine( - // "ScriptEngines", - // m_Scene.RegionInfo.RegionID.ToString()); + appSetup.PrivateBinPath = Path.Combine( + m_ScriptEnginesPath, + m_Scene.RegionInfo.RegionID.ToString()); Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; Evidence evidence = new Evidence(baseEvidence); -- cgit v1.1 From 78a6e5489beccbd4de7385219d0d214323a3d9a1 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Oct 2010 20:50:16 +0200 Subject: Fix merge issues --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 7ec3697..0321515 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -191,7 +191,6 @@ namespace OpenSim.Region.Framework.Scenes public UUID FromFolderID; -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectPart.cs // The following two are to hold the attachment data // while an object is inworld [XmlIgnore] @@ -201,9 +200,6 @@ namespace OpenSim.Region.Framework.Scenes public Vector3 AttachOffset = Vector3.Zero; [XmlIgnore] -======= - ->>>>>>> master:OpenSim/Region/Framework/Scenes/SceneObjectPart.cs public int STATUS_ROTATE_X; @@ -633,20 +629,12 @@ namespace OpenSim.Region.Framework.Scenes set { m_LoopSoundSlavePrims = value; } } -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectPart.cs -======= - ->>>>>>> master:OpenSim/Region/Framework/Scenes/SceneObjectPart.cs public Byte[] TextureAnimation { get { return m_TextureAnimation; } set { m_TextureAnimation = value; } } -<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectPart.cs -======= - ->>>>>>> master:OpenSim/Region/Framework/Scenes/SceneObjectPart.cs public Byte[] ParticleSystem { get { return m_particleSystem; } -- cgit v1.1 From ce3594f7f2b5a4af2d92d6b2c812f7241c61e82b Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 18 Oct 2010 22:58:04 +0100 Subject: Change substring matching to prefix matching in region search. This affects both map and login, as they use the same method. --- OpenSim/Services/GridService/GridService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/GridService/GridService.cs b/OpenSim/Services/GridService/GridService.cs index ce6f64b..e7988d6 100644 --- a/OpenSim/Services/GridService/GridService.cs +++ b/OpenSim/Services/GridService/GridService.cs @@ -323,7 +323,7 @@ namespace OpenSim.Services.GridService { m_log.DebugFormat("[GRID SERVICE]: GetRegionsByName {0}", name); - List rdatas = m_Database.Get("%" + name + "%", scopeID); + List rdatas = m_Database.Get(name + "%", scopeID); int count = 0; List rinfos = new List(); -- cgit v1.1 From 8853c21763790389f4bcc3b21993221630fdfd2e Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 19 Oct 2010 01:22:31 +0100 Subject: COmmented the wrong line instead, now I commented them all to be on the safe side --- .../Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index 49ebe81..e33ad4a 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -1363,7 +1363,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization } else { - m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element {0}", nodeName); +// m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element {0}", nodeName); reader.ReadOuterXml(); // ignore } @@ -1467,7 +1467,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization p(shape, reader); else { - m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element in Shape {0}", reader.Name); +// m_log.DebugFormat("[SceneObjectSerializer]: caught unknown element in Shape {0}", reader.Name); reader.ReadOuterXml(); } } -- cgit v1.1 From fa7da00cc3113bf57d12bdec84ebdf748cae07f7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 21 Oct 2010 09:35:33 +0100 Subject: COnvert some funky K&R notation to proper (MS) style --- .../Shared/Api/Implementation/LSL_Api.cs | 61 +++++++++++++++------- 1 file changed, 41 insertions(+), 20 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e94790f..296a50e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3824,7 +3824,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (targetPart != null) { - if (parent != 0) { + if (parent != 0) + { parentPrim = m_host.ParentGroup; childPrim = targetPart.ParentGroup; } @@ -5426,7 +5427,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } } - else { + else + { object[] array = new object[src.Length]; Array.Copy(src.Data, 0, array, 0, src.Length); result = new LSL_List(array); @@ -6271,7 +6273,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SetParticleSystem(m_host, rules); } - private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { + private void SetParticleSystem(SceneObjectPart part, LSL_List rules) + { if (rules.Length == 0) @@ -8965,17 +8968,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api * Convert separator and spacer lists to C# strings. * Also filter out null strings so we don't hang. */ - for (i = 0; i < seplen; i ++) { + for (i = 0; i < seplen; i ++) + { d = separray[i].ToString(); - if (d.Length > 0) { + if (d.Length > 0) + { delarray[dellen++] = d; } } seplen = dellen; - for (i = 0; i < spclen; i ++) { + for (i = 0; i < spclen; i ++) + { d = spcarray[i].ToString(); - if (d.Length > 0) { + if (d.Length > 0) + { delarray[dellen++] = d; } } @@ -8983,7 +8990,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /* * Scan through source string from beginning to end. */ - for (i = 0;;) { + for (i = 0;;) + { /* * Find earliest delimeter in src starting at i (if any). @@ -8991,13 +8999,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api int earliestDel = -1; int earliestSrc = srclen; string earliestStr = null; - for (j = 0; j < dellen; j ++) { + for (j = 0; j < dellen; j ++) + { d = delarray[j]; - if (d != null) { + if (d != null) + { int index = src.IndexOf(d, i); - if (index < 0) { + if (index < 0) + { delarray[j] = null; // delim nowhere in src, don't check it anymore - } else if (index < earliestSrc) { + } + else if (index < earliestSrc) + { earliestSrc = index; // where delimeter starts in source string earliestDel = j; // where delimeter is in delarray[] earliestStr = d; // the delimeter string from delarray[] @@ -9009,7 +9022,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /* * Output source string starting at i through start of earliest delimeter. */ - if (keepNulls || (earliestSrc > i)) { + if (keepNulls || (earliestSrc > i)) + { outarray[outlen++] = src.Substring(i, earliestSrc - i); } @@ -9021,7 +9035,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /* * If delimeter was a spacer, output the spacer. */ - if (earliestDel >= seplen) { + if (earliestDel >= seplen) + { outarray[outlen++] = earliestStr; } @@ -9035,7 +9050,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api * Make up an exact-sized output array suitable for an LSL_List object. */ object[] outlist = new object[outlen]; - for (i = 0; i < outlen; i ++) { + for (i = 0; i < outlen; i ++) + { outlist[i] = new LSL_String(outarray[i]); } return new LSL_List(outlist); @@ -10002,12 +10018,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api SortedDictionary parameters = new SortedDictionary(); object[] data = rules.Data; - for (int i = 0; i < data.Length; ++i) { + for (int i = 0; i < data.Length; ++i) + { int type = Convert.ToInt32(data[i++].ToString()); if (i >= data.Length) break; // odd number of entries => ignore the last // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) - switch (type) { + switch (type) + { case ScriptBaseClass.CAMERA_FOCUS: case ScriptBaseClass.CAMERA_FOCUS_OFFSET: case ScriptBaseClass.CAMERA_POSITION: @@ -10213,12 +10231,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Regex r = new Regex(authregex); int[] gnums = r.GetGroupNumbers(); Match m = r.Match(url); - if (m.Success) { - for (int i = 1; i < gnums.Length; i++) { + if (m.Success) + { + for (int i = 1; i < gnums.Length; i++) + { //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; //CaptureCollection cc = g.Captures; } - if (m.Groups.Count == 5) { + if (m.Groups.Count == 5) + { httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); url = m.Groups[1].ToString() + m.Groups[4].ToString(); } -- cgit v1.1 From 301a926015f0bdc1c99c814f18b7a0505bd59869 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 22 Oct 2010 13:29:59 +0100 Subject: Change some exception to use ToString(). e.Message is not sufficient to fix errors. Please don't use e.Message, devs NEED to see the dumps! --- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 4b24ba2..5428e5d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2466,7 +2466,7 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception e) { - m_log.WarnFormat("[SCENE]: Problem casting object: {0}", e.Message); + m_log.WarnFormat("[SCENE]: Problem casting object: " + e.ToString()); return false; } @@ -3464,7 +3464,7 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception e) { - m_log.DebugFormat("[CONNECTION BEGIN]: Exception verifying presence {0}", e.Message); + m_log.ErrorFormat("[CONNECTION BEGIN]: Exception verifying presence " + e.ToString()); return false; } @@ -3475,7 +3475,7 @@ namespace OpenSim.Region.Framework.Scenes } catch (Exception e) { - m_log.DebugFormat("[CONNECTION BEGIN]: Exception authorizing user {0}", e.Message); + m_log.ErrorFormat("[CONNECTION BEGIN]: Exception authorizing user " + e.ToString()); return false; } -- cgit v1.1 From c3ddf461880ded2bff0f9ca6bd6b956fbe4c23d5 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 23 Oct 2010 00:18:56 +0200 Subject: Prevent database lookups on every avatar movement when land is set to group access. Fixes a massive performance degradation. --- .../Region/CoreModules/World/Land/LandObject.cs | 28 +++++++--------------- 1 file changed, 8 insertions(+), 20 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandObject.cs b/OpenSim/Region/CoreModules/World/Land/LandObject.cs index bd1dd66..d0517b7 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandObject.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandObject.cs @@ -290,28 +290,16 @@ namespace OpenSim.Region.CoreModules.World.Land public bool HasGroupAccess(UUID avatar) { - if ((LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) + if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup) { - IGroupsModule groupsModule = - m_scene.RequestModuleInterface(); + ScenePresence sp; + if (!m_scene.TryGetScenePresence(avatar, out sp)) + return false; - List agentGroups = new List(); - if (groupsModule != null) - { - GroupMembershipData[] GroupMembership = - groupsModule.GetMembershipData(avatar); - - if (GroupMembership != null) - { - for (int i = 0; i < GroupMembership.Length; i++) - { - if (LandData.GroupID == GroupMembership[i].GroupID) - { - return true; - } - } - } - } + if (!sp.ControllingClient.IsGroupMember(LandData.GroupID)) + return false; + + return true; } return false; } -- cgit v1.1 From d0c707209abf50902d4fb748138d8a52070ea3ed Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 23 Oct 2010 22:40:56 +0100 Subject: Prevent an exception if a string passed into llXorBase64StringsCorrect is not a base 64 string. Return the empty string in this case. --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3249ae2..36ca542 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10145,8 +10145,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (str2 == String.Empty) return str1; - byte[] data1 = Convert.FromBase64String(str1); - byte[] data2 = Convert.FromBase64String(str2); + byte[] data1; + byte[] data2; + try + { + data1 = Convert.FromBase64String(str1); + data2 = Convert.FromBase64String(str2); + } + catch (Exception) + { + return new LSL_String(String.Empty); + } byte[] d2 = new Byte[data1.Length]; int pos = 0; -- cgit v1.1 From 5f266fd57131193a9ff37b03f214aa0476e2e3aa Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 24 Oct 2010 17:18:21 +0200 Subject: Change the results from llGetPrimitiveParams to be the same as SL for the prim position. This will make attached resizer scripts work like SL. Existing resizers may be affected adversely. --- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 0321515..5521326 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -1060,7 +1060,7 @@ namespace OpenSim.Region.Framework.Scenes { get { if (IsAttachment) - return GroupPosition; + return GroupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset); // return m_offsetPosition + m_groupPosition; } return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored! diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 3249ae2..94d3dee 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8029,13 +8029,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); - // For some reason, the part.AbsolutePosition.* values do not change if the - // linkset is rotated; they always reflect the child prim's world position - // as though the linkset is unrotated. This is incompatible behavior with SL's - // implementation, so will break scripts imported from there (not to mention it - // makes it more difficult to determine a child prim's actual inworld position). - if (part.ParentID != 0) - v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition(); res.Add(v); break; -- cgit v1.1 From 61137eac22b222720a24fa248f22b58c439c0560 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 24 Oct 2010 18:19:48 +0200 Subject: Add PRIM_NAME, PRIM_DESC and PRIM_ROT_LOCAL --- .../Shared/Api/Implementation/LSL_Api.cs | 27 ++++++++++++++++++++++ .../Shared/Api/Runtime/LSL_Constants.cs | 3 +++ 2 files changed, 30 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index db124f7..1b11f2c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7691,6 +7691,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api part.SetText(primText, av3, Util.Clip((float)primTextAlpha, 0.0f, 1.0f)); break; + case (int)ScriptBaseClass.PRIM_NAME: + if (remain < 1) + return; + string primName = rules.GetLSLStringItem(idx++); + part.Name = primName; + break; + case (int)ScriptBaseClass.PRIM_DESC: + if (remain < 1) + return; + string primDesc = rules.GetLSLStringItem(idx++); + part.Description = primDesc; + break; + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + if (remain < 1) + return; + LSL_Rotation lr = rules.GetQuaternionItem(idx++); + SetRot(part, Rot2Quaternion(lr)); + break; } } } @@ -8373,6 +8391,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api textColor.B)); res.Add(new LSL_Float(textColor.A)); break; + case (int)ScriptBaseClass.PRIM_NAME: + res.Add(part.Name); + break; + case (int)ScriptBaseClass.PRIM_DESC: + res.Add(part.Description); + break; + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); + break; } } return res; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 6e8435d..0342283 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -317,6 +317,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase public const int PRIM_POINT_LIGHT = 23; // Huh? public const int PRIM_GLOW = 25; public const int PRIM_TEXT = 26; + public const int PRIM_NAME = 27; + public const int PRIM_DESC = 28; + public const int PRIM_ROT_LOCAL = 29; public const int PRIM_TEXGEN_DEFAULT = 0; public const int PRIM_TEXGEN_PLANAR = 1; -- cgit v1.1 From dd7f9ed7bf3a6776ccdb1efe06a820f51ef6af1e Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 25 Oct 2010 00:33:34 +0200 Subject: Implement llGetLinkNumberOfSides(), needed for 1-script sculptie foot shoe scripts. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 9 +++++++++ OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs | 1 + OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs | 5 +++++ 3 files changed, 15 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1b11f2c..2527757 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10777,6 +10777,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return GetLinkPrimitiveParams(obj, rules); } + + public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) + { + List parts = GetLinkParts(link); + if (parts.Count < 1) + return 0; + + return GetNumberOfSides(parts[0]); + } } public class NotecardCache diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 561e3b3..bae7d4b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -398,6 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Vector llWind(LSL_Vector offset); LSL_String llXorBase64Strings(string str1, string str2); LSL_String llXorBase64StringsCorrect(string str1, string str2); + LSL_Integer llGetLinkNumberOfSides(LSL_Integer link); void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index f14967e..7c26824 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -1849,5 +1849,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase { return m_LSL_Functions.llClearPrimMedia(face); } + + public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link) + { + return m_LSL_Functions.llGetLinkNumberOfSides(link); + } } } -- cgit v1.1 From cf78f3fae311be4aa4c0ab37d2a7c8b6679fb22d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 25 Oct 2010 00:53:38 +0200 Subject: Comment repeated add and remove of avatars from the physical scene. It's no longer needed. --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 38 ++++++++++++++---------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 618f425..7bf0a99 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -2865,22 +2865,28 @@ namespace OpenSim.Region.Framework.Scenes { lock (m_syncRoot) { - if (m_physicsActor != null) - { - if (!IsChildAgent) - { - // This may seem like it's redundant, remove the avatar from the physics scene - // just to add it back again, but it saves us from having to update - // 3 variables 10 times a second. - bool flyingTemp = m_physicsActor.Flying; - RemoveFromPhysicalScene(); - //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); - - //PhysicsActor = null; - - AddToPhysicalScene(flyingTemp); - } - } +// MT: Commented this because it's no longer needed. +// It used to be that the avatar height was calculated from the visual +// params, so any call to this method could change the physical actor's +// height. Now the height is supplied in the agent circuit data and never +// changes here. So, we can leave physics alone. +// +// if (m_physicsActor != null) +// { +// if (!IsChildAgent) +// { +// // This may seem like it's redundant, remove the avatar from the physics scene +// // just to add it back again, but it saves us from having to update +// // 3 variables 10 times a second. +// bool flyingTemp = m_physicsActor.Flying; +// RemoveFromPhysicalScene(); +// //m_scene.PhysicsScene.RemoveAvatar(m_physicsActor); +// +// //PhysicsActor = null; +// +// AddToPhysicalScene(flyingTemp); +// } +// } #region Bake Cache Check -- cgit v1.1 From a51a545cb9489f3b02ed7a9a7691c5b5dd557bd7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 28 Oct 2010 13:24:45 +0100 Subject: Fix attached sounds from HUDs erroneously being delivered to other avatars --- OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index a52fea4..e77062b 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -62,6 +62,12 @@ namespace OpenSim.Region.CoreModules.World.Sound public virtual void PlayAttachedSound( UUID soundID, UUID ownerID, UUID objectID, double gain, Vector3 position, byte flags, float radius) { + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); + if (part == null) + return; + + SceneObjectGroup grp = part.ParentGroup; + m_scene.ForEachScenePresence(delegate(ScenePresence sp) { if (sp.IsChildAgent) @@ -71,6 +77,19 @@ namespace OpenSim.Region.CoreModules.World.Sound if (dis > 100.0) // Max audio distance return; + if (grp.IsAttachment) + { + + if (grp.GetAttachmentPoint() > 30) // HUD + { + if (sp.ControllingClient.AgentId != grp.OwnerID) + return; + } + + if (sp.ControllingClient.AgentId == grp.OwnerID) + dis = 0; + } + // Scale by distance if (radius == 0) gain = (float)((double)gain * ((100.0 - dis) / 100.0)); -- cgit v1.1 From e6a8d2872c3ff4992cd7e9615f69e0c6773e461f Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Oct 2010 18:59:53 +0200 Subject: Preliminary work on appearance layers. No user functionality yet. --- OpenSim/Framework/AvatarAppearance.cs | 451 +++++++++------------ .../InventoryAccess/InventoryAccessModule.cs | 12 +- .../Shared/Api/Implementation/LSL_Api.cs | 11 +- 3 files changed, 209 insertions(+), 265 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 5da8ba1..829ad79 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -32,6 +32,125 @@ using OpenMetaverse; namespace OpenSim.Framework { + // A special dictionary for avatar appearance + public struct LayerItem + { + public UUID ItemID; + public UUID AssetID; + + public LayerItem(UUID itemID, UUID assetID) + { + ItemID = itemID; + AssetID = assetID; + } + } + + public class Layer + { + protected int m_layerType; + protected Dictionary m_items = new Dictionary(); + protected List m_ids = new List(); + + public Layer(int type) + { + m_layerType = type; + } + + public int LayerType + { + get { return m_layerType; } + } + + public int Count + { + get { return m_ids.Count; } + } + + public void Add(UUID itemID, UUID assetID) + { + if (m_items.ContainsKey(itemID)) + return; + if (m_ids.Count >= 5) + return; + + m_ids.Add(itemID); + m_items[itemID] = assetID; + } + + public void Wear(UUID itemID, UUID assetID) + { + Clear(); + Add(itemID, assetID); + } + + public void Clear() + { + m_ids.Clear(); + m_items.Clear(); + } + + public void RemoveItem(UUID itemID) + { + if (m_items.ContainsKey(itemID)) + { + m_ids.Remove(itemID); + m_items.Remove(itemID); + } + } + + public void RemoveAsset(UUID assetID) + { + UUID itemID = UUID.Zero; + + foreach (KeyValuePair kvp in m_items) + { + if (kvp.Value == assetID) + { + itemID = kvp.Key; + break; + } + } + + if (itemID != UUID.Zero) + { + m_ids.Remove(itemID); + m_items.Remove(itemID); + } + } + + public LayerItem this [int idx] + { + get + { + if (idx >= m_ids.Count || idx < 0) + return new LayerItem(UUID.Zero, UUID.Zero); + + return new LayerItem(m_ids[idx], m_items[m_ids[idx]]); + } + } + } + + public enum AppearanceLayer + { + BODY = 0, + SKIN = 1, + HAIR = 2, + EYES = 3, + SHIRT = 4, + PANTS = 5, + SHOES = 6, + SOCKS = 7, + JACKET = 8, + GLOVES = 9, + UNDERSHIRT = 10, + UNDERPANTS = 11, + SKIRT = 12, + ALPHA = 13, + TATTOO = 14, + + MAX_WEARABLES = 15 + } + /// /// Contains the Avatar's Appearance and methods to manipulate the appearance. /// @@ -39,25 +158,6 @@ namespace OpenSim.Framework { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // these are guessed at by the list here - - // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll - // correct them over time for when were are wrong. - public readonly static int BODY = 0; - public readonly static int SKIN = 1; - public readonly static int HAIR = 2; - public readonly static int EYES = 3; - public readonly static int SHIRT = 4; - public readonly static int PANTS = 5; - public readonly static int SHOES = 6; - public readonly static int SOCKS = 7; - public readonly static int JACKET = 8; - public readonly static int GLOVES = 9; - public readonly static int UNDERSHIRT = 10; - public readonly static int UNDERPANTS = 11; - public readonly static int SKIRT = 12; - - private readonly static int MAX_WEARABLES = 13; - private static UUID BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); private static UUID BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); private static UUID SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb"); @@ -68,6 +168,10 @@ namespace OpenSim.Framework private static UUID PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111"); private static UUID HAIR_ASSET = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66"); private static UUID HAIR_ITEM = new UUID("d342e6c1-b9d2-11dc-95ff-0800200c9a66"); + private static UUID ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594"); + private static UUID TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007"); + private static UUID ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8"); + private static UUID TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1"); public readonly static int VISUALPARAM_COUNT = 218; @@ -103,152 +207,156 @@ namespace OpenSim.Framework } public virtual UUID BodyItem { - get { return m_wearables[BODY].ItemID; } - set { m_wearables[BODY].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.BODY].ItemID; } + set { m_wearables[(int)AppearanceLayer.BODY].ItemID = value; } } public virtual UUID BodyAsset { - get { return m_wearables[BODY].AssetID; } - set { m_wearables[BODY].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.BODY].AssetID; } + set { m_wearables[(int)AppearanceLayer.BODY].AssetID = value; } } public virtual UUID SkinItem { - get { return m_wearables[SKIN].ItemID; } - set { m_wearables[SKIN].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.SKIN].ItemID; } + set { m_wearables[(int)AppearanceLayer.SKIN].ItemID = value; } } public virtual UUID SkinAsset { - get { return m_wearables[SKIN].AssetID; } - set { m_wearables[SKIN].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.SKIN].AssetID; } + set { m_wearables[(int)AppearanceLayer.SKIN].AssetID = value; } } public virtual UUID HairItem { - get { return m_wearables[HAIR].ItemID; } - set { m_wearables[HAIR].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.HAIR].ItemID; } + set { m_wearables[(int)AppearanceLayer.HAIR].ItemID = value; } } public virtual UUID HairAsset { - get { return m_wearables[HAIR].AssetID; } - set { m_wearables[HAIR].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.HAIR].AssetID; } + set { m_wearables[(int)AppearanceLayer.HAIR].AssetID = value; } } public virtual UUID EyesItem { - get { return m_wearables[EYES].ItemID; } - set { m_wearables[EYES].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.EYES].ItemID; } + set { m_wearables[(int)AppearanceLayer.EYES].ItemID = value; } } public virtual UUID EyesAsset { - get { return m_wearables[EYES].AssetID; } - set { m_wearables[EYES].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.EYES].AssetID; } + set { m_wearables[(int)AppearanceLayer.EYES].AssetID = value; } } public virtual UUID ShirtItem { - get { return m_wearables[SHIRT].ItemID; } - set { m_wearables[SHIRT].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.SHIRT].ItemID; } + set { m_wearables[(int)AppearanceLayer.SHIRT].ItemID = value; } } public virtual UUID ShirtAsset { - get { return m_wearables[SHIRT].AssetID; } - set { m_wearables[SHIRT].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.SHIRT].AssetID; } + set { m_wearables[(int)AppearanceLayer.SHIRT].AssetID = value; } } public virtual UUID PantsItem { - get { return m_wearables[PANTS].ItemID; } - set { m_wearables[PANTS].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.PANTS].ItemID; } + set { m_wearables[(int)AppearanceLayer.PANTS].ItemID = value; } } public virtual UUID PantsAsset { - get { return m_wearables[PANTS].AssetID; } - set { m_wearables[PANTS].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.PANTS].AssetID; } + set { m_wearables[(int)AppearanceLayer.PANTS].AssetID = value; } } public virtual UUID ShoesItem { - get { return m_wearables[SHOES].ItemID; } - set { m_wearables[SHOES].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.SHOES].ItemID; } + set { m_wearables[(int)AppearanceLayer.SHOES].ItemID = value; } } public virtual UUID ShoesAsset { - get { return m_wearables[SHOES].AssetID; } - set { m_wearables[SHOES].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.SHOES].AssetID; } + set { m_wearables[(int)AppearanceLayer.SHOES].AssetID = value; } } public virtual UUID SocksItem { - get { return m_wearables[SOCKS].ItemID; } - set { m_wearables[SOCKS].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.SOCKS].ItemID; } + set { m_wearables[(int)AppearanceLayer.SOCKS].ItemID = value; } } public virtual UUID SocksAsset { - get { return m_wearables[SOCKS].AssetID; } - set { m_wearables[SOCKS].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.SOCKS].AssetID; } + set { m_wearables[(int)AppearanceLayer.SOCKS].AssetID = value; } } public virtual UUID JacketItem { - get { return m_wearables[JACKET].ItemID; } - set { m_wearables[JACKET].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.JACKET].ItemID; } + set { m_wearables[(int)AppearanceLayer.JACKET].ItemID = value; } } public virtual UUID JacketAsset { - get { return m_wearables[JACKET].AssetID; } - set { m_wearables[JACKET].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.JACKET].AssetID; } + set { m_wearables[(int)AppearanceLayer.JACKET].AssetID = value; } } public virtual UUID GlovesItem { - get { return m_wearables[GLOVES].ItemID; } - set { m_wearables[GLOVES].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.GLOVES].ItemID; } + set { m_wearables[(int)AppearanceLayer.GLOVES].ItemID = value; } } public virtual UUID GlovesAsset { - get { return m_wearables[GLOVES].AssetID; } - set { m_wearables[GLOVES].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.GLOVES].AssetID; } + set { m_wearables[(int)AppearanceLayer.GLOVES].AssetID = value; } } public virtual UUID UnderShirtItem { - get { return m_wearables[UNDERSHIRT].ItemID; } - set { m_wearables[UNDERSHIRT].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.UNDERSHIRT].ItemID; } + set { m_wearables[(int)AppearanceLayer.UNDERSHIRT].ItemID = value; } } public virtual UUID UnderShirtAsset { - get { return m_wearables[UNDERSHIRT].AssetID; } - set { m_wearables[UNDERSHIRT].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.UNDERSHIRT].AssetID; } + set { m_wearables[(int)AppearanceLayer.UNDERSHIRT].AssetID = value; } } public virtual UUID UnderPantsItem { - get { return m_wearables[UNDERPANTS].ItemID; } - set { m_wearables[UNDERPANTS].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.UNDERPANTS].ItemID; } + set { m_wearables[(int)AppearanceLayer.UNDERPANTS].ItemID = value; } } public virtual UUID UnderPantsAsset { - get { return m_wearables[UNDERPANTS].AssetID; } - set { m_wearables[UNDERPANTS].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.UNDERPANTS].AssetID; } + set { m_wearables[(int)AppearanceLayer.UNDERPANTS].AssetID = value; } } public virtual UUID SkirtItem { - get { return m_wearables[SKIRT].ItemID; } - set { m_wearables[SKIRT].ItemID = value; } + get { return m_wearables[(int)AppearanceLayer.SKIRT].ItemID; } + set { m_wearables[(int)AppearanceLayer.SKIRT].ItemID = value; } } public virtual UUID SkirtAsset { - get { return m_wearables[SKIRT].AssetID; } - set { m_wearables[SKIRT].AssetID = value; } + get { return m_wearables[(int)AppearanceLayer.SKIRT].AssetID; } + set { m_wearables[(int)AppearanceLayer.SKIRT].AssetID = value; } } public virtual void SetDefaultWearables() { - m_wearables[BODY].AssetID = BODY_ASSET; - m_wearables[BODY].ItemID = BODY_ITEM; - m_wearables[SKIN].AssetID = SKIN_ASSET; - m_wearables[SKIN].ItemID = SKIN_ITEM; - m_wearables[HAIR].AssetID = HAIR_ASSET; - m_wearables[HAIR].ItemID = HAIR_ITEM; - m_wearables[SHIRT].AssetID = SHIRT_ASSET; - m_wearables[SHIRT].ItemID = SHIRT_ITEM; - m_wearables[PANTS].AssetID = PANTS_ASSET; - m_wearables[PANTS].ItemID = PANTS_ITEM; + m_wearables[(int)AppearanceLayer.BODY].AssetID = BODY_ASSET; + m_wearables[(int)AppearanceLayer.BODY].ItemID = BODY_ITEM; + m_wearables[(int)AppearanceLayer.SKIN].AssetID = SKIN_ASSET; + m_wearables[(int)AppearanceLayer.SKIN].ItemID = SKIN_ITEM; + m_wearables[(int)AppearanceLayer.HAIR].AssetID = HAIR_ASSET; + m_wearables[(int)AppearanceLayer.HAIR].ItemID = HAIR_ITEM; + m_wearables[(int)AppearanceLayer.SHIRT].AssetID = SHIRT_ASSET; + m_wearables[(int)AppearanceLayer.SHIRT].ItemID = SHIRT_ITEM; + m_wearables[(int)AppearanceLayer.PANTS].AssetID = PANTS_ASSET; + m_wearables[(int)AppearanceLayer.PANTS].ItemID = PANTS_ITEM; + m_wearables[(int)AppearanceLayer.ALPHA].AssetID = ALPHA_ASSET; + m_wearables[(int)AppearanceLayer.ALPHA].ItemID = ALPHA_ITEM; + m_wearables[(int)AppearanceLayer.TATTOO].AssetID = TATTOO_ASSET; + m_wearables[(int)AppearanceLayer.TATTOO].ItemID = TATTOO_ITEM; } public virtual void ClearWearables() { - for (int i = 0; i < 13; i++) + for (int i = 0; i < m_wearables.Length ; i++) { m_wearables[i].AssetID = UUID.Zero; m_wearables[i].ItemID = UUID.Zero; @@ -286,70 +394,12 @@ namespace OpenSim.Framework get { return m_hipOffset; } } - //Builds the VisualParam Enum using LIBOMV's Visual Param NameValues - /* - public void BuildVisualParamEnum() - { - Dictionary IndexedParams = new Dictionary(); - int vpIndex = 0; - IndexedParams = new Dictionary(); - - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - - sb.Append("public enum VPElement: int\n"); - sb.Append("{\n"); - foreach (KeyValuePair kvp in OpenMetaverse.VisualParams.Params) - { - VisualParam vp = kvp.Value; - - // Only Group-0 parameters are sent in AgentSetAppearance packets - if (kvp.Value.Group == 0) - { - - if (!IndexedParams.ContainsKey(vp.Name)) - { - - if (vp.Label.Length > 0 || vp.LabelMin.Length > 0 || vp.LabelMax.Length > 0) - { - - sb.Append("/// \n"); - if (vp.LabelMin.Length > 0 && vp.LabelMax.Length > 0) - sb.Append(string.Format("/// {0} - {1} 0--+255 {2}\n", vp.Label, vp.LabelMin, - vp.LabelMax)); - - else - sb.Append(string.Format("/// {0}\n", vp.Label)); - - sb.Append("/// \n"); - } - sb.Append(string.Format(" {0}_{1} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"),vpIndex)); - - IndexedParams.Add(vp.Name, vpIndex++); - } - else - { - sb.Append(string.Format(" {0}_{1}_{2} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"), vpIndex)); - vpIndex++; - //int i = 0; - } - } - if (vpIndex < 217) - sb.Append(",\n"); - else - sb.Append("\n"); - - } - sb.Append("}\n"); - - } - */ - public AvatarAppearance() : this(UUID.Zero) {} public AvatarAppearance(UUID owner) { - m_wearables = new AvatarWearable[MAX_WEARABLES]; - for (int i = 0; i < MAX_WEARABLES; i++) + m_wearables = new AvatarWearable[(int)AppearanceLayer.MAX_WEARABLES]; + for (int i = 0; i < (int)AppearanceLayer.MAX_WEARABLES; i++) { // this makes them all null m_wearables[i] = new AvatarWearable(); @@ -442,121 +492,6 @@ namespace OpenSim.Framework return visualParams; } - public override String ToString() - { - String s = "[Wearables] =>"; - s += " Body Item: " + BodyItem.ToString() + ";"; - s += " Skin Item: " + SkinItem.ToString() + ";"; - s += " Shirt Item: " + ShirtItem.ToString() + ";"; - s += " Pants Item: " + PantsItem.ToString() + ";"; - return s; - } - - // this is used for OGS1 - public virtual Hashtable ToHashTable() - { - Hashtable h = new Hashtable(); - h["owner"] = Owner.ToString(); - h["serial"] = Serial.ToString(); - h["visual_params"] = VisualParams; - h["texture"] = Texture.GetBytes(); - h["avatar_height"] = AvatarHeight.ToString(); - h["body_item"] = BodyItem.ToString(); - h["body_asset"] = BodyAsset.ToString(); - h["skin_item"] = SkinItem.ToString(); - h["skin_asset"] = SkinAsset.ToString(); - h["hair_item"] = HairItem.ToString(); - h["hair_asset"] = HairAsset.ToString(); - h["eyes_item"] = EyesItem.ToString(); - h["eyes_asset"] = EyesAsset.ToString(); - h["shirt_item"] = ShirtItem.ToString(); - h["shirt_asset"] = ShirtAsset.ToString(); - h["pants_item"] = PantsItem.ToString(); - h["pants_asset"] = PantsAsset.ToString(); - h["shoes_item"] = ShoesItem.ToString(); - h["shoes_asset"] = ShoesAsset.ToString(); - h["socks_item"] = SocksItem.ToString(); - h["socks_asset"] = SocksAsset.ToString(); - h["jacket_item"] = JacketItem.ToString(); - h["jacket_asset"] = JacketAsset.ToString(); - h["gloves_item"] = GlovesItem.ToString(); - h["gloves_asset"] = GlovesAsset.ToString(); - h["undershirt_item"] = UnderShirtItem.ToString(); - h["undershirt_asset"] = UnderShirtAsset.ToString(); - h["underpants_item"] = UnderPantsItem.ToString(); - h["underpants_asset"] = UnderPantsAsset.ToString(); - h["skirt_item"] = SkirtItem.ToString(); - h["skirt_asset"] = SkirtAsset.ToString(); - - string attachments = GetAttachmentsString(); - if (attachments != String.Empty) - h["attachments"] = attachments; - - return h; - } - - public AvatarAppearance(Hashtable h) - { - Owner = new UUID((string)h["owner"]); - Serial = Convert.ToInt32((string)h["serial"]); - VisualParams = (byte[])h["visual_params"]; - - if (h.Contains("texture")) - { - byte[] te = h["texture"] as byte[]; - if (te != null && te.Length > 0) - Texture = new Primitive.TextureEntry(te, 0, te.Length); - } - else - { - // We shouldn't be receiving appearance hashtables without a TextureEntry, - // but in case we do this will prevent a failure when saving to the database - Texture = GetDefaultTexture(); - } - - - AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); - - m_wearables = new AvatarWearable[MAX_WEARABLES]; - for (int i = 0; i < MAX_WEARABLES; i++) - { - // this makes them all null - m_wearables[i] = new AvatarWearable(); - } - - BodyItem = new UUID((string)h["body_item"]); - BodyAsset = new UUID((string)h["body_asset"]); - SkinItem = new UUID((string)h["skin_item"]); - SkinAsset = new UUID((string)h["skin_asset"]); - HairItem = new UUID((string)h["hair_item"]); - HairAsset = new UUID((string)h["hair_asset"]); - EyesItem = new UUID((string)h["eyes_item"]); - EyesAsset = new UUID((string)h["eyes_asset"]); - ShirtItem = new UUID((string)h["shirt_item"]); - ShirtAsset = new UUID((string)h["shirt_asset"]); - PantsItem = new UUID((string)h["pants_item"]); - PantsAsset = new UUID((string)h["pants_asset"]); - ShoesItem = new UUID((string)h["shoes_item"]); - ShoesAsset = new UUID((string)h["shoes_asset"]); - SocksItem = new UUID((string)h["socks_item"]); - SocksAsset = new UUID((string)h["socks_asset"]); - JacketItem = new UUID((string)h["jacket_item"]); - JacketAsset = new UUID((string)h["jacket_asset"]); - GlovesItem = new UUID((string)h["gloves_item"]); - GlovesAsset = new UUID((string)h["gloves_asset"]); - UnderShirtItem = new UUID((string)h["undershirt_item"]); - UnderShirtAsset = new UUID((string)h["undershirt_asset"]); - UnderPantsItem = new UUID((string)h["underpants_item"]); - UnderPantsAsset = new UUID((string)h["underpants_asset"]); - SkirtItem = new UUID((string)h["skirt_item"]); - SkirtAsset = new UUID((string)h["skirt_asset"]); - - if (h.ContainsKey("attachments")) - { - SetAttachmentsString(h["attachments"].ToString()); - } - } - private Dictionary m_attachments = new Dictionary(); public void SetAttachments(AttachmentData[] data) @@ -1489,4 +1424,4 @@ namespace OpenSim.Framework SKIRT_SKIRT_BLUE = 217 } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d429979..0700aa5 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -762,10 +762,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // affect the name stored in the serialization, transfer // the correct name from the inventory to the // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - rootPart.ObjectSaleType = item.SaleType; - rootPart.SalePrice = item.SalePrice; + // On coalesced objects, this has no effect. + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; + } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if ((rootPart.OwnerID != item.Owner) || diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2527757..8f05359 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2187,9 +2187,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // try to let this work as in SL... - if (m_host.ParentID == 0) - { - // special case: If we are root, rotate complete SOG to new rotation + if (m_host.LinkNum < 2) + { + // Special case: If we are root, rotate complete SOG to new + // rotation. + // We are root if the link number is 0 (single prim) or 1 + // (root prim). ParentID may be nonzero in attachments and + // using it would cause attachments and HUDs to rotate + // to the wrong positions. SetRot(m_host, Rot2Quaternion(rot)); } else -- cgit v1.1 From 3231602b885556cc5327d2a3369a1b82fb01df95 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Oct 2010 20:34:53 +0200 Subject: Revert "Preliminary work on appearance layers. No user functionality yet." This reverts commit e6a8d2872c3ff4992cd7e9615f69e0c6773e461f. --- OpenSim/Framework/AvatarAppearance.cs | 451 ++++++++++++--------- .../InventoryAccess/InventoryAccessModule.cs | 12 +- .../Shared/Api/Implementation/LSL_Api.cs | 11 +- 3 files changed, 265 insertions(+), 209 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 829ad79..5da8ba1 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -32,125 +32,6 @@ using OpenMetaverse; namespace OpenSim.Framework { - // A special dictionary for avatar appearance - public struct LayerItem - { - public UUID ItemID; - public UUID AssetID; - - public LayerItem(UUID itemID, UUID assetID) - { - ItemID = itemID; - AssetID = assetID; - } - } - - public class Layer - { - protected int m_layerType; - protected Dictionary m_items = new Dictionary(); - protected List m_ids = new List(); - - public Layer(int type) - { - m_layerType = type; - } - - public int LayerType - { - get { return m_layerType; } - } - - public int Count - { - get { return m_ids.Count; } - } - - public void Add(UUID itemID, UUID assetID) - { - if (m_items.ContainsKey(itemID)) - return; - if (m_ids.Count >= 5) - return; - - m_ids.Add(itemID); - m_items[itemID] = assetID; - } - - public void Wear(UUID itemID, UUID assetID) - { - Clear(); - Add(itemID, assetID); - } - - public void Clear() - { - m_ids.Clear(); - m_items.Clear(); - } - - public void RemoveItem(UUID itemID) - { - if (m_items.ContainsKey(itemID)) - { - m_ids.Remove(itemID); - m_items.Remove(itemID); - } - } - - public void RemoveAsset(UUID assetID) - { - UUID itemID = UUID.Zero; - - foreach (KeyValuePair kvp in m_items) - { - if (kvp.Value == assetID) - { - itemID = kvp.Key; - break; - } - } - - if (itemID != UUID.Zero) - { - m_ids.Remove(itemID); - m_items.Remove(itemID); - } - } - - public LayerItem this [int idx] - { - get - { - if (idx >= m_ids.Count || idx < 0) - return new LayerItem(UUID.Zero, UUID.Zero); - - return new LayerItem(m_ids[idx], m_items[m_ids[idx]]); - } - } - } - - public enum AppearanceLayer - { - BODY = 0, - SKIN = 1, - HAIR = 2, - EYES = 3, - SHIRT = 4, - PANTS = 5, - SHOES = 6, - SOCKS = 7, - JACKET = 8, - GLOVES = 9, - UNDERSHIRT = 10, - UNDERPANTS = 11, - SKIRT = 12, - ALPHA = 13, - TATTOO = 14, - - MAX_WEARABLES = 15 - } - /// /// Contains the Avatar's Appearance and methods to manipulate the appearance. /// @@ -158,6 +39,25 @@ namespace OpenSim.Framework { //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + // these are guessed at by the list here - + // http://wiki.secondlife.com/wiki/Avatar_Appearance. We'll + // correct them over time for when were are wrong. + public readonly static int BODY = 0; + public readonly static int SKIN = 1; + public readonly static int HAIR = 2; + public readonly static int EYES = 3; + public readonly static int SHIRT = 4; + public readonly static int PANTS = 5; + public readonly static int SHOES = 6; + public readonly static int SOCKS = 7; + public readonly static int JACKET = 8; + public readonly static int GLOVES = 9; + public readonly static int UNDERSHIRT = 10; + public readonly static int UNDERPANTS = 11; + public readonly static int SKIRT = 12; + + private readonly static int MAX_WEARABLES = 13; + private static UUID BODY_ASSET = new UUID("66c41e39-38f9-f75a-024e-585989bfab73"); private static UUID BODY_ITEM = new UUID("66c41e39-38f9-f75a-024e-585989bfaba9"); private static UUID SKIN_ASSET = new UUID("77c41e39-38f9-f75a-024e-585989bbabbb"); @@ -168,10 +68,6 @@ namespace OpenSim.Framework private static UUID PANTS_ITEM = new UUID("77c41e39-38f9-f75a-0000-5859892f1111"); private static UUID HAIR_ASSET = new UUID("d342e6c0-b9d2-11dc-95ff-0800200c9a66"); private static UUID HAIR_ITEM = new UUID("d342e6c1-b9d2-11dc-95ff-0800200c9a66"); - private static UUID ALPHA_ASSET = new UUID("1578a2b1-5179-4b53-b618-fe00ca5a5594"); - private static UUID TATTOO_ASSET = new UUID("00000000-0000-2222-3333-100000001007"); - private static UUID ALPHA_ITEM = new UUID("bfb9923c-4838-4d2d-bf07-608c5b1165c8"); - private static UUID TATTOO_ITEM = new UUID("c47e22bd-3021-4ba4-82aa-2b5cb34d35e1"); public readonly static int VISUALPARAM_COUNT = 218; @@ -207,156 +103,152 @@ namespace OpenSim.Framework } public virtual UUID BodyItem { - get { return m_wearables[(int)AppearanceLayer.BODY].ItemID; } - set { m_wearables[(int)AppearanceLayer.BODY].ItemID = value; } + get { return m_wearables[BODY].ItemID; } + set { m_wearables[BODY].ItemID = value; } } public virtual UUID BodyAsset { - get { return m_wearables[(int)AppearanceLayer.BODY].AssetID; } - set { m_wearables[(int)AppearanceLayer.BODY].AssetID = value; } + get { return m_wearables[BODY].AssetID; } + set { m_wearables[BODY].AssetID = value; } } public virtual UUID SkinItem { - get { return m_wearables[(int)AppearanceLayer.SKIN].ItemID; } - set { m_wearables[(int)AppearanceLayer.SKIN].ItemID = value; } + get { return m_wearables[SKIN].ItemID; } + set { m_wearables[SKIN].ItemID = value; } } public virtual UUID SkinAsset { - get { return m_wearables[(int)AppearanceLayer.SKIN].AssetID; } - set { m_wearables[(int)AppearanceLayer.SKIN].AssetID = value; } + get { return m_wearables[SKIN].AssetID; } + set { m_wearables[SKIN].AssetID = value; } } public virtual UUID HairItem { - get { return m_wearables[(int)AppearanceLayer.HAIR].ItemID; } - set { m_wearables[(int)AppearanceLayer.HAIR].ItemID = value; } + get { return m_wearables[HAIR].ItemID; } + set { m_wearables[HAIR].ItemID = value; } } public virtual UUID HairAsset { - get { return m_wearables[(int)AppearanceLayer.HAIR].AssetID; } - set { m_wearables[(int)AppearanceLayer.HAIR].AssetID = value; } + get { return m_wearables[HAIR].AssetID; } + set { m_wearables[HAIR].AssetID = value; } } public virtual UUID EyesItem { - get { return m_wearables[(int)AppearanceLayer.EYES].ItemID; } - set { m_wearables[(int)AppearanceLayer.EYES].ItemID = value; } + get { return m_wearables[EYES].ItemID; } + set { m_wearables[EYES].ItemID = value; } } public virtual UUID EyesAsset { - get { return m_wearables[(int)AppearanceLayer.EYES].AssetID; } - set { m_wearables[(int)AppearanceLayer.EYES].AssetID = value; } + get { return m_wearables[EYES].AssetID; } + set { m_wearables[EYES].AssetID = value; } } public virtual UUID ShirtItem { - get { return m_wearables[(int)AppearanceLayer.SHIRT].ItemID; } - set { m_wearables[(int)AppearanceLayer.SHIRT].ItemID = value; } + get { return m_wearables[SHIRT].ItemID; } + set { m_wearables[SHIRT].ItemID = value; } } public virtual UUID ShirtAsset { - get { return m_wearables[(int)AppearanceLayer.SHIRT].AssetID; } - set { m_wearables[(int)AppearanceLayer.SHIRT].AssetID = value; } + get { return m_wearables[SHIRT].AssetID; } + set { m_wearables[SHIRT].AssetID = value; } } public virtual UUID PantsItem { - get { return m_wearables[(int)AppearanceLayer.PANTS].ItemID; } - set { m_wearables[(int)AppearanceLayer.PANTS].ItemID = value; } + get { return m_wearables[PANTS].ItemID; } + set { m_wearables[PANTS].ItemID = value; } } public virtual UUID PantsAsset { - get { return m_wearables[(int)AppearanceLayer.PANTS].AssetID; } - set { m_wearables[(int)AppearanceLayer.PANTS].AssetID = value; } + get { return m_wearables[PANTS].AssetID; } + set { m_wearables[PANTS].AssetID = value; } } public virtual UUID ShoesItem { - get { return m_wearables[(int)AppearanceLayer.SHOES].ItemID; } - set { m_wearables[(int)AppearanceLayer.SHOES].ItemID = value; } + get { return m_wearables[SHOES].ItemID; } + set { m_wearables[SHOES].ItemID = value; } } public virtual UUID ShoesAsset { - get { return m_wearables[(int)AppearanceLayer.SHOES].AssetID; } - set { m_wearables[(int)AppearanceLayer.SHOES].AssetID = value; } + get { return m_wearables[SHOES].AssetID; } + set { m_wearables[SHOES].AssetID = value; } } public virtual UUID SocksItem { - get { return m_wearables[(int)AppearanceLayer.SOCKS].ItemID; } - set { m_wearables[(int)AppearanceLayer.SOCKS].ItemID = value; } + get { return m_wearables[SOCKS].ItemID; } + set { m_wearables[SOCKS].ItemID = value; } } public virtual UUID SocksAsset { - get { return m_wearables[(int)AppearanceLayer.SOCKS].AssetID; } - set { m_wearables[(int)AppearanceLayer.SOCKS].AssetID = value; } + get { return m_wearables[SOCKS].AssetID; } + set { m_wearables[SOCKS].AssetID = value; } } public virtual UUID JacketItem { - get { return m_wearables[(int)AppearanceLayer.JACKET].ItemID; } - set { m_wearables[(int)AppearanceLayer.JACKET].ItemID = value; } + get { return m_wearables[JACKET].ItemID; } + set { m_wearables[JACKET].ItemID = value; } } public virtual UUID JacketAsset { - get { return m_wearables[(int)AppearanceLayer.JACKET].AssetID; } - set { m_wearables[(int)AppearanceLayer.JACKET].AssetID = value; } + get { return m_wearables[JACKET].AssetID; } + set { m_wearables[JACKET].AssetID = value; } } public virtual UUID GlovesItem { - get { return m_wearables[(int)AppearanceLayer.GLOVES].ItemID; } - set { m_wearables[(int)AppearanceLayer.GLOVES].ItemID = value; } + get { return m_wearables[GLOVES].ItemID; } + set { m_wearables[GLOVES].ItemID = value; } } public virtual UUID GlovesAsset { - get { return m_wearables[(int)AppearanceLayer.GLOVES].AssetID; } - set { m_wearables[(int)AppearanceLayer.GLOVES].AssetID = value; } + get { return m_wearables[GLOVES].AssetID; } + set { m_wearables[GLOVES].AssetID = value; } } public virtual UUID UnderShirtItem { - get { return m_wearables[(int)AppearanceLayer.UNDERSHIRT].ItemID; } - set { m_wearables[(int)AppearanceLayer.UNDERSHIRT].ItemID = value; } + get { return m_wearables[UNDERSHIRT].ItemID; } + set { m_wearables[UNDERSHIRT].ItemID = value; } } public virtual UUID UnderShirtAsset { - get { return m_wearables[(int)AppearanceLayer.UNDERSHIRT].AssetID; } - set { m_wearables[(int)AppearanceLayer.UNDERSHIRT].AssetID = value; } + get { return m_wearables[UNDERSHIRT].AssetID; } + set { m_wearables[UNDERSHIRT].AssetID = value; } } public virtual UUID UnderPantsItem { - get { return m_wearables[(int)AppearanceLayer.UNDERPANTS].ItemID; } - set { m_wearables[(int)AppearanceLayer.UNDERPANTS].ItemID = value; } + get { return m_wearables[UNDERPANTS].ItemID; } + set { m_wearables[UNDERPANTS].ItemID = value; } } public virtual UUID UnderPantsAsset { - get { return m_wearables[(int)AppearanceLayer.UNDERPANTS].AssetID; } - set { m_wearables[(int)AppearanceLayer.UNDERPANTS].AssetID = value; } + get { return m_wearables[UNDERPANTS].AssetID; } + set { m_wearables[UNDERPANTS].AssetID = value; } } public virtual UUID SkirtItem { - get { return m_wearables[(int)AppearanceLayer.SKIRT].ItemID; } - set { m_wearables[(int)AppearanceLayer.SKIRT].ItemID = value; } + get { return m_wearables[SKIRT].ItemID; } + set { m_wearables[SKIRT].ItemID = value; } } public virtual UUID SkirtAsset { - get { return m_wearables[(int)AppearanceLayer.SKIRT].AssetID; } - set { m_wearables[(int)AppearanceLayer.SKIRT].AssetID = value; } + get { return m_wearables[SKIRT].AssetID; } + set { m_wearables[SKIRT].AssetID = value; } } public virtual void SetDefaultWearables() { - m_wearables[(int)AppearanceLayer.BODY].AssetID = BODY_ASSET; - m_wearables[(int)AppearanceLayer.BODY].ItemID = BODY_ITEM; - m_wearables[(int)AppearanceLayer.SKIN].AssetID = SKIN_ASSET; - m_wearables[(int)AppearanceLayer.SKIN].ItemID = SKIN_ITEM; - m_wearables[(int)AppearanceLayer.HAIR].AssetID = HAIR_ASSET; - m_wearables[(int)AppearanceLayer.HAIR].ItemID = HAIR_ITEM; - m_wearables[(int)AppearanceLayer.SHIRT].AssetID = SHIRT_ASSET; - m_wearables[(int)AppearanceLayer.SHIRT].ItemID = SHIRT_ITEM; - m_wearables[(int)AppearanceLayer.PANTS].AssetID = PANTS_ASSET; - m_wearables[(int)AppearanceLayer.PANTS].ItemID = PANTS_ITEM; - m_wearables[(int)AppearanceLayer.ALPHA].AssetID = ALPHA_ASSET; - m_wearables[(int)AppearanceLayer.ALPHA].ItemID = ALPHA_ITEM; - m_wearables[(int)AppearanceLayer.TATTOO].AssetID = TATTOO_ASSET; - m_wearables[(int)AppearanceLayer.TATTOO].ItemID = TATTOO_ITEM; + m_wearables[BODY].AssetID = BODY_ASSET; + m_wearables[BODY].ItemID = BODY_ITEM; + m_wearables[SKIN].AssetID = SKIN_ASSET; + m_wearables[SKIN].ItemID = SKIN_ITEM; + m_wearables[HAIR].AssetID = HAIR_ASSET; + m_wearables[HAIR].ItemID = HAIR_ITEM; + m_wearables[SHIRT].AssetID = SHIRT_ASSET; + m_wearables[SHIRT].ItemID = SHIRT_ITEM; + m_wearables[PANTS].AssetID = PANTS_ASSET; + m_wearables[PANTS].ItemID = PANTS_ITEM; } public virtual void ClearWearables() { - for (int i = 0; i < m_wearables.Length ; i++) + for (int i = 0; i < 13; i++) { m_wearables[i].AssetID = UUID.Zero; m_wearables[i].ItemID = UUID.Zero; @@ -394,12 +286,70 @@ namespace OpenSim.Framework get { return m_hipOffset; } } + //Builds the VisualParam Enum using LIBOMV's Visual Param NameValues + /* + public void BuildVisualParamEnum() + { + Dictionary IndexedParams = new Dictionary(); + int vpIndex = 0; + IndexedParams = new Dictionary(); + + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + + sb.Append("public enum VPElement: int\n"); + sb.Append("{\n"); + foreach (KeyValuePair kvp in OpenMetaverse.VisualParams.Params) + { + VisualParam vp = kvp.Value; + + // Only Group-0 parameters are sent in AgentSetAppearance packets + if (kvp.Value.Group == 0) + { + + if (!IndexedParams.ContainsKey(vp.Name)) + { + + if (vp.Label.Length > 0 || vp.LabelMin.Length > 0 || vp.LabelMax.Length > 0) + { + + sb.Append("/// \n"); + if (vp.LabelMin.Length > 0 && vp.LabelMax.Length > 0) + sb.Append(string.Format("/// {0} - {1} 0--+255 {2}\n", vp.Label, vp.LabelMin, + vp.LabelMax)); + + else + sb.Append(string.Format("/// {0}\n", vp.Label)); + + sb.Append("/// \n"); + } + sb.Append(string.Format(" {0}_{1} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"),vpIndex)); + + IndexedParams.Add(vp.Name, vpIndex++); + } + else + { + sb.Append(string.Format(" {0}_{1}_{2} = {2}", vp.Wearable.ToUpper(), vp.Name.ToUpper().Replace(" ", "_"), vpIndex)); + vpIndex++; + //int i = 0; + } + } + if (vpIndex < 217) + sb.Append(",\n"); + else + sb.Append("\n"); + + } + sb.Append("}\n"); + + } + */ + public AvatarAppearance() : this(UUID.Zero) {} public AvatarAppearance(UUID owner) { - m_wearables = new AvatarWearable[(int)AppearanceLayer.MAX_WEARABLES]; - for (int i = 0; i < (int)AppearanceLayer.MAX_WEARABLES; i++) + m_wearables = new AvatarWearable[MAX_WEARABLES]; + for (int i = 0; i < MAX_WEARABLES; i++) { // this makes them all null m_wearables[i] = new AvatarWearable(); @@ -492,6 +442,121 @@ namespace OpenSim.Framework return visualParams; } + public override String ToString() + { + String s = "[Wearables] =>"; + s += " Body Item: " + BodyItem.ToString() + ";"; + s += " Skin Item: " + SkinItem.ToString() + ";"; + s += " Shirt Item: " + ShirtItem.ToString() + ";"; + s += " Pants Item: " + PantsItem.ToString() + ";"; + return s; + } + + // this is used for OGS1 + public virtual Hashtable ToHashTable() + { + Hashtable h = new Hashtable(); + h["owner"] = Owner.ToString(); + h["serial"] = Serial.ToString(); + h["visual_params"] = VisualParams; + h["texture"] = Texture.GetBytes(); + h["avatar_height"] = AvatarHeight.ToString(); + h["body_item"] = BodyItem.ToString(); + h["body_asset"] = BodyAsset.ToString(); + h["skin_item"] = SkinItem.ToString(); + h["skin_asset"] = SkinAsset.ToString(); + h["hair_item"] = HairItem.ToString(); + h["hair_asset"] = HairAsset.ToString(); + h["eyes_item"] = EyesItem.ToString(); + h["eyes_asset"] = EyesAsset.ToString(); + h["shirt_item"] = ShirtItem.ToString(); + h["shirt_asset"] = ShirtAsset.ToString(); + h["pants_item"] = PantsItem.ToString(); + h["pants_asset"] = PantsAsset.ToString(); + h["shoes_item"] = ShoesItem.ToString(); + h["shoes_asset"] = ShoesAsset.ToString(); + h["socks_item"] = SocksItem.ToString(); + h["socks_asset"] = SocksAsset.ToString(); + h["jacket_item"] = JacketItem.ToString(); + h["jacket_asset"] = JacketAsset.ToString(); + h["gloves_item"] = GlovesItem.ToString(); + h["gloves_asset"] = GlovesAsset.ToString(); + h["undershirt_item"] = UnderShirtItem.ToString(); + h["undershirt_asset"] = UnderShirtAsset.ToString(); + h["underpants_item"] = UnderPantsItem.ToString(); + h["underpants_asset"] = UnderPantsAsset.ToString(); + h["skirt_item"] = SkirtItem.ToString(); + h["skirt_asset"] = SkirtAsset.ToString(); + + string attachments = GetAttachmentsString(); + if (attachments != String.Empty) + h["attachments"] = attachments; + + return h; + } + + public AvatarAppearance(Hashtable h) + { + Owner = new UUID((string)h["owner"]); + Serial = Convert.ToInt32((string)h["serial"]); + VisualParams = (byte[])h["visual_params"]; + + if (h.Contains("texture")) + { + byte[] te = h["texture"] as byte[]; + if (te != null && te.Length > 0) + Texture = new Primitive.TextureEntry(te, 0, te.Length); + } + else + { + // We shouldn't be receiving appearance hashtables without a TextureEntry, + // but in case we do this will prevent a failure when saving to the database + Texture = GetDefaultTexture(); + } + + + AvatarHeight = (float)Convert.ToDouble((string)h["avatar_height"]); + + m_wearables = new AvatarWearable[MAX_WEARABLES]; + for (int i = 0; i < MAX_WEARABLES; i++) + { + // this makes them all null + m_wearables[i] = new AvatarWearable(); + } + + BodyItem = new UUID((string)h["body_item"]); + BodyAsset = new UUID((string)h["body_asset"]); + SkinItem = new UUID((string)h["skin_item"]); + SkinAsset = new UUID((string)h["skin_asset"]); + HairItem = new UUID((string)h["hair_item"]); + HairAsset = new UUID((string)h["hair_asset"]); + EyesItem = new UUID((string)h["eyes_item"]); + EyesAsset = new UUID((string)h["eyes_asset"]); + ShirtItem = new UUID((string)h["shirt_item"]); + ShirtAsset = new UUID((string)h["shirt_asset"]); + PantsItem = new UUID((string)h["pants_item"]); + PantsAsset = new UUID((string)h["pants_asset"]); + ShoesItem = new UUID((string)h["shoes_item"]); + ShoesAsset = new UUID((string)h["shoes_asset"]); + SocksItem = new UUID((string)h["socks_item"]); + SocksAsset = new UUID((string)h["socks_asset"]); + JacketItem = new UUID((string)h["jacket_item"]); + JacketAsset = new UUID((string)h["jacket_asset"]); + GlovesItem = new UUID((string)h["gloves_item"]); + GlovesAsset = new UUID((string)h["gloves_asset"]); + UnderShirtItem = new UUID((string)h["undershirt_item"]); + UnderShirtAsset = new UUID((string)h["undershirt_asset"]); + UnderPantsItem = new UUID((string)h["underpants_item"]); + UnderPantsAsset = new UUID((string)h["underpants_asset"]); + SkirtItem = new UUID((string)h["skirt_item"]); + SkirtAsset = new UUID((string)h["skirt_asset"]); + + if (h.ContainsKey("attachments")) + { + SetAttachmentsString(h["attachments"].ToString()); + } + } + private Dictionary m_attachments = new Dictionary(); public void SetAttachments(AttachmentData[] data) @@ -1424,4 +1489,4 @@ namespace OpenSim.Framework SKIRT_SKIRT_BLUE = 217 } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 0700aa5..d429979 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -762,14 +762,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // affect the name stored in the serialization, transfer // the correct name from the inventory to the // object itself before we rez. - // On coalesced objects, this has no effect. - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - rootPart.Name = item.Name; - rootPart.Description = item.Description; - rootPart.ObjectSaleType = item.SaleType; - rootPart.SalePrice = item.SalePrice; - } + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if ((rootPart.OwnerID != item.Owner) || diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8f05359..2527757 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2187,14 +2187,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // try to let this work as in SL... - if (m_host.LinkNum < 2) - { - // Special case: If we are root, rotate complete SOG to new - // rotation. - // We are root if the link number is 0 (single prim) or 1 - // (root prim). ParentID may be nonzero in attachments and - // using it would cause attachments and HUDs to rotate - // to the wrong positions. + if (m_host.ParentID == 0) + { + // special case: If we are root, rotate complete SOG to new rotation SetRot(m_host, Rot2Quaternion(rot)); } else -- cgit v1.1 From dbd1a68b581c80b50f243ce6896e96b8ed0461dc Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Oct 2010 20:35:06 +0200 Subject: Fix a LSL issue and a prim naming issue --- .../Framework/InventoryAccess/InventoryAccessModule.cs | 12 ++++++++---- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 11 ++++++++--- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d429979..0700aa5 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -762,10 +762,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // affect the name stored in the serialization, transfer // the correct name from the inventory to the // object itself before we rez. - rootPart.Name = item.Name; - rootPart.Description = item.Description; - rootPart.ObjectSaleType = item.SaleType; - rootPart.SalePrice = item.SalePrice; + // On coalesced objects, this has no effect. + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) + { + rootPart.Name = item.Name; + rootPart.Description = item.Description; + rootPart.ObjectSaleType = item.SaleType; + rootPart.SalePrice = item.SalePrice; + } group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if ((rootPart.OwnerID != item.Owner) || diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2527757..8f05359 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2187,9 +2187,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); // try to let this work as in SL... - if (m_host.ParentID == 0) - { - // special case: If we are root, rotate complete SOG to new rotation + if (m_host.LinkNum < 2) + { + // Special case: If we are root, rotate complete SOG to new + // rotation. + // We are root if the link number is 0 (single prim) or 1 + // (root prim). ParentID may be nonzero in attachments and + // using it would cause attachments and HUDs to rotate + // to the wrong positions. SetRot(m_host, Rot2Quaternion(rot)); } else -- cgit v1.1 From 840b75ca9b9af2f98109a54b442669221014b854 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 29 Oct 2010 20:48:37 +0200 Subject: Add my work on top of cmickeyb's --- OpenSim/Framework/AvatarAppearance.cs | 100 +++++++++++++++++++++++++++++++++- 1 file changed, 99 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/AvatarAppearance.cs b/OpenSim/Framework/AvatarAppearance.cs index 55646dd..4738d88 100644 --- a/OpenSim/Framework/AvatarAppearance.cs +++ b/OpenSim/Framework/AvatarAppearance.cs @@ -35,6 +35,104 @@ using log4net; namespace OpenSim.Framework { + // A special dictionary for avatar appearance + public struct LayerItem + { + public UUID ItemID; + public UUID AssetID; + + public LayerItem(UUID itemID, UUID assetID) + { + ItemID = itemID; + AssetID = assetID; + } + } + + public class Layer + { + protected int m_layerType; + protected Dictionary m_items = new Dictionary(); + protected List m_ids = new List(); + + public Layer(int type) + { + m_layerType = type; + } + + public int LayerType + { + get { return m_layerType; } + } + + public int Count + { + get { return m_ids.Count; } + } + + public void Add(UUID itemID, UUID assetID) + { + if (m_items.ContainsKey(itemID)) + return; + if (m_ids.Count >= 5) + return; + + m_ids.Add(itemID); + m_items[itemID] = assetID; + } + + public void Wear(UUID itemID, UUID assetID) + { + Clear(); + Add(itemID, assetID); + } + + public void Clear() + { + m_ids.Clear(); + m_items.Clear(); + } + + public void RemoveItem(UUID itemID) + { + if (m_items.ContainsKey(itemID)) + { + m_ids.Remove(itemID); + m_items.Remove(itemID); + } + } + + public void RemoveAsset(UUID assetID) + { + UUID itemID = UUID.Zero; + + foreach (KeyValuePair kvp in m_items) + { + if (kvp.Value == assetID) + { + itemID = kvp.Key; + break; + } + } + + if (itemID != UUID.Zero) + { + m_ids.Remove(itemID); + m_items.Remove(itemID); + } + } + + public LayerItem this [int idx] + { + get + { + if (idx >= m_ids.Count || idx < 0) + return new LayerItem(UUID.Zero, UUID.Zero); + + return new LayerItem(m_ids[idx], m_items[m_ids[idx]]); + } + } + } + /// /// Contains the Avatar's Appearance and methods to manipulate the appearance. /// @@ -1456,4 +1554,4 @@ namespace OpenSim.Framework SKIRT_SKIRT_BLUE = 217 } } -} \ No newline at end of file +} -- cgit v1.1 From d5d0e81df2415203711fc418ac901b007f1e6607 Mon Sep 17 00:00:00 2001 From: mores Date: Tue, 2 Nov 2010 21:46:45 -0400 Subject: Admin Server can now bind to a private ip address Signed-off-by: Melanie --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 4 +++- OpenSim/Framework/MainServer.cs | 9 +++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 4ac9ada..946f1b2 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -116,7 +116,9 @@ namespace OpenSim.ApplicationPlugins.RemoteController int port = m_config.GetInt("port", 0); m_application = openSim; - m_httpServer = MainServer.GetHttpServer((uint)port); + string bind_ip_address = m_config.GetString("bind_ip_address", "127.0.0.1"); + IPAddress ipaddr = IPAddress.Parse( bind_ip_address ); + m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr); Dictionary availableMethods = new Dictionary(); availableMethods["admin_create_region"] = XmlRpcCreateRegionMethod; diff --git a/OpenSim/Framework/MainServer.cs b/OpenSim/Framework/MainServer.cs index 1f5f208..8ccabec 100644 --- a/OpenSim/Framework/MainServer.cs +++ b/OpenSim/Framework/MainServer.cs @@ -27,6 +27,7 @@ using System.Collections.Generic; using System.Reflection; +using System.Net; using log4net; using OpenSim.Framework.Servers.HttpServer; @@ -48,6 +49,11 @@ namespace OpenSim.Framework public static IHttpServer GetHttpServer(uint port) { + return GetHttpServer(port,null); + } + + public static IHttpServer GetHttpServer(uint port, IPAddress ipaddr) + { if (port == 0) return Instance; if (instance != null && port == Instance.Port) @@ -58,6 +64,9 @@ namespace OpenSim.Framework m_Servers[port] = new BaseHttpServer(port); + if (ipaddr != null ) + m_Servers[port].ListenIPAddress = ipaddr; + m_log.InfoFormat("[MAIN HTTP SERVER]: Starting main http server on port {0}", port); m_Servers[port].Start(); -- cgit v1.1 From 636ca6218d2ad63cdec7f0b68d84a565542c1fe2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 3 Nov 2010 01:11:04 +0000 Subject: Change the default of the new bind_ip_address RemoteAdmin option to 0.0.0.0 so it reflects the prior default. We are not in the habot of changing default behavior without good reason and making localhost the default would break most current use cases. --- OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs index 946f1b2..ba95426 100644 --- a/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs +++ b/OpenSim/ApplicationPlugins/RemoteController/RemoteAdminPlugin.cs @@ -116,7 +116,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController int port = m_config.GetInt("port", 0); m_application = openSim; - string bind_ip_address = m_config.GetString("bind_ip_address", "127.0.0.1"); + string bind_ip_address = m_config.GetString("bind_ip_address", "0.0.0.0"); IPAddress ipaddr = IPAddress.Parse( bind_ip_address ); m_httpServer = MainServer.GetHttpServer((uint)port,ipaddr); -- cgit v1.1 From c2bd6ccdb8f9a5063450f684c31d75df537ff5e8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 3 Nov 2010 23:20:30 +0100 Subject: Fix playing sound from HUDs --- OpenSim/Region/CoreModules/World/Sound/SoundModule.cs | 18 ++++++++++++++++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 8 -------- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index e77062b..8df645d 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -31,12 +31,14 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; +using System.Reflection; +using log4net; namespace OpenSim.Region.CoreModules.World.Sound { public class SoundModule : IRegionModule, ISoundModule { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); protected Scene m_scene; @@ -79,7 +81,6 @@ namespace OpenSim.Region.CoreModules.World.Sound if (grp.IsAttachment) { - if (grp.GetAttachmentPoint() > 30) // HUD { if (sp.ControllingClient.AgentId != grp.OwnerID) @@ -96,6 +97,7 @@ namespace OpenSim.Region.CoreModules.World.Sound else gain = (float)((double)gain * ((radius - dis) / radius)); + m_log.DebugFormat("Play sound, gain {0}", gain); sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, ownerID, (float)gain, flags); }); } @@ -103,6 +105,18 @@ namespace OpenSim.Region.CoreModules.World.Sound public virtual void TriggerSound( UUID soundId, UUID ownerID, UUID objectID, UUID parentID, double gain, Vector3 position, UInt64 handle, float radius) { + SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); + if (part == null) + return; + + SceneObjectGroup grp = part.ParentGroup; + + if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) + { + objectID = ownerID; + parentID = ownerID; + } + m_scene.ForEachScenePresence(delegate(ScenePresence sp) { if (sp.IsChildAgent) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 5521326..be3e87f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3115,14 +3115,6 @@ namespace OpenSim.Region.Framework.Scenes UUID objectID = ParentGroup.RootPart.UUID; UUID parentID = GetRootPartUUID(); - if (ParentGroup.IsAttachment && ParentGroup.RootPart.Shape.State > 30) - { - // Use the avatar as the parent for HUDs, since the prims - // are not sent to other avatars - objectID = _ownerID; - parentID = _ownerID; - } - UUID soundID = UUID.Zero; Vector3 position = AbsolutePosition; // region local ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle; -- cgit v1.1 From b8924167e004cba5e9b426cbb0b2619816ee6858 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Nov 2010 10:37:39 +0100 Subject: Fix creation of a duplicate physics actor on chained drag-copy operations, the main cause for "ghost prims" --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index c870797..93d223e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1704,23 +1704,6 @@ namespace OpenSim.Region.Framework.Scenes if (userExposed) dupe.m_rootPart.TrimPermissions(); - /// may need to create a new Physics actor. - if (dupe.RootPart.PhysActor != null && userExposed) - { - PrimitiveBaseShape pbs = dupe.RootPart.Shape; - - dupe.RootPart.PhysActor = m_scene.PhysicsScene.AddPrimShape( - dupe.RootPart.Name, - pbs, - dupe.RootPart.AbsolutePosition, - dupe.RootPart.Scale, - dupe.RootPart.RotationOffset, - dupe.RootPart.PhysActor.IsPhysical); - - dupe.RootPart.PhysActor.LocalID = dupe.RootPart.LocalId; - dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); - } - List partList = new List(m_parts.GetArray()); partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) -- cgit v1.1 From 82e534a0291c2a2c54ad95991d7b8ed6b6524839 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Nov 2010 19:07:43 +0100 Subject: Fix avatar to avatar inventory gives across servers --- .../Inventory/Transfer/InventoryTransferModule.cs | 58 +++++++++++++++++++--- 1 file changed, 50 insertions(+), 8 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index 6badc74..e9e7c25 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -175,8 +175,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer if (im.binaryBucket.Length < 17) // Invalid return; - UUID receipientID = new UUID(im.toAgentID); - ScenePresence user = scene.GetScenePresence(receipientID); + UUID recipientID = new UUID(im.toAgentID); + ScenePresence user = scene.GetScenePresence(recipientID); UUID copyID; // First byte is the asset type @@ -191,7 +191,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer folderID, new UUID(im.toAgentID)); InventoryFolderBase folderCopy - = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); + = scene.GiveInventoryFolder(recipientID, client.AgentId, folderID, UUID.Zero); if (folderCopy == null) { @@ -419,22 +419,64 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer /// /// /// - private void OnGridInstantMessage(GridInstantMessage msg) + private void OnGridInstantMessage(GridInstantMessage im) { // Check if this is ours to handle // - Scene scene = FindClientScene(new UUID(msg.toAgentID)); + Scene scene = FindClientScene(new UUID(im.toAgentID)); if (scene == null) return; // Find agent to deliver to // - ScenePresence user = scene.GetScenePresence(new UUID(msg.toAgentID)); + ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); + if (user == null) + return; + + // This requires a little bit of processing because we have to make the + // new item visible in the recipient's inventory here + // + if (im.dialog == (byte) InstantMessageDialog.InventoryOffered) + { + if (im.binaryBucket.Length < 17) // Invalid + return; + + UUID recipientID = new UUID(im.toAgentID); + + // First byte is the asset type + AssetType assetType = (AssetType)im.binaryBucket[0]; + + if (AssetType.Folder == assetType) + { + UUID folderID = new UUID(im.binaryBucket, 1); - // Just forward to local handling - OnInstantMessage(user.ControllingClient, msg); + InventoryFolderBase given = + new InventoryFolderBase(folderID, recipientID); + InventoryFolderBase folder = + scene.InventoryService.GetFolder(given); + + if (folder != null) + user.ControllingClient.SendBulkUpdateInventory(folder); + } + else + { + UUID itemID = new UUID(im.binaryBucket, 1); + + InventoryItemBase given = + new InventoryItemBase(itemID, recipientID); + InventoryItemBase item = + scene.InventoryService.GetItem(given); + + if (item != null) + { + user.ControllingClient.SendBulkUpdateInventory(item); + } + } + } + // Just forward to the client + user.ControllingClient.SendInstantMessage(im); } } } -- cgit v1.1 From 893915ce0b88348bc7e2053e8942f76ad7ef830b Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 4 Nov 2010 21:09:59 +0100 Subject: Fix child prims returning after being unlinked and deleted where the root is not deleted --- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index b016065..a462133 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1760,6 +1760,11 @@ namespace OpenSim.Region.Framework.Scenes // foreach (SceneObjectGroup g in affectedGroups) { + // Child prims that have been unlinked and deleted will + // return unless the root is deleted. This will remove them + // from the database. They will be rewritten immediately, + // minus the rows for the unlinked child prims. + m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID); g.TriggerScriptChangedEvent(Changed.LINK); g.HasGroupChanged = true; // Persist g.areUpdatesSuspended = false; -- cgit v1.1 From f985775962ae8da0010cc5ef5f903a53b550f5d2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 5 Nov 2010 14:27:14 +0100 Subject: Revert "Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready." This reverts commit 91b1d17e5bd3ff6ed006744bc529b53a67af1a64. Conflicts: OpenSim/Client/Sirikata/ClientStack/SirikataClientView.cs OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs OpenSim/Region/Framework/Scenes/ScenePresence.cs --- OpenSim/Client/MXP/ClientStack/MXPClientView.cs | 4 -- .../Client/VWoHTTP/ClientStack/VWHClientView.cs | 4 -- OpenSim/Framework/IClientAPI.cs | 1 - .../Region/ClientStack/LindenUDP/LLClientView.cs | 42 ++--------- .../Region/Examples/SimpleModule/MyNpcCharacter.cs | 4 -- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 84 +++++++++++++++------- .../Server/IRCClientView.cs | 4 -- .../Region/OptionalModules/World/NPC/NPCAvatar.cs | 4 -- OpenSim/Tests/Common/Mock/TestClient.cs | 4 -- 9 files changed, 63 insertions(+), 88 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index a720db4..06110c3 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -820,10 +820,6 @@ namespace OpenSim.Client.MXP.ClientStack //throw new System.NotImplementedException(); } - public void ProcessPendingPackets() - { - } - public void ProcessInPacket(Packet NewPack) { //throw new System.NotImplementedException(); diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 1b4c0c5..bc5dc9e 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -446,10 +446,6 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } - public void ProcessPendingPackets() - { - } - public void ProcessInPacket(Packet NewPack) { throw new System.NotImplementedException(); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 1e1dfa8..f8be9ad 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -944,7 +944,6 @@ namespace OpenSim.Framework void SetDebugPacketLevel(int newDebug); void InPacket(object NewPack); - void ProcessPendingPackets(); void ProcessInPacket(Packet NewPack); void Close(); void Close(bool sendStop); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 4c9011a..7e9a82a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -342,7 +342,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private AgentUpdateArgs lastarg; private bool m_IsActive = true; private bool m_IsLoggingOut = false; - private bool m_IsPresenceReady = false; protected Dictionary m_packetHandlers = new Dictionary(); protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers @@ -365,7 +364,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP private Timer m_propertiesPacketTimer; private List m_propertiesBlocks = new List(); - private List m_pendingPackets; #endregion Class Members @@ -418,7 +416,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP get { return m_IsActive; } set { m_IsActive = value; } } - public bool IsLoggingOut { get { return m_IsLoggingOut; } @@ -11355,47 +11352,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP } /// - /// This processes packets which have accumulated while the presence was still in the process of initialising. - /// - public void ProcessPendingPackets() - { - m_IsPresenceReady = true; - if (m_pendingPackets == null) - return; - foreach (Packet p in m_pendingPackets) - { - ProcessInPacket(p); - } - m_pendingPackets.Clear(); - } - - /// /// Entryway from the client to the simulator. All UDP packets from the client will end up here /// /// OpenMetaverse.packet public void ProcessInPacket(Packet packet) { - if (m_debugPacketLevel > 0) - { - bool outputPacket = true; - - if (m_debugPacketLevel <= 255 && packet.Type == PacketType.AgentUpdate) - outputPacket = false; - - if (m_debugPacketLevel <= 200 && packet.Type == PacketType.RequestImage) - outputPacket = false; - - if (m_debugPacketLevel <= 100 && (packet.Type == PacketType.ViewerEffect || packet.Type == PacketType.AgentAnimation)) - outputPacket = false; - - if (outputPacket) - m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type); - } + if (m_debugPacketLevel >= 255) + m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); - if (!ProcessPacketMethod(packet)) - m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); + if (!ProcessPacketMethod(Pack)) + m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); - PacketPool.Instance.ReturnPacket(packet); + PacketPool.Instance.ReturnPacket(Pack); } private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index 09f615f..7441a60 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -821,10 +821,6 @@ namespace OpenSim.Region.Examples.SimpleModule { } - public void ProcessPendingPackets() - { - } - public void ProcessInPacket(Packet NewPack) { } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 3866647..ec39df8 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -127,7 +127,7 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; + private Vector3 m_lastPosition; private Vector3 m_lastWorldPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; @@ -766,11 +766,8 @@ namespace OpenSim.Region.Framework.Scenes // MIC: This gets called again in CompleteMovement SendInitialFullUpdateToAllClients(); + RegisterToEvents(); - if (m_controllingClient != null) - { - m_controllingClient.ProcessPendingPackets(); - } SetDirectionVectors(); } @@ -895,7 +892,11 @@ namespace OpenSim.Region.Framework.Scenes m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; +<<<<<<< HEAD m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); +======= + m_scene.SetRootAgentScene(m_uuid); +>>>>>>> 91b1d17... Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. // Moved this from SendInitialData to ensure that m_appearance is initialized // before the inventory is processed in MakeRootAgent. This fixes a race condition @@ -911,6 +912,7 @@ namespace OpenSim.Region.Framework.Scenes { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); pos.Y = crossedBorder.BorderLine.Z - 1; +<<<<<<< HEAD } //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. @@ -927,6 +929,24 @@ namespace OpenSim.Region.Framework.Scenes pos = land.LandData.UserLocation; } } +======= + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } +>>>>>>> 91b1d17... Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. } if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) @@ -1110,8 +1130,8 @@ namespace OpenSim.Region.Framework.Scenes bool isFlying = false; if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - + isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -1122,7 +1142,7 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_appearance.AvatarHeight); } - SendTerseUpdateToAllClients(); + SendTerseUpdateToAllClients(); } @@ -1240,6 +1260,7 @@ namespace OpenSim.Region.Framework.Scenes pos.Z = ground + 1.5f; AbsolutePosition = pos; } + m_isChildAgent = false; bool m_flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); MakeRootAgent(AbsolutePosition, m_flying); @@ -1827,14 +1848,14 @@ namespace OpenSim.Region.Framework.Scenes // else // { // single or child prim -// } - if (part == null) //CW: Part may be gone. llDie() for example. - { - partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - partRot = part.GetWorldRotation(); +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); } Quaternion partIRot = Quaternion.Inverse(partRot); @@ -1842,6 +1863,7 @@ namespace OpenSim.Region.Framework.Scenes Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av +<<<<<<< HEAD if (m_physicsActor == null) { @@ -1854,11 +1876,24 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = avWorldStandUp; //KF: Fix stand up. part.IsOccupied = false; part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); +======= + + if (m_physicsActor == null) + { + AddToPhysicalScene(false); +>>>>>>> 91b1d17... Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. } - else - { - //CW: Since the part doesn't exist, a coarse standup position isn't an issue - AbsolutePosition = m_lastWorldPosition; + //CW: If the part isn't null then we can set the current position + if (part != null) + { + Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! + AbsolutePosition = avWorldStandUp; //KF: Fix stand up. + part.IsOccupied = false; + } + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; } m_parentPosition = Vector3.Zero; @@ -2022,7 +2057,7 @@ namespace OpenSim.Region.Framework.Scenes // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) ) { - autopilot = false; // close enough + autopilot = false; // close enough m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. Not using the part's position because returning the AV to the last known standing position is likely to be more friendly, isn't it? */ @@ -2032,7 +2067,7 @@ namespace OpenSim.Region.Framework.Scenes } // else the autopilot will get us close } else - { // its a scripted sit + { // its a scripted sit m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. I *am* using the part's position this time because we have no real idea how far away the avatar is from the sit target. */ @@ -3993,10 +4028,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju m_scene = scene; RegisterToEvents(); - if (m_controllingClient != null) - { - m_controllingClient.ProcessPendingPackets(); - } + /* AbsolutePosition = client.StartPos; diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 96c3d8e..276e46d 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -877,10 +877,6 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } - public void ProcessPendingPackets() - { - } - public void ProcessInPacket(Packet NewPack) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 737ca1b..39c3364 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -836,10 +836,6 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } - public void ProcessPendingPackets() - { - } - public void ProcessInPacket(Packet NewPack) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 4e600b5..fbc339a 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -879,10 +879,6 @@ namespace OpenSim.Tests.Common.Mock { } - public void ProcessPendingPackets() - { - } - public void ProcessInPacket(Packet NewPack) { } -- cgit v1.1 From ddd3c6824ada0c2a6b87d7176f23b636caafa72f Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 5 Nov 2010 14:27:53 +0100 Subject: Revert "Spin the AddNewClient process off into a new thread to avoid locking up the LLUDPServer (and therefore the entire scene)" This reverts commit 40e05f41098bdedac7296d84c9aa8d915c5c9ede. Conflicts: OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs --- .../Region/ClientStack/LindenUDP/LLUDPServer.cs | 25 +--------------------- 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index b8c692f..626f7eb 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs @@ -918,30 +918,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP client.DisableFacelights = m_disableFacelights; // Start the IClientAPI - // Spin it off so that it doesn't clog up the LLUDPServer - - //First, and very importantly: - // - //Set our DeliverPackets flag in the client to *false* - //this will prevent us from missing important messages - //before the modules are bound - client.DeliverPackets = false; - client.DisableFacelights = m_disableFacelights; - - Util.FireAndForget( - delegate - { - try - { - client.Start(); - } - finally - { - //Now, release the hounds. er, packets. - client.DeliverPackets = true; - } - } - ); + client.Start(); } else { -- cgit v1.1 From 78448720671e364862ae5c17464ccf112bbf7034 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 5 Nov 2010 14:46:13 +0100 Subject: Fix merge artefacts --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 8 +-- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 73 ++++++---------------- 2 files changed, 22 insertions(+), 59 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 7e9a82a..bcfb633 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -11358,12 +11358,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP public void ProcessInPacket(Packet packet) { if (m_debugPacketLevel >= 255) - m_log.DebugFormat("[CLIENT]: Packet IN {0}", Pack.Type); + m_log.DebugFormat("[CLIENT]: Packet IN {0}", packet.Type); - if (!ProcessPacketMethod(Pack)) - m_log.Warn("[CLIENT]: unhandled packet " + Pack.Type); + if (!ProcessPacketMethod(packet)) + m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); - PacketPool.Instance.ReturnPacket(Pack); + PacketPool.Instance.ReturnPacket(packet); } private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index ec39df8..b637317 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -127,7 +127,7 @@ namespace OpenSim.Region.Framework.Scenes private Vector3 m_avInitialPos; // used to calculate unscripted sit rotation private Vector3 m_avUnscriptedSitPos; // for non-scripted prims - private Vector3 m_lastPosition; + private Vector3 m_lastPosition; private Vector3 m_lastWorldPosition; private Quaternion m_lastRotation; private Vector3 m_lastVelocity; @@ -892,11 +892,7 @@ namespace OpenSim.Region.Framework.Scenes m_rootRegionHandle = m_scene.RegionInfo.RegionHandle; -<<<<<<< HEAD m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); -======= - m_scene.SetRootAgentScene(m_uuid); ->>>>>>> 91b1d17... Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. // Moved this from SendInitialData to ensure that m_appearance is initialized // before the inventory is processed in MakeRootAgent. This fixes a race condition @@ -912,7 +908,6 @@ namespace OpenSim.Region.Framework.Scenes { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); pos.Y = crossedBorder.BorderLine.Z - 1; -<<<<<<< HEAD } //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. @@ -929,24 +924,6 @@ namespace OpenSim.Region.Framework.Scenes pos = land.LandData.UserLocation; } } -======= - } - - //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. - //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, - //they'll bypass the landing point. But I can't think of any decent way of fixing this. - if (KnownChildRegionHandles.Count == 0) - { - ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (land != null) - { - //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. - if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_userLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) - { - pos = land.LandData.UserLocation; - } - } ->>>>>>> 91b1d17... Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. } if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) @@ -1130,8 +1107,8 @@ namespace OpenSim.Region.Framework.Scenes bool isFlying = false; if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; - + isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -1142,7 +1119,7 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_appearance.AvatarHeight); } - SendTerseUpdateToAllClients(); + SendTerseUpdateToAllClients(); } @@ -1848,14 +1825,14 @@ namespace OpenSim.Region.Framework.Scenes // else // { // single or child prim -// } - if (part == null) //CW: Part may be gone. llDie() for example. - { - partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - } - else - { - partRot = part.GetWorldRotation(); +// } + if (part == null) //CW: Part may be gone. llDie() for example. + { + partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); + } + else + { + partRot = part.GetWorldRotation(); } Quaternion partIRot = Quaternion.Inverse(partRot); @@ -1863,7 +1840,6 @@ namespace OpenSim.Region.Framework.Scenes Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av Vector3 avStandUp = new Vector3(1.0f, 0f, 0f) * avatarRot; // 1M infront of av -<<<<<<< HEAD if (m_physicsActor == null) { @@ -1876,24 +1852,11 @@ namespace OpenSim.Region.Framework.Scenes AbsolutePosition = avWorldStandUp; //KF: Fix stand up. part.IsOccupied = false; part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); -======= - - if (m_physicsActor == null) - { - AddToPhysicalScene(false); ->>>>>>> 91b1d17... Fix for hanging on "Connecting to region".. caused by packets being processed before the presence has bound to receive events. Fixed this by adding packets to a queue and then processing them when the presence is ready. } - //CW: If the part isn't null then we can set the current position - if (part != null) - { - Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + (m_pos * partRot); // + av sit offset! - AbsolutePosition = avWorldStandUp; //KF: Fix stand up. - part.IsOccupied = false; - } - else - { - //CW: Since the part doesn't exist, a coarse standup position isn't an issue - AbsolutePosition = m_lastWorldPosition; + else + { + //CW: Since the part doesn't exist, a coarse standup position isn't an issue + AbsolutePosition = m_lastWorldPosition; } m_parentPosition = Vector3.Zero; @@ -2057,7 +2020,7 @@ namespace OpenSim.Region.Framework.Scenes // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) ) { - autopilot = false; // close enough + autopilot = false; // close enough m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. Not using the part's position because returning the AV to the last known standing position is likely to be more friendly, isn't it? */ @@ -2067,7 +2030,7 @@ namespace OpenSim.Region.Framework.Scenes } // else the autopilot will get us close } else - { // its a scripted sit + { // its a scripted sit m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. I *am* using the part's position this time because we have no real idea how far away the avatar is from the sit target. */ -- cgit v1.1 From 4db60a5a40580bf5aa56d80c319534e2e312a306 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 5 Nov 2010 15:24:08 +0100 Subject: Fix the inventory transfer module to not cause duplicated text IMs --- .../Avatar/Inventory/Transfer/InventoryTransferModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs index e9e7c25..528bc8d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Inventory/Transfer/InventoryTransferModule.cs @@ -473,10 +473,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Inventory.Transfer user.ControllingClient.SendBulkUpdateInventory(item); } } + user.ControllingClient.SendInstantMessage(im); + } + else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted || + im.dialog == (byte) InstantMessageDialog.InventoryDeclined) + { + user.ControllingClient.SendInstantMessage(im); } - - // Just forward to the client - user.ControllingClient.SendInstantMessage(im); } } } -- cgit v1.1 From 5a3cd9f1d0480c57585b629a4f9cc8ba08dec7cf Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 7 Nov 2010 16:08:41 +0100 Subject: Decrease min search length to 2 chars for map search. --- OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 9f88517..d2c3afb 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -86,9 +86,9 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { - if (mapName.Length < 3) + if (mapName.Length < 2) { - remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); + remoteClient.SendAlertMessage("Use a search string with at least 2 characters"); return; } -- cgit v1.1 From 15da52d73aab37ba32447d317bab89baaceb38ba Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 8 Nov 2010 19:00:03 +0100 Subject: Prevent temp-on-rez prims from being persisted --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 93d223e..79f7162 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -1553,6 +1553,9 @@ namespace OpenSim.Region.Framework.Scenes return; } + if ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0) + return; + // Since this is the top of the section of call stack for backing up a particular scene object, don't let // any exception propogate upwards. try -- cgit v1.1 From 09ea73f7cc859978de7ae6dd30eb8dc943d71162 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Nov 2010 15:33:03 +0100 Subject: Change "OpenSim" to "Careminster" and remove CM suffix. --- OpenSim/Framework/Servers/VersionInfo.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index f852e54..ce6ecf8 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs @@ -29,7 +29,7 @@ namespace OpenSim { public class VersionInfo { - private const string VERSION_NUMBER = "0.7.1CM"; + private const string VERSION_NUMBER = "0.7.1"; private const Flavour VERSION_FLAVOUR = Flavour.Dev; public enum Flavour @@ -49,7 +49,7 @@ namespace OpenSim public static string GetVersionString(string versionNumber, Flavour flavour) { - string versionString = "OpenSim " + versionNumber + " " + flavour; + string versionString = "Careminster " + versionNumber + " " + flavour; return versionString.PadRight(VERSIONINFO_VERSION_LENGTH); } -- cgit v1.1 From ccfbce3176b429b0e590a8fedbf32185a6014c55 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Nov 2010 16:07:43 +0100 Subject: Remove "OpenSimulator" from startup message --- OpenSim/Framework/Servers/BaseOpenSimServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index cbab2db..8ff27c8 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -280,7 +280,7 @@ namespace OpenSim.Framework.Servers EnhanceVersionInformation(); - m_log.Info("[STARTUP]: OpenSimulator version: " + m_version + Environment.NewLine); + m_log.Info("[STARTUP]: Careminster version: " + m_version + Environment.NewLine); // clr version potentially is more confusing than helpful, since it doesn't tell us if we're running under Mono/MS .NET and // the clr version number doesn't match the project version number under Mono. //m_log.Info("[STARTUP]: Virtual machine runtime version: " + Environment.Version + Environment.NewLine); -- cgit v1.1 From dfe11566f43a60aaf0dda466a9425d8a1cc1d2e4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Nov 2010 20:18:36 +0100 Subject: Fix parcel bans to work only on the avatars they're supposed to work on instead of pushing all avatars, even the ones that are allowed. --- .../CoreModules/World/Land/LandManagementModule.cs | 29 +++++++++++----------- OpenSim/Region/Framework/Scenes/Scene.cs | 1 - 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 5bd72ee..6e0072e 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -90,7 +90,8 @@ namespace OpenSim.Region.CoreModules.World.Land // caches ExtendedLandData private Cache parcelInfoCache; - private Vector3? forcedPosition = null; + private Dictionary forcedPosition = + new Dictionary(); #region INonSharedRegionModule Members @@ -185,7 +186,7 @@ namespace OpenSim.Region.CoreModules.World.Land void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { //If we are forcing a position for them to go - if (forcedPosition != null) + if (forcedPosition.ContainsKey(remoteClient.AgentId)) { ScenePresence clientAvatar = m_scene.GetScenePresence(remoteClient.AgentId); @@ -195,23 +196,23 @@ namespace OpenSim.Region.CoreModules.World.Land //Make sure we stop if they get about to the right place to prevent yoyo and prevents getting stuck on banlines - if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) < .2) + if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) < .2) { - Debug.WriteLine(string.Format("Stopping force position because {0} is close enough to position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition)); - forcedPosition = null; + Debug.WriteLine(string.Format("Stopping force position because {0} is close enough to position {1}", forcedPosition[remoteClient.AgentId], clientAvatar.AbsolutePosition)); + forcedPosition.Remove(remoteClient.AgentId); } //if we are far away, teleport - else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition.Value) > 3) + else if (Vector3.Distance(clientAvatar.AbsolutePosition, forcedPosition[remoteClient.AgentId]) > 3) { - Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}", forcedPosition.Value, clientAvatar.AbsolutePosition)); - clientAvatar.Teleport(forcedPosition.Value); - forcedPosition = null; + Debug.WriteLine(string.Format("Teleporting out because {0} is too far from avatar position {1}", forcedPosition[remoteClient.AgentId], clientAvatar.AbsolutePosition)); + clientAvatar.Teleport(forcedPosition[remoteClient.AgentId]); + forcedPosition.Remove(remoteClient.AgentId); } else { //Forces them toward the forced position we want if they aren't there yet agentData.UseClientAgentPosition = true; - agentData.ClientAgentPosition = forcedPosition.Value; + agentData.ClientAgentPosition = forcedPosition[remoteClient.AgentId]; } } } @@ -334,7 +335,7 @@ namespace OpenSim.Region.CoreModules.World.Land if (m_scene.Permissions.IsGod(avatar.UUID)) return; if (position.HasValue) { - forcedPosition = position; + forcedPosition[avatar.ControllingClient.AgentId] = (Vector3)position; } } @@ -465,7 +466,7 @@ namespace OpenSim.Region.CoreModules.World.Land parcel.IsBannedFromLand(clientAvatar.UUID)) { //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition == null) + if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) { SendYouAreBannedNotice(clientAvatar); ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); @@ -474,7 +475,7 @@ namespace OpenSim.Region.CoreModules.World.Land else if (parcel.IsRestrictedFromLand(clientAvatar.UUID)) { //once we've sent the message once, keep going toward the target until we are done - if (forcedPosition == null) + if (forcedPosition.ContainsKey(clientAvatar.ControllingClient.AgentId)) { SendYouAreRestrictedNotice(clientAvatar); ForceAvatarToPosition(clientAvatar, m_scene.GetNearestAllowedPosition(clientAvatar)); @@ -483,7 +484,7 @@ namespace OpenSim.Region.CoreModules.World.Land else { //when we are finally in a safe place, lets release the forced position lock - forcedPosition = null; + forcedPosition.Remove(clientAvatar.ControllingClient.AgentId); } } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index ae48c02..b6d9a02 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -4878,7 +4878,6 @@ namespace OpenSim.Region.Framework.Scenes Vector3 nearestRegionEdgePoint = GetNearestRegionEdgePosition(avatar); //Debug.WriteLine("They are really in a place they don't belong, sending them to: " + nearestRegionEdgePoint.ToString()); return nearestRegionEdgePoint; - return null; } private Vector3 GetParcelCenterAtGround(ILandObject parcel) -- cgit v1.1 From d206721e2f8833f6c95fa9fda350f0187c24d34f Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Nov 2010 22:41:40 +0100 Subject: Add option SeeIntoBannedRegion to allow band to act like SL, where you can see in but not enter. Defaults to false, so no change. --- OpenSim/Region/Framework/Scenes/Scene.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index b6d9a02..a449cca 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -84,6 +84,7 @@ namespace OpenSim.Region.Framework.Scenes // TODO: need to figure out how allow client agents but deny // root agents when ACL denies access to root agent public bool m_strictAccessControl = true; + public bool m_seeIntoBannedRegion = false; public int MaxUndoCount = 5; public bool LoginsDisabled = true; public bool LoadingPrims; @@ -683,6 +684,7 @@ namespace OpenSim.Region.Framework.Scenes } m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); + m_seeIntoBannedRegion = startupConfig.GetBoolean("SeeIntoBannedRegion", m_seeIntoBannedRegion); CombineRegions = startupConfig.GetBoolean("CombineContiguousRegions", false); m_generateMaptiles = startupConfig.GetBoolean("GenerateMaptiles", true); @@ -3688,7 +3690,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_regInfo.EstateSettings != null) { - if (m_regInfo.EstateSettings.IsBanned(agent.AgentID)) + if ((!m_seeIntoBannedRegion) && m_regInfo.EstateSettings.IsBanned(agent.AgentID)) { m_log.WarnFormat("[CONNECTION BEGIN]: Denied access to: {0} ({1} {2}) at {3} because the user is on the banlist", agent.AgentID, agent.firstname, agent.lastname, RegionInfo.RegionName); @@ -3878,6 +3880,12 @@ namespace OpenSim.Region.Framework.Scenes // We have to wait until the viewer contacts this region after receiving EAC. // That calls AddNewClient, which finally creates the ScenePresence + if (m_regInfo.EstateSettings.IsBanned(cAgentData.AgentID)) + { + m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: banned", cAgentData.AgentID); + return false; + } + int num = m_sceneGraph.GetNumberOfScenePresences(); if (num >= RegionInfo.RegionSettings.AgentLimit) -- cgit v1.1 From fa64f2e56e6f3375c1417172b134eacb1a00f16c Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 9 Nov 2010 23:54:08 +0000 Subject: Although the Allow Voice setting is per estate rather than per region, apparently it is required in the region handshake to let the client enable parcel voice controls. So, send it. --- OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 9df13d8..ab142f7 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs @@ -1115,12 +1115,14 @@ namespace OpenSim.Region.CoreModules.World.Estate if (m_scene.RegionInfo.RegionSettings.AllowLandJoinDivide) flags |= RegionFlags.AllowParcelChanges; if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch) - flags |= (RegionFlags)(1 << 29); + flags |= RegionFlags.BlockParcelSearch; if (m_scene.RegionInfo.RegionSettings.FixedSun) flags |= RegionFlags.SunFixed; if (m_scene.RegionInfo.RegionSettings.Sandbox) flags |= RegionFlags.Sandbox; + if (m_scene.RegionInfo.EstateSettings.AllowVoice) + flags |= RegionFlags.AllowVoice; // Fudge these to always on, so the menu options activate // -- cgit v1.1 From aace455249b2ea8c033871f39f23409119760932 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 10 Nov 2010 16:22:55 +0100 Subject: Prevent teleporting to a region when the egent is banned in all parcels --- OpenSim/Region/Framework/Scenes/Scene.cs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index a449cca..dd06be2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3886,6 +3886,13 @@ namespace OpenSim.Region.Framework.Scenes return false; } + ILandObject nearestParcel = GetNearestAllowedParcel(cAgentData.AgentID, Constants.RegionSize / 2, Constants.RegionSize / 2); + if (nearestParcel == null) + { + m_log.DebugFormat("[SCENE]: Denying root agent entry to {0}: no allowed parcel", cAgentData.AgentID); + return false; + } + int num = m_sceneGraph.GetNumberOfScenePresences(); if (num >= RegionInfo.RegionSettings.AgentLimit) -- cgit v1.1 From 9462a1861b3a10467370380d11cf2e82a91c4ab7 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Thu, 11 Nov 2010 04:49:47 +0000 Subject: Fix excessive forward motion and flailing while descending a slope, prevent adding motion while falling from flying. --- .../Scenes/Animation/ScenePresenceAnimator.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs index 9658e11..9c103cb 100644 --- a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs +++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs @@ -248,7 +248,7 @@ TrySetMovementAnimation("STAND"); m_animTickFall = Environment.TickCount; } // else if (!jumping && fallElapsed > FALL_DELAY) - else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) ) // add for falling and jumping + else if (!m_jumping && (fallElapsed > FALL_DELAY) && (fallVelocity < -3.0f) && (m_scenePresence.m_wasFlying)) // add for falling and jumping { // Falling long enough to trigger the animation //Console.WriteLine("FALLDOWN"); //## diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b637317..f20eb33 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -161,6 +161,8 @@ namespace OpenSim.Region.Framework.Scenes private bool m_setAlwaysRun; private bool m_forceFly; private bool m_flyDisabled; + private bool m_flyingOld; // add for fly velocity control + public bool m_wasFlying; // add for fly velocity control private float m_speedModifier = 1.0f; @@ -2564,14 +2566,22 @@ namespace OpenSim.Region.Framework.Scenes Vector3 direc = vec * rotation; direc.Normalize(); PhysicsActor actor = m_physicsActor; + + if (actor.Flying != m_flyingOld) // add for fly velocity control + { + m_flyingOld = actor.Flying; // add for fly velocity control + if (!actor.Flying) m_wasFlying = true; // add for fly velocity control + } + + if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control + if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. direc *= 0.03f * 128f * m_speedModifier; if (actor != null) { -// rm falling if (actor.Flying) - if ((actor.Flying) || Animator.m_falling) // add for falling lateral speed + if (actor.Flying) { // rm speed mod direc *= 4.0f; direc *= 5.2f; // for speed mod @@ -2587,6 +2597,10 @@ namespace OpenSim.Region.Framework.Scenes // m_log.Info("[AGENT]: Stop FLying"); //} } + if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add + { + direc *= 0.0f; + } /* This jumping section removed to SPA else if (!actor.Flying && actor.IsColliding) { -- cgit v1.1 From 0f152bfe8c6e9723da3abec3eeef83d0f2d18796 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Nov 2010 01:33:24 +0100 Subject: Diva needs a spanking! Serializing OldItemID breaks script state persistence in agent inventory. --- .../Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs index a398dfd..dfc69d8 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs @@ -735,7 +735,10 @@ namespace OpenSim.Region.Framework.Scenes.Serialization private static void ProcessTIOldItemID(TaskInventoryItem item, XmlTextReader reader) { - item.OldItemID = ReadUUID(reader, "OldItemID"); + ReadUUID(reader, "OldItemID"); + // On deserialization, the old item id MUST BE UUID.Zero!!!!! + // Setting this to the saved value will BREAK script persistence! + // item.OldItemID = ReadUUID(reader, "OldItemID"); } private static void ProcessTILastOwnerID(TaskInventoryItem item, XmlTextReader reader) -- cgit v1.1 From 7a9c57a81ec979564b089429bb93655912f823a2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Nov 2010 01:35:45 +0100 Subject: When detaching a scripted item, always consider it modified. Script states will have changed and for real usability, we need to save it. It bloats assets, but that can't be avoided. --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 8 +++++++- OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 6122cc2..929db21 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -527,10 +527,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - protected void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) + public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) { if (grp != null) { + // If an item contains scripts, it's always changed. + // This ensures script state is saved on detach + foreach (SceneObjectPart p in grp.Parts) + if (p.Inventory.ContainsScripts()) + grp.HasGroupChanged = true; + if (!grp.HasGroupChanged) { m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index a675928..1d9aeb9 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -133,5 +133,7 @@ namespace OpenSim.Region.Framework.Interfaces /// /// void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos); + + void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID); } } -- cgit v1.1 From c2ac5dc35822fd85751b1da4a96a0062e600b55c Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Nov 2010 01:37:44 +0100 Subject: Can't detach an object from within the script thread because it will throw. Use FireAndForget for that. --- .../Shared/Api/Implementation/LSL_Api.cs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8f05359..c602307 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3213,17 +3213,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((item.PermsMask & ScriptBaseClass.PERMISSION_ATTACH) != 0) { - SceneObjectGroup grp = m_host.ParentGroup; - UUID itemID = grp.GetFromItemID(); - - ScenePresence presence = World.GetScenePresence(m_host.OwnerID); - IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; if (attachmentsModule != null) - attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient); + Util.FireAndForget(DetachWrapper, m_host); } } + private void DetachWrapper(object o) + { + SceneObjectPart host = (SceneObjectPart)o; + + SceneObjectGroup grp = host.ParentGroup; + UUID itemID = grp.GetFromItemID(); + ScenePresence presence = World.GetScenePresence(host.OwnerID); + + IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; + if (attachmentsModule != null) + attachmentsModule.ShowDetachInUserInventory(itemID, presence.ControllingClient); + } + public void llTakeCamera(string avatar) { m_host.AddScriptLPS(1); -- cgit v1.1 From 4f15b8d4e6be1e1fe88ad32aa43595861d1005ad Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Nov 2010 20:44:39 +0100 Subject: Change the way attachments are persisted. Editing a worn attachment will now save properly, as will the results of a resizer script working. Attachment positions are no longer saved on each move, but instead are saved once on logout. Attachment script states are saved as part of the attachment now when detaching. --- OpenSim/Framework/ISceneObject.cs | 1 + .../Avatar/Attachments/AttachmentsModule.cs | 40 +++++++--------------- .../InventoryAccess/InventoryAccessModule.cs | 21 +++++++----- .../Framework/Interfaces/IAttachmentsModule.cs | 19 ++++++---- .../Framework/Interfaces/IEntityInventory.cs | 1 + OpenSim/Region/Framework/Scenes/Scene.cs | 4 ++- OpenSim/Region/Framework/Scenes/SceneGraph.cs | 17 ++++++--- .../Region/Framework/Scenes/SceneObjectGroup.cs | 6 ++-- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 37 +++++++++++--------- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 18 ++++++++++ .../Server/Handlers/Simulation/ObjectHandlers.cs | 7 +++- .../Simulation/SimulationServiceConnector.cs | 1 + 13 files changed, 105 insertions(+), 69 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/ISceneObject.cs b/OpenSim/Framework/ISceneObject.cs index 5147901..18631f1 100644 --- a/OpenSim/Framework/ISceneObject.cs +++ b/OpenSim/Framework/ISceneObject.cs @@ -39,5 +39,6 @@ namespace OpenSim.Framework void ExtraFromXmlString(string xmlstr); string GetStateSnapshot(); void SetState(string xmlstr, IScene s); + bool HasGroupChanged { get; set; } } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 929db21..fc92fc3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -276,6 +276,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (objatt != null) { + // Loading the inventory from XML will have set this, but + // there is no way the object could have changed yet, + // since scripts aren't running yet. So, clear it here. + objatt.HasGroupChanged = false; bool tainted = false; if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) tainted = true; @@ -486,9 +490,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); // CM / XMREngine!!!! Needed to conclude attach event - SceneObjectSerializer.ToOriginalXmlFormat(group); + //SceneObjectSerializer.ToOriginalXmlFormat(group); group.DetachToInventoryPrep(); m_log.Debug("[ATTACHMENTS MODULE]: Saving attachpoint: " + ((uint)group.GetAttachmentPoint()).ToString()); + + // If an item contains scripts, it's always changed. + // This ensures script state is saved on detach + foreach (SceneObjectPart p in group.Parts) + if (p.Inventory.ContainsScripts()) + group.HasGroupChanged = true; + UpdateKnownItem(remoteClient, group, group.GetFromItemID(), group.OwnerID); m_scene.DeleteSceneObject(group, false); return; @@ -497,25 +508,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos) - { - // If this is an attachment, then we need to save the modified - // object back into the avatar's inventory. First we save the - // attachment point information, then we update the relative - // positioning (which caused this method to get driven in the - // first place. Then we have to mark the object as NOT an - // attachment. This is necessary in order to correctly save - // and retrieve GroupPosition information for the attachment. - // Then we save the asset back into the appropriate inventory - // entry. Finally, we restore the object's attachment status. - byte attachmentPoint = sog.GetAttachmentPoint(); - sog.UpdateGroupPosition(pos); - sog.RootPart.IsAttachment = false; - sog.AbsolutePosition = sog.RootPart.AttachedPos; - UpdateKnownItem(client, sog, sog.GetFromItemID(), sog.OwnerID); - sog.SetAttachmentPoint(attachmentPoint); - } - /// /// Update the attachment asset for the new sog details if they have changed. /// @@ -531,12 +523,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { if (grp != null) { - // If an item contains scripts, it's always changed. - // This ensures script state is saved on detach - foreach (SceneObjectPart p in grp.Parts) - if (p.Inventory.ContainsScripts()) - grp.HasGroupChanged = true; - if (!grp.HasGroupChanged) { m_log.WarnFormat("[ATTACHMENTS MODULE]: Save request for {0} which is unchanged", grp.UUID); @@ -548,7 +534,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments grp.UUID, grp.GetAttachmentPoint()); string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); - InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); @@ -642,7 +627,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // In case it is later dropped again, don't let // it get cleaned up so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); - so.HasGroupChanged = false; } } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 0700aa5..2e3db48 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -719,15 +719,20 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { group.RootPart.Flags |= PrimFlags.Phantom; group.RootPart.IsAttachment = true; - } - // If we're rezzing an attachment then don't ask - // AddNewSceneObject() to update the client since - // we'll be doing that later on. Scheduling more than - // one full update during the attachment - // process causes some clients to fail to display the - // attachment properly. - m_Scene.AddNewSceneObject(group, true, false); + // If we're rezzing an attachment then don't ask + // AddNewSceneObject() to update the client since + // we'll be doing that later on. Scheduling more + // than one full update during the attachment + // process causes some clients to fail to display + // the attachment properly. + // Also, don't persist attachments. + m_Scene.AddNewSceneObject(group, false, false); + } + else + { + m_Scene.AddNewSceneObject(group, true, false); + } // if attachment we set it's asset id so object updates // can reflect that, if not, we set it's position in world. diff --git a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs index 1d9aeb9..788f42b 100644 --- a/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IAttachmentsModule.cs @@ -127,13 +127,20 @@ namespace OpenSim.Region.Framework.Interfaces void ShowDetachInUserInventory(UUID itemID, IClientAPI remoteClient); /// - /// Update the position of an attachment + /// Update the user inventory with a changed attachment /// - /// - /// - /// - void UpdateAttachmentPosition(IClientAPI client, SceneObjectGroup sog, Vector3 pos); - + /// + /// A + /// + /// + /// A + /// + /// + /// A + /// + /// + /// A + /// void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID); } } diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 59ce090..ed40da9 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -185,6 +185,7 @@ namespace OpenSim.Region.Framework.Interfaces /// false if the item did not exist, true if the update occurred successfully bool UpdateInventoryItem(TaskInventoryItem item); bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents); + bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged); /// /// Remove an item from this entity's inventory diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index dd06be2..c4639c3 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3255,7 +3255,6 @@ namespace OpenSim.Region.Framework.Scenes List regions = new List(avatar.KnownChildRegionHandles); regions.Remove(RegionInfo.RegionHandle); m_sceneGridService.SendCloseChildAgentConnections(agentID, regions); - } m_log.Debug("[Scene] Beginning ClientClosed"); m_eventManager.TriggerClientClosed(agentID, this); @@ -3271,6 +3270,9 @@ namespace OpenSim.Region.Framework.Scenes m_eventManager.TriggerOnRemovePresence(agentID); m_log.Debug("[Scene] Finished OnRemovePresence"); + if (avatar != null && (!avatar.IsChildAgent)) + avatar.SaveChangedAttachments(); + ForEachClient( delegate(IClientAPI client) { diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index a462133..b2d9358 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -281,7 +281,7 @@ namespace OpenSim.Region.Framework.Scenes } } - if (!alreadyPersisted) + if (attachToBackup && (!alreadyPersisted)) { sceneObject.ForceInventoryPersistence(); sceneObject.HasGroupChanged = true; @@ -304,8 +304,10 @@ namespace OpenSim.Region.Framework.Scenes /// protected internal bool AddNewSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { - // Ensure that we persist this new scene object - sceneObject.HasGroupChanged = true; + // Ensure that we persist this new scene object if it's not an + // attachment + if (attachToBackup) + sceneObject.HasGroupChanged = true; return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates); } @@ -1342,8 +1344,13 @@ namespace OpenSim.Region.Framework.Scenes { if (group.IsAttachment || (group.RootPart.Shape.PCode == 9 && group.RootPart.Shape.State != 0)) { - if (m_parentScene.AttachmentsModule != null) - m_parentScene.AttachmentsModule.UpdateAttachmentPosition(remoteClient, group, pos); + // Set the new attachment point data in the object + byte attachmentPoint = group.GetAttachmentPoint(); + group.UpdateGroupPosition(pos); + group.RootPart.IsAttachment = false; + group.AbsolutePosition = group.RootPart.AttachedPos; + group.SetAttachmentPoint(attachmentPoint); + group.HasGroupChanged = true; } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 79f7162..ee08072 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -586,13 +586,15 @@ namespace OpenSim.Region.Framework.Scenes XmlNodeList nodes = doc.GetElementsByTagName("SavedScriptState"); if (nodes.Count > 0) { - m_savedScriptState = new Dictionary(); + if (m_savedScriptState == null) + m_savedScriptState = new Dictionary(); foreach (XmlNode node in nodes) { if (node.Attributes["UUID"] != null) { UUID itemid = new UUID(node.Attributes["UUID"].Value); - m_savedScriptState.Add(itemid, node.InnerXml); + if (itemid != UUID.Zero) + m_savedScriptState[itemid] = node.InnerXml; } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index be3e87f..b615d42 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -4822,7 +4822,7 @@ namespace OpenSim.Region.Framework.Scenes { TaskInventoryItem item = Inventory.GetInventoryItem(itemID); item.OwnerChanged = false; - Inventory.UpdateInventoryItem(item); + Inventory.UpdateInventoryItem(item, false, false); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 522f75e..8fcfcc5 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -131,12 +131,6 @@ namespace OpenSim.Region.Framework.Scenes return; } - HasInventoryChanged = true; - if (m_part.ParentGroup != null) - { - m_part.ParentGroup.HasGroupChanged = true; - } - IList items = new List(Items.Values); Items.Clear(); @@ -158,12 +152,6 @@ namespace OpenSim.Region.Framework.Scenes return; } - HasInventoryChanged = true; - if (m_part.ParentGroup != null) - { - m_part.ParentGroup.HasGroupChanged = true; - } - IList items = new List(Items.Values); Items.Clear(); @@ -216,8 +204,15 @@ namespace OpenSim.Region.Framework.Scenes return; } - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; + // Don't let this set the HasGroupChanged flag for attachments + // as this happens during rez and we don't want a new asset + // for each attachment each time + if (!m_part.ParentGroup.RootPart.IsAttachment) + { + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + } + IList items = new List(Items.Values); foreach (TaskInventoryItem item in items) { @@ -824,11 +819,16 @@ namespace OpenSim.Region.Framework.Scenes /// false if the item did not exist, true if the update occurred successfully public bool UpdateInventoryItem(TaskInventoryItem item) { - return UpdateInventoryItem(item, true); + return UpdateInventoryItem(item, true, true); } public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) { + return UpdateInventoryItem(item, fireScriptEvents, true); + } + + public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) + { m_items.LockItemsForWrite(true); if (m_items.ContainsKey(item.ItemID)) @@ -849,8 +849,11 @@ namespace OpenSim.Region.Framework.Scenes m_inventorySerial++; if (fireScriptEvents) m_part.TriggerScriptChangedEvent(Changed.INVENTORY); - HasInventoryChanged = true; - m_part.ParentGroup.HasGroupChanged = true; + if (considerChanged) + { + HasInventoryChanged = true; + m_part.ParentGroup.HasGroupChanged = true; + } m_items.LockItemsForWrite(false); return true; } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index cc9c445..dfaf06d 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4340,6 +4340,24 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju return(new Vector3(x,y,z)); } + public void SaveChangedAttachments() + { + // Need to copy this list because DetachToInventoryPrep mods it + List attachments = new List(Attachments.ToArray()); + IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule; + if (attachmentsModule != null) + { + foreach (SceneObjectGroup grp in attachments) + { + if (grp.HasGroupChanged) // Resizer scripts? + { + grp.DetachToInventoryPrep(); + attachmentsModule.UpdateKnownItem(ControllingClient, + grp, grp.GetFromItemID(), grp.OwnerID); + } + } + } + } } } diff --git a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs index 33e5aa6..04ff83f 100644 --- a/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs +++ b/OpenSim/Server/Handlers/Simulation/ObjectHandlers.cs @@ -162,6 +162,11 @@ namespace OpenSim.Server.Handlers.Simulation return; } + if (args.ContainsKey("modified")) + sog.HasGroupChanged = args["modified"].AsBoolean(); + else + sog.HasGroupChanged = false; + if ((args["state"] != null) && s.AllowScriptCrossings) { stateXmlStr = args["state"].AsString(); @@ -243,4 +248,4 @@ namespace OpenSim.Server.Handlers.Simulation } } -} \ No newline at end of file +} diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs index 0626ebe..1730b95 100644 --- a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -565,6 +565,7 @@ namespace OpenSim.Services.Connectors.Simulation OSDMap args = new OSDMap(2); args["sog"] = OSD.FromString(sog.ToXml2()); args["extra"] = OSD.FromString(sog.ExtraToXmlString()); + args["modified"] = OSD.FromBoolean(sog.HasGroupChanged); string state = sog.GetStateSnapshot(); if (state.Length > 0) args["state"] = OSD.FromString(state); -- cgit v1.1 From 0049ec16f56eab51c812eef5e2e4396f23d91507 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 16 Nov 2010 22:26:07 +0100 Subject: Prevent leftover attachments from clogging up the pipes --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b340bda..d2c6a29 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -4366,9 +4366,12 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju { if (grp.HasGroupChanged) // Resizer scripts? { - grp.DetachToInventoryPrep(); + grp.RootPart.IsAttachment = false; + grp.AbsolutePosition = grp.RootPart.AttachedPos; +// grp.DetachToInventoryPrep(); attachmentsModule.UpdateKnownItem(ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); + grp.RootPart.IsAttachment = true; } } } -- cgit v1.1 From 80d3998001b35ccf249218561817969ce78bf900 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 17 Nov 2010 17:54:03 +0100 Subject: Recalculate prim counts when a parcel is deeded --- OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs index 6e0072e..9779c68 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs @@ -1297,7 +1297,7 @@ namespace OpenSim.Region.CoreModules.World.Land { land.DeedToGroup(groupID); } - + EventManagerOnParcelPrimCountTainted(); } -- cgit v1.1 From 2e5ae1b013e2960f6651bc8cf2d74cfbb181012e Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 17 Nov 2010 17:54:32 +0100 Subject: Fix gesture and viewer preview sounds not playing --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 5 +++-- .../Region/CoreModules/World/Sound/SoundModule.cs | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index c6ce1b6..5419ede 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -6047,8 +6047,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP SoundTrigger handlerSoundTrigger = OnSoundTrigger; if (handlerSoundTrigger != null) { - handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, soundTriggerPacket.SoundData.OwnerID, - soundTriggerPacket.SoundData.ObjectID, soundTriggerPacket.SoundData.ParentID, + // UUIDS are sent as zeroes by the client, substitute agent's id + handlerSoundTrigger(soundTriggerPacket.SoundData.SoundID, AgentId, + AgentId, AgentId, soundTriggerPacket.SoundData.Gain, soundTriggerPacket.SoundData.Position, soundTriggerPacket.SoundData.Handle, 0); diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index abd28c8..8df44fe 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -106,14 +106,20 @@ namespace OpenSim.Region.CoreModules.World.Sound { SceneObjectPart part = m_scene.GetSceneObjectPart(objectID); if (part == null) - return; - - SceneObjectGroup grp = part.ParentGroup; - - if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) { - objectID = ownerID; - parentID = ownerID; + ScenePresence sp; + if (!m_scene.TryGetScenePresence(objectID, out sp)) + return; + } + else + { + SceneObjectGroup grp = part.ParentGroup; + + if (grp.IsAttachment && grp.GetAttachmentPoint() > 30) + { + objectID = ownerID; + parentID = ownerID; + } } m_scene.ForEachScenePresence(delegate(ScenePresence sp) -- cgit v1.1 From 095e3aae670a706406414b6ee069872463ec83e7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 18 Nov 2010 01:11:11 +0100 Subject: Allow llDialog without any buttons and add the automatic OK button as it is in SL. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 254ed0f..6d8e558 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6736,8 +6736,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if (buttons.Length < 1) { - LSLError("No less than 1 button can be shown"); - return; + buttons.Add("OK"); } if (buttons.Length > 12) { -- cgit v1.1 From 47f04689953b9a84a9e718a5e7a75fe9fc9028aa Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 18 Nov 2010 04:18:43 +0100 Subject: Send parcel data upon becoming root. This will make streams play and build flags be set properly --- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index d2c6a29..c35df08 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -915,10 +915,10 @@ namespace OpenSim.Region.Framework.Scenes //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, //they'll bypass the landing point. But I can't think of any decent way of fixing this. - if (KnownChildRegionHandles.Count == 0) + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) { - ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); - if (land != null) + if (KnownChildRegionHandles.Count == 0) { //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && UserLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) @@ -926,6 +926,8 @@ namespace OpenSim.Region.Framework.Scenes pos = land.LandData.UserLocation; } } + + land.SendLandUpdateToClient(ControllingClient); } if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) -- cgit v1.1 From f3e4000a552e5dcb7d3f3612badb622e1d412055 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 18 Nov 2010 13:26:35 +0100 Subject: Send media and other parcel data to client on login. Makes streams visible right away and starts media. --- OpenSim/Region/Framework/Scenes/Scene.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 3ae8a38..a0ae82f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -2706,12 +2706,19 @@ namespace OpenSim.Region.Framework.Scenes } } - if (GetScenePresence(client.AgentId) != null) + if (TryGetScenePresence(client.AgentId, out presence)) { m_LastLogin = Util.EnvironmentTickCount(); EventManager.TriggerOnNewClient(client); if (vialogin) + { EventManager.TriggerOnClientLogin(client); + + // Send initial parcel data + Vector3 pos = presence.AbsolutePosition; + ILandObject land = LandChannel.GetLandObject(pos.X, pos.Y); + land.SendLandUpdateToClient(presence.ControllingClient); + } } } -- cgit v1.1 From 1cf8eb8a90749b215bc4e8b7beb37b927e101dce Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 21 Nov 2010 20:59:01 +0000 Subject: Start implementing Freeswitch in ROBUST --- .../Freeswitch/FreeswitchServerConnector.cs | 46 +++++++++++++- .../Freeswitch/FreeswitchServerGetHandler.cs | 72 ---------------------- .../FreeswitchService/FreeswitchService.cs | 12 +++- .../FreeswitchService/FreeswitchServiceBase.cs | 36 ++++++++++- OpenSim/Services/Interfaces/IFreeswitchService.cs | 4 +- 5 files changed, 93 insertions(+), 77 deletions(-) delete mode 100644 OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs b/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs index 07bafc8..150df45 100644 --- a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs +++ b/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerConnector.cs @@ -26,18 +26,25 @@ */ using System; +using System.Collections; +using System.Web; +using System.Reflection; using Nini.Config; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Handlers.Base; +using log4net; namespace OpenSim.Server.Handlers.Freeswitch { public class FreeswitchServerConnector : ServiceConnector { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IFreeswitchService m_FreeswitchService; private string m_ConfigName = "FreeswitchService"; + protected readonly string m_freeSwitchAPIPrefix = "/fsapi"; public FreeswitchServerConnector(IConfigSource config, IHttpServer server, string configName) : base(config, server, configName) @@ -59,7 +66,44 @@ namespace OpenSim.Server.Handlers.Freeswitch m_FreeswitchService = ServerUtils.LoadPlugin(freeswitchService, args); - server.AddStreamHandler(new FreeswitchServerGetHandler(m_FreeswitchService)); + server.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), FreeSwitchConfigHTTPHandler); + } + + public Hashtable FreeSwitchConfigHTTPHandler(Hashtable request) + { + Hashtable response = new Hashtable(); + response["str_response_string"] = string.Empty; + + Hashtable requestBody = ParseRequestBody((string) request["body"]); + + string section = (string) requestBody["section"]; + + if (section == "directory") + response = m_FreeswitchService.HandleDirectoryRequest(requestBody); + else if (section == "dialplan") + response = m_FreeswitchService.HandleDialplanRequest(requestBody); + else + m_log.WarnFormat("[FreeSwitchVoice]: section was {0}", section); + + return response; + } + + private Hashtable ParseRequestBody(string body) + { + Hashtable bodyParams = new Hashtable(); + // split string + string [] nvps = body.Split(new Char [] {'&'}); + + foreach (string s in nvps) + { + if (s.Trim() != "") + { + string [] nvp = s.Split(new Char [] {'='}); + bodyParams.Add(HttpUtility.UrlDecode(nvp[0]), HttpUtility.UrlDecode(nvp[1])); + } + } + + return bodyParams; } } } diff --git a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs b/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs deleted file mode 100644 index 8b41742..0000000 --- a/OpenSim/Server/Handlers/Freeswitch/FreeswitchServerGetHandler.cs +++ /dev/null @@ -1,72 +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 OpenSimulator Project nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using Nini.Config; -using log4net; -using System; -using System.IO; -using System.Reflection; -using System.Net; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using System.Xml.Serialization; -using OpenSim.Server.Base; -using OpenSim.Services.Interfaces; -using OpenSim.Framework; -using OpenSim.Framework.Servers.HttpServer; - -namespace OpenSim.Server.Handlers.Freeswitch -{ - public class FreeswitchServerGetHandler : BaseStreamHandler - { - // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - //private IFreeswitchService m_FreeswitchService; - - public FreeswitchServerGetHandler(IFreeswitchService service) : - base("GET", "/api") - { - //m_FreeswitchService = service; - } - - public override byte[] Handle(string path, Stream request, - OSHttpRequest httpRequest, OSHttpResponse httpResponse) - { - byte[] result = new byte[0]; - - string[] p = SplitParams(path); - - if (p.Length == 0) - return result; - - // Process web request - - return result; - } - } -} diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs index 0a38300..109ef9b 100644 --- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs +++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs @@ -33,19 +33,27 @@ using OpenSim.Framework; using OpenSim.Data; using OpenSim.Services.Interfaces; using OpenMetaverse; +using System.Collections; namespace OpenSim.Services.FreeswitchService { public class FreeswitchService : FreeswitchServiceBase, IFreeswitchService { - //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public FreeswitchService(IConfigSource config) : base(config) { // Perform initilialization here } + public Hashtable HandleDirectoryRequest(Hashtable requestBody) + { + return new Hashtable(); + } - // Implement IFreeswitchService here + public Hashtable HandleDialplanRequest(Hashtable requestBody) + { + return new Hashtable(); + } } } diff --git a/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs b/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs index 83fecef..ebbb1b0 100644 --- a/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs +++ b/OpenSim/Services/FreeswitchService/FreeswitchServiceBase.cs @@ -31,11 +31,28 @@ using Nini.Config; using OpenSim.Framework; using OpenSim.Services.Interfaces; using OpenSim.Services.Base; +using log4net; namespace OpenSim.Services.FreeswitchService { public class FreeswitchServiceBase : ServiceBase { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected string m_freeSwitchRealm; + protected string m_freeSwitchSIPProxy; + protected bool m_freeSwitchAttemptUseSTUN = false; + protected string m_freeSwitchEchoServer; + protected int m_freeSwitchEchoPort = 50505; + protected string m_freeSwitchDefaultWellKnownIP; + protected int m_freeSwitchDefaultTimeout = 5000; + protected string m_freeSwitchContext = "default"; + protected string m_freeSwitchServerUser = "freeswitch"; + protected string m_freeSwitchServerPass = "password"; + protected readonly string m_freeSwitchAPIPrefix = "/fsapi"; + + protected bool m_Enabled = false; + public FreeswitchServiceBase(IConfigSource config) : base(config) { // @@ -44,7 +61,24 @@ namespace OpenSim.Services.FreeswitchService IConfig freeswitchConfig = config.Configs["FreeswitchService"]; if (freeswitchConfig != null) { - // Read config here !! + m_freeSwitchDefaultWellKnownIP = freeswitchConfig.GetString("ServerAddress", String.Empty); + if (m_freeSwitchDefaultWellKnownIP == String.Empty) + { + m_log.Error("[FREESWITCH]: No FreeswitchServerAddress given, can't continue"); + return; + } + + m_freeSwitchRealm = freeswitchConfig.GetString("Realm", m_freeSwitchDefaultWellKnownIP); + m_freeSwitchSIPProxy = freeswitchConfig.GetString("SIPProxy", m_freeSwitchDefaultWellKnownIP + ":5060"); + m_freeSwitchEchoServer = freeswitchConfig.GetString("EchoServer", m_freeSwitchDefaultWellKnownIP); + m_freeSwitchEchoPort = freeswitchConfig.GetInt("EchoPort", m_freeSwitchEchoPort); + m_freeSwitchAttemptUseSTUN = freeswitchConfig.GetBoolean("AttemptSTUN", false); // This may not work + m_freeSwitchDefaultTimeout = freeswitchConfig.GetInt("DefaultTimeout", m_freeSwitchDefaultTimeout); + m_freeSwitchContext = freeswitchConfig.GetString("Context", m_freeSwitchContext); + m_freeSwitchServerUser = freeswitchConfig.GetString("UserName", m_freeSwitchServerUser); + m_freeSwitchServerPass = freeswitchConfig.GetString("Password", m_freeSwitchServerPass); + + m_Enabled = true; } } } diff --git a/OpenSim/Services/Interfaces/IFreeswitchService.cs b/OpenSim/Services/Interfaces/IFreeswitchService.cs index d1f635b..2b3ffeb 100644 --- a/OpenSim/Services/Interfaces/IFreeswitchService.cs +++ b/OpenSim/Services/Interfaces/IFreeswitchService.cs @@ -27,11 +27,13 @@ using System; using OpenSim.Framework; +using System.Collections; namespace OpenSim.Services.Interfaces { public interface IFreeswitchService { - // Place anything the connector eeds to access here! + Hashtable HandleDirectoryRequest(Hashtable requestBody); + Hashtable HandleDialplanRequest(Hashtable requestBody); } } -- cgit v1.1 From 83a427a8f9ef0ea99beab3f7f196be1f064879c8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 21 Nov 2010 21:18:03 +0000 Subject: Move Dialplan and Directory from the region module to the ROBUST server --- .../FreeswitchService/FreeswitchService.cs | 337 ++++++++++++++++++++- 1 file changed, 333 insertions(+), 4 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Services/FreeswitchService/FreeswitchService.cs b/OpenSim/Services/FreeswitchService/FreeswitchService.cs index 109ef9b..b62a65a 100644 --- a/OpenSim/Services/FreeswitchService/FreeswitchService.cs +++ b/OpenSim/Services/FreeswitchService/FreeswitchService.cs @@ -26,6 +26,7 @@ */ using System; +using System.Text; using System.Reflection; using Nini.Config; using log4net; @@ -46,14 +47,342 @@ namespace OpenSim.Services.FreeswitchService // Perform initilialization here } - public Hashtable HandleDirectoryRequest(Hashtable requestBody) + public Hashtable HandleDialplanRequest(Hashtable request) { - return new Hashtable(); + m_log.DebugFormat("[FreeSwitchVoice] HandleDialplanRequest called with {0}",request.ToString()); + + Hashtable response = new Hashtable(); + + foreach (DictionaryEntry item in request) + { + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}",item.Key, item.Value); + } + + string requestcontext = (string) request["Hunt-Context"]; + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + + if (m_freeSwitchContext != String.Empty && m_freeSwitchContext != requestcontext) + { + m_log.Debug("[FreeSwitchDirectory] returning empty as it's for another context"); + response["str_response_string"] = ""; + } + else + { + response["str_response_string"] = String.Format(@" + +
+ " + + +/* + + + + + + */ + + @" + + + + + + + + + + + + + + + + + + + + +
+
", m_freeSwitchContext, m_freeSwitchRealm); + } + + return response; } - public Hashtable HandleDialplanRequest(Hashtable requestBody) + public Hashtable HandleDirectoryRequest(Hashtable request) + { + Hashtable response = new Hashtable(); + string domain = (string) request["domain"]; + if (domain != m_freeSwitchRealm) { + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = ""; + } else { + m_log.DebugFormat("[FreeSwitchDirectory] HandleDirectoryRequest called with {0}",request.ToString()); + + // information in the request we might be interested in + + // Request 1 sip_auth for users account + + //Event-Calling-Function=sofia_reg_parse_auth + //Event-Calling-Line-Number=1494 + //action=sip_auth + //sip_user_agent=Vivox-SDK-2.1.3010.6151-Mac%20(Feb-11-2009/16%3A42%3A41) + //sip_auth_username=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_auth_realm=9.20.151.43 + //sip_contact_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D (==) + //sip_contact_host=192.168.0.3 // this shouldnt really be a local IP, investigate STUN servers + //sip_to_user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //sip_to_host=9.20.151.43 + //sip_auth_method=REGISTER + //user=xhZuXKmRpECyr2AARJYyGgg%3D%3D + //domain=9.20.151.43 + //ip=9.167.220.137 // this is the correct IP rather than sip_contact_host above when through a vpn or NAT setup + + foreach (DictionaryEntry item in request) + { + m_log.InfoFormat("[FreeSwitchDirectory] requestBody item {0} {1}", item.Key, item.Value); + } + + string eventCallingFunction = (string) request["Event-Calling-Function"]; + if (eventCallingFunction == null) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } + + if (eventCallingFunction.Length == 0) + { + eventCallingFunction = "sofia_reg_parse_auth"; + } + + if (eventCallingFunction == "sofia_reg_parse_auth") + { + string sipAuthMethod = (string)request["sip_auth_method"]; + + if (sipAuthMethod == "REGISTER") + { + response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request); + } + else if (sipAuthMethod == "INVITE") + { + response = HandleInvite(m_freeSwitchContext, m_freeSwitchRealm, request); + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown sip_auth_method {0}",sipAuthMethod); + response["int_response_code"] = 404; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + } + else if (eventCallingFunction == "switch_xml_locate_user") + { + response = HandleLocateUser(m_freeSwitchRealm, request); + } + else if (eventCallingFunction == "user_data_function") // gets called when an avatar to avatar call is made + { + response = HandleLocateUser(m_freeSwitchRealm, request); + } + else if (eventCallingFunction == "user_outgoing_channel") + { + response = HandleRegister(m_freeSwitchContext, m_freeSwitchRealm, request); + } + else if (eventCallingFunction == "config_sofia") // happens once on freeswitch startup + { + response = HandleConfigSofia(m_freeSwitchContext, m_freeSwitchRealm, request); + } + else if (eventCallingFunction == "switch_load_network_lists") + { + //response = HandleLoadNetworkLists(request); + response["int_response_code"] = 404; + response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + else + { + m_log.ErrorFormat("[FreeSwitchVoice] HandleDirectoryRequest unknown Event-Calling-Function {0}",eventCallingFunction); + response["int_response_code"] = 404; + response["keepalive"] = false; + response["content_type"] = "text/xml"; + response["str_response_string"] = ""; + } + } + return response; + } + + private Hashtable HandleRegister(string Context, string Realm, Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleRegister called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string password = "1234"; + string domain = (string) request["domain"]; + string user = (string) request["user"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""+ + "\r\n" + + "\r\n" + + "\r\n" + + "
\r\n" + + "
\r\n", + domain , user, password, Context); + + return response; + } + + private Hashtable HandleInvite(string Context, string Realm, Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleInvite called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string password = "1234"; + string domain = (string) request["domain"]; + string user = (string) request["user"]; + string sipRequestUser = (string) request["sip_request_user"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""+ + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + ""+ + "\r\n" + + "\r\n" + + "\r\n" + + "
\r\n" + + "
\r\n", + domain , user, password,sipRequestUser, Context); + + return response; + } + + private Hashtable HandleLocateUser(String Realm, Hashtable request) + { + m_log.Info("[FreeSwitchDirectory] HandleLocateUser called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string domain = (string) request["domain"]; + string user = (string) request["user"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n"+ + "\r\n"+ + ""+ + "\r\n"+ + "\r\n" + + "\r\n" + + "
\r\n" + + "
\r\n", + domain , user); + + return response; + } + + private Hashtable HandleConfigSofia(string Context, string Realm, Hashtable request) { - return new Hashtable(); + m_log.Info("[FreeSwitchDirectory] HandleConfigSofia called"); + + // TODO the password we return needs to match that sent in the request, this is hard coded for now + string domain = (string) request["domain"]; + + Hashtable response = new Hashtable(); + response["content_type"] = "text/xml"; + response["keepalive"] = false; + response["int_response_code"] = 200; + response["str_response_string"] = String.Format( + "\r\n" + + "\r\n" + + "
\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n" + + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n"+ + ""+ + "\r\n" + + "\r\n"+ + "\r\n"+ + "\r\n"+ + "\r\n" + + "
\r\n" + + "
\r\n", + domain, Context); + + return response; } } } -- cgit v1.1 From 5f8a0f3d1f4cd9948ced87e312bcd0c4a616ef2a Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 21 Nov 2010 23:41:56 +0000 Subject: Add the remote connector for freeswitch config retrieval --- .../Freeswitch/RemoteFreeswitchConnector.cs | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs (limited to 'OpenSim') diff --git a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs new file mode 100644 index 0000000..d63d99d --- /dev/null +++ b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs @@ -0,0 +1,103 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using log4net; +using System; +using System.IO; +using System.Collections; +using System.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; +using OpenMetaverse; + +namespace OpenSim.Services.Connectors +{ + public class RemoteFreeswitchConnector : IFreeswitchService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private string m_ServerURI = String.Empty; + + public RemoteFreeswitchConnector() + { + } + + public RemoteFreeswitchConnector(string serverURI) + { + m_ServerURI = Path.Combine(serverURI.TrimEnd('/'), "region-config"); + } + + public RemoteFreeswitchConnector(IConfigSource source) + { + Initialise(source); + } + + public virtual void Initialise(IConfigSource source) + { + IConfig freeswitchConfig = source.Configs["FreeSwitchVoice"]; + if (freeswitchConfig == null) + { + m_log.Error("[FREESWITCH CONNECTOR]: FreeSwitchVoice missing from OpenSim.ini"); + throw new Exception("Freeswitch connector init error"); + } + + string serviceURI = freeswitchConfig.GetString("FreeswitchServiceURL", + String.Empty); + + if (serviceURI == String.Empty) + { + m_log.Error("[FREESWITCH CONNECTOR]: No FreeswitchServiceURL named in section FreeSwitchVoice"); + throw new Exception("Freeswitch connector init error"); + } + m_ServerURI = serviceURI; + } + + public Hashtable HandleDirectoryRequest(Hashtable requestBody) + { + // not used here + return new Hashtable(); + } + + public Hashtable HandleDialplanRequest(Hashtable requestBody) + { + // not used here + return new Hashtable(); + } + + public string GetJsonConfig() + { + return SynchronousRestFormsRequester.MakeRequest("GET", + m_ServerURI, String.Empty); + } + } +} -- cgit v1.1 From 7e9a3019ac719b88defd69bded0f9b801194fe85 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 00:55:11 +0100 Subject: Fox the buglets in Freeswitch. Grid mode works now and there is no reason why standalone should not. --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 1 + OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index a5e553c..294d4f0 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -134,6 +134,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice m_FreeswitchService = ServerUtils.LoadPlugin(serviceDll, args); string jsonConfig = m_FreeswitchService.GetJsonConfig(); + m_log.Debug("[FreeSwitchVoice]: Configuration string: " + jsonConfig); OSDMap map = (OSDMap)OSDParser.DeserializeJson(jsonConfig); m_freeSwitchAPIPrefix = map["APIPrefix"].AsString(); diff --git a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs index d63d99d..c9bba0b 100644 --- a/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs +++ b/OpenSim/Services/Connectors/Freeswitch/RemoteFreeswitchConnector.cs @@ -54,7 +54,7 @@ namespace OpenSim.Services.Connectors public RemoteFreeswitchConnector(string serverURI) { - m_ServerURI = Path.Combine(serverURI.TrimEnd('/'), "region-config"); + m_ServerURI = serverURI.TrimEnd('/') + "/region-config"; } public RemoteFreeswitchConnector(IConfigSource source) @@ -79,7 +79,7 @@ namespace OpenSim.Services.Connectors m_log.Error("[FREESWITCH CONNECTOR]: No FreeswitchServiceURL named in section FreeSwitchVoice"); throw new Exception("Freeswitch connector init error"); } - m_ServerURI = serviceURI; + m_ServerURI = serviceURI.TrimEnd('/') + "/region-config"; } public Hashtable HandleDirectoryRequest(Hashtable requestBody) @@ -96,6 +96,7 @@ namespace OpenSim.Services.Connectors public string GetJsonConfig() { + m_log.DebugFormat("[FREESWITCH CONNECTOR]: Requesting config from {0}", m_ServerURI); return SynchronousRestFormsRequester.MakeRequest("GET", m_ServerURI, String.Empty); } -- cgit v1.1 From 54d1d6d917e565e1e5f7ba39f7b2cfbdf199a260 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 14:32:51 +0100 Subject: Fox case on a method --- .../Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index 9a17233..a583cca 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs @@ -603,7 +603,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice response["str_response_string"] = string.Empty; response["content-type"] = "text/xml"; - Hashtable requestBody = parseRequestBody((string)request["body"]); + Hashtable requestBody = ParseRequestBody((string)request["body"]); if (!requestBody.ContainsKey("auth_token")) return response; @@ -675,7 +675,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice string uri = (string)request["uri"]; string contenttype = (string)request["content-type"]; - Hashtable requestBody = parseRequestBody((string)request["body"]); + Hashtable requestBody = ParseRequestBody((string)request["body"]); //string pwd = (string) requestBody["pwd"]; string userid = (string) requestBody["userid"]; @@ -719,7 +719,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice return response; } - public Hashtable parseRequestBody(string body) + public Hashtable ParseRequestBody(string body) { Hashtable bodyParams = new Hashtable(); // split string -- cgit v1.1 From 506192e4663456d1d35976cc854e2a675660463a Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 15:16:28 +0100 Subject: Make an invalud key string in llTextBox and llDialog non fatal to avoid breakinf sloppily made no-mod scripted items. --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index dee0d9a..1ba28dc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4469,7 +4469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID av = new UUID(); if (!UUID.TryParse(agent,out av)) { - LSLError("First parameter to llDialog needs to be a key"); + //LSLError("First parameter to llDialog needs to be a key"); return; } @@ -6731,7 +6731,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID av = new UUID(); if (!UUID.TryParse(avatar,out av)) { - LSLError("First parameter to llDialog needs to be a key"); + //LSLError("First parameter to llDialog needs to be a key"); return; } if (buttons.Length < 1) -- cgit v1.1 From 571becefb652869fa844188cadf8aca1fea774ab Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 22 Nov 2010 23:31:29 +0100 Subject: Fix some crashes caused by the addition of the CreatorData column --- OpenSim/Framework/Capabilities/Caps.cs | 1 + OpenSim/Framework/TaskInventoryDictionary.cs | 1 + .../InventoryAccess/InventoryAccessModule.cs | 6 ++++++ .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 19 ++++++++++++++++++- .../Connectors/Inventory/XInventoryConnector.cs | 9 ++++++++- 5 files changed, 34 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 7b0e053..e7f2e13 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -967,6 +967,7 @@ namespace OpenSim.Framework.Capabilities InventoryItemBase item = new InventoryItemBase(); item.Owner = m_agentID; item.CreatorId = m_agentID.ToString(); + item.CreatorData = String.Empty; item.ID = inventoryItem; item.AssetID = asset.FullID; item.Description = assetDescription; diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index a8a53f2..940e567 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs @@ -151,6 +151,7 @@ namespace OpenSim.Framework while (!m_itemLock.TryEnterWriteLock(60000)) { m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); + System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); if (m_itemLock.IsWriteLockHeld) { m_itemLock = new System.Threading.ReaderWriterLockSlim(); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 2e3db48..22da665 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -436,9 +436,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess item = new InventoryItemBase(); // Can't know creator is the same, so null it in inventory if (objlist.Count > 1) + { item.CreatorId = UUID.Zero.ToString(); + item.CreatorData = String.Empty; + } else + { item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); + item.CreatorData = objlist[0].RootPart.CreatorData; + } item.ID = UUID.Random(); item.InvType = (int)InventoryType.Object; item.Folder = folder.ID; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 1ba28dc..7e9224d 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -10177,6 +10177,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (str2 == String.Empty) return str1; + int len = str2.Length; + if ((len % 4) != 0) // LL is EVIL!!!! + { + while (str2.EndsWith("=")) + str2 = str2.Substring(0, str2.Length - 1); + + len = str2.Length; + int mod = len % 4; + + if (mod == 1) + str2 = str2.Substring(0, str2.Length - 1); + else if (mod == 2) + str2 += "=="; + else if (mod == 3) + str2 += "="; + } + byte[] data1; byte[] data2; try @@ -10200,7 +10217,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { while (pos < data1.Length) { - int len = data1.Length - pos; + len = data1.Length - pos; if (len > data2.Length) len = data2.Length; diff --git a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs index 88fbda3..b3bfcc2 100644 --- a/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs +++ b/OpenSim/Services/Connectors/Inventory/XInventoryConnector.cs @@ -302,6 +302,8 @@ namespace OpenSim.Services.Connectors public bool AddItem(InventoryItemBase item) { + if (item.CreatorData == null) + item.CreatorData = String.Empty; Dictionary ret = MakeRequest("ADDITEM", new Dictionary { { "AssetID", item.AssetID.ToString() }, @@ -335,6 +337,8 @@ namespace OpenSim.Services.Connectors public bool UpdateItem(InventoryItemBase item) { + if (item.CreatorData == null) + item.CreatorData = String.Empty; Dictionary ret = MakeRequest("UPDATEITEM", new Dictionary { { "AssetID", item.AssetID.ToString() }, @@ -558,7 +562,10 @@ namespace OpenSim.Services.Connectors item.InvType = int.Parse(data["InvType"].ToString()); item.Folder = new UUID(data["Folder"].ToString()); item.CreatorId = data["CreatorId"].ToString(); - item.CreatorData = data["CreatorData"].ToString(); + if (data.ContainsKey("CreatorData")) + item.CreatorData = data["CreatorData"].ToString(); + else + item.CreatorData = String.Empty; item.Description = data["Description"].ToString(); item.NextPermissions = uint.Parse(data["NextPermissions"].ToString()); item.CurrentPermissions = uint.Parse(data["CurrentPermissions"].ToString()); -- cgit v1.1 From 4a54b3318b202d75bde2f1fcde3e80114df91d2e Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 23 Nov 2010 00:31:09 +0100 Subject: Fix more potential nullrefs --- OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs index 456b6fc..ce72c78 100644 --- a/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs +++ b/OpenSim/Server/Handlers/Inventory/XInventoryInConnector.cs @@ -601,8 +601,10 @@ namespace OpenSim.Server.Handlers.Asset ret["AssetType"] = item.AssetType.ToString(); ret["BasePermissions"] = item.BasePermissions.ToString(); ret["CreationDate"] = item.CreationDate.ToString(); - ret["CreatorId"] = item.CreatorId.ToString(); - ret["CreatorData"] = item.CreatorData.ToString(); + if (item.CreatorId != null) + ret["CreatorId"] = item.CreatorId.ToString(); + else + ret["CreatorId"] = String.Empty; ret["CurrentPermissions"] = item.CurrentPermissions.ToString(); ret["Description"] = item.Description.ToString(); ret["EveryOnePermissions"] = item.EveryOnePermissions.ToString(); -- cgit v1.1 From a47fb93b7419c08549b27dc0d5c27896ecf744c7 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 23 Nov 2010 23:48:52 +0100 Subject: Prevent a dump in the llGetLinkKey method when using LINK_ROOT in a single prim --- OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'OpenSim') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 7e9224d..ec4d815 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -4007,6 +4007,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { linknum -= (m_host.ParentGroup.PrimCount) + 1; + if (linknum < 0) + return UUID.Zero.ToString(); + List avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET); if (avatars.Count > linknum) { -- cgit v1.1 From b3a71c6df1538c61247f7d4711aba4c840508db8 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 24 Nov 2010 18:56:25 +0100 Subject: Prevent an overlength button label from producing a debug dump and aborting the script. --- OpenSim/Framework/AgentCircuitData.cs | 35 ++-- OpenSim/Framework/ChildAgentDataUpdate.cs | 10 +- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 30 +-- .../EntityTransfer/EntityTransferModule.cs | 4 +- .../Region/Framework/Scenes/SceneObjectGroup.cs | 2 +- OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 2 +- OpenSim/Region/Framework/Scenes/ScenePresence.cs | 233 +++++++++++---------- .../Avatar/XmlRpcGroups/GroupsModule.cs | 9 +- .../Shared/Api/Implementation/LSL_Api.cs | 6 +- 9 files changed, 155 insertions(+), 176 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Framework/AgentCircuitData.cs b/OpenSim/Framework/AgentCircuitData.cs index cc9fcea..1600bdc 100644 --- a/OpenSim/Framework/AgentCircuitData.cs +++ b/OpenSim/Framework/AgentCircuitData.cs @@ -302,31 +302,26 @@ namespace OpenSim.Framework if (args["start_pos"] != null) Vector3.TryParse(args["start_pos"].AsString(), out startpos); -// DEBUG ON - m_log.WarnFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString()); -// DEBUG OFF + m_log.InfoFormat("[AGENTCIRCUITDATA] agentid={0}, child={1}, startpos={2}",AgentID,child,startpos.ToString()); try { - // Unpack various appearance elements - Appearance = new AvatarAppearance(AgentID); + // Unpack various appearance elements + Appearance = new AvatarAppearance(AgentID); - // Eventually this code should be deprecated, use full appearance - // packing in packed_appearance - if (args["appearance_serial"] != null) - Appearance.Serial = args["appearance_serial"].AsInteger(); + // Eventually this code should be deprecated, use full appearance + // packing in packed_appearance + if (args["appearance_serial"] != null) + Appearance.Serial = args["appearance_serial"].AsInteger(); - if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map)) - { - Appearance.Unpack((OSDMap)args["packed_appearance"]); -// DEBUG ON - m_log.WarnFormat("[AGENTCIRCUITDATA] unpacked appearance"); -// DEBUG OFF + if (args.ContainsKey("packed_appearance") && (args["packed_appearance"].Type == OSDType.Map)) + { + Appearance.Unpack((OSDMap)args["packed_appearance"]); + m_log.InfoFormat("[AGENTCIRCUITDATA] unpacked appearance"); + } + else + m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); } -// DEBUG ON - else - m_log.Warn("[AGENTCIRCUITDATA] failed to find a valid packed_appearance"); -// DEBUG OFF - } catch (Exception e) + catch (Exception e) { m_log.ErrorFormat("[AGENTCIRCUITDATA] failed to unpack appearance; {0}",e.Message); } diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index a227338..ce0b2fb 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs @@ -331,9 +331,7 @@ namespace OpenSim.Framework public virtual OSDMap Pack() { -// DEBUG ON - m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Pack data"); -// DEBUG OFF + m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Pack data"); OSDMap args = new OSDMap(); args["message_type"] = OSD.FromString("AgentData"); @@ -454,9 +452,7 @@ namespace OpenSim.Framework /// public virtual void Unpack(OSDMap args) { -// DEBUG ON - m_log.WarnFormat("[CHILDAGENTDATAUPDATE] Unpack data"); -// DEBUG OFF + m_log.InfoFormat("[CHILDAGENTDATAUPDATE] Unpack data"); if (args.ContainsKey("region_id")) UUID.TryParse(args["region_id"].AsString(), out RegionID); @@ -613,10 +609,8 @@ namespace OpenSim.Framework if (args.ContainsKey("packed_appearance") && (args["packed_appearance"]).Type == OSDType.Map) Appearance = new AvatarAppearance(AgentID,(OSDMap)args["packed_appearance"]); -// DEBUG ON else m_log.WarnFormat("[CHILDAGENTDATAUPDATE] No packed appearance"); -// DEBUG OFF if ((args["controllers"] != null) && (args["controllers"]).Type == OSDType.Array) { diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 0df4585..ab1c206 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory }); } - // m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); + m_log.WarnFormat("[AVFACTORY]: Complete texture check for {0}",client.AgentId); } // Process the visual params, this may change height as well @@ -196,12 +196,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory sp.SetHeight(sp.Appearance.AvatarHeight); } } - - // Send the appearance back to the avatar, not clear that this is needed - sp.ControllingClient.SendAvatarDataImmediate(sp); - // AvatarAppearance avp = sp.Appearance; - // sp.ControllingClient.SendAppearance(avp.Owner,avp.VisualParams,avp.Texture.GetBytes()); - } @@ -274,21 +268,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Send the appearance to everyone in the scene sp.SendAppearanceToAllOtherAgents(); - // sp.ControllingClient.SendAvatarDataImmediate(sp); - - // Send the appearance back to the avatar - // AvatarAppearance avp = sp.Appearance; - // sp.ControllingClient.SendAppearance(avp.Owner, avp.VisualParams, avp.Texture.GetBytes()); - -/* -// this needs to be fixed, the flag should be on scene presence not the region module - // Start the animations if necessary - if (!m_startAnimationSet) - { - sp.Animator.UpdateMovementAnimations(); - m_startAnimationSet = true; - } -*/ } private void HandleAppearanceSave(UUID agentid) @@ -374,6 +353,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // m_log.WarnFormat("[AVFACTORY]: AvatarIsWearing called for {0}", client.AgentId); + // operate on a copy of the appearance so we don't have to lock anything AvatarAppearance avatAppearance = new AvatarAppearance(sp.Appearance, false); foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) @@ -388,9 +368,11 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory SetAppearanceAssets(sp.UUID, ref avatAppearance); // could get fancier with the locks here, but in the spirit of "last write wins" - // this should work correctly + // this should work correctly, also, we don't need to send the appearance here + // since the "iswearing" will trigger a new set of visual param and baked texture changes + // when those complete, the new appearance will be sent sp.Appearance = avatAppearance; - m_scene.AvatarService.SetAppearance(client.AgentId, sp.Appearance); + QueueAppearanceSave(client.AgentId); } private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 81d6f70..aa7a1cd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -925,8 +925,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } agent.MakeChildAgent(); + // now we have a child agent in this region. Request all interesting data about other (root) agents - agent.SendInitialFullUpdateToAllClients(); + agent.SendOtherAgentsAvatarDataToMe(); + agent.SendOtherAgentsAppearanceToMe(); CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index f3964c2..bcb715b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -398,7 +398,7 @@ namespace OpenSim.Region.Framework.Scenes Vector3 offset = p.GetWorldPosition() - av.ParentPosition; av.AbsolutePosition += offset; av.ParentPosition = p.GetWorldPosition(); //ParentPosition gets cleared by AbsolutePosition - av.SendFullUpdateToAllClients(); + av.SendAvatarDataToAllAgents(); } } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index bdd42fc..8cc2be1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -803,7 +803,7 @@ namespace OpenSim.Region.Framework.Scenes { Vector3 offset = (m_offsetPosition - oldpos); av.OffsetPosition += offset; - av.SendFullUpdateToAllClients(); + av.SendAvatarDataToAllAgents(); } } } diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c35df08..98a3b29 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -767,7 +767,9 @@ namespace OpenSim.Region.Framework.Scenes // Note: This won't send data *to* other clients in that region (children don't send) // MIC: This gets called again in CompleteMovement - SendInitialFullUpdateToAllClients(); + // SendInitialFullUpdateToAllClients(); + SendOtherAgentsAvatarDataToMe(); + SendOtherAgentsAppearanceToMe(); RegisterToEvents(); SetDirectionVectors(); @@ -1757,7 +1759,7 @@ namespace OpenSim.Region.Framework.Scenes { AbsolutePosition = part.AbsolutePosition; Velocity = Vector3.Zero; - SendFullUpdateToAllClients(); + SendAvatarDataToAllAgents(); HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? } @@ -1867,7 +1869,7 @@ namespace OpenSim.Region.Framework.Scenes m_parentID = 0; m_linkedPrim = UUID.Zero; m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); - SendFullUpdateToAllClients(); + SendAvatarDataToAllAgents(); m_requestedSitTargetID = 0; if (m_physicsActor != null && m_appearance != null) { @@ -2462,8 +2464,8 @@ namespace OpenSim.Region.Framework.Scenes Velocity = Vector3.Zero; RemoveFromPhysicalScene(); Animator.TrySetMovementAnimation(sitAnimation); - SendFullUpdateToAllClients(); - SendTerseUpdateToAllClients(); + SendAvatarDataToAllAgents(); + //SendTerseUpdateToAllClients(); } public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) @@ -2742,165 +2744,169 @@ namespace OpenSim.Region.Framework.Scenes } /// - /// Tell other client about this avatar (The client previously didn't know or had outdated details about this avatar) + /// Do everything required once a client completes its movement into a region and becomes + /// a root agent. /// - /// - public void SendFullUpdateToOtherClient(ScenePresence remoteAvatar) + private void SendInitialData() { - // 2 stage check is needed. - if (remoteAvatar == null) - return; + // Moved this into CompleteMovement to ensure that m_appearance is initialized before + // the inventory arrives + // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); - IClientAPI cl = remoteAvatar.ControllingClient; - if (cl == null) - return; + // This agent just became root. We are going to tell everyone about it. The process of + // getting other avatars information was initiated in the constructor... don't do it + // again here... + SendAvatarDataToAllAgents(); - if (m_appearance.Texture == null) - return; - -// MT: This is needed for sit. It's legal to send it to oneself, and the name -// of the method is a misnomer -// -// if (LocalId == remoteAvatar.LocalId) -// { -// m_log.WarnFormat("[SCENEPRESENCE]: An agent is attempting to send avatar data to itself; {0}", UUID); -// return; -// } + // We have an appearance but we may not have the baked textures. Check the asset cache + // to see if all the baked textures are already here. + if (m_scene.AvatarFactory != null) + { + if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) + { +// m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); + SendAppearanceToAgent(this); - if (IsChildAgent) + // If the avatars baked textures are all in the cache, then we have a + // complete appearance... send it out, if not, then we'll send it when + // the avatar finishes updating its appearance + SendAppearanceToAllOtherAgents(); + } + } + else { - m_log.WarnFormat("[SCENEPRESENCE]: A child agent is attempting to send out avatar data; {0}", UUID); - return; + m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); } - - remoteAvatar.m_controllingClient.SendAvatarDataImmediate(this); - m_scene.StatsReporter.AddAgentUpdates(1); } /// - /// Tell *ALL* agents about this agent + /// Send this agent's avatar data to all other root and child agents in the scene + /// This agent must be root. This avatar will receive its own update. /// - public void SendInitialFullUpdateToAllClients() + public void SendAvatarDataToAllAgents() { - m_perfMonMS = Util.EnvironmentTickCount(); - int avUpdates = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence avatar) + // only send update from root agents to other clients; children are only "listening posts" + if (IsChildAgent) { - ++avUpdates; - - // Don't update ourselves - if (avatar.LocalId == LocalId) - return; - - // If this is a root agent, then get info about the avatar - if (!IsChildAgent) - { - SendFullUpdateToOtherClient(avatar); - } + m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); + return; + } + + m_perfMonMS = Util.EnvironmentTickCount(); - // If the other avatar is a root - if (!avatar.IsChildAgent) - { - avatar.SendFullUpdateToOtherClient(this); - avatar.SendAppearanceToOtherAgent(this); - avatar.Animator.SendAnimPackToClient(ControllingClient); - } - }); + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + SendAvatarDataToAgent(scenePresence); + count++; + }); - m_scene.StatsReporter.AddAgentUpdates(avUpdates); + m_scene.StatsReporter.AddAgentUpdates(count); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - //Animator.SendAnimPack(); } - public void SendFullUpdateToAllClients() + /// + /// Send avatar data for all other root agents to this agent, this agent + /// can be either a child or root + /// + public void SendOtherAgentsAvatarDataToMe() { m_perfMonMS = Util.EnvironmentTickCount(); - // only send update from root agents to other clients; children are only "listening posts" - if (IsChildAgent) - { - m_log.Warn("[SCENEPRESENCE] attempt to send update from a childagent"); - return; - } - int count = 0; - m_scene.ForEachScenePresence(delegate(ScenePresence sp) - { - if (sp.IsChildAgent) - return; - SendFullUpdateToOtherClient(sp); - ++count; - }); + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + // only send information about root agents + if (scenePresence.IsChildAgent) + return; + + // only send information about other root agents + if (scenePresence.UUID == UUID) + return; + + scenePresence.SendAvatarDataToAgent(this); + count++; + }); + m_scene.StatsReporter.AddAgentUpdates(count); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); - - Animator.SendAnimPack(); } /// - /// Do everything required once a client completes its movement into a region + /// Send avatar data to an agent. /// - public void SendInitialData() + /// + private void SendAvatarDataToAgent(ScenePresence avatar) { - // Moved this into CompleteMovement to ensure that m_appearance is initialized before - // the inventory arrives - // m_scene.GetAvatarAppearance(m_controllingClient, out m_appearance); +// m_log.WarnFormat("[SP] Send avatar data from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); - m_controllingClient.SendAvatarDataImmediate(this); - if (m_scene.AvatarFactory != null) - { - if (m_scene.AvatarFactory.ValidateBakedTextureCache(m_controllingClient)) - { -// m_log.WarnFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); - m_controllingClient.SendAppearance( - m_appearance.Owner,m_appearance.VisualParams,m_appearance.Texture.GetBytes()); - } - } - else + avatar.ControllingClient.SendAvatarDataImmediate(this); + Animator.SendAnimPackToClient(avatar.ControllingClient); + } + + /// + /// Send this agent's appearance to all other root and child agents in the scene + /// This agent must be root. + /// + public void SendAppearanceToAllOtherAgents() + { + // only send update from root agents to other clients; children are only "listening posts" + if (IsChildAgent) { - m_log.WarnFormat("[SCENEPRESENCE]: AvatarFactory not set for {0}", Name); + m_log.Warn("[SCENEPRESENCE] attempt to send avatar data from a child agent"); + return; } + + m_perfMonMS = Util.EnvironmentTickCount(); + + int count = 0; + m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) + { + if (scenePresence.UUID == UUID) + return; - SendInitialFullUpdateToAllClients(); + SendAppearanceToAgent(scenePresence); + count++; + }); + + m_scene.StatsReporter.AddAgentUpdates(count); + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } /// - /// + /// Send appearance from all other root agents to this agent. this agent + /// can be either root or child /// - public void SendAppearanceToAllOtherAgents() + public void SendOtherAgentsAppearanceToMe() { -// DEBUG ON -// m_log.WarnFormat("[SCENEPRESENCE]: Send appearance from {0} to all other agents", m_uuid); -// DEBUG OFF m_perfMonMS = Util.EnvironmentTickCount(); + int count = 0; m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence) { - if (scenePresence.UUID != UUID) - { - SendAppearanceToOtherAgent(scenePresence); - } + // only send information about root agents + if (scenePresence.IsChildAgent) + return; + + // only send information about other root agents + if (scenePresence.UUID == UUID) + return; + + scenePresence.SendAppearanceToAgent(this); + count++; }); + m_scene.StatsReporter.AddAgentUpdates(count); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } /// - /// Send appearance data to an agent that isn't this one. + /// Send appearance data to an agent. /// /// - public void SendAppearanceToOtherAgent(ScenePresence avatar) + private void SendAppearanceToAgent(ScenePresence avatar) { - if (LocalId == avatar.LocalId) - { - m_log.WarnFormat("[SCENE PRESENCE]: An agent is attempting to send appearance data to itself; {0}", UUID); - return; - } - -// DEBUG ON // m_log.WarnFormat("[SP] Send appearance from {0} to {1}",m_uuid,avatar.ControllingClient.AgentId); -// DEBUG OFF avatar.ControllingClient.SendAppearance( m_appearance.Owner, m_appearance.VisualParams, m_appearance.Texture.GetBytes()); @@ -3413,9 +3419,6 @@ namespace OpenSim.Region.Framework.Scenes public void CopyFrom(AgentData cAgent) { -// DEBUG ON - m_log.ErrorFormat("[SCENEPRESENCE] CALLING COPYFROM"); -// DEBUG OFF m_originRegionID = cAgent.RegionID; m_callbackURI = cAgent.CallbackURI; diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index 0c8113e..ccf5289 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs @@ -1173,10 +1173,13 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups presence = scene.GetScenePresence(AgentID); if (presence != null) { - presence.Grouptitle = Title; + if (presence.Grouptitle != Title) + { + presence.Grouptitle = Title; - // FixMe: Ter suggests a "Schedule" method that I can't find. - presence.SendFullUpdateToAllClients(); + if (! presence.IsChildAgent) + presence.SendAvatarDataToAllAgents(); + } } } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index ec4d815..1dd4ca4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -6756,7 +6756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } if (buttons.Data[i].ToString().Length > 24) { - LSLError("button label cannot be longer than 24 characters"); + llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters"); return; } buts[i] = buttons.Data[i].ToString(); @@ -7319,7 +7319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Vector v; v = rules.GetVector3Item(idx++); av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); - av.SendFullUpdateToAllClients(); + av.SendAvatarDataToAllAgents(); break; @@ -7329,7 +7329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Rotation r; r = rules.GetQuaternionItem(idx++); av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); - av.SendFullUpdateToAllClients(); + av.SendAvatarDataToAllAgents(); break; } } -- cgit v1.1 From 152256792084639f67ec085fe4d19abb95b68e1d Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Nov 2010 02:37:50 +0100 Subject: Finish the RestartModule and fix some bugs. Add new console commands: region restart bluebox