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);
        }
Example #2
0
        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);
            }
Example #4
0
        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);
            }
        }
Example #5
0
        /// <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;
        }
Example #6
0
        public void NextValue()
        {
            var source = new StateSource();

            for (int i = 0; i < 10; i++)
            {
                var nextValue = source.NextValue(null);
                _output.WriteLine($"Value {i}: {nextValue}");
            }
        }
Example #7
0
        /// <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);
        }
Example #13
0
        /// <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);
            }
        }
Example #14
0
        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);
        }
Example #15
0
        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);
            }
        }
Example #16
0
        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;
        }
Example #19
0
 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);
 }
Example #20
0
        /// <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);
        }
Example #21
0
        /// <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);
        }
Example #22
0
 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);
 }
Example #23
0
 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;
        }
Example #25
0
        /// <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);
        }
Example #26
0
        /// <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);
            }
        }
Example #27
0
 /// <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);

//            }
        }
Example #32
0
        /// <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);
        }
Example #33
0
        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");
            }
        }
Example #34
0
 /// <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;
 }
Example #35
0
 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);
 }
Example #36
0
        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);
        }
Example #37
0
 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);
 }
Example #38
0
 public static void Set(Query query, string key, object value, StateSource source)
 {
     query.Set(key, value, source);
 }
Example #39
0
        /// <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;
        }
Example #40
0
        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();
        }
Example #42
0
 /// <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);
 }
Example #43
0
 /// <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;
        }