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; }
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; }
/** * @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)); }
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; }