From 7d26815d0e615b60c708768e8aab19ffd4d118fb Mon Sep 17 00:00:00 2001 From: Magnuz Binder Date: Thu, 14 May 2015 18:28:45 +0200 Subject: Throttle llCastRay V3. Signed-off-by: Michael Cerquoni --- .../Shared/Api/Implementation/LSL_Api.cs | 92 +++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 8359440..d75afb6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -28,6 +28,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Runtime.Remoting.Lifetime; @@ -234,6 +235,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected bool m_detectExitsInCastRay = false; protected bool m_filterPartsInCastRay = false; protected bool m_doAttachmentsInCastRay = false; + protected int m_msThrottleInCastRay = 200; + protected int m_msPerRegionInCastRay = 40; + protected int m_msPerAvatarInCastRay = 10; + protected int m_msMinInCastRay = 2; + protected int m_msMaxInCastRay = 40; + protected static List m_castRayCalls = new List(); //An array of HTTP/1.1 headers that are not allowed to be used //as custom headers by llHTTPRequest. @@ -353,6 +360,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_detectExitsInCastRay = lslConfig.GetBoolean("DetectExitHitsInLlCastRay", m_detectExitsInCastRay); m_filterPartsInCastRay = lslConfig.GetBoolean("FilterPartsInLlCastRay", m_filterPartsInCastRay); m_doAttachmentsInCastRay = lslConfig.GetBoolean("DoAttachmentsInLlCastRay", m_doAttachmentsInCastRay); + m_msThrottleInCastRay = lslConfig.GetInt("ThrottleTimeInMsInLlCastRay", m_msThrottleInCastRay); + m_msPerRegionInCastRay = lslConfig.GetInt("AvailableTimeInMsPerRegionInLlCastRay", m_msPerRegionInCastRay); + m_msPerAvatarInCastRay = lslConfig.GetInt("AvailableTimeInMsPerAvatarInLlCastRay", m_msPerAvatarInCastRay); + m_msMinInCastRay = lslConfig.GetInt("RequiredAvailableTimeInMsInLlCastRay", m_msMinInCastRay); + m_msMaxInCastRay = lslConfig.GetInt("MaximumAvailableTimeInMsInLlCastRay", m_msMaxInCastRay); } IConfig smtpConfig = seConfigSource.Configs["SMTP"]; @@ -14058,10 +14070,61 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// public LSL_List llCastRayV3(LSL_Vector start, LSL_Vector end, LSL_List options) { - // Initialize m_host.AddScriptLPS(1); - List rayHits = new List(); LSL_List result = new LSL_List(); + + // Prepare throttle data + int calledMs = Environment.TickCount; + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); + UUID regionId = World.RegionInfo.RegionID; + UUID userId = UUID.Zero; + int msAvailable = 0; + // Throttle per owner when attachment or "vehicle" (sat upon) + if (m_host.ParentGroup.IsAttachment || m_host.ParentGroup.GetSittingAvatars().Count > 0) + { + userId = m_host.OwnerID; + msAvailable = m_msPerAvatarInCastRay; + } + // Throttle per parcel when not attachment or vehicle + else + { + LandData land = World.GetLandData(m_host.GetWorldPosition()); + if (land != null) + msAvailable = m_msPerRegionInCastRay * land.Area / 65536; + } + // Clamp for "oversized" parcels on varregions + if (msAvailable > m_msMaxInCastRay) + msAvailable = m_msMaxInCastRay; + + // Check throttle data + int fromCalledMs = calledMs - m_msThrottleInCastRay; + lock (m_castRayCalls) + { + for (int i = m_castRayCalls.Count - 1; i >= 0; i--) + { + // Delete old calls from throttle data + if (m_castRayCalls[i].CalledMs < fromCalledMs) + m_castRayCalls.RemoveAt(i); + // Use current region (in multi-region sims) + else if (m_castRayCalls[i].RegionId == regionId) + { + // Reduce available time with recent calls + if (m_castRayCalls[i].UserId == userId) + msAvailable -= m_castRayCalls[i].UsedMs; + } + } + } + + // Return failure if not enough available time + if (msAvailable < m_msMinInCastRay) + { + result.Add(new LSL_Integer(ScriptBaseClass.RCERR_CAST_TIME_EXCEEDED)); + return result; + } + + // Initialize + List rayHits = new List(); float tol = m_floatToleranceInCastRay; Vector3 pos1Ray = start; Vector3 pos2Ray = end; @@ -14378,6 +14441,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api result.Add(new LSL_Vector(rayHit.Normal)); } result.Add(new LSL_Integer(hitCount)); + + // Add to throttle data + stopWatch.Stop(); + CastRayCall castRayCall = new CastRayCall(); + castRayCall.RegionId = regionId; + castRayCall.UserId = userId; + castRayCall.CalledMs = calledMs; + castRayCall.UsedMs = (int)stopWatch.ElapsedMilliseconds; + lock (m_castRayCalls) + { + m_castRayCalls.Add(castRayCall); + } + + // Return hits return result; } @@ -14412,6 +14489,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } /// + /// Struct for llCastRay throttle data. + /// + public struct CastRayCall + { + public UUID RegionId; + public UUID UserId; + public int CalledMs; + public int UsedMs; + } + + /// /// Helper to check if a ray intersects a shape bounding box. /// private bool RayIntersectsShapeBox(Vector3 pos1RayProj, Vector3 pos2RayProj, Vector3 shapeBoxMax) -- cgit v1.1