From e2a521742a737aa54e43dd934c0a0d5f2e380e8f Mon Sep 17 00:00:00 2001 From: kitto Date: Sun, 4 Apr 2010 22:57:32 -0400 Subject: [PATCH 01/25] 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 ++++++++++-------- .../Region/Physics/ChOdePlugin/OdePlugin.cs | 111 ++++------ 2 files changed, 157 insertions(+), 156 deletions(-) diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index e8894f701a..67f8af5a3e 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 + 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; - } -*/ + 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)) { - if (m_crossingfailures < _parent_scene.geomCrossingFailuresBeforeOutofbounds) + 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) + { +//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 deb61641e2..79e2986231 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); - } } From 2fbbc13c71052e66269035031e894b736e2ead5d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 5 Apr 2010 19:42:15 +0100 Subject: [PATCH 02/25] Fix some overlooked merge conflicts that got committed --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5951a924c0..0785f7f788 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) From f34cc6b46949033803c79235b9d82da9bf9634dd Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Mon, 5 Apr 2010 22:08:34 +0200 Subject: [PATCH 03/25] 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 +- .../Rest/Regions/GETRegionInfoHandler.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 10 +++++++++- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs b/OpenSim/ApplicationPlugins/Rest/Regions/GETHandler.cs index ed18207216..dea166d2ec 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 5798286130..82e9d9b024 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 ab0d39777c..e5e6fc9e8f 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) { @@ -4338,6 +4338,14 @@ namespace OpenSim.Region.Framework.Scenes return m_sceneGraph.GetAvatars(); } + /// + /// 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 10ebf67b40..a76f386599 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() From 7a3bb266ebc057a1af589fc642bfeca08de72c98 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Mon, 5 Apr 2010 22:11:05 +0200 Subject: [PATCH 04/25] This commit adds some randomness to object persistence. It's a Work In Progress, I am working on improving this to a tiered approach. --- .../Framework/Scenes/SceneObjectGroup.cs | 46 +++++++++++++++++-- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 5443c28477..9a205e02cb 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)); } From 5c04d768a69814324521181f37c7da87ba2b4819 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 5 Apr 2010 22:26:18 +0200 Subject: [PATCH 05/25] Bump version number --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index 58d65d1575..d7c2ed0fac 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 From a573b5767b42766a6782d549b22cc53f079ecc14 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 5 Apr 2010 22:31:30 +0200 Subject: [PATCH 06/25] Test commit --- OpenSim/Framework/Servers/VersionInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index d7c2ed0fac..cf417d72e8 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, From 2f454843d82ce0253af393817cf6f0ebb9046112 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Mon, 5 Apr 2010 23:17:06 +0200 Subject: [PATCH 07/25] Fix up my own shoddy code! Fixes prim rez break. Whups! --- .../Framework/Scenes/SceneObjectGroup.cs | 48 ++++++++++--------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 0277ed8aaf..13d1d4e01d 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; From e7be131b8990e5397e13c5049caaafde4c0c447c Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Mon, 5 Apr 2010 23:20:56 +0200 Subject: [PATCH 08/25] 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 diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs new file mode 100644 index 0000000000..9790fc7558 --- /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); +} From 335c1b44206531bc6c0996157884d6873a580527 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 07:48:26 +0200 Subject: [PATCH 09/25] Implement PSYS_SRC_INNERANGLE and PSYS_SRC_OUTERANGLE --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index a76f386599..5be892919e 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; } } From 20e3de1f0a1434d51cf833b6418e983101438568 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 08:28:57 +0200 Subject: [PATCH 10/25] 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(+) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index ee35fa4b6a..b3e474004e 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; From db5ea850f66308038b16c4adcabd9e0d529ec947 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 09:49:11 +0200 Subject: [PATCH 11/25] 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(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 5be892919e..75dd615730 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) From 309f440fc04cc965e31232947bed698864308356 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 10:13:47 +0200 Subject: [PATCH 12/25] 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(-) diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index ebcdd62015..b0e3655223 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; From e80e04c5fd3892cf3c988baaa00aa8ccfa330256 Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 22:59:13 +0200 Subject: [PATCH 13/25] 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(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index 5f84252194..04626d3c20 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); From d834a2c3da1aa97887e087e5a265e73a914c5f7b Mon Sep 17 00:00:00 2001 From: Thomas Grimshaw Date: Wed, 7 Apr 2010 23:53:08 +0200 Subject: [PATCH 14/25] 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 ++++++++++-------- .../Shared/Api/Interface/ICM_Api.cs | 3 +- .../Shared/Api/Runtime/CM_Stub.cs | 14 +- 3 files changed, 87 insertions(+), 60 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs index 99973b4ac1..9f829da577 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs @@ -85,6 +85,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); } + /// + /// 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 /// @@ -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; + 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; - } - /// - /// 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 ef990a1567..6239726e73 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 5bc3a88483..aaffbe47fb 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(); } } } From 0f3314c04ccd07e0ff9b5be69903b0a72dd73115 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:00:01 -0700 Subject: [PATCH 15/25] Backported GetTextureModule and IAssetService.GetCached() --- .../ClientStack/LindenUDP/LLClientView.cs | 7 +- .../CoreModules/Asset/FlotsamAssetCache.cs | 5 + .../Avatar/Assets/GetTextureModule.cs | 220 ++++++++++++++++++ .../Asset/HGAssetBroker.cs | 8 + .../Asset/LocalAssetServiceConnector.cs | 8 + OpenSim/Services/AssetService/AssetService.cs | 5 + .../Connectors/Asset/AssetServiceConnector.cs | 8 + .../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 diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 2ca26578fa..8b8137794d 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 967c0a1f09..dd796dafb6 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 0000000000..53d2cefeac --- /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 0aa753d312..0522256c19 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 50348da728..1b3419d12f 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 b9723a84b3..ed87f3f6fc 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 8e311d70d8..84fbcd366b 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 677169d76a..34df54a90b 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 6dfe78d724..3be6815728 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 cb380431d4..4118308bed 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(); From c4c4c3696edbe99496ad7e6db9b3eb0b339f09c5 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:26:51 -0700 Subject: [PATCH 16/25] 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 diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs new file mode 100644 index 0000000000..2843e202be --- /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 + } +} From 94a46867ed763752dc69b3218ab54fcd338b0ad9 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:38:58 -0700 Subject: [PATCH 17/25] Added a missing reference to prebuild.xml --- prebuild.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/prebuild.xml b/prebuild.xml index 6b2579248e..fd714755fb 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -157,6 +157,7 @@ + From 54cedfe4320573ac302b11716e293086110a4f9b Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Thu, 8 Apr 2010 15:57:00 -0700 Subject: [PATCH 18/25] Changed the GetTextureModule backport to work with the 0.6.9 codebase --- OpenSim/Framework/WebUtil.cs | 361 ------------------ .../Avatar/Assets/GetTextureModule.cs | 13 +- prebuild.xml | 1 - 3 files changed, 11 insertions(+), 364 deletions(-) delete mode 100644 OpenSim/Framework/WebUtil.cs diff --git a/OpenSim/Framework/WebUtil.cs b/OpenSim/Framework/WebUtil.cs deleted file mode 100644 index 2843e202be..0000000000 --- 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 53d2cefeac..3b6685938d 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; + } } } diff --git a/prebuild.xml b/prebuild.xml index fd714755fb..6b2579248e 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -157,7 +157,6 @@ - From 7701ea27983be851a3c9d3954346018e07680ae6 Mon Sep 17 00:00:00 2001 From: Melanie Date: Fri, 9 Apr 2010 06:49:14 +0100 Subject: [PATCH 19/25] 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(+) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 55f455029e..db073e8384 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; From d975bd8e5c937314bbcd5c3b66a48f87057358d0 Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 17:51:51 +0200 Subject: [PATCH 20/25] Fixing Trap --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 OpenSim/Region/Framework/Interfaces/ISnmpModule.cs diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs deleted file mode 100644 index 9790fc7558..0000000000 --- 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); -} From c4eaf195b53be3f19fe25bd7ac4a41bd002bbc8d Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 17:59:08 +0200 Subject: [PATCH 21/25] dding this deleted file... --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index 9790fc7558..cdd1bd8e3d 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); } From 58dac970afb09bc003c7089f35fe592516fb209e Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 18:05:08 +0200 Subject: [PATCH 22/25] 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 diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs new file mode 100644 index 0000000000..4e03df5271 --- /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); +} From 0b2b2daf23dbf7a51f3d568903548cd964334ce2 Mon Sep 17 00:00:00 2001 From: Mike Rieker Date: Sat, 10 Apr 2010 14:43:26 -0400 Subject: [PATCH 23/25] 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 +- .../Framework/Scenes/Scene.Inventory.cs | 3 +- .../Scenes/SceneObjectPartInventory.cs | 76 +++++++++++++++++-- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index f58904f8c8..16ca3f9e21 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 b04871eca9..6c57d18ee5 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 5d00917584..d03b464082 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. /// From c6ba50b7e29789937170c6efdee5386bce54ff3d Mon Sep 17 00:00:00 2001 From: lcc Date: Sat, 10 Apr 2010 23:39:06 +0200 Subject: [PATCH 24/25] Adding ColdStart event --- OpenSim/Region/Framework/Interfaces/ISnmpModule.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs b/OpenSim/Region/Framework/Interfaces/ISnmpModule.cs index cdd1bd8e3d..6fd6ba7224 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); } From 9b6e89457c692fd65a0a221ef7809cc0e4836fe7 Mon Sep 17 00:00:00 2001 From: Kitto Flora Date: Sun, 11 Apr 2010 14:12:01 -0400 Subject: [PATCH 25/25] Fixed LINEAR_MOTOR Z drive, Mantis #30 --- OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/ChOdePlugin/ODEPrim.cs index 67f8af5a3e..01c3f81a5d 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);