public void StateBeforeFrame() { var ss = new StateSource { PaddingData = new byte[1000] }; var zw = new ZwinderStateManager(new ZwinderStateManagerSettings { CurrentBufferSize = 1, CurrentTargetFrameLength = 10000, RecentBufferSize = 1, RecentTargetFrameLength = 100000, AncientStateInterval = 50000 }, f => false); { var ms = new MemoryStream(); ss.SaveStateBinary(new BinaryWriter(ms)); zw.Engage(ms.ToArray()); } for (int frame = 0; frame <= 10440; frame++) { ss.Frame = frame; zw.Capture(frame, ss); } var kvp = zw.GetStateClosestToFrame(10440); var actual = StateSource.GetFrameNumberInState(kvp.Value); Assert.AreEqual(kvp.Key, actual); Assert.IsTrue(actual <= 10440); }
private static Rememberer SetInt(RuleSplit split, StateSource source) { var @int = int.Parse(split.Value); switch (split.Operator) { case '=': return((query) => Rememberers.Set(query, split.Key, @int, source)); case '-': return((query) => Rememberers.SubtractInt(query, split.Key, @int, source)); case '+': return((query) => Rememberers.AddInt(query, split.Key, @int, source)); case '*': Debug.LogError($"Integer multiplication not supported: {split}. Add a decimal."); return(null); case '/': Debug.LogError($"Integer division not supported: {split}. Add a decimal."); return(null); default: Debug.LogError($"Couldn't interpret criteria as int operation: {split}."); return(null); } }
public static int GetFrameNumberInState(Stream stream) { var ss = new StateSource(); ss.LoadStateBinary(new BinaryReader(stream)); return(ss.Frame); }
private static Rememberer SetFloat(RuleSplit split, StateSource source) { var @float = float.Parse(split.Value); switch (split.Operator) { case '=': return((query) => Rememberers.Set(query, split.Key, @float, source)); case '-': return((query) => Rememberers.SubtractFloat(query, split.Key, @float, source)); case '+': return((query) => Rememberers.AddFloat(query, split.Key, @float, source)); case '*': return((query) => Rememberers.MultiplyFloat(query, split.Key, @float, source)); case '/': return((query) => Rememberers.DivideFloat(query, split.Key, @float, source)); default: Debug.LogError($"Couldn't interpret criteria as float operation: {split}."); return(null); } }
/// <summary> /// Updates a script which is in this prim's inventory. /// </summary> /// <param name="itemID"></param> /// <param name="assetData"></param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> /// <returns></returns> public void UpdateScriptInstance(UUID itemID, byte[] assetData, int startParam, bool postOnRez, StateSource stateSource) { TaskInventoryItem item = m_items[itemID]; if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) { return; } m_part.AddFlag(PrimFlags.Scripted); if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { lock (m_itemsLock) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } string script = Utils.BytesToString(assetData); IScriptModule[] modules = m_part.ParentGroup.Scene.RequestModuleInterfaces <IScriptModule>(); foreach (IScriptModule module in modules) { module.UpdateScript(m_part.UUID, item.ItemID, script, startParam, postOnRez, stateSource); } ResumeScript(item); } HasInventoryChanged = true; }
public void NextValue() { var source = new StateSource(); for (int i = 0; i < 10; i++) { var nextValue = source.NextValue(null); _output.WriteLine($"Value {i}: {nextValue}"); } }
/// <summary> /// Set a value in memory. /// A new value for the key will be created if it doesn't already exist. /// </summary> public void Set(string key, object value, StateSource source) { if (source == StateSource.Event || source == StateSource.Character) { Debug.LogError($"Cannot set values in source {source}."); } var state = GetState(source); state[key] = value; }
/// <summary> /// Start the scripts contained in all the prims in this group. /// </summary> public void CreateScriptInstances(int startParam, bool postOnRez, StateSource stateSource, UUID RezzedFrom) { // Don't start scripts if they're turned off in the region! if (!m_scene.RegionInfo.RegionSettings.DisableScripts) { foreach (SceneObjectPart part in m_partsList) { part.Inventory.CreateScriptInstances(startParam, postOnRez, stateSource, RezzedFrom); } } }
/// <summary> /// Start the scripts contained in all the prims in this group. /// </summary> public void CreateScriptInstances(int startParam, bool postOnRez, StateSource stateSource, UUID RezzedFrom, bool clearStateSaves) { // Don't start scripts if they're turned off in the region! if (!m_scene.RegionInfo.RegionSettings.DisableScripts) { foreach (SceneObjectPart part in m_partsList) { part.Inventory.CreateScriptInstances(startParam, postOnRez, stateSource, RezzedFrom, clearStateSaves); } } }
/// <summary> /// Start multiple scripts in the object /// </summary> /// <param name="part"></param> /// <param name="items"></param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> /// <param name="rezzedFrom"></param> /// <param name="clearStateSaves"></param> public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items, int startParam, bool postOnRez, StateSource stateSource, UUID rezzedFrom, bool clearStateSaves) { List <LUStruct> ItemsToStart = items.Select( item => m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom, clearStateSaves)) .Where(itemToQueue => itemToQueue.Action != LUType.Unknown) .ToList(); if (ItemsToStart.Count != 0) { m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray(), LoadPriority.FirstStart); } }
/// <summary> /// Start all the scripts contained in this prim's inventory /// </summary> public void CreateScriptInstances(int startParam, bool postOnRez, StateSource stateSource, UUID RezzedFrom) { List <TaskInventoryItem> LSLItems = GetInventoryScripts(); if (LSLItems.Count == 0) { return; } bool SendUpdate = m_part.AddFlag(PrimFlags.Scripted); m_part.ParentGroup.Scene.EventManager.TriggerRezScripts( m_part, LSLItems.ToArray(), startParam, postOnRez, stateSource, RezzedFrom); if (SendUpdate) { m_part.ScheduleUpdate(PrimUpdateFlags.PrimFlags); //We only need to send a compressed } ResumeScripts(); }
public void CountEvictWorks() { using var zb = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); var ss = new StateSource { PaddingData = new byte[10] }; var stateCount = 0; for (int i = 0; i < 1000000; i++) { zb.Capture(i, s => ss.SaveStateBinary(new BinaryWriter(s)), j => stateCount--, true); stateCount++; } Assert.AreEqual(zb.Count, stateCount); }
/// <summary> /// Returns true if a value of type [T] exists in state, populating it into [result]. /// [result] will return the default value if not present or of mismatching type. /// IMPORTANT: If the value is not present, the default value _will be set into state_. /// </summary> public bool Get <T>(string key, StateSource source, out T result) { GetState(source).TryGetValue(key, out var value); if (value is T t) { result = t; return(true); } else if (source != StateSource.Event && source != StateSource.Character) { result = default; Set(key, result, source); return(false); } else { result = default; return(false); } }
public void SaveCreateBufferRoundTrip() { RewindConfig config = new RewindConfig { BufferSize = 1, TargetFrameLength = 10 }; var buff = new ZwinderBuffer(config); var ss = new StateSource { PaddingData = new byte[500] }; for (var frame = 0; frame < 2090; frame++) { ss.Frame = frame; buff.Capture(frame, (s) => ss.SaveStateBinary(new BinaryWriter(s))); } // states are 504 bytes large, buffer is 1048576 bytes large Assert.AreEqual(buff.Count, 2080); Assert.AreEqual(buff.GetState(0).Frame, 10); Assert.AreEqual(buff.GetState(2079).Frame, 2089); Assert.AreEqual(StateSource.GetFrameNumberInState(buff.GetState(0).GetReadStream()), 10); Assert.AreEqual(StateSource.GetFrameNumberInState(buff.GetState(2079).GetReadStream()), 2089); var ms = new MemoryStream(); buff.SaveStateBinary(new BinaryWriter(ms)); ms.Position = 0; var buff2 = ZwinderBuffer.Create(new BinaryReader(ms), config); Assert.AreEqual(buff.Size, buff2.Size); Assert.AreEqual(buff.Used, buff2.Used); Assert.AreEqual(buff2.Count, 2080); Assert.AreEqual(buff2.GetState(0).Frame, 10); Assert.AreEqual(buff2.GetState(2079).Frame, 2089); Assert.AreEqual(StateSource.GetFrameNumberInState(buff2.GetState(0).GetReadStream()), 10); Assert.AreEqual(StateSource.GetFrameNumberInState(buff2.GetState(2079).GetReadStream()), 2089); }
private Dictionary <string, object> GetState(StateSource source) { switch (source) { case StateSource.Event: return(@event); case StateSource.Character: return(character); case StateSource.Memory: return(memory); case StateSource.World: return(world); case StateSource.Target: return(GetTargetMemory()); default: return(null); } }
private static Criterion IsFloat(RuleSplit split, StateSource source) { var f = float.Parse(split.Value); switch (split.Operator) { case '=': return((query) => Criteria.Equal(query, split.Key, f, source)); case '>': return((query) => Criteria.GreaterThan(query, split.Key, f, source)); case '<': return((query) => Criteria.LessThan(query, split.Key, f, source)); case '!': return((query) => !Criteria.Equal(query, split.Key, f, source)); default: Debug.LogError($"Couldn't interpret criteria as float operation: {split.Key}, {split.Operator}, {split.Value}."); return(null); } }
public void WhatIfTheHeadStateWrapsAround() { var ss = new StateSource { PaddingData = new byte[400 * 1000] }; using var zw = new ZwinderBuffer(new RewindConfig { BufferSize = 1, TargetFrameLength = 1 }); // Need to get data in the zwinderbuffer so that the last state, and the last state in particular, wraps around ss.Frame = 1; zw.Capture(1, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); ss.Frame = 2; zw.Capture(2, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); ss.Frame = 3; zw.Capture(3, s => ss.SaveStateBinary(new BinaryWriter(s)), null, true); zw.SaveStateBinary(new BinaryWriter(new MemoryStream())); }
/// <summary> /// Load the script from an assembly into an AppDomain. /// </summary> /// <param name='dom'></param> /// <param name='assembly'></param> /// <param name='stateSource'></param> /// <returns>false if load failed, true if suceeded</returns> public bool Load(AppDomain dom, string assembly, StateSource stateSource) { m_Assembly = assembly; m_stateSource = stateSource; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle); } try { object[] constructorParams; Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly)); Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript"); if (scriptType != null) { constructorParams = new object[] { m_coopSleepHandle }; } else if (!m_coopTermination) { scriptType = scriptAssembly.GetType("SecondLife.Script"); constructorParams = null; } else { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. You must remove all existing {6}* script DLL files before using enabling co-op termination" + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run" + " or by deleting these files manually.", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly); return false; } // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}", // scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name); if (dom != System.AppDomain.CurrentDomain) m_Script = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), scriptType.FullName, false, BindingFlags.Default, null, constructorParams, null, null, null); else m_Script = (IScript)scriptAssembly.CreateInstance( scriptType.FullName, false, BindingFlags.Default, null, constructorParams, null, null); //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // lease.Register(this); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly, e.Message, e.StackTrace); return false; } try { foreach (KeyValuePair<string,IScriptApi> kv in m_Apis) { m_Script.InitApi(kv.Key, kv.Value); } // // m_log.Debug("[Script] Script instance created"); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace); return false; } m_SaveState = true; string savedState = Path.Combine(Path.GetDirectoryName(assembly), 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)) { Byte[] data = new Byte[size]; fs.Read(data, 0, size); xml = Encoding.UTF8.GetString(data); ScriptSerializer.Deserialize(xml, this); AsyncCommandManager.CreateFromData(Engine, LocalID, ItemID, ObjectID, PluginData); // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) m_startOnInit = false; Running = false; // 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; m_startedFromSavedState = true; } } else { m_log.WarnFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); } } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace); } } // else // { // ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID); // if (presence != null && (!postOnRez)) // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // } return true; }
public static void DivideFloat(Query query, string key, float division, StateSource source) { query.Get <float>(key, source, out var current); query.Set(key, current / division, source); }
/// <summary> /// Start multiple scripts in the object /// </summary> /// <param name="part"></param> /// <param name="items"></param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> /// <param name="rezzedFrom"></param> /// <param name="clearStateSaves"></param> public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items, int startParam, bool postOnRez, StateSource stateSource, UUID rezzedFrom, bool clearStateSaves) { List<LUStruct> ItemsToStart = items.Select( item => m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom, clearStateSaves)) .Where(itemToQueue => itemToQueue.Action != LUType.Unknown) .ToList(); if (ItemsToStart.Count != 0) m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray(), LoadPriority.FirstStart); }
/// <summary> /// Start a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> /// <returns></returns> public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, StateSource stateSource) { // MainConsole.Instance.InfoFormat( // "[PRIM INVENTORY]: " + // "Starting script {0}, {1} in prim {2}, {3}", // item.Name, item.ItemID, Name, UUID); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) { return; } if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { lock (m_itemsLock) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } bool SendUpdate = m_part.AddFlag(PrimFlags.Scripted); m_part.ParentGroup.Scene.EventManager.TriggerRezScripts( m_part, new[] { item }, startParam, postOnRez, stateSource, UUID.Zero, false); if (SendUpdate) { m_part.ScheduleUpdate(PrimUpdateFlags.PrimFlags); //We only need to send a compressed } } HasInventoryChanged = true; ResumeScript(item); }
public static void AddFloat(Query query, string key, float addition, StateSource source) { query.Get <float>(key, source, out var current); query.Set(key, current + addition, source); }
public void TriggerRezScripts(ISceneChildEntity part, TaskInventoryItem[] taskInventoryItem, int startParam, bool postOnRez, StateSource stateSource, UUID RezzedFrom, bool clearStateSaves) { NewRezScripts handlerRezScripts = OnRezScripts; if (handlerRezScripts != null) { foreach (NewRezScripts d in handlerRezScripts.GetInvocationList()) { try { d(part, taskInventoryItem, startParam, postOnRez, stateSource, RezzedFrom, clearStateSaves); } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[EVENT MANAGER]: Delegate for TriggerRezScript failed - continuing. {0} {1}", e, e.StackTrace); } } } }
/// <summary> /// Updates a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <returns></returns> public void UpdateScriptInstance(UUID itemID, int startParam, bool postOnRez, StateSource stateSource) { TaskInventoryItem item = m_items[itemID]; if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) { return; } m_part.AddFlag(PrimFlags.Scripted); if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); if (null == asset) { MainConsole.Instance.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", item.Name, item.ItemID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); } else { lock (m_itemsLock) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } string script = Utils.BytesToString(asset.Data); IScriptModule[] modules = m_part.ParentGroup.Scene.RequestModuleInterfaces <IScriptModule>(); foreach (IScriptModule module in modules) { module.UpdateScript(m_part.UUID, item.ItemID, script, startParam, postOnRez, stateSource); } ResumeScript(item); } } HasInventoryChanged = true; }
/// <summary> /// Load the script from an assembly into an AppDomain. /// </summary> /// <param name='dom'></param> /// <param name='assembly'></param> /// <param name='dataPath'> /// Path for all script associated data (state, etc.). In a multi-region set up /// with all scripts loading into the same AppDomain this may not be the same place as the DLL itself. /// </param> /// <param name='stateSource'></param> /// <returns>false if load failed, true if suceeded</returns> public bool Load( IScript script, EventWaitHandle coopSleepHandle, string assemblyPath, string dataPath, StateSource stateSource, bool coopTermination) { m_Script = script; m_coopSleepHandle = coopSleepHandle; m_assemblyPath = assemblyPath; m_dataPath = dataPath; m_stateSource = stateSource; m_coopTermination = coopTermination; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle); } try { foreach (KeyValuePair <string, IScriptApi> kv in m_Apis) { m_Script.InitApi(kv.Key, kv.Value); } // // m_log.Debug("[Script] Script instance created"); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace); return(false); } // For attachments, XEngine saves the state into a .state file when XEngine.SetXMLState() is called. string savedState = Path.Combine(m_dataPath, ItemID.ToString() + ".state"); if (File.Exists(savedState)) { // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Found state for script {0} for {1} ({2}) at {3} in {4}", // ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name); 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)) { Byte[] data = new Byte[size]; fs.Read(data, 0, size); xml = Encoding.UTF8.GetString(data); ScriptSerializer.Deserialize(xml, this); AsyncCommandManager.CreateFromData(Engine, LocalID, ItemID, ObjectID, PluginData); // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) { m_startOnInit = false; } Running = false; // 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; m_startedFromSavedState = true; } // If this script is in an attachment then we no longer need the state file. if (!StatePersistedHere) { RemoveState(); } } // else // { // m_log.WarnFormat( // "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", // ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); // } } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace); } } // else // { // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Did not find state for script {0} for {1} ({2}) at {3} in {4}", // ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name); // } return(true); }
/// <summary> /// Start a script which is in this prim's inventory. /// </summary> /// <param name="itemId"> /// A <see cref="UUID" /> /// </param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, StateSource stateSource) { TaskInventoryItem item = GetInventoryItem(itemId); if (item != null) { CreateScriptInstance(item, startParam, postOnRez, stateSource); } else { MainConsole.Instance.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", itemId, m_part.Name, m_part.UUID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); } }
/// <summary> /// Runs a method on the value at [key], setting it back in state. /// The transformation will be ran on a new default value if not present in state. /// </summary> public void Transform <T>(string key, Func <T, T> transformation, StateSource source) { Get(key, source, out T value); Set(key, transformation.Invoke(value), source); }
/// <summary> /// Start a script which is in this prim's inventory. /// </summary> /// <param name="itemId"> /// A <see cref="UUID"/> /// </param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, StateSource stateSource) { TaskInventoryItem item = GetInventoryItem(itemId); if (item != null) CreateScriptInstance(item, startParam, postOnRez, stateSource); else MainConsole.Instance.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", itemId, m_part.Name, m_part.UUID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); }
/// <summary> /// Start a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="stateSource"></param> /// <returns></returns> public void CreateScriptInstance(TaskInventoryItem item, int startParam, bool postOnRez, StateSource stateSource) { // MainConsole.Instance.InfoFormat( // "[PRIM INVENTORY]: " + // "Starting script {0}, {1} in prim {2}, {3}", // item.Name, item.ItemID, Name, UUID); if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) return; if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { lock (m_itemsLock) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } bool SendUpdate = m_part.AddFlag (PrimFlags.Scripted); m_part.ParentGroup.Scene.EventManager.TriggerRezScripts ( m_part, new[] { item }, startParam, postOnRez, stateSource, UUID.Zero); if (SendUpdate) m_part.ScheduleUpdate (PrimUpdateFlags.PrimFlags); //We only need to send a compressed } HasInventoryChanged = true; ResumeScript(item); }
/// <summary> /// Updates a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <returns></returns> public void UpdateScriptInstance (UUID itemID, int startParam, bool postOnRez, StateSource stateSource) { TaskInventoryItem item = m_items[itemID]; if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) return; m_part.AddFlag(PrimFlags.Scripted); if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); if (null == asset) { MainConsole.Instance.ErrorFormat( "[PRIM INVENTORY]: " + "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", item.Name, item.ItemID, m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); } else { lock (m_itemsLock) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } string script = Utils.BytesToString(asset.Data); IScriptModule[] modules = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); foreach (IScriptModule module in modules) { module.UpdateScript(m_part.UUID, item.ItemID, script, startParam, postOnRez, stateSource); } ResumeScript(item); } } HasInventoryChanged = true; }
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) { State = "default"; EventQueue = new Queue(32); Engine = engine; LocalID = part.LocalId; ObjectID = part.UUID; RootLocalID = part.ParentGroup.LocalId; RootObjectID = part.ParentGroup.UUID; ItemID = itemID; AssetID = assetID; PrimName = primName; ScriptName = scriptName; m_Assembly = assembly; StartParam = startParam; m_MaxScriptQueue = maxScriptQueue; m_stateSource = stateSource; m_postOnRez = postOnRez; m_AttachedAvatar = part.ParentGroup.AttachedAvatar; m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; if (part != null) { lock (part.TaskInventory) { if (part.TaskInventory.ContainsKey(ItemID)) { ScriptTask = part.TaskInventory[ItemID]; } } } ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(engine, part, LocalID, itemID); } try { if (dom != System.AppDomain.CurrentDomain) { m_Script = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), "SecondLife.Script"); } else { m_Script = (IScript)Assembly.Load( Path.GetFileNameWithoutExtension(assembly)).CreateInstance( "SecondLife.Script"); } //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // lease.Register(this); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); } try { foreach (KeyValuePair <string, IScriptApi> kv in m_Apis) { m_Script.InitApi(kv.Key, kv.Value); } // // m_log.Debug("[Script] Script instance created"); part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); return; } m_SaveState = true; string savedState = Path.Combine(Path.GetDirectoryName(assembly), 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.UTF8Encoding enc = new System.Text.UTF8Encoding(); Byte[] data = new Byte[size]; fs.Read(data, 0, size); xml = enc.GetString(data); ScriptSerializer.Deserialize(xml, this); AsyncCommandManager.CreateFromData(Engine, LocalID, ItemID, ObjectID, PluginData); // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); Running = false; if (ShuttingDown) { m_startOnInit = false; } // 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; m_startedFromSavedState = true; } } else { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}: Memory limit exceeded", assembly); } } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}. XML is {1}. Exception {2}{3}", assembly, xml, e.Message, e.StackTrace); } } // else // { // ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID); // if (presence != null && (!postOnRez)) // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // } }
/// <summary> /// Load the script from an assembly into an AppDomain. /// </summary> /// <param name='dom'></param> /// <param name='assembly'></param> /// <param name='stateSource'></param> /// <returns>false if load failed, true if suceeded</returns> public bool Load(AppDomain dom, string assembly, StateSource stateSource) { m_Assembly = assembly; m_stateSource = stateSource; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(Engine, Part, ScriptTask, m_coopSleepHandle); } try { object[] constructorParams; Assembly scriptAssembly = dom.Load(Path.GetFileNameWithoutExtension(assembly)); Type scriptType = scriptAssembly.GetType("SecondLife.XEngineScript"); if (scriptType != null) { constructorParams = new object[] { m_coopSleepHandle }; } else { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. You must remove all existing {6}* script DLL files before using enabling co-op termination" + ", either by setting DeleteScriptsOnStartup = true in [XEngine] for one run" + " or by deleting these files manually.", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly); return(false); } // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Looking to load {0} from assembly {1} in {2}", // scriptType.FullName, Path.GetFileNameWithoutExtension(assembly), Engine.World.Name); if (dom != System.AppDomain.CurrentDomain) { m_Script = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), scriptType.FullName, false, BindingFlags.Default, null, constructorParams, null, null); } else { m_Script = (IScript)scriptAssembly.CreateInstance( scriptType.FullName, false, BindingFlags.Default, null, constructorParams, null, null); } //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // lease.Register(this); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error loading assembly {6}. Exception {7}{8}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, assembly, e.Message, e.StackTrace); return(false); } try { foreach (KeyValuePair <string, IScriptApi> kv in m_Apis) { m_Script.InitApi(kv.Key, kv.Value); } // // m_log.Debug("[Script] Script instance created"); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace); return(false); } m_SaveState = true; string savedState = Path.Combine(Path.GetDirectoryName(assembly), 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)) { Byte[] data = new Byte[size]; fs.Read(data, 0, size); xml = Encoding.UTF8.GetString(data); ScriptSerializer.Deserialize(xml, this); AsyncCommandManager.CreateFromData(Engine, LocalID, ItemID, ObjectID, PluginData); // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) { m_startOnInit = false; } Running = false; // 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; m_startedFromSavedState = true; } } else { m_log.WarnFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); } } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace); } } // else // { // ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID); // if (presence != null && (!postOnRez)) // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // } return(true); }
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; m_stateSource = stateSource; m_postOnRez = postOnRez; m_AttachedAvatar = part.AttachedAvatar; m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; if (part != null) { lock (part.TaskInventory) { if (part.TaskInventory.ContainsKey(m_ItemID)) { m_thisScriptTask = part.TaskInventory[m_ItemID]; } } } 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"); // Add a sponsor to the script // ISponsor scriptSponsor = new ScriptSponsor(); // ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as MarshalByRefObject); // lease.Register(scriptSponsor); //m_ScriptSponsor = scriptSponsor; } catch (Exception) { // m_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_log.Debug("[Script] Script instance created"); part.SetScriptEvents(m_ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception) { // m_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_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; } else { m_RunEvents = false; m_startOnInit = false; } // 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; m_startedFromSavedState = true; } } else { // m_log.Error("[Script] Unable to load script state: Memory limit exceeded"); } } catch (Exception) { // m_log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml); } } else { ScenePresence presence = m_Engine.World.GetScenePresence(part.OwnerID); if (presence != null && (!postOnRez)) presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // // m_log.ErrorFormat("[Script] Unable to load script state, file not found"); } }
/// <summary> /// Fetches, loads and hooks up a script to an objects events /// </summary> /// <param name="itemID"></param> /// <param name="localID"></param> public LUStruct StartScript(SceneObjectPart part, UUID itemID, string Script, int startParam, bool postOnRez, StateSource statesource, UUID RezzedFrom) { ScriptData id = ScriptProtection.GetScript(part.UUID, itemID); LUStruct ls = new LUStruct(); //Its a change of the script source, needs to be recompiled and such. if (id != null) { //Ignore prims that have crossed regions, they are already started and working if ((statesource & StateSource.PrimCrossing) != 0) { //Post the changed event though AddToScriptQueue(id, "changed", new DetectParams[0], id.VersionID, EventPriority.FirstStart, new Object[] { new LSL_Types.LSLInteger(512) }); return new LUStruct() { Action = LUType.Unknown }; } else { //Restart other scripts ls.Action = LUType.Load; } id.EventDelayTicks = 0; ScriptEngine.ScriptProtection.RemovePreviouslyCompiled(id.Source); } else ls.Action = LUType.Load; if (id == null) id = new ScriptData(this); id.ItemID = itemID; id.PostOnRez = postOnRez; id.StartParam = startParam; id.stateSource = statesource; id.State = "default"; id.Source = Script; id.part = part; id.World = part.ParentGroup.Scene; id.RezzedFrom = RezzedFrom; ls.ID = id; return ls; }
public static void MultiplyFloat(Query query, string key, float multiplication, StateSource source) { query.Get <float>(key, source, out var current); query.Set(key, current * multiplication, source); }
private bool DoOnRezScript(object parm) { Object[] p = (Object[])parm; uint localID = (uint)p[0]; UUID itemID = (UUID)p[1]; string script = (string)p[2]; int startParam = (int)p[3]; bool postOnRez = (bool)p[4]; StateSource stateSource = (StateSource)p[5]; // Get the asset ID of the script, so we can check if we // already have it. // We must look for the part outside the m_Scripts lock because GetSceneObjectPart later triggers the // m_parts lock on SOG. At the same time, a scene object that is being deleted will take the m_parts lock // and then later on try to take the m_scripts lock in this class when it calls OnRemoveScript() SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); if (part == null) { m_log.Error("[Script] SceneObjectPart unavailable. Script NOT started."); m_ScriptErrorMessage += "SceneObjectPart unavailable. Script NOT started.\n"; m_ScriptFailCount++; return(false); } TaskInventoryItem item = part.Inventory.GetInventoryItem(itemID); if (item == null) { m_ScriptErrorMessage += "Can't find script inventory item.\n"; m_ScriptFailCount++; return(false); } UUID assetID = item.AssetID; //m_log.DebugFormat("[XEngine] Compiling script {0} ({1} on object {2})", // item.Name, itemID.ToString(), part.ParentGroup.RootPart.Name); ScenePresence presence = m_Scene.GetScenePresence(item.OwnerID); string assembly = ""; CultureInfo USCulture = new CultureInfo("en-US"); Thread.CurrentThread.CurrentCulture = USCulture; Dictionary <KeyValuePair <int, int>, KeyValuePair <int, int> > linemap; try { lock (m_AddingAssemblies) { assembly = m_Compiler.PerformScriptCompile(script, assetID.ToString()); if (!m_AddingAssemblies.ContainsKey(assembly)) { m_AddingAssemblies[assembly] = 1; } else { m_AddingAssemblies[assembly]++; } linemap = m_Compiler.LineMap(); } string[] warnings = m_Compiler.GetWarnings(); if (warnings != null && warnings.Length != 0) { if (presence != null && (!postOnRez)) { presence.ControllingClient.SendAgentAlertMessage("Script saved with warnings, check debug window!", false); } foreach (string warning in warnings) { try { // DISPLAY WARNING INWORLD string text = "Warning:\n" + warning; if (text.Length > 1000) { text = text.Substring(0, 1000); } World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); } catch (Exception e2) // LEGIT: User Scripting { m_log.Error("[XEngine]: " + "Error displaying warning in-world: " + e2.ToString()); m_log.Error("[XEngine]: " + "Warning:\r\n" + warning); } } } } catch (Exception e) { if (presence != null && (!postOnRez)) { presence.ControllingClient.SendAgentAlertMessage("Script saved with errors, check debug window!", false); } try { // DISPLAY ERROR INWORLD m_ScriptErrorMessage += "Failed to compile script in object: '" + part.ParentGroup.RootPart.Name + "' Script name: '" + item.Name + "' Error message: " + e.Message.ToString(); m_ScriptFailCount++; string text = "Error compiling script:\n" + e.Message.ToString(); if (text.Length > 1000) { text = text.Substring(0, 1000); } World.SimChat(Utils.StringToBytes(text), ChatTypeEnum.DebugChannel, 2147483647, part.AbsolutePosition, part.Name, part.UUID, false); } catch (Exception e2) // LEGIT: User Scripting { m_log.Error("[XEngine]: " + "Error displaying error in-world: " + e2.ToString()); m_log.Error("[XEngine]: " + "Errormessage: Error compiling script:\r\n" + e.Message.ToString()); } return(false); } lock (m_Scripts) { ScriptInstance instance = null; // Create the object record if ((!m_Scripts.ContainsKey(itemID)) || (m_Scripts[itemID].AssetID != assetID)) { UUID appDomain = assetID; if (part.ParentGroup.IsAttachment) { appDomain = part.ParentGroup.RootPart.UUID; } if (!m_AppDomains.ContainsKey(appDomain)) { try { AppDomainSetup appSetup = new AppDomainSetup(); // appSetup.ApplicationBase = Path.Combine( // "ScriptEngines", // m_Scene.RegionInfo.RegionID.ToString()); Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; Evidence evidence = new Evidence(baseEvidence); AppDomain sandbox = AppDomain.CreateDomain( m_Scene.RegionInfo.RegionID.ToString(), evidence, appSetup); /* * PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); * AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); * PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); * PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); * CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); * sandboxPolicy.RootCodeGroup = sandboxCodeGroup; * sandbox.SetAppDomainPolicy(sandboxPolicy); */ m_AppDomains[appDomain] = sandbox; m_AppDomains[appDomain].AssemblyResolve += new ResolveEventHandler( AssemblyResolver.OnAssemblyResolve); m_DomainScripts[appDomain] = new List <UUID>(); } catch (Exception e) { m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); m_ScriptErrorMessage += "Exception creating app domain:\n"; m_ScriptFailCount++; lock (m_AddingAssemblies) { m_AddingAssemblies[assembly]--; } return(false); } } m_DomainScripts[appDomain].Add(itemID); instance = new ScriptInstance(this, part, itemID, assetID, assembly, m_AppDomains[appDomain], part.ParentGroup.RootPart.Name, item.Name, startParam, postOnRez, stateSource, m_MaxScriptQueue); m_log.DebugFormat("[XEngine] Loaded script {0}.{1}", part.ParentGroup.RootPart.Name, item.Name); instance.AppDomain = appDomain; instance.LineMap = linemap; m_Scripts[itemID] = instance; } lock (m_PrimObjects) { if (!m_PrimObjects.ContainsKey(localID)) { m_PrimObjects[localID] = new List <UUID>(); } if (!m_PrimObjects[localID].Contains(itemID)) { m_PrimObjects[localID].Add(itemID); } } if (!m_Assemblies.ContainsKey(assetID)) { m_Assemblies[assetID] = assembly; } lock (m_AddingAssemblies) { m_AddingAssemblies[assembly]--; } if (instance != null) { instance.Init(); } } return(true); }
public static void SubtractFloat(Query query, string key, float subtraction, StateSource source) { query.Get <float>(key, source, out var current); query.Set(key, current - subtraction, source); }
public static void Set(Query query, string key, object value, StateSource source) { query.Set(key, value, source); }
/// <summary> /// Load the script from an assembly into an AppDomain. /// </summary> /// <param name='dom'></param> /// <param name='assembly'></param> /// <param name='dataPath'> /// Path for all script associated data (state, etc.). In a multi-region set up /// with all scripts loading into the same AppDomain this may not be the same place as the DLL itself. /// </param> /// <param name='stateSource'></param> /// <returns>false if load failed, true if suceeded</returns> public bool Load( IScript script, EventWaitHandle coopSleepHandle, string assemblyPath, string dataPath, StateSource stateSource, bool coopTermination) { m_Script = script; m_coopSleepHandle = coopSleepHandle; m_assemblyPath = assemblyPath; m_dataPath = dataPath; m_stateSource = stateSource; m_coopTermination = coopTermination; if (m_coopTermination) CoopWaitHandle = coopSleepHandle; else CoopWaitHandle = null; ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(Engine, Part, ScriptTask); } try { foreach (KeyValuePair<string,IScriptApi> kv in m_Apis) { m_Script.InitApi(kv.Key, kv.Value); } // // m_log.Debug("[Script] Script instance created"); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Error initializing script instance. Exception {6}{7}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, e.Message, e.StackTrace); return false; } // For attachments, XEngine saves the state into a .state file when XEngine.SetXMLState() is called. string savedState = Path.Combine(m_dataPath, ItemID.ToString() + ".state"); if (File.Exists(savedState)) { // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Found state for script {0} for {1} ({2}) at {3} in {4}", // ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name); 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)) { Byte[] data = new Byte[size]; fs.Read(data, 0, size); xml = Encoding.UTF8.GetString(data); ScriptSerializer.Deserialize(xml, this); AsyncCommandManager.CreateFromData(Engine, LocalID, ItemID, ObjectID, PluginData); // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) m_startOnInit = false; Running = false; // 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; m_startedFromSavedState = true; } // If this script is in an attachment then we no longer need the state file. if (!StatePersistedHere) RemoveState(); } // else // { // m_log.WarnFormat( // "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. Memory limit exceeded.", // ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState); // } } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Not starting script {0} (id {1}) in part {2} (id {3}) in object {4} in {5}. Unable to load script state file {6}. XML is {7}. Exception {8}{9}", ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name, savedState, xml, e.Message, e.StackTrace); } } // else // { // m_log.DebugFormat( // "[SCRIPT INSTANCE]: Did not find state for script {0} for {1} ({2}) at {3} in {4}", // ItemID, savedState, Part.Name, Part.ParentGroup.Name, Part.ParentGroup.Scene.Name); // } return true; }
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) { State = "default"; EventQueue = new Queue(32); Engine = engine; LocalID = part.LocalId; ObjectID = part.UUID; RootLocalID = part.ParentGroup.LocalId; RootObjectID = part.ParentGroup.UUID; ItemID = itemID; AssetID = assetID; PrimName = primName; ScriptName = scriptName; m_Assembly = assembly; StartParam = startParam; m_MaxScriptQueue = maxScriptQueue; m_stateSource = stateSource; m_postOnRez = postOnRez; m_AttachedAvatar = part.ParentGroup.AttachedAvatar; m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID; if (part != null) { lock (part.TaskInventory) { if (part.TaskInventory.ContainsKey(ItemID)) { ScriptTask = part.TaskInventory[ItemID]; } } } ApiManager am = new ApiManager(); foreach (string api in am.GetApis()) { m_Apis[api] = am.CreateApi(api); m_Apis[api].Initialize(engine, part, ScriptTask); } try { if (dom != System.AppDomain.CurrentDomain) m_Script = (IScript)dom.CreateInstanceAndUnwrap( Path.GetFileNameWithoutExtension(assembly), "SecondLife.Script"); else m_Script = (IScript)Assembly.Load( Path.GetFileNameWithoutExtension(assembly)).CreateInstance( "SecondLife.Script"); //ILease lease = (ILease)RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); // lease.Register(this); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); } try { foreach (KeyValuePair<string,IScriptApi> kv in m_Apis) { m_Script.InitApi(kv.Key, kv.Value); } // // m_log.Debug("[Script] Script instance created"); part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}", assembly, e.Message, e.StackTrace); return; } m_SaveState = true; string savedState = Path.Combine(Path.GetDirectoryName(assembly), 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)) { Byte[] data = new Byte[size]; fs.Read(data, 0, size); xml = Encoding.UTF8.GetString(data); ScriptSerializer.Deserialize(xml, this); AsyncCommandManager.CreateFromData(Engine, LocalID, ItemID, ObjectID, PluginData); // m_log.DebugFormat("[Script] Successfully retrieved state for script {0}.{1}", PrimName, m_ScriptName); part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); if (!Running) m_startOnInit = false; Running = false; // 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; m_startedFromSavedState = true; } } else { m_log.WarnFormat( "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). Memory limit exceeded", savedState, ScriptName, ItemID, PrimName, ObjectID, assembly); } } catch (Exception e) { m_log.ErrorFormat( "[SCRIPT INSTANCE]: Unable to load script state file {0} for script {1} {2} in {3} {4} (assembly {5}). XML is {6}. Exception {7}{8}", savedState, ScriptName, ItemID, PrimName, ObjectID, assembly, xml, e.Message, e.StackTrace); } } // else // { // ScenePresence presence = Engine.World.GetScenePresence(part.OwnerID); // if (presence != null && (!postOnRez)) // presence.ControllingClient.SendAgentAlertMessage("Compile successful", false); // } }
/// <summary> /// Start all the scripts contained in this prim's inventory /// </summary> public void CreateScriptInstances(int startParam, bool postOnRez, StateSource stateSource, UUID RezzedFrom) { List<TaskInventoryItem> LSLItems = GetInventoryScripts(); if (LSLItems.Count == 0) return; bool SendUpdate = m_part.AddFlag(PrimFlags.Scripted); m_part.ParentGroup.Scene.EventManager.TriggerRezScripts( m_part, LSLItems.ToArray(), startParam, postOnRez, stateSource, RezzedFrom); if(SendUpdate) m_part.ScheduleUpdate(PrimUpdateFlags.PrimFlags); //We only need to send a compressed ResumeScripts(); }
/// <summary> /// Increments an int stored at [key] by [amount]. /// Will increment and set a new value from 0 if not present in state. /// </summary> public void Increment(string key, int amount, StateSource source) { Get(key, source, out int value); Set(key, value + amount, source); }
/// <summary> /// Start multiple scripts in the object /// </summary> /// <param name="part"></param> /// <param name="items"></param> /// <param name="startParam"></param> /// <param name="postOnRez"></param> /// <param name="engine"></param> /// <param name="stateSource"></param> /// <param name="RezzedFrom"></param> public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items, int startParam, bool postOnRez, StateSource stateSource, UUID RezzedFrom) { List<LUStruct> ItemsToStart = new List<LUStruct>(); foreach (TaskInventoryItem item in items) { LUStruct itemToQueue = m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, RezzedFrom); if (itemToQueue.Action != LUType.Unknown) ItemsToStart.Add(itemToQueue); } if (ItemsToStart.Count != 0) m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray(), LoadPriority.FirstStart); }
/// <summary> /// Updates a script which is in this prim's inventory. /// </summary> /// <param name="item"></param> /// <returns></returns> public void UpdateScriptInstance(UUID itemID, byte[] assetData, int startParam, bool postOnRez, StateSource stateSource) { TaskInventoryItem item = m_items[itemID]; if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) return; m_part.AddFlag(PrimFlags.Scripted); if (!m_part.ParentGroup.Scene.RegionInfo.RegionSettings.DisableScripts) { lock (m_itemsLock) { m_items[item.ItemID].PermsMask = 0; m_items[item.ItemID].PermsGranter = UUID.Zero; } string script = Utils.BytesToString(assetData); IScriptModule[] modules = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); foreach (IScriptModule module in modules) { module.UpdateScript(m_part.UUID, item.ItemID, script, startParam, postOnRez, stateSource); } ResumeScript(item); } HasInventoryChanged = true; }