Пример #1
0
        public bool EventSchProcessQIS(ref QueueItemStruct QIS)
        {
            try
            {
                Exception      ex      = null;
                EnumeratorInfo Running = QIS.ID.Script.ExecuteEvent(QIS.State,
                                                                    QIS.functionName,
                                                                    QIS.param, QIS.CurrentlyAt, out ex);

                if (ex != null)
                {
                    //Check exceptions, some are ours to deal with, and others are to be logged
                    if (ex.Message.Contains("SelfDeleteException"))
                    {
                        if (QIS.ID.Part != null && QIS.ID.Part.ParentEntity != null)
                        {
                            IBackupModule backup =
                                QIS.ID.Part.ParentEntity.Scene.RequestModuleInterface <IBackupModule>();
                            if (backup != null)
                            {
                                backup.DeleteSceneObjects(
                                    new ISceneEntity[1] {
                                    QIS.ID.Part.ParentEntity
                                }, true, true);
                            }
                        }
                    }
                    else if (ex.Message.Contains("ScriptDeleteException"))
                    {
                        if (QIS.ID.Part != null && QIS.ID.Part.ParentEntity != null)
                        {
                            QIS.ID.Part.Inventory.RemoveInventoryItem(QIS.ID.ItemID);
                        }
                    }
                    //Log it for the user
                    else if (!(ex.Message.Contains("EventAbortException")) &&
                             !(ex.Message.Contains("MinEventDelayException")))
                    {
                        QIS.ID.DisplayUserNotification(ex.ToString(), "executing", false, true);
                    }
                    EventManager.EventComplete(QIS);
                    return(false);
                }
                else if (Running != null)
                {
                    //Did not finish so requeue it
                    QIS.CurrentlyAt = Running;
                    QIS.RunningNumber++;
                    return(true); //Do the return... otherwise we open the queue for this event back up
                }
            }
            catch (Exception ex)
            {
                //Error, tell the user
                QIS.ID.DisplayUserNotification(ex.ToString(), "executing", false, true);
            }
            //Tell the event manager about it so that the events will be removed from the queue
            EventManager.EventComplete(QIS);
            return(false);
        }
Пример #2
0
 public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start, out Exception ex)
 {
     return m_Executor.ExecuteEvent(state, FunctionName, args, Start, out ex);
 }
Пример #3
0
 public EnumeratorInfo ExecuteEvent (string state, string FunctionName, object[] args, EnumeratorInfo Start, out System.Exception ex)
 {
     ex = null;
     return null;
 }
Пример #4
0
        public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start, out Exception ex)
        {
            ex = null;
            // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
            // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
            string EventName = state + "_event_" + FunctionName;
            if (state == "")
                EventName = FunctionName;

            //#if DEBUG
            //m_log.Debug("ScriptEngine: Script event function name: " + EventName);
            //#endif

            #region Find Event
            // not sure it's need
            if (InTimeSlice)
            {
                //OpenSim.Framework.Console.MainConsole.Instance.Output("ScriptEngine TimeSlice Overlap" + FunctionName);
                return Start;
            }

            MethodInfo ev = null;
            if (m_scriptType == null)
                m_scriptType = m_Script.GetType();

            if (!Events.TryGetValue(EventName, out ev))
            {
                // Not found, create
                ev = m_scriptType.GetMethod(EventName);
                Events.Add(EventName, ev);
            }
            if (ev == null) // No event by that event name!
            {
                //Attempt to find it just by name

                if (!Events.TryGetValue(EventName, out ev))
                {
                    // Not found, create
                    ev = m_scriptType.GetMethod(FunctionName);
                    Events.Add(FunctionName, ev);
                }
                if (ev == null) // No event by that name!
                {
                    //m_log.Debug("ScriptEngine Can not find any event named:" + EventName);
                    return null;
                }
            }
            #endregion

            return FireAsEnumerator(Start, ev, args, out ex);
        }
