Пример #1
0
        private void RunScriptMethod(LSLScriptInstance instance, string methodName, object[] parameters)
        {
            try
            {
                if (parameters != null && parameters.Length > 0)
                {
                    instance.CallScriptMethod(methodName, parameters);
                }
                else
                {
                    instance.CallScriptMethod(methodName);
                }
            }
            catch (Exception ex)
            {
                m_log.Error("Error executing method " + methodName + " in script " + instance.ID + ": " + ex);
            }

            lock (m_syncRoot)
            {
                // Mark this script as not having a running event
                instance.CurrentExecution = null;

                // Check if this script has more events. If so, add it back to
                // the end of the queue
                if (instance.EventCount > 0)
                {
                    m_scriptsWithEvents.Enqueue(instance);
                }
            }
        }
Пример #2
0
        private void SaveScriptState(LSLScriptInstance instance)
        {
            // Create a state file for this script
            byte[] scriptState = instance.GetSerializedState();

            m_assetClient.StoreAsset(new Asset
            {
                ContentType  = "application/vnd.ll.lslstate",
                CreatorID    = instance.Host.OwnerID,
                Data         = scriptState,
                ID           = UUID.Combine(instance.ID, SCRIPT_STATE_MAGIC_ID),
                Local        = true,
                Temporary    = true,
                CreationDate = DateTime.UtcNow
            });
        }
Пример #3
0
        public void Init(byte[] scriptBinary, LSLScriptInstance instance)
        {
            m_instance = instance;

            // Load the assembly into this AppDomain and create an instance of the
            // SecondLife.Script class (the main script class)
            Assembly scriptAssembly = Assembly.Load(scriptBinary);

            m_script = scriptAssembly.CreateInstance("SecondLife.Script") as LSLScriptBase;
            m_script.Init(this);

            // Create a dictionary of FastInvoke delegates for each method in the script
            MethodInfo[] methodInfos = m_script.GetType().GetMethods();
            m_methods = new Dictionary <string, FastInvokeDelegate>();
            for (int i = 0; i < methodInfos.Length; i++)
            {
                if (methodInfos[i].Module.Assembly == scriptAssembly)
                {
                    m_methods.Add(methodInfos[i].Name, FastInvoke.Create(methodInfos[i]));
                }
            }
        }
Пример #4
0
        public void Init(byte[] scriptBinary, LSLScriptInstance instance)
        {
            m_instance = instance;

            // Load the assembly into this AppDomain and create an instance of the
            // SecondLife.Script class (the main script class)
            Assembly scriptAssembly = Assembly.Load(scriptBinary);
            m_script = scriptAssembly.CreateInstance("SecondLife.Script") as LSLScriptBase;
            m_script.Init(this);

            // Create a dictionary of FastInvoke delegates for each method in the script
            MethodInfo[] methodInfos = m_script.GetType().GetMethods();
            m_methods = new Dictionary<string, FastInvokeDelegate>();
            for (int i = 0; i < methodInfos.Length; i++)
            {
                if (methodInfos[i].Module.Assembly == scriptAssembly)
                    m_methods.Add(methodInfos[i].Name, FastInvoke.Create(methodInfos[i]));
            }
        }
