예제 #1
0
        public void CheckRunLockInvariants(bool throwIt)
        {
            /*
             * If not executing any event handler, there shouldn't be any saved stack frames.
             * If executing an event handler, there should be some saved stack frames.
             */
            bool            active = (stackFrames != null);
            ScriptEventCode ec     = this.eventCode;

            if (((ec == ScriptEventCode.None) && active) ||
                ((ec != ScriptEventCode.None) && !active))
            {
                m_log.Error("CheckRunLockInvariants: script=" + m_DescName);
                m_log.Error("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString());
                m_log.Error("CheckRunLockInvariants: m_RunOnePhase=" + m_RunOnePhase);
                m_log.Error("CheckRunLockInvariants: lastec=" + lastEventCode + ", lastAct=" + lastActive + ", lastPhase=" + lastRunPhase);
                if (throwIt)
                {
                    throw new Exception("CheckRunLockInvariants: eventcode=" + ec.ToString() + ", active=" + active.ToString());
                }
            }
            lastEventCode = ec;
            lastActive    = active;
            lastRunPhase  = m_RunOnePhase;
        }
예제 #2
0
        private void SendScriptErrorMessage(Exception e, ScriptEventCode ev)
        {
            StringBuilder msg = new StringBuilder();

            msg.Append("YEngine: ");
            if (e.Message != null)
            {
                msg.Append(e.Message);
            }

            msg.Append(" (script: ");
            msg.Append(m_Item.Name);
            msg.Append(" event: ");
            msg.Append(ev.ToString());
            msg.Append(" primID: ");
            msg.Append(m_Part.UUID.ToString());
            msg.Append(" at: <");
            Vector3 pos = m_Part.AbsolutePosition;

            msg.Append((int)Math.Floor(pos.X));
            msg.Append(',');
            msg.Append((int)Math.Floor(pos.Y));
            msg.Append(',');
            msg.Append((int)Math.Floor(pos.Z));
            msg.Append(">) Script must be Reset to re-enable.\n");

            string msgst = msg.ToString();

            if (msgst.Length > 1000)
            {
                msgst = msgst.Substring(0, 1000);
            }

            m_Engine.World.SimChat(Utils.StringToBytes(msgst),
                                   ChatTypeEnum.DebugChannel, 2147483647,
                                   m_Part.AbsolutePosition,
                                   m_Part.Name, m_Part.UUID, false);
            m_log.Debug(string.Format(
                            "[SCRIPT ERROR]: {0} (at event {1}, part {2} {3} at {4} in {5}",
                            (e.Message == null)? "" : e.Message,
                            ev.ToString(),
                            m_Part.Name,
                            m_Part.UUID,
                            m_Part.AbsolutePosition,
                            m_Part.ParentGroup.Scene.Name));

            m_SleepUntil = DateTime.MaxValue;
        }
예제 #3
0
        /**
         * @brief Enqueue an event
         * @param ev = as returned by xmrEventDequeue saying which event type to queue
         *             and what argument list to pass to it.  The llDetect...() parameters
         *             are as currently set for the script (use xmrEventLoadDets to set how
         *             you want them to be different).
         */
        public override void xmrEventEnqueue(LSL_List ev)
        {
            object[]        data = ev.Data;
            ScriptEventCode evc  = (ScriptEventCode)ListInt(data[0]);

            int nargs = data.Length - 1;

            object[] args = new object[nargs];
            Array.Copy(data, 1, args, 0, nargs);

            PostEvent(new EventParams(evc.ToString(), args, m_DetectParams));
        }
예제 #4
0
        public override LSL_List xmrEventDequeue(double timeout, int returnMask1, int returnMask2,
                                                 int backgroundMask1, int backgroundMask2)
        {
            DateTime    sleepUntil = DateTime.UtcNow + TimeSpan.FromMilliseconds(timeout * 1000.0);
            EventParams evt = null;
            int         callNo, evc2;
            int         evc1                 = 0;
            int         mask1                = returnMask1 | backgroundMask1; // codes 00..31
            int         mask2                = returnMask2 | backgroundMask2; // codes 32..63
            LinkedListNode <EventParams> lln = null;

            object[]        sv;
            ScriptEventCode evc = ScriptEventCode.None;

            callNo = -1;
            try
            {
                if (callMode == CallMode_NORMAL)
                {
                    goto findevent;
                }

                // Stack frame is being restored as saved via CheckRun...().
                // Restore necessary values then jump to __call<n> label to resume processing.
                sv          = RestoreStackFrame("xmrEventDequeue", out callNo);
                sleepUntil  = DateTime.Parse((string)sv[0]);
                returnMask1 = (int)sv[1];
                returnMask2 = (int)sv[2];
                mask1       = (int)sv[3];
                mask2       = (int)sv[4];
                switch (callNo)
                {
                case 0:
                    goto __call0;

                case 1:
                {
                    evc1 = (int)sv[5];
                    evc  = (ScriptEventCode)(int)sv[6];
                    DetectParams[] detprms = ObjArrToDetPrms((object[])sv[7]);
                    object[]       ehargs  = (object[])sv[8];
                    evt = new EventParams(evc.ToString(), ehargs, detprms);
                    goto __call1;
                }
                }
                throw new ScriptBadCallNoException(callNo);

                // Find first event that matches either the return or background masks.
findevent:
                Monitor.Enter(m_QueueLock);
                for (lln = m_EventQueue.First; lln != null; lln = lln.Next)
                {
                    evt  = lln.Value;
                    evc  = (ScriptEventCode)Enum.Parse(typeof(ScriptEventCode), evt.EventName);
                    evc1 = (int)evc;
                    evc2 = evc1 - 32;
                    if ((((uint)evc1 < (uint)32) && (((mask1 >> evc1) & 1) != 0)) ||
                        (((uint)evc2 < (uint)32) && (((mask2 >> evc2) & 1) != 0)))
                    {
                        goto remfromq;
                    }
                }

                // Nothing found, sleep while one comes in.
                m_SleepUntil      = sleepUntil;
                m_SleepEventMask1 = mask1;
                m_SleepEventMask2 = mask2;
                Monitor.Exit(m_QueueLock);
                suspendOnCheckRunTemp = true;
                callNo = 0;
__call0:
                CheckRunQuick();
                goto checktmo;

                // Found one, remove it from queue.
remfromq:
                m_EventQueue.Remove(lln);
                if ((uint)evc1 < (uint)m_EventCounts.Length)
                {
                    m_EventCounts[evc1]--;
                }

                Monitor.Exit(m_QueueLock);
                m_InstEHEvent++;

                // See if returnable or background event.
                if ((((uint)evc1 < (uint)32) && (((returnMask1 >> evc1) & 1) != 0)) ||
                    (((uint)evc2 < (uint)32) && (((returnMask2 >> evc2) & 1) != 0)))
                {
                    // Returnable event, return its parameters in a list.
                    // Also set the detect parameters to what the event has.
                    int      plen  = evt.Params.Length;
                    object[] plist = new object[plen + 1];
                    plist[0] = (LSL_Integer)evc1;
                    for (int i = 0; i < plen;)
                    {
                        object ob = evt.Params[i];
                        if (ob is int)
                        {
                            ob = (LSL_Integer)(int)ob;
                        }
                        else if (ob is double)
                        {
                            ob = (LSL_Float)(double)ob;
                        }
                        else if (ob is string)
                        {
                            ob = (LSL_String)(string)ob;
                        }
                        plist[++i] = ob;
                    }
                    m_DetectParams = evt.DetectParams;
                    return(new LSL_List(plist));
                }

                // It is a background event, simply call its event handler,
                // then check event queue again.
                callNo = 1;
__call1:
                ScriptEventHandler seh = m_ObjCode.scriptEventHandlerTable[stateCode, evc1];
                if (seh == null)
                {
                    goto checktmo;
                }

                DetectParams[]  saveDetParams = this.m_DetectParams;
                object[]        saveEHArgs    = this.ehArgs;
                ScriptEventCode saveEventCode = this.eventCode;

                this.m_DetectParams = evt.DetectParams;
                this.ehArgs         = evt.Params;
                this.eventCode      = evc;

                try
                {
                    seh(this);
                }
                finally
                {
                    this.m_DetectParams = saveDetParams;
                    this.ehArgs         = saveEHArgs;
                    this.eventCode      = saveEventCode;
                }

                // Keep waiting until we find a returnable event or timeout.
checktmo:
                if (DateTime.UtcNow < sleepUntil)
                {
                    goto findevent;
                }

                // We timed out, return an empty list.
                return(emptyList);
            }
            finally
            {
                if (callMode != CallMode_NORMAL)
                {
                    // Stack frame is being saved by CheckRun...().
                    // Save everything we need at the __call<n> labels so we can restore it
                    // when we need to.
                    sv    = CaptureStackFrame("xmrEventDequeue", callNo, 9);
                    sv[0] = sleepUntil.ToString();                  // needed at __call0,__call1
                    sv[1] = returnMask1;                            // needed at __call0,__call1
                    sv[2] = returnMask2;                            // needed at __call0,__call1
                    sv[3] = mask1;                                  // needed at __call0,__call1
                    sv[4] = mask2;                                  // needed at __call0,__call1
                    if (callNo == 1)
                    {
                        sv[5] = evc1;                               // needed at __call1
                        sv[6] = (int)evc;                           // needed at __call1
                        sv[7] = DetPrmsToObjArr(evt.DetectParams);  // needed at __call1
                        sv[8] = evt.Params;                         // needed at __call1
                    }
                }
            }
        }
        private void SendScriptErrorMessage(Exception e, ScriptEventCode ev)
        {
            StringBuilder msg     = new StringBuilder();
            bool          toowner = false;

            msg.Append("YEngine: ");
            if (e.Message != null)
            {
                string text = e.Message;
                if (text.StartsWith("(OWNER)"))
                {
                    text    = text.Substring(7);
                    toowner = true;
                }
                msg.Append(text);
            }

            msg.Append(" (script: ");
            msg.Append(m_Item.Name);
            msg.Append(" event: ");
            msg.Append(ev.ToString());
            msg.Append(" primID: ");
            msg.Append(m_Part.UUID.ToString());
            msg.Append(" at: <");
            Vector3 pos = m_Part.AbsolutePosition;

            msg.Append((int)Math.Floor(pos.X));
            msg.Append(',');
            msg.Append((int)Math.Floor(pos.Y));
            msg.Append(',');
            msg.Append((int)Math.Floor(pos.Z));
            msg.Append(">) Script must be Reset to re-enable.\n");

            string msgst = msg.ToString();

            if (msgst.Length > 1000)
            {
                msgst = msgst.Substring(0, 1000);
            }

            if (toowner)
            {
                ScenePresence sp = m_Engine.World.GetScenePresence(m_Part.OwnerID);
                if (sp != null && !sp.IsNPC)
                {
                    m_Engine.World.SimChatToAgent(m_Part.OwnerID, Utils.StringToBytes(msgst), 0x7FFFFFFF, m_Part.AbsolutePosition,
                                                  m_Part.Name, m_Part.UUID, false);
                }
            }
            else
            {
                m_Engine.World.SimChat(Utils.StringToBytes(msgst),
                                       ChatTypeEnum.DebugChannel, 0x7FFFFFFF,
                                       m_Part.AbsolutePosition,
                                       m_Part.Name, m_Part.UUID, false);
            }
            m_log.Debug(string.Format(
                            "[SCRIPT ERROR]: {0} (at event {1}, part {2} {3} at {4} in {5}",
                            (e.Message == null)? "" : e.Message,
                            ev.ToString(),
                            m_Part.Name,
                            m_Part.UUID,
                            m_Part.AbsolutePosition,
                            m_Part.ParentGroup.Scene.Name));

            m_SleepUntil = DateTime.MaxValue;
        }