Пример #5
0
        public EnumeratorInfo FireAsEnumerator(EnumeratorInfo Start, MethodInfo ev, object[] args, out Exception ex)
        {
            IEnumerator thread = null;

            OpenTimeSlice(Start);
            bool running = true;
            ex = null;

            try
            {
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.TryGetValue(Start.Key, out thread);
                    }
                }
                else
                    thread = (IEnumerator)ev.Invoke(m_Script, args);
                if (thread != null)
                    running = thread.MoveNext();
            }
            catch (Exception tie)
            {
                // Grab the inner exception and rethrow it, unless the inner
                // exception is an EventAbortException as this indicates event
                // invocation termination due to a state change.
                // DO NOT THROW JUST THE INNER EXCEPTION!
                // FriendlyErrors depends on getting the whole exception!
                //
                if (!(tie is EventAbortException) &&
                        !(tie is MinEventDelayException))
                    ex = tie;
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return null;
            }

            if (running && thread != null)
            {
                if (Start == null)
                {
                    Start = new EnumeratorInfo();
                    Start.Key = UUID.Random().Guid;
                }
                lock (m_enumerators)
                {
                    m_enumerators[Start.Key] = thread;
                }

                if (thread.Current is DateTime)
                    Start.SleepTo = (DateTime)thread.Current;
                else if (thread.Current is string)
                {
                    ex = new Exception((string)thread.Current);
                    running = false;
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return Start;
            }
            else
            {
                //No enumerator.... errr.... something went really wrong here
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return null;
            }
        }
Пример #6
0
        /// <summary>
        ///     This closes the scrpit, removes it from any known spots, and disposes of itself.
        /// </summary>
        /// <param name="shouldbackup">Should we back up this script and fire state_exit?</param>
        public void CloseAndDispose(bool shouldbackup)
        {
            m_ScriptEngine.MaintenanceThread.RemoveFromEventSchQueue(this, true);

            if (Script != null)
            {
                //Fire the exit event for scripts that support it
                Exception      ex;
                EnumeratorInfo info = null;
                while ((info = Script.ExecuteEvent(State, "exit", new object[0], info, out ex))
                       != null)
                {
                }
            }
            m_ScriptEngine.MaintenanceThread.SetEventSchSetIgnoreNew(this, false);

            //Give the user back any controls we took
            ReleaseControls();

            // Tell script not to accept new requests
            //These are fine to set as the state wont be saved again
            if (shouldbackup)
            {
                Running  = false;
                Disabled = true;
            }

            // Remove from internal structure
            ScriptEngine.ScriptProtection.RemoveScript(this);

            //Remove any errors that might be sitting around
            m_ScriptEngine.ScriptErrorReporter.RemoveError(ItemID);

            #region Clean out script parts

            //Only if this script changed target omega do we reset it
            if (TargetOmegaWasSet)
            {
                Part.AngularVelocity = Vector3.Zero;                  // Removed in SL
                Part.ScheduleUpdate(PrimUpdateFlags.AngularVelocity); // Send changes to client.
            }

            #endregion

            if (Script != null)
            {
                // Stop long command on script
                m_ScriptEngine.RemoveScriptFromPlugins(Part.UUID, ItemID);

                //Release the script and destroy it
                ILease lease = (ILease)RemotingServices.GetLifetimeService(Script as MarshalByRefObject);
                if (lease != null)
                {
                    lease.Unregister(Script.Sponsor);
                }

                Script.Close();
                Script = null;
            }

            if (InventoryItem != null && Part != null)
            {
                MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Closed Script " +
                                           InventoryItem.Name + " in " +
                                           Part.Name);
            }
            if (AppDomain == null)
            {
                return;
            }

            // Tell AppDomain that we have stopped script
            m_ScriptEngine.AppDomainManager.UnloadScriptAppDomain(AppDomain);
            AppDomain = null;
        }
Пример #7
0
        public void OpenTimeSlice(EnumeratorInfo Start)
        {

            TimeSliceStart = DateTime.Now;
            if(Start==null)
                TimeSliceEnd = TimeSliceStart.AddMilliseconds(MaxTimeSlice);
            else
                TimeSliceEnd = TimeSliceStart.AddMilliseconds(MaxTimeSlice/2);
            InTimeSlice = true;
        }
