The binaries are still different, but that is only a small step away now. The OSSLPrim has been removed. This commit will breal all scripts using Prim.Scale(), etc, syntax. It was not secure and will have to be brought back in another form.
817 lines
28 KiB
C#
817 lines
28 KiB
C#
/*
|
|
* 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 OpenSim 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.IO;
|
|
using System.Threading;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Security.Policy;
|
|
using System.Reflection;
|
|
using System.Globalization;
|
|
using System.Xml;
|
|
using OpenMetaverse;
|
|
//using log4net;
|
|
using Nini.Config;
|
|
using Amib.Threading;
|
|
using OpenSim.Framework;
|
|
using OpenSim.Region.Environment;
|
|
using OpenSim.Region.Environment.Scenes;
|
|
using OpenSim.Region.Environment.Interfaces;
|
|
using OpenSim.Region.ScriptEngine.Shared;
|
|
using OpenSim.Region.ScriptEngine.Shared.Api;
|
|
using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
|
|
using OpenSim.Region.ScriptEngine.Shared.CodeTools;
|
|
using OpenSim.Region.ScriptEngine.Interfaces;
|
|
|
|
namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|
{
|
|
public class ScriptInstance : IScriptInstance
|
|
{
|
|
//private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
private IScriptEngine m_Engine;
|
|
private IScriptWorkItem m_CurrentResult = null;
|
|
private Queue m_EventQueue = new Queue(32);
|
|
private bool m_RunEvents = false;
|
|
private UUID m_ItemID;
|
|
private uint m_LocalID;
|
|
private UUID m_ObjectID;
|
|
private UUID m_AssetID;
|
|
private IScript m_Script;
|
|
private UUID m_AppDomain;
|
|
private DetectParams[] m_DetectParams;
|
|
private bool m_TimerQueued;
|
|
private DateTime m_EventStart;
|
|
private bool m_InEvent;
|
|
private string m_PrimName;
|
|
private string m_ScriptName;
|
|
private string m_Assembly;
|
|
private int m_StartParam = 0;
|
|
private string m_CurrentEvent = String.Empty;
|
|
private bool m_InSelfDelete = false;
|
|
private int m_MaxScriptQueue;
|
|
private bool m_SaveState = true;
|
|
private bool m_ShuttingDown = false;
|
|
private int m_ControlEventsInQueue = 0;
|
|
private int m_LastControlLevel = 0;
|
|
private bool m_CollisionInQueue = false;
|
|
|
|
private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
|
|
|
|
// Script state
|
|
private string m_State="default";
|
|
|
|
public Object[] PluginData = new Object[0];
|
|
|
|
public bool Running
|
|
{
|
|
get { return m_RunEvents; }
|
|
set { m_RunEvents = value; }
|
|
}
|
|
|
|
public bool ShuttingDown
|
|
{
|
|
get { return m_ShuttingDown; }
|
|
set { m_ShuttingDown = value; }
|
|
}
|
|
|
|
public string State
|
|
{
|
|
get { return m_State; }
|
|
set { m_State = value; }
|
|
}
|
|
|
|
public IScriptEngine Engine
|
|
{
|
|
get { return m_Engine; }
|
|
}
|
|
|
|
public UUID AppDomain
|
|
{
|
|
get { return m_AppDomain; }
|
|
set { m_AppDomain = value; }
|
|
}
|
|
|
|
public string PrimName
|
|
{
|
|
get { return m_PrimName; }
|
|
}
|
|
|
|
public string ScriptName
|
|
{
|
|
get { return m_ScriptName; }
|
|
}
|
|
|
|
public UUID ItemID
|
|
{
|
|
get { return m_ItemID; }
|
|
}
|
|
|
|
public UUID ObjectID
|
|
{
|
|
get { return m_ObjectID; }
|
|
}
|
|
|
|
public uint LocalID
|
|
{
|
|
get { return m_LocalID; }
|
|
}
|
|
|
|
public UUID AssetID
|
|
{
|
|
get { return m_AssetID; }
|
|
}
|
|
|
|
public Queue EventQueue
|
|
{
|
|
get { return m_EventQueue; }
|
|
}
|
|
|
|
public void ClearQueue()
|
|
{
|
|
m_TimerQueued = false;
|
|
m_EventQueue.Clear();
|
|
}
|
|
|
|
public int StartParam
|
|
{
|
|
get { return m_StartParam; }
|
|
set { m_StartParam = value; }
|
|
}
|
|
|
|
public ScriptInstance(IScriptEngine engine, SceneObjectPart part,
|
|
UUID itemID, UUID assetID, string assembly,
|
|
AppDomain dom, string primName, string scriptName,
|
|
int startParam, bool postOnRez, StateSource stateSource,
|
|
int maxScriptQueue)
|
|
{
|
|
m_Engine = engine;
|
|
|
|
m_LocalID = part.LocalId;
|
|
m_ObjectID = part.UUID;
|
|
m_ItemID = itemID;
|
|
m_AssetID = assetID;
|
|
m_PrimName = primName;
|
|
m_ScriptName = scriptName;
|
|
m_Assembly = assembly;
|
|
m_StartParam = startParam;
|
|
m_MaxScriptQueue = maxScriptQueue;
|
|
|
|
ApiManager am = new ApiManager();
|
|
|
|
foreach (string api in am.GetApis())
|
|
{
|
|
m_Apis[api] = am.CreateApi(api);
|
|
m_Apis[api].Initialize(engine, part, m_LocalID, itemID);
|
|
}
|
|
|
|
try
|
|
{
|
|
m_Script = (IScript)dom.CreateInstanceAndUnwrap(
|
|
Path.GetFileNameWithoutExtension(assembly),
|
|
"SecondLife.Script");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_Engine.Log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
|
|
}
|
|
|
|
try
|
|
{
|
|
foreach (KeyValuePair<string,IScriptApi> kv in m_Apis)
|
|
{
|
|
m_Script.InitApi(kv.Key, kv.Value);
|
|
}
|
|
|
|
// m_Engine.Log.Debug("[Script] Script instance created");
|
|
|
|
part.SetScriptEvents(m_ItemID,
|
|
(int)m_Script.GetStateEventFlags(State));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_Engine.Log.Error("[Script] Error loading script instance\n"+e.ToString());
|
|
return;
|
|
}
|
|
|
|
m_SaveState = true;
|
|
|
|
string savedState = Path.Combine(Path.GetDirectoryName(assembly),
|
|
m_ItemID.ToString() + ".state");
|
|
if (File.Exists(savedState))
|
|
{
|
|
string xml = String.Empty;
|
|
|
|
try
|
|
{
|
|
FileInfo fi = new FileInfo(savedState);
|
|
int size=(int)fi.Length;
|
|
if (size < 512000)
|
|
{
|
|
using (FileStream fs = File.Open(savedState,
|
|
FileMode.Open, FileAccess.Read, FileShare.None))
|
|
{
|
|
System.Text.ASCIIEncoding enc =
|
|
new System.Text.ASCIIEncoding();
|
|
|
|
Byte[] data = new Byte[size];
|
|
fs.Read(data, 0, size);
|
|
|
|
xml = enc.GetString(data);
|
|
|
|
ScriptSerializer.Deserialize(xml, this);
|
|
|
|
AsyncCommandManager.CreateFromData(m_Engine,
|
|
m_LocalID, m_ItemID, m_ObjectID,
|
|
PluginData);
|
|
|
|
m_Engine.Log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", m_PrimName, m_ScriptName);
|
|
|
|
part.SetScriptEvents(m_ItemID,
|
|
(int)m_Script.GetStateEventFlags(State));
|
|
|
|
if (m_RunEvents && (!m_ShuttingDown))
|
|
{
|
|
m_RunEvents = false;
|
|
Start();
|
|
if (postOnRez)
|
|
PostEvent(new EventParams("on_rez",
|
|
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
|
}
|
|
|
|
// we get new rez events on sim restart, too
|
|
// but if there is state, then we fire the change
|
|
// event
|
|
|
|
// We loaded state, don't force a re-save
|
|
m_SaveState = false;
|
|
|
|
if (stateSource == StateSource.NewRez)
|
|
{
|
|
// m_Engine.Log.Debug("[Script] Posted changed(CHANGED_REGION_RESTART) to script");
|
|
PostEvent(new EventParams("changed",
|
|
new Object[] {new LSL_Types.LSLInteger(256)}, new DetectParams[0]));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_Engine.Log.Error("[Script] Unable to load script state: Memory limit exceeded");
|
|
Start();
|
|
PostEvent(new EventParams("state_entry",
|
|
new Object[0], new DetectParams[0]));
|
|
if (postOnRez)
|
|
PostEvent(new EventParams("on_rez",
|
|
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
|
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_Engine.Log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml);
|
|
Start();
|
|
PostEvent(new EventParams("state_entry",
|
|
new Object[0], new DetectParams[0]));
|
|
if (postOnRez)
|
|
PostEvent(new EventParams("on_rez",
|
|
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// m_Engine.Log.ErrorFormat("[Script] Unable to load script state, file not found");
|
|
Start();
|
|
PostEvent(new EventParams("state_entry",
|
|
new Object[0], new DetectParams[0]));
|
|
|
|
if (postOnRez)
|
|
PostEvent(new EventParams("on_rez",
|
|
new Object[] {new LSL_Types.LSLInteger(startParam)}, new DetectParams[0]));
|
|
}
|
|
}
|
|
|
|
private void ReleaseControls()
|
|
{
|
|
SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID);
|
|
if (part != null && part.TaskInventory.ContainsKey(m_ItemID))
|
|
{
|
|
UUID permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
|
|
int permsMask = part.TaskInventory[m_ItemID].PermsMask;
|
|
|
|
if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
|
|
{
|
|
|
|
ScenePresence presence = m_Engine.World.GetScenePresence(permsGranter);
|
|
if (presence != null)
|
|
presence.UnRegisterControlEventsToScript(m_LocalID, m_ItemID);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void DestroyScriptInstance()
|
|
{
|
|
ReleaseControls();
|
|
AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
|
|
}
|
|
|
|
public void RemoveState()
|
|
{
|
|
string savedState = Path.Combine(Path.GetDirectoryName(m_Assembly),
|
|
m_ItemID.ToString() + ".state");
|
|
|
|
try
|
|
{
|
|
File.Delete(savedState);
|
|
}
|
|
catch(Exception)
|
|
{
|
|
}
|
|
}
|
|
|
|
public void VarDump(Dictionary<string, object> vars)
|
|
{
|
|
Console.WriteLine("Variable dump for script {0}", m_ItemID.ToString());
|
|
foreach (KeyValuePair<string, object> v in vars)
|
|
{
|
|
Console.WriteLine("Variable: {0} = '{1}'", v. Key,
|
|
v.Value.ToString());
|
|
}
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
lock (m_EventQueue)
|
|
{
|
|
if (Running)
|
|
return;
|
|
|
|
m_RunEvents = true;
|
|
|
|
if (m_EventQueue.Count > 0)
|
|
{
|
|
if (m_CurrentResult == null)
|
|
m_CurrentResult = m_Engine.QueueEventHandler(this);
|
|
else
|
|
m_Engine.Log.Error("[Script] Tried to start a script that was already queued");
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool Stop(int timeout)
|
|
{
|
|
IScriptWorkItem result;
|
|
|
|
lock (m_EventQueue)
|
|
{
|
|
if (!Running)
|
|
return true;
|
|
|
|
if (m_CurrentResult == null)
|
|
{
|
|
m_RunEvents = false;
|
|
return true;
|
|
}
|
|
|
|
if (m_CurrentResult.Cancel())
|
|
{
|
|
m_CurrentResult = null;
|
|
m_RunEvents = false;
|
|
return true;
|
|
}
|
|
|
|
result = m_CurrentResult;
|
|
m_RunEvents = false;
|
|
}
|
|
|
|
if (result.Wait(new TimeSpan((long)timeout * 100000)))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
lock (m_EventQueue)
|
|
{
|
|
result = m_CurrentResult;
|
|
}
|
|
|
|
if (result == null)
|
|
return true;
|
|
|
|
if (!m_InSelfDelete)
|
|
result.Abort();
|
|
|
|
lock (m_EventQueue)
|
|
{
|
|
m_CurrentResult = null;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void SetState(string state)
|
|
{
|
|
if (state == State)
|
|
return;
|
|
|
|
PostEvent(new EventParams("state_exit", new Object[0],
|
|
new DetectParams[0]));
|
|
PostEvent(new EventParams("state", new Object[] { state },
|
|
new DetectParams[0]));
|
|
PostEvent(new EventParams("state_entry", new Object[0],
|
|
new DetectParams[0]));
|
|
|
|
throw new EventAbortException();
|
|
}
|
|
|
|
public void PostEvent(EventParams data)
|
|
{
|
|
// m_Engine.Log.DebugFormat("[Script] Posted event {2} in state {3} to {0}.{1}",
|
|
// m_PrimName, m_ScriptName, data.EventName, m_State);
|
|
|
|
if (!Running)
|
|
return;
|
|
|
|
lock (m_EventQueue)
|
|
{
|
|
if (m_EventQueue.Count >= m_MaxScriptQueue)
|
|
return;
|
|
|
|
if (data.EventName == "timer")
|
|
{
|
|
if (m_TimerQueued)
|
|
return;
|
|
m_TimerQueued = true;
|
|
}
|
|
|
|
if (data.EventName == "control")
|
|
{
|
|
int held = ((LSL_Types.LSLInteger)data.Params[1]).value;
|
|
// int changed = ((LSL_Types.LSLInteger)data.Params[2]).value;
|
|
|
|
// If the last message was a 0 (nothing held)
|
|
// and this one is also nothing held, drop it
|
|
//
|
|
if (m_LastControlLevel == held && held == 0)
|
|
return;
|
|
|
|
// If there is one or more queued, then queue
|
|
// only changed ones, else queue unconditionally
|
|
//
|
|
if (m_ControlEventsInQueue > 0)
|
|
{
|
|
if (m_LastControlLevel == held)
|
|
return;
|
|
}
|
|
|
|
m_LastControlLevel = held;
|
|
m_ControlEventsInQueue++;
|
|
}
|
|
|
|
if (data.EventName == "collision")
|
|
{
|
|
if (m_CollisionInQueue)
|
|
return;
|
|
if (data.DetectParams == null)
|
|
return;
|
|
|
|
m_CollisionInQueue = true;
|
|
}
|
|
|
|
m_EventQueue.Enqueue(data);
|
|
|
|
if (m_CurrentResult == null)
|
|
{
|
|
m_CurrentResult = m_Engine.QueueEventHandler(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Process the next event queued for this script
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public object EventProcessor()
|
|
{
|
|
lock (m_Script)
|
|
{
|
|
EventParams data = null;
|
|
|
|
lock (m_EventQueue)
|
|
{
|
|
data = (EventParams) m_EventQueue.Dequeue();
|
|
if (data == null) // Shouldn't happen
|
|
{
|
|
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
|
{
|
|
m_CurrentResult = m_Engine.QueueEventHandler(this);
|
|
}
|
|
else
|
|
{
|
|
m_CurrentResult = null;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
if (data.EventName == "timer")
|
|
m_TimerQueued = false;
|
|
if (data.EventName == "control")
|
|
{
|
|
if (m_ControlEventsInQueue > 0)
|
|
m_ControlEventsInQueue--;
|
|
}
|
|
if (data.EventName == "collision")
|
|
m_CollisionInQueue = false;
|
|
}
|
|
|
|
//m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
|
|
|
|
m_DetectParams = data.DetectParams;
|
|
|
|
if (data.EventName == "state") // Hardcoded state change
|
|
{
|
|
// m_Engine.Log.DebugFormat("[Script] Script {0}.{1} state set to {2}",
|
|
// m_PrimName, m_ScriptName, data.Params[0].ToString());
|
|
m_State=data.Params[0].ToString();
|
|
AsyncCommandManager.RemoveScript(m_Engine,
|
|
m_LocalID, m_ItemID);
|
|
|
|
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
|
m_LocalID);
|
|
if (part != null)
|
|
{
|
|
part.SetScriptEvents(m_ItemID,
|
|
(int)m_Script.GetStateEventFlags(State));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_Engine.World.PipeEventsForScript(m_LocalID) ||
|
|
data.EventName == "control") // Don't freeze avies!
|
|
{
|
|
SceneObjectPart part = m_Engine.World.GetSceneObjectPart(
|
|
m_LocalID);
|
|
// m_Engine.Log.DebugFormat("[Script] Delivered event {2} in state {3} to {0}.{1}",
|
|
// m_PrimName, m_ScriptName, data.EventName, m_State);
|
|
|
|
try
|
|
{
|
|
m_CurrentEvent = data.EventName;
|
|
m_EventStart = DateTime.Now;
|
|
m_InEvent = true;
|
|
|
|
m_Script.ExecuteEvent(State, data.EventName, data.Params);
|
|
|
|
m_InEvent = false;
|
|
m_CurrentEvent = String.Empty;
|
|
|
|
if (m_SaveState)
|
|
{
|
|
// This will be the very first event we deliver
|
|
// (state_entry) in defualt state
|
|
//
|
|
|
|
SaveState(m_Assembly);
|
|
|
|
m_SaveState = false;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
m_InEvent = false;
|
|
m_CurrentEvent = String.Empty;
|
|
|
|
if (!(e is TargetInvocationException) || (!(e.InnerException is EventAbortException) && (!(e.InnerException is SelfDeleteException))))
|
|
{
|
|
if (e is System.Threading.ThreadAbortException)
|
|
{
|
|
lock (m_EventQueue)
|
|
{
|
|
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
|
{
|
|
m_CurrentResult=m_Engine.QueueEventHandler(this);
|
|
}
|
|
else
|
|
{
|
|
m_CurrentResult = null;
|
|
}
|
|
}
|
|
|
|
m_DetectParams = null;
|
|
|
|
return 0;
|
|
}
|
|
|
|
try
|
|
{
|
|
// DISPLAY ERROR INWORLD
|
|
string text = "Runtime error:\n" + e.InnerException.ToString();
|
|
if (text.Length > 1000)
|
|
text = text.Substring(0, 1000);
|
|
m_Engine.World.SimChat(Utils.StringToBytes(text),
|
|
ChatTypeEnum.DebugChannel, 2147483647,
|
|
part.AbsolutePosition,
|
|
part.Name, part.UUID, false);
|
|
}
|
|
catch (Exception e2) // LEGIT: User Scripting
|
|
{
|
|
m_Engine.Log.Error("[Script]: "+
|
|
"Error displaying error in-world: " +
|
|
e2.ToString());
|
|
m_Engine.Log.Error("[Script]: " +
|
|
"Errormessage: Error compiling script:\r\n" +
|
|
e.ToString());
|
|
}
|
|
}
|
|
else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
|
|
{
|
|
m_InSelfDelete = true;
|
|
if (part != null && part.ParentGroup != null)
|
|
m_Engine.World.DeleteSceneObject(part.ParentGroup);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lock (m_EventQueue)
|
|
{
|
|
if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
|
|
{
|
|
m_CurrentResult = m_Engine.QueueEventHandler(this);
|
|
}
|
|
else
|
|
{
|
|
m_CurrentResult = null;
|
|
}
|
|
}
|
|
|
|
m_DetectParams = null;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
public int EventTime()
|
|
{
|
|
if (!m_InEvent)
|
|
return 0;
|
|
|
|
return (DateTime.Now - m_EventStart).Seconds;
|
|
}
|
|
|
|
public void ResetScript()
|
|
{
|
|
if (m_Script == null)
|
|
return;
|
|
|
|
bool running = Running;
|
|
|
|
RemoveState();
|
|
ReleaseControls();
|
|
|
|
Stop(0);
|
|
SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID);
|
|
part.GetInventoryItem(m_ItemID).PermsMask = 0;
|
|
part.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero;
|
|
AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
|
|
m_EventQueue.Clear();
|
|
m_Script.ResetVars();
|
|
m_State = "default";
|
|
|
|
part.SetScriptEvents(m_ItemID,
|
|
(int)m_Script.GetStateEventFlags(State));
|
|
if (running)
|
|
Start();
|
|
m_SaveState = true;
|
|
PostEvent(new EventParams("state_entry",
|
|
new Object[0], new DetectParams[0]));
|
|
}
|
|
|
|
public void ApiResetScript()
|
|
{
|
|
// bool running = Running;
|
|
|
|
RemoveState();
|
|
ReleaseControls();
|
|
|
|
m_Script.ResetVars();
|
|
SceneObjectPart part=m_Engine.World.GetSceneObjectPart(m_LocalID);
|
|
part.GetInventoryItem(m_ItemID).PermsMask = 0;
|
|
part.GetInventoryItem(m_ItemID).PermsGranter = UUID.Zero;
|
|
AsyncCommandManager.RemoveScript(m_Engine, m_LocalID, m_ItemID);
|
|
|
|
m_EventQueue.Clear();
|
|
m_Script.ResetVars();
|
|
m_State = "default";
|
|
|
|
part.SetScriptEvents(m_ItemID,
|
|
(int)m_Script.GetStateEventFlags(State));
|
|
|
|
if (m_CurrentEvent != "state_entry")
|
|
{
|
|
m_SaveState = true;
|
|
PostEvent(new EventParams("state_entry",
|
|
new Object[0], new DetectParams[0]));
|
|
throw new EventAbortException();
|
|
}
|
|
}
|
|
|
|
public Dictionary<string, object> GetVars()
|
|
{
|
|
return m_Script.GetVars();
|
|
}
|
|
|
|
public void SetVars(Dictionary<string, object> vars)
|
|
{
|
|
m_Script.SetVars(vars);
|
|
}
|
|
|
|
public DetectParams GetDetectParams(int idx)
|
|
{
|
|
if (m_DetectParams == null)
|
|
return null;
|
|
if (idx < 0 || idx >= m_DetectParams.Length)
|
|
return null;
|
|
|
|
return m_DetectParams[idx];
|
|
}
|
|
|
|
public UUID GetDetectID(int idx)
|
|
{
|
|
if (m_DetectParams == null)
|
|
return UUID.Zero;
|
|
if (idx < 0 || idx >= m_DetectParams.Length)
|
|
return UUID.Zero;
|
|
|
|
return m_DetectParams[idx].Key;
|
|
}
|
|
|
|
public void SaveState(string assembly)
|
|
{
|
|
// If we're currently in an event, just tell it to save upon return
|
|
//
|
|
if (m_InEvent)
|
|
{
|
|
m_SaveState = true;
|
|
return;
|
|
}
|
|
|
|
PluginData = AsyncCommandManager.GetSerializationData(m_Engine, m_ItemID);
|
|
|
|
string xml = ScriptSerializer.Serialize(this);
|
|
|
|
try
|
|
{
|
|
FileStream fs = File.Create(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state"));
|
|
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
|
|
Byte[] buf = enc.GetBytes(xml);
|
|
fs.Write(buf, 0, buf.Length);
|
|
fs.Close();
|
|
}
|
|
catch(Exception e)
|
|
{
|
|
Console.WriteLine("Unable to save xml\n"+e.ToString());
|
|
}
|
|
if (!File.Exists(Path.Combine(Path.GetDirectoryName(assembly), m_ItemID.ToString() + ".state")))
|
|
{
|
|
throw new Exception("Completed persistence save, but no file was created");
|
|
}
|
|
}
|
|
|
|
public IScriptApi GetApi(string name)
|
|
{
|
|
if (m_Apis.ContainsKey(name))
|
|
return m_Apis[name];
|
|
return null;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return String.Format("{0} {1} on {2}", m_ScriptName, m_ItemID, m_PrimName);
|
|
}
|
|
}
|
|
}
|