Yengine: we also need to cancel timer events in queue, because some bad scripts that do work on X

0.9.1.1
UbitUmarov 2019-11-11 12:51:09 +00:00
parent 38a77a8bb5
commit e87dfd48bf
5 changed files with 50 additions and 2 deletions

View File

@ -54,6 +54,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
IScriptModule ScriptModule { get; }
void CancelScriptEvent(UUID itemID, string eventName);
/// <summary>
/// Post an event to a single script
/// </summary>

View File

@ -110,8 +110,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
string key = MakeTimerKey(m_localID, m_itemID);
lock (TimerListLock)
{
if (Timers.ContainsKey(key))
if (Timers.TryGetValue(key, out TimerInfo ts))
{
m_CmdManager.m_ScriptEngine.CancelScriptEvent(ts.itemID, "timer");
Timers.Remove(key);
}
}

View File

@ -1794,6 +1794,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
return result;
}
public void CancelScriptEvent(UUID itemID, string eventName)
{
}
/// <summary>
/// Post an event to a single script
/// </summary>

View File

@ -854,7 +854,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public bool PostScriptEvent(UUID itemID, EventParams parms)
{
XMRInstance instance = GetInstance(itemID);
if(instance == null)
if (instance == null)
return false;
TraceCalls("[YEngine]: YEngine.PostScriptEvent({0},{1})", itemID.ToString(), parms.EventName);
@ -863,6 +863,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return true;
}
public void CancelScriptEvent(UUID itemID, string eventName)
{
XMRInstance instance = GetInstance(itemID);
if (instance == null)
return;
TraceCalls("[YEngine]: YEngine.CancelScriptEvent({0},{1})", itemID.ToString(), eventName);
instance.CancelEvent(eventName);
}
// Events targeted at all scripts in the given prim.
// localID = which prim
// parms = event to post

View File

@ -237,6 +237,37 @@ namespace OpenSim.Region.ScriptEngine.Yengine
}
}
public void CancelEvent(string eventName)
{
ScriptEventCode evc;
try
{
evc = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), eventName);
}
catch
{
return;
}
lock (m_QueueLock)
{
if(m_EventQueue.Count == 0)
return;
LinkedListNode<EventParams> lln2 = null;
for (lln2 = m_EventQueue.First; lln2 != null; lln2 = lln2.Next)
{
EventParams evt2 = lln2.Value;
if(evt2.EventName.Equals(eventName))
{
m_EventQueue.Remove(lln2);
if (evc >= 0 && m_EventCounts[(int)evc] > 0)
m_EventCounts[(int)evc]--;
}
}
}
}
// This is called in the script thread to step script until it calls
// CheckRun(). It returns what the instance's next state should be,
// ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.