Пример #8
0
        public EnumeratorInfo ExecuteEvent(string state, string FunctionName, object[] args, EnumeratorInfo Start, out Exception ex)
        {
            ex = null;
            string EventName = state == "" ? FunctionName : state + "_event_" + FunctionName;

            if (InTimeSlice)
                //OpenSim.Framework.Console.MainConsole.Instance.Output("ScriptEngine TimeSlice Overlap" + FunctionName);
                return Start;

            IEnumerator thread = null;

            OpenTimeSlice(Start);
            bool running = true;

            try
            {
                if (Start != null)
                {
                    lock (m_enumerators)
                        m_enumerators.TryGetValue (Start.Key, out thread);
                }
                else
                    thread = m_Script.FireEvent (EventName, args);

                if (thread != null)
                    running = thread.MoveNext();
            }
            catch (Exception tie)
            {
                // Grab the inner exception and rethrow it, unless the inner
                // exception is an EventAbortException as this indicates event
                // invocation termination due to a state change.
                // DO NOT THROW JUST THE INNER EXCEPTION!
                // FriendlyErrors depends on getting the whole exception!
                //
                if (!(tie is EventAbortException) &&
                        !(tie is MinEventDelayException) &&
                        !(tie.InnerException != null && 
                        ((tie.InnerException.Message.Contains("EventAbortException")) ||
                        (tie.InnerException.Message.Contains ("MinEventDelayException")))))
                    ex = tie;
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return null;
            }

            if (running && thread != null)
            {
                if (Start == null)
                {
                    Start = new EnumeratorInfo();
                    Start.Key = UUID.Random().Guid;
                }
                lock (m_enumerators)
                {
                    m_enumerators[Start.Key] = thread;
                }

                if (thread.Current is DateTime)
                    Start.SleepTo = (DateTime)thread.Current;
                else if (thread.Current is string)
                {
                    ex = new Exception((string)thread.Current);
                    running = false;
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return Start;
            }
            else
            {
                //No enumerator.... errr.... something went really wrong here
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return null;
            }
        }
Пример #9
0
 public void OpenTimeSlice(EnumeratorInfo Start)
 {
     if(Start==null)
         TimeSliceEnd = Util.EnvironmentTickCountAdd (MaxTimeSlice);
     else
         TimeSliceEnd = Util.EnvironmentTickCountAdd (MaxTimeSlice/2);
     InTimeSlice = true;
 }
Пример #10
0
        public EnumeratorInfo FireAsEnumerator(EnumeratorInfo Start, MethodInfo ev, object[] args, out Exception ex)
        {
            IEnumerator thread = null;

            bool running = true;
            ex = null;

            try
            {
                for(int i = 0; i < 5; i++) //We do 5 so that we do not kill the loops/queues above with many repeated event firings
                {
                    if (Start != null) //Make sure we have some info, otherwise start a new thread
                    {
                        //Open the slice at the beginning of every iteration
                        OpenTimeSlice();
                        InTimeSlice = true;

                        if (thread == null) //Only do this once
                        {
                            lock (m_enumerators)
                            {
                                m_enumerators.TryGetValue(Start.Key, out thread);
                            }
                        }
                        if (thread != null) //Push the event forward
                            running = thread.MoveNext();

                        if (!running) //Break out of the loop as we are done
                            break;

                        //Close the time slice at the end of every enumeration
                        CloseTimeSlice();
                    }
                    else
                        thread = (IEnumerator)ev.Invoke(m_Script, args);
                }
            }
            catch (Exception tie)
            {
                // Grab the inner exception and rethrow it, unless the inner
                // exception is an EventAbortException as this indicates event
                // invocation termination due to a state change.
                // DO NOT THROW JUST THE INNER EXCEPTION!
                // FriendlyErrors depends on getting the whole exception!
                //
                if (!(tie is EventAbortException) ||
                        !(tie is MinEventDelayException) ||
                        !(tie is EventAbortException) ||
                        !(tie is EventAbortException))
                    ex = tie;
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                InTimeSlice = false;
                return null;
            }

            if (running && thread != null)
            {
                if (Start == null)
                {
                    Start = new EnumeratorInfo();
                    Start.Key = System.Guid.NewGuid();
                }
                lock (m_enumerators)
                {
                    m_enumerators[Start.Key] = thread;
                }

                if (thread.Current is DateTime)
                    Start.SleepTo = (DateTime)thread.Current;
                return Start;
            }
            else
            {
                //No enumerator.... errr.... something went really wrong here
                if (Start != null)
                {
                    lock (m_enumerators)
                    {
                        m_enumerators.Remove(Start.Key);
                    }
                }
                CloseTimeSlice();
                return null;
            }
        }
Пример #11
0
        /// <summary>
        ///   This closes the scrpit, removes it from any known spots, and disposes of itself.
        /// </summary>
        /// <param name = "shouldbackup">Should we back up this script and fire state_exit?</param>
        public void CloseAndDispose(bool shouldbackup)
        {
            m_ScriptEngine.MaintenanceThread.RemoveFromEventSchQueue(this, true);

            if (shouldbackup)
            {
                if (Script != null)
                {
                    /*
                     * //Fire this directly so its not closed before its fired
                     * SetEventParams("state_exit", new DetectParams[0]);
                     *
                     * m_ScriptEngine.MaintenanceThread.ProcessQIS(new QueueItemStruct()
                     * {
                     *  ID = this,
                     *  CurrentlyAt = null,
                     *  functionName = "state_exit",
                     *  param = new object[0],
                     *  llDetectParams = new DetectParams[0],
                     *  VersionID = VersionID
                     * });
                     */
                    // dont think we should fire state_exit here
                    //                    m_ScriptEngine.MaintenanceThread.DoAndWaitEventSch(this, "state_exit",
                    //                        new DetectParams[0], VersionID, EventPriority.FirstStart, new object[0]);
                    m_ScriptEngine.StateSave.SaveStateTo(this);
                }
            }
            if (Script != null)
            {
                //Fire the exit event for scripts that support it
                Exception      ex;
                EnumeratorInfo info = null;
                while ((info = Script.ExecuteEvent(State, "exit", new object[0], info, out ex))
                       != null)
                {
                }
            }
            m_ScriptEngine.MaintenanceThread.SetEventSchSetIgnoreNew(this, false);

            //Give the user back any controls we took
            ReleaseControls();

            // Tell script not to accept new requests
            //These are fine to set as the state wont be saved again
            if (shouldbackup)
            {
                Running  = false;
                Disabled = true;
            }

            // Remove from internal structure
            ScriptEngine.ScriptProtection.RemoveScript(this);
//            if (!Silent) //Don't remove on a recompile because we'll make it under a different assembly
//                ScriptEngine.ScriptProtection.RemovePreviouslyCompiled(Source);

            //Remove any errors that might be sitting around
            m_ScriptEngine.ScriptErrorReporter.RemoveError(ItemID);

            #region Clean out script parts

            //Only if this script changed target omega do we reset it
            if (TargetOmegaWasSet)
            {
                Part.AngularVelocity = Vector3.Zero;                  // Removed in SL
                Part.ScheduleUpdate(PrimUpdateFlags.AngularVelocity); // Send changes to client.
            }

            #endregion

            if (Script != null)
            {
                // Stop long command on script
                m_ScriptEngine.RemoveScriptFromPlugins(Part.UUID, ItemID);

                //Release the script and destroy it
                ILease lease = (ILease)RemotingServices.GetLifetimeService(Script as MarshalByRefObject);
                if (lease != null)
                {
                    lease.Unregister(Script.Sponsor);
                }

                Script.Close();
                Script = null;
            }

            MainConsole.Instance.Debug("[" + m_ScriptEngine.ScriptEngineName + "]: Closed Script " + InventoryItem.Name + " in " +
                                       Part.Name);
            if (AppDomain == null)
            {
                return;
            }

            // Tell AppDomain that we have stopped script
            m_ScriptEngine.AppDomainManager.UnloadScriptAppDomain(AppDomain);
            AppDomain = null;
        }
Пример #12
0
        public EnumeratorInfo FireAsEnumerator(EnumeratorInfo Start, MethodInfo ev, object[] args, out Exception ex)
        {
            IEnumerator thread = null;
            if (Start != null)
                lock (m_enumerators)
                {
                    m_enumerators.TryGetValue(Start.Key, out thread);
                }
            else
                thread = (IEnumerator)ev.Invoke(m_Script, args);

            int i = 0;
            bool running = false;
            if (thread != null)
            {
                while (i < i + 10)
                {
                    i++;
                    try
                    {
                        running = CallAndWait(timeout, thread);
                        //Sleep processing
                        if (running && thread.Current != null)
                        {
                            if (thread.Current is DateTime)
                            {
                                if (Start == null)
                                {
                                    Start = new EnumeratorInfo();
                                    Start.Key = System.Guid.NewGuid();
                                }
                                Start.SleepTo = (DateTime)thread.Current;
                                lock (m_enumerators)
                                {
                                    m_enumerators[Start.Key] = thread;
                                }
                                ex = null;
                                return Start;
                            }
                        }
                        if (!running)
                        {
                            lock (m_enumerators)
                            {
                                if(Start != null)
                                    m_enumerators.Remove(Start.Key);
                            }
                            ex = null;
                            return null;
                        }
                    }
                    catch (Exception tie)
                    {
                        // Grab the inner exception and rethrow it, unless the inner
                        // exception is an EventAbortException as this indicates event
                        // invocation termination due to a state change.
                        // DO NOT THROW JUST THE INNER EXCEPTION!
                        // FriendlyErrors depends on getting the whole exception!
                        //
                        ex = null;
                        if (!(tie is EventAbortException) ||
                            !(tie is MinEventDelayException) ||
                            !(tie is EventAbortException) ||
                            !(tie is EventAbortException))
                            ex = tie;
                        return null;
                    }
                }
            }
            else
            {
                //No enumerator.... errr.... something went really wrong here
                ex = null;
                return Start;
            }
            if (Start == null)
            {
                Start = new EnumeratorInfo();
                Start.Key = System.Guid.NewGuid();
            }

            lock (m_enumerators)
            {
                m_enumerators[Start.Key] = thread;
            }
            ex = null;
            return Start;
        }