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; } IScriptModule ScriptModule { get; }
void CancelScriptEvent(UUID itemID, string eventName);
/// <summary> /// <summary>
/// Post an event to a single script /// Post an event to a single script
/// </summary> /// </summary>

View File

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

View File

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

View File

@ -854,7 +854,7 @@ namespace OpenSim.Region.ScriptEngine.Yengine
public bool PostScriptEvent(UUID itemID, EventParams parms) public bool PostScriptEvent(UUID itemID, EventParams parms)
{ {
XMRInstance instance = GetInstance(itemID); XMRInstance instance = GetInstance(itemID);
if(instance == null) if (instance == null)
return false; return false;
TraceCalls("[YEngine]: YEngine.PostScriptEvent({0},{1})", itemID.ToString(), parms.EventName); TraceCalls("[YEngine]: YEngine.PostScriptEvent({0},{1})", itemID.ToString(), parms.EventName);
@ -863,6 +863,17 @@ namespace OpenSim.Region.ScriptEngine.Yengine
return true; 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. // Events targeted at all scripts in the given prim.
// localID = which prim // localID = which prim
// parms = event to post // 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 // This is called in the script thread to step script until it calls
// CheckRun(). It returns what the instance's next state should be, // CheckRun(). It returns what the instance's next state should be,
// ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED. // ONSLEEPQ, ONYIELDQ, SUSPENDED or FINISHED.