Пример #5
0
        private void ScriptEventsThread()
        {
            while (m_running)
            {
                // Check if there are free threads in the script thread pool
                if (m_eventThreadPool.MaxThreads - m_eventThreadPool.InUseThreads > 0)
                {
                    // Check HTTP requests

                    // Check XML-RPC requests

                    // Check listeners

                    // Check timers
                    CheckTimerEvents();

                    // Check sensors

                    // Check grid requests

                    // Dequeue the next script event
                    LSLScriptInstance instance    = null;
                    EventParams       scriptEvent = null;
                    lock (m_syncRoot)
                    {
                        // Try to dequeue the next script with a pending event,
                        // then the next pending event for that script
                        if (m_scriptsWithEvents.Count > 0)
                        {
                            instance = m_scriptsWithEvents.Dequeue();
                            if (instance != null)
                            {
                                scriptEvent = instance.DequeueEvent();
                            }
                        }
                    }

                    if (instance != null && scriptEvent != null)
                    {
                        if (scriptEvent.EventName == "timer")
                        {
                            instance.IsTimerEventQueued = false;
                        }
                        if (scriptEvent.EventName == "control")
                        {
                            instance.ControlEventsQueued--;
                        }
                        if (scriptEvent.EventName == "collision")
                        {
                            instance.IsCollisionEventQueued = false;
                        }

                        if (scriptEvent.EventName == "state")
                        {
                            // FIXME:
                            //instance.SetState(scriptEvent.EventName);
                            //LSLEventFlags flags = GetEventsForState(instance.ID, instance.State);
                        }
                        else
                        {
                            string methodName = instance.State + "_event_" + scriptEvent.EventName;

                            // Convert the method arguments to LSL types and queue
                            // this event handler on the thread pool
                            ConvertParamsToLSLTypes(ref scriptEvent.Params);
                            instance.CurrentExecution = m_eventThreadPool.QueueWorkItem(RunScriptMethod, instance, methodName, scriptEvent.Params);
                        }
                    }
                }
                else
                {
                    m_log.Debug("No free threads in the script thread pool, sleeping...");
                }

                // TODO: Dynamic sleeping interval?
                Thread.Sleep(XENGINE_LONG_SLEEP_INTERVAL);

                m_scheduler.ThreadKeepAlive();
            }

            m_eventThreadPool.Dispose();
            m_scheduler.RemoveThread();
        }
Пример #6
0
        private void StartScript(UUID sourceItemID, UUID sourceAssetID, ISceneEntity hostObject, byte[] scriptBinary)
        {
            // Create a new AppDomain for this script
            AppDomainSetup domainSetup = new AppDomainSetup();

            domainSetup.LoaderOptimization = LoaderOptimization.SingleDomain;
            AppDomain scriptDomain = AppDomain.CreateDomain(sourceItemID + ".lsl", null, domainSetup);

            // Create an instance (that lives in this AppDomain) and a wrapper
            // (that lives in the script AppDomain) for this script
            LSLScriptInstance instance = new LSLScriptInstance(sourceItemID, sourceAssetID, hostObject, scriptDomain);
            LSLScriptWrapper  wrapper  = (LSLScriptWrapper)scriptDomain.CreateInstanceAndUnwrap(
                Assembly.GetExecutingAssembly().FullName, "Simian.Scripting.Linden.LSLScriptWrapper");

            wrapper.Init(scriptBinary, instance);
            instance.Init(wrapper);

            lock (m_syncRoot)
            {
                // If this script is already running, shut it down
                StopScript(sourceItemID, false);

                // Keep track of this script
                m_scripts[sourceItemID] = instance;

                // Keep track of the entity containing this script
                Dictionary <UUID, LSLScriptInstance> entityScripts;
                if (!m_scriptedEntities.TryGetValue(hostObject.ID, out entityScripts))
                {
                    entityScripts = new Dictionary <UUID, LSLScriptInstance>();
                    m_scriptedEntities[hostObject.ID] = entityScripts;
                }
                entityScripts[instance.ID] = instance;
            }

            if (hostObject is LLPrimitive)
            {
                // Update the PrimFlags for the containing LLPrimitive
                LLPrimitive obj = (LLPrimitive)hostObject;
                bool        hasCollisionEvents;

                PrimFlags     oldFlags   = obj.Prim.Flags;
                LSLEventFlags eventFlags = wrapper.GetEventsForState("default");

                PrimFlags newFlags = oldFlags;
                newFlags &= ~(PrimFlags.Touch | PrimFlags.Money);
                newFlags |= PrimFlags.Scripted | LSLEventFlagsToPrimFlags(eventFlags, out hasCollisionEvents);

                // FIXME: Do something with hasCollisionEvents

                // Either update the PrimFlags for this prim or just schedule
                // it for serialization (since it has a new script)
                if (newFlags != oldFlags)
                {
                    obj.Prim.Flags = newFlags;
                    m_scene.EntityAddOrUpdate(this, obj, 0, (uint)LLUpdateFlags.PrimFlags);
                }
                else
                {
                    m_scene.EntityAddOrUpdate(this, obj, UpdateFlags.Serialize, 0);
                }
            }

            // Fire the state_entry event to get this script started
            PostScriptEvent(new EventParams(sourceItemID, "state_entry", new object[0], new DetectParams[0]));
        }