From c20f7d6171a9df151c3ccde063336338da9ae322 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Sun, 25 May 2008 20:50:45 +0000 Subject: * A hacky Top Scripts display. It isn't accurate as far as ms accounting, however you can use it to help find out what scripts are causing your simulator to cry. * Access it from the Estate tools/Debug tab. --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 7 +++++ .../Modules/World/Estate/EstateManagementModule.cs | 36 ++++++++++++++++------ OpenSim/Region/Environment/Scenes/EventManager.cs | 15 +++++++++ OpenSim/Region/Environment/Scenes/InnerScene.cs | 31 +++++++++++++++++++ .../Region/Environment/Scenes/SceneObjectGroup.cs | 5 +++ .../Region/Environment/Scenes/SceneObjectPart.cs | 32 +++++++++++++++++++ .../ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 8 ++--- .../AsyncCommandPlugins/SensorRepeat.cs | 1 + .../ScriptEngineBase/AsyncCommandPlugins/Timer.cs | 1 + 9 files changed, 123 insertions(+), 13 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 484518a..11fb5be 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -5652,6 +5652,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP handlerLandStatRequest(0, 1, 0, "", this); } break; + case "scripts": + handlerLandStatRequest = OnLandStatRequest; + if (handlerLandStatRequest != null) + { + handlerLandStatRequest(0, 0, 0, "", this); + } + break; default: m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket.ToString()); break; diff --git a/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs index d3aa4aa..ab5898d 100644 --- a/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Estate/EstateManagementModule.cs @@ -313,12 +313,21 @@ namespace OpenSim.Region.Environment.Modules.World.Estate } private void HandleLandStatRequest(int parcelID, uint reportType, uint requestFlags, string filter, IClientAPI remoteClient) { - Dictionary colliders = m_scene.PhysicsScene.GetTopColliders(); - - List collidera = new List(); - lock (colliders) + Dictionary SceneData = new Dictionary(); + + if (reportType == 1) + { + SceneData = m_scene.PhysicsScene.GetTopColliders(); + } + else if (reportType == 0) { - foreach (uint obj in colliders.Keys) + SceneData = m_scene.m_innerScene.GetTopScripts(); + } + + List SceneReport = new List(); + lock (SceneData) + { + foreach (uint obj in SceneData.Keys) { SceneObjectPart prt = m_scene.GetSceneObjectPart(obj); if (prt != null) @@ -332,21 +341,30 @@ namespace OpenSim.Region.Environment.Modules.World.Estate lsri.LocationX = sog.AbsolutePosition.X; lsri.LocationY = sog.AbsolutePosition.Y; lsri.LocationZ = sog.AbsolutePosition.Z; - lsri.Score = colliders[obj]; + lsri.Score = SceneData[obj]; lsri.TaskID = sog.UUID; lsri.TaskLocalID = sog.LocalId; lsri.TaskName = sog.GetPartName(obj); lsri.OwnerName = m_scene.CommsManager.UUIDNameRequestString(sog.OwnerID); - + if (filter.Length != 0) + { + if ((lsri.OwnerName.Contains(filter) || lsri.TaskName.Contains(filter))) + { + } + else + { + continue; + } + } - collidera.Add(lsri); + SceneReport.Add(lsri); } } } } } - remoteClient.SendLandStatReply(reportType, requestFlags, (uint)collidera.Count,collidera.ToArray()); + remoteClient.SendLandStatReply(reportType, requestFlags, (uint)SceneReport.Count,SceneReport.ToArray()); } diff --git a/OpenSim/Region/Environment/Scenes/EventManager.cs b/OpenSim/Region/Environment/Scenes/EventManager.cs index a3f5d2f..1c345ba 100644 --- a/OpenSim/Region/Environment/Scenes/EventManager.cs +++ b/OpenSim/Region/Environment/Scenes/EventManager.cs @@ -174,6 +174,9 @@ namespace OpenSim.Region.Environment.Scenes public event AvatarKillData OnAvatarKilled; + public delegate void ScriptTimerEvent(uint localID, double timerinterval); + + public event ScriptTimerEvent OnScriptTimerEvent; public delegate void ObjectBeingRemovedFromScene(SceneObjectGroup obj); @@ -332,6 +335,7 @@ namespace OpenSim.Region.Environment.Scenes private RequestParcelPrimCountUpdate handlerRequestParcelPrimCountUpdate = null; private ParcelPrimCountTainted handlerParcelPrimCountTainted = null; private ObjectBeingRemovedFromScene handlerObjectBeingRemovedFromScene = null; + private ScriptTimerEvent handlerScriptTimerEvent = null; public void TriggerOnScriptChangedEvent(uint localID, uint change) { @@ -755,5 +759,16 @@ namespace OpenSim.Region.Environment.Scenes } } + // this lets us keep track of nasty script events like timer, etc. + public void TriggerTimerEvent(uint objLocalID, double Interval) + { + handlerScriptTimerEvent = OnScriptTimerEvent; + if (handlerScriptTimerEvent != null) + { + handlerScriptTimerEvent(objLocalID, Interval); + + } + + } } } diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 84de71f..d6e905b 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs @@ -846,6 +846,37 @@ namespace OpenSim.Region.Environment.Scenes return result; } + public Dictionary GetTopScripts() + { + Dictionary topScripts = new Dictionary(); + + List EntityList = GetEntities(); + int limit = 0; + foreach (EntityBase ent in EntityList) + { + if (ent is SceneObjectGroup) + { + SceneObjectGroup grp = (SceneObjectGroup)ent; + if ((grp.RootPart.GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Scripted) != 0) + { + if (grp.scriptScore >= 0.01) + { + topScripts.Add(grp.LocalId, grp.scriptScore); + limit++; + if (limit >= 100) + { + break; + } + + } + grp.scriptScore = 0; + } + } + } + + return topScripts; + } + #endregion #region Other Methods diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 25b3d16..cd4be99 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -90,6 +90,7 @@ namespace OpenSim.Region.Environment.Scenes /// since the group's last persistent backup /// public bool HasGroupChanged = false; + public float scriptScore = 0f; @@ -959,6 +960,10 @@ namespace OpenSim.Region.Environment.Scenes public void AddScriptLPS(int count) { + if (scriptScore + count >= float.MaxValue - count) + scriptScore = 0; + + scriptScore += (float)count; InnerScene d = m_scene.m_innerScene; d.AddToScriptLPS(count); } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index b724bda..c6b3059 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -2752,6 +2752,14 @@ namespace OpenSim.Region.Environment.Scenes PhysActor.OnCollisionUpdate -= PhysicsCollision; } } + if ((GetEffectiveObjectFlags() & (uint)LLObject.ObjectFlags.Scripted) != 0) + { + m_parentGroup.Scene.EventManager.OnScriptTimerEvent += handleTimerAccounting; + } + else + { + m_parentGroup.Scene.EventManager.OnScriptTimerEvent -= handleTimerAccounting; + } LocalFlags=(LLObject.ObjectFlags)objectflagupdate; @@ -2812,6 +2820,30 @@ namespace OpenSim.Region.Environment.Scenes GetProperties(client); m_updateFlag = 2; } + private void handleTimerAccounting(uint localID, double interval) + { + if (localID == LocalId) + { + + float sec = (float)interval; + if (m_parentGroup != null) + { + if (sec == 0) + { + if (m_parentGroup.scriptScore + 0.001f >= float.MaxValue - 0.001) + m_parentGroup.scriptScore = 0; + + m_parentGroup.scriptScore += 0.001f; + return; + } + + if (m_parentGroup.scriptScore + (0.001f / sec) >= float.MaxValue - (0.001f / sec)) + m_parentGroup.scriptScore = 0; + m_parentGroup.scriptScore += (0.001f / sec); + } + + } + } } } diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index 3fa65f5..fbfb400 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -474,7 +474,7 @@ namespace OpenSim.Region.ScriptEngine.Common public void llSensor(string name, string id, int type, double range, double arc) { - m_host.AddScriptLPS(1); + m_host.AddScriptLPS(300); LLUUID keyID = LLUUID.Zero; LLUUID.TryParse(id, out keyID); @@ -1818,7 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Common public void llSleep(double sec) { - m_host.AddScriptLPS(1); + m_host.AddScriptLPS((int)(sec * 100)); Thread.Sleep((int)(sec * 1000)); } @@ -2582,7 +2582,7 @@ namespace OpenSim.Region.ScriptEngine.Common public void llResetScript() { - m_host.AddScriptLPS(1); + m_host.AddScriptLPS(800); m_ScriptEngine.m_ScriptManager.ResetScript(m_localID, m_itemID); } @@ -4279,7 +4279,7 @@ namespace OpenSim.Region.ScriptEngine.Common ScriptManager sm; IScript script = null; - m_host.AddScriptLPS(1); + m_host.AddScriptLPS(8000); // These functions are supposed to be robust, // so get the state one step at a time. diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs index 13c9d25..82bd3ac 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/SensorRepeat.cs @@ -316,6 +316,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugin m_CmdManager.m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull, new object[] { new LSL_Types.LSLInteger(SensedObjects.Length) }); } + m_CmdManager.m_ScriptEngine.World.EventManager.TriggerTimerEvent(ts.localID, ts.interval); } } } diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/Timer.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/Timer.cs index 6f88e11..f6de3c6 100644 --- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/Timer.cs +++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncCommandPlugins/Timer.cs @@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase.AsyncCommandPlugin // Add it to queue m_CmdManager.m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "timer", EventQueueManager.llDetectNull, null); + m_CmdManager.m_ScriptEngine.World.EventManager.TriggerTimerEvent(ts.localID, ((double)ts.interval / 10000000)); // set next interval //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval); -- cgit v1.1