public EventParams(uint localID, string eventName, Object[] eventParams, DetectParams[] detectParams) { LocalID = localID; EventName = eventName; Params = eventParams; DetectParams = detectParams; }
public static DetectParams FromDetectedObject(DetectedObject detobj) { DetectParams parms = new DetectParams(); parms.Key = detobj.keyUUID; parms.Group = detobj.groupUUID; parms.LinkNum = detobj.linkNum; parms.Name = detobj.nameStr; parms.Owner = detobj.ownerUUID; parms.Position = detobj.posVector; parms.Rotation = detobj.rotQuat; parms.Type = detobj.colliderType; parms.Velocity = detobj.velVector; return(parms); }
public void touch_end(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { // Add to queue for all scripts in ObjectID object DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = remoteClient.AgentId; det[0].Populate(myScriptEngine.World); if (originalID == 0) { SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); if (part == null) return; det[0].LinkNum = part.LinkNum; } else { SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); det[0].LinkNum = originalPart.LinkNum; } if (surfaceArgs != null) { det[0].SurfaceTouchArgs = surfaceArgs; } myScriptEngine.PostObjectEvent(localID, new EventParams( "touch_end", new Object[] { new LSL_Types.LSLInteger(1) }, det)); }
public void UpdateTouchData(uint localID, DetectParams[] det) { throw new System.NotImplementedException(); }
private void SensorSweep(SenseRepeatClass ts) { if (ts.host == null) { return; } List<SensedEntity> sensedEntities = new List<SensedEntity>(); // Is the sensor type is AGENT and not SCRIPTED then include agents if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) { sensedEntities.AddRange(doAgentSensor(ts)); } // If SCRIPTED or PASSIVE or ACTIVE check objects if ((ts.type & SCRIPTED) != 0 || (ts.type & PASSIVE) != 0 || (ts.type & ACTIVE) != 0) { sensedEntities.AddRange(doObjectSensor(ts)); } lock (SenseLock) { List<DetectParams> detected = new List<DetectParams>(); if (sensedEntities.Count == 0) { if (ts.host is ScenePresence) { //If it is a scenePresence, then it is a bot that is being used for scanning. // We need to set the bot parameter in the detectParams so that iwDetectedBot works properly // so we have to have at least one detectParam object DetectParams detect = new DetectParams(); detect.BotID = ((ScenePresence)ts.host).UUID; detected.Add(detect); } // send a "no_sensor" // Add it to queue m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, new EventParams("no_sensor", new Object[0], detected.ToArray())); } else { // Sort the list to get everything ordered by distance sensedEntities.Sort(); int count = sensedEntities.Count; int idx; for (idx = 0; idx < count; idx++) { try { DetectParams detect = new DetectParams(); detect.Key = sensedEntities[idx].itemID; if (ts.host is ScenePresence) { //If it is a scenePresence, then it is a bot that is being used for scanning. // We need to set the bot parameter in the detectParams so that iwDetectedBot works properly detect.BotID = ((ScenePresence)ts.host).UUID; if (detect.BotID == detect.Key) continue;//Don't allow the ScenePresence that is scanning to detect itself } detect.Populate(m_CmdManager.m_ScriptEngine.World); detected.Add(detect); } catch (Exception) { // Ignore errors, the object has been deleted or the avatar has gone and // there was a problem in detect.Populate so nothing added to the list } if (detected.Count == maximumToReturn) break; } if (detected.Count == 0) { if (ts.host is ScenePresence) { //If it is a scenePresence, then it is a bot that is being used for scanning. // We need to set the bot parameter in the detectParams so that iwDetectedBot works properly // so we have to have at least one detectParam object DetectParams detect = new DetectParams(); detect.BotID = ((ScenePresence)ts.host).UUID; detected.Add(detect); } // To get here with zero in the list there must have been some sort of problem // like the object being deleted or the avatar leaving to have caused some // difficulty during the Populate above so fire a no_sensor event m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, new EventParams("no_sensor", new Object[0], detected.ToArray())); } else { m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, new EventParams("sensor", new Object[] {detected.Count}, detected.ToArray())); } } } }
/// <summary> /// Add event to event execution queue /// </summary> /// <param name="localID">Region object ID</param> /// <param name="itemID">Region script ID</param> /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> /// <param name="param">Array of parameters to match event mask</param> public bool AddToScriptQueue(uint localID, UUID itemID, string FunctionName, DetectParams[] qParams, params object[] param) { List<UUID> keylist = m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID); if (!keylist.Contains(itemID)) // We don't manage that script { return false; } lock (eventQueue) { if (eventQueue.Count >= EventExecutionMaxQueueSize) { m_log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: ERROR: Event execution queue item count is at " + eventQueue.Count + ". Config variable \"EventExecutionMaxQueueSize\" is set to " + EventExecutionMaxQueueSize + ", so ignoring new event."); m_log.Error("[" + m_ScriptEngine.ScriptEngineName + "]: Event ignored: localID: " + localID + ", itemID: " + itemID + ", FunctionName: " + FunctionName); return false; } InstanceData id = m_ScriptEngine.m_ScriptManager.GetScript( localID, itemID); // Create a structure and add data QueueItemStruct QIS = new QueueItemStruct(); QIS.localID = localID; QIS.itemID = itemID; QIS.functionName = FunctionName; QIS.llDetectParams = qParams; QIS.param = param; if (id != null) QIS.LineMap = id.LineMap; // Add it to queue eventQueue.Enqueue(QIS); } return true; }
public EventParams(string eventName, Object[] eventParams, DetectParams[] detectParams) { EventName = eventName; Params = eventParams; DetectParams = detectParams; }
public void TestScriptCrossOnSameSimulator() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); int sceneObjectIdTail = 0x2; EntityTransferModule etmA = new EntityTransferModule(); EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); XEngine xEngineA = new XEngine(); XEngine xEngineB = new XEngine(); xEngineA.DebugLevel = 1; xEngineB.DebugLevel = 1; IConfigSource configSource = new IniConfigSource(); IConfig startupConfig = configSource.AddConfig("Startup"); startupConfig.Set("DefaultScriptEngine", "XEngine"); startupConfig.Set("TrustBinaries", "true"); IConfig xEngineConfig = configSource.AddConfig("XEngine"); xEngineConfig.Set("Enabled", "true"); xEngineConfig.Set("StartDelay", "0"); // These tests will not run with AppDomainLoading = true, at least on mono. For unknown reasons, the call // to AssemblyResolver.OnAssemblyResolve fails. xEngineConfig.Set("AppDomainLoading", "false"); IConfig modulesConfig = configSource.AddConfig("Modules"); modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); SceneHelpers sh = new SceneHelpers(); TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000, configSource); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1000, 999, configSource); SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, configSource, lscm); SceneHelpers.SetupSceneModules(sceneA, configSource, etmA, xEngineA); SceneHelpers.SetupSceneModules(sceneB, configSource, etmB, xEngineB); sceneA.StartScripts(); sceneB.StartScripts(); SceneObjectGroup soSceneA = SceneHelpers.AddSceneObject(sceneA, 1, userId, "so1-", sceneObjectIdTail); soSceneA.AbsolutePosition = new Vector3(128, 10, 20); string soSceneAName = soSceneA.Name; string scriptItemSceneAName = "script1"; // CREATE SCRIPT TODO InventoryItemBase scriptItemSceneA = new InventoryItemBase(); // itemTemplate.ID = itemId; scriptItemSceneA.Name = scriptItemSceneAName; scriptItemSceneA.Folder = soSceneA.UUID; scriptItemSceneA.InvType = (int)InventoryType.LSL; AutoResetEvent chatEvent = new AutoResetEvent(false); OSChatMessage messageReceived = null; sceneA.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEvent.Set(); }; sceneA.RezNewScript(userId, scriptItemSceneA, @"integer c = 0; default { state_entry() { llSay(0, ""Script running""); } changed(integer change) { llSay(0, ""Changed""); } touch_start(integer n) { c = c + 1; llSay(0, (string)c); } }"); chatEvent.WaitOne(60000); Assert.That(messageReceived, Is.Not.Null, "No chat message received."); Assert.That(messageReceived.Message, Is.EqualTo("Script running")); { // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = userId; det[0].Populate(sceneA); EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); messageReceived = null; chatEvent.Reset(); xEngineA.PostObjectEvent(soSceneA.LocalId, ep); chatEvent.WaitOne(60000); Assert.That(messageReceived.Message, Is.EqualTo("1")); } AutoResetEvent chatEventB = new AutoResetEvent(false); sceneB.EventManager.OnChatFromWorld += (s, m) => { messageReceived = m; chatEventB.Set(); }; messageReceived = null; chatEventB.Reset(); // Cross with a negative value soSceneA.AbsolutePosition = new Vector3(128, -10, 20); chatEventB.WaitOne(60000); Assert.That(messageReceived, Is.Not.Null, "No Changed message received."); Assert.That(messageReceived.Message, Is.Not.Null, "Changed message without content"); Assert.That(messageReceived.Message, Is.EqualTo("Changed")); // TEST sending event to moved prim and output { SceneObjectGroup soSceneB = sceneB.GetSceneObjectGroup(soSceneAName); TaskInventoryItem scriptItemSceneB = soSceneB.RootPart.Inventory.GetInventoryItem(scriptItemSceneAName); // XXX: Should not be doing this so directly. Should call some variant of EventManager.touch() instead. DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = userId; det[0].Populate(sceneB); EventParams ep = new EventParams("touch_start", new Object[] { new LSL_Types.LSLInteger(1) }, det); Thread.Sleep(250); // wait for other change messages to pass messageReceived = null; chatEventB.Reset(); xEngineB.PostObjectEvent(soSceneB.LocalId, ep); chatEventB.WaitOne(60000); Assert.That(messageReceived.Message, Is.EqualTo("2")); } }
public void llMapDestination(string simname, LSL_Vector pos, LSL_Vector lookAt) { m_host.AddScriptLPS(1); DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); if (detectedParams == null) { if (m_host.ParentGroup.IsAttachment == true) { detectedParams = new DetectParams(); detectedParams.Key = m_host.OwnerID; } else { return; } } ScenePresence avatar = World.GetScenePresence(detectedParams.Key); if (avatar != null) { avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, simname, pos, lookAt); } ScriptSleep(m_sleepMsOnMapDestination); }
// Execute a LL-event-function in Script internal void ExecuteEvent(uint localID, UUID itemID, string FunctionName, DetectParams[] qParams, object[] args) { int ExeStage=0; // ;^) Ewe Loon, for debuging InstanceData id=null; try // ;^) Ewe Loon,fix { // ;^) Ewe Loon,fix ExeStage = 1; // ;^) Ewe Loon, for debuging id = GetScript(localID, itemID); if (id == null) return; ExeStage = 2; // ;^) Ewe Loon, for debuging if (qParams.Length>0) // ;^) Ewe Loon,fix detparms[id] = qParams; ExeStage = 3; // ;^) Ewe Loon, for debuging if (id.Running) id.Script.ExecuteEvent(id.State, FunctionName, args); ExeStage = 4; // ;^) Ewe Loon, for debuging if (qParams.Length>0) // ;^) Ewe Loon,fix detparms.Remove(id); ExeStage = 5; // ;^) Ewe Loon, for debuging } catch (Exception e) // ;^) Ewe Loon, From here down tis fix { if ((ExeStage == 3)&&(qParams.Length>0)) detparms.Remove(id); SceneObjectPart ob = m_scriptEngine.World.GetSceneObjectPart(localID); m_log.InfoFormat("[Script Error] ,{0},{1},@{2},{3},{4},{5}", ob.Name , FunctionName, ExeStage, e.Message, qParams.Length, detparms.Count); if (ExeStage != 2) throw e; } }
public static void Deserialize(string xml, ScriptInstance instance) { XmlDocument doc = new XmlDocument(); Dictionary<string, object> vars = instance.GetVars(); instance.PluginData = new Object[0]; doc.LoadXml(xml); XmlNodeList rootL = doc.GetElementsByTagName("ScriptState"); if (rootL.Count != 1) { return; } XmlNode rootNode = rootL[0]; if (rootNode != null) { object varValue; XmlNodeList partL = rootNode.ChildNodes; instance.Run = true; foreach (XmlNode part in partL) { switch (part.Name) { case "State": instance.State=part.InnerText; break; case "Running": instance.Running=bool.Parse(part.InnerText); break; case "Run": instance.Run = bool.Parse(part.InnerText); break; case "Variables": XmlNodeList varL = part.ChildNodes; foreach (XmlNode var in varL) { string varName; varValue=ReadTypedValue(var, out varName); if (vars.ContainsKey(varName)) vars[varName] = varValue; } instance.SetVars(vars); break; case "Queue": XmlNodeList itemL = part.ChildNodes; foreach (XmlNode item in itemL) { List<Object> parms = new List<Object>(); List<DetectParams> detected = new List<DetectParams>(); string eventName = item.Attributes.GetNamedItem("event").Value; XmlNodeList eventL = item.ChildNodes; foreach (XmlNode evt in eventL) { switch (evt.Name) { case "Params": XmlNodeList prms = evt.ChildNodes; foreach (XmlNode pm in prms) parms.Add(ReadTypedValue(pm)); break; case "Detected": XmlNodeList detL = evt.ChildNodes; foreach (XmlNode det in detL) { string vect = det.Attributes.GetNamedItem( "pos").Value; LSL_Types.Vector3 v = new LSL_Types.Vector3(vect); int d_linkNum=0; UUID d_group = UUID.Zero; string d_name = String.Empty; UUID d_owner = UUID.Zero; LSL_Types.Vector3 d_position = new LSL_Types.Vector3(); LSL_Types.Quaternion d_rotation = new LSL_Types.Quaternion(); int d_type = 0; LSL_Types.Vector3 d_velocity = new LSL_Types.Vector3(); try { string tmp; tmp = det.Attributes.GetNamedItem( "linkNum").Value; int.TryParse(tmp, out d_linkNum); tmp = det.Attributes.GetNamedItem( "group").Value; UUID.TryParse(tmp, out d_group); d_name = det.Attributes.GetNamedItem( "name").Value; tmp = det.Attributes.GetNamedItem( "owner").Value; UUID.TryParse(tmp, out d_owner); tmp = det.Attributes.GetNamedItem( "position").Value; d_position = new LSL_Types.Vector3(tmp); tmp = det.Attributes.GetNamedItem( "rotation").Value; d_rotation = new LSL_Types.Quaternion(tmp); tmp = det.Attributes.GetNamedItem( "type").Value; int.TryParse(tmp, out d_type); tmp = det.Attributes.GetNamedItem( "velocity").Value; d_velocity = new LSL_Types.Vector3(tmp); } catch (Exception) // Old version XML { } UUID uuid = new UUID(); UUID.TryParse(det.InnerText, out uuid); DetectParams d = new DetectParams(); d.Key = uuid; d.OffsetPos = v; d.LinkNum = d_linkNum; d.Group = d_group; d.Name = d_name; d.Owner = d_owner; d.Position = d_position; d.Rotation = d_rotation; d.Type = d_type; d.Velocity = d_velocity; detected.Add(d); } break; } } EventParams ep = new EventParams( eventName, parms.ToArray(), detected.ToArray()); instance.EventQueue.Enqueue(ep); } break; case "Plugins": instance.PluginData = ReadList(part).Data; break; case "Permissions": string tmpPerm; int mask = 0; tmpPerm = part.Attributes.GetNamedItem("mask").Value; if (tmpPerm != null) { int.TryParse(tmpPerm, out mask); if (mask != 0) { tmpPerm = part.Attributes.GetNamedItem("granter").Value; if (tmpPerm != null) { UUID granter = new UUID(); UUID.TryParse(tmpPerm, out granter); if (granter != UUID.Zero) { instance.ScriptTask.PermsMask = mask; instance.ScriptTask.PermsGranter = granter; } } } } break; case "MinEventDelay": double minEventDelay = 0.0; double.TryParse(part.InnerText, NumberStyles.Float, Culture.NumberFormatInfo, out minEventDelay); instance.MinEventDelay = minEventDelay; break; } } } }
public void money(SceneObjectPart part, UUID agentID, int amount, int paidLinkNum) { DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = agentID; det[0].LinkNum = paidLinkNum; myScriptEngine.PostObjectEvent(part.LocalId, new EventParams( "money", new object[] { agentID.ToString(), amount }, det)); }
void EventManager_OnObjectGrabUpdate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { // Add to queue for all scripts in ObjectID object DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = remoteClient.AgentId; det[0].Populate(myScriptEngine.World); det[0].OffsetPos = offsetPos; if (originalID == 0) { SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); if (part == null) return; det[0].LinkNum = part.LinkNum; } else { SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); det[0].LinkNum = originalPart.LinkNum; } if (surfaceArgs != null) { det[0].SurfaceTouchArgs = surfaceArgs; } myScriptEngine.UpdateTouchData(localID, det); }
public void collision_end(uint localID, ColliderArgs col) { // Add to queue for all scripts in ObjectID object List<DetectParams> det = new List<DetectParams>(); foreach (DetectedObject detobj in col.Colliders) { DetectParams d = new DetectParams(); d.Key =detobj.keyUUID; d.Populate(myScriptEngine.World); det.Add(d); } if (det.Count > 0) myScriptEngine.PostObjectEvent(localID, new EventParams( "collision_end", new Object[] { new LSL_Types.LSLInteger(det.Count) }, det.ToArray())); }
public void land_collision_end(uint localID, ColliderArgs col) { List<DetectParams> det = new List<DetectParams>(); foreach (DetectedObject detobj in col.Colliders) { DetectParams d = new DetectParams(); d.Position = detobj.posVector; d.Populate(myScriptEngine.World); det.Add(d); myScriptEngine.PostObjectEvent(localID, new EventParams( "land_collision_end", new Object[] { new LSL_Types.Vector3(d.Position) }, det.ToArray())); } }
public void touch(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient) { // Add to queue for all scripts in ObjectID object DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = remoteClient.AgentId; det[0].Populate(myScriptEngine.World); det[0].OffsetPos = new LSL_Types.Vector3(offsetPos.X, offsetPos.Y, offsetPos.Z); if (originalID == 0) { SceneObjectPart part = myScriptEngine.World.GetSceneObjectPart(localID); if (part == null) return; det[0].LinkNum = part.LinkNum; } else { SceneObjectPart originalPart = myScriptEngine.World.GetSceneObjectPart(originalID); det[0].LinkNum = originalPart.LinkNum; } myScriptEngine.PostObjectEvent(localID, new EventParams( "touch", new Object[] { new LSL_Types.LSLInteger(1) }, det)); }
private void SensorSweep(SensorInfo ts) { if (ts.host == null) { return; } List<SensedEntity> sensedEntities = new List<SensedEntity>(); // Is the sensor type is AGENT and not SCRIPTED then include agents if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) { sensedEntities.AddRange(doAgentSensor(ts)); } // If SCRIPTED or PASSIVE or ACTIVE check objects if ((ts.type & SCRIPTED) != 0 || (ts.type & PASSIVE) != 0 || (ts.type & ACTIVE) != 0) { sensedEntities.AddRange(doObjectSensor(ts)); } lock (SenseLock) { if (sensedEntities.Count == 0) { // send a "no_sensor" // Add it to queue m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, new EventParams("no_sensor", new Object[0], new DetectParams[0])); } else { // Sort the list to get everything ordered by distance sensedEntities.Sort(); int count = sensedEntities.Count; int idx; List<DetectParams> detected = new List<DetectParams>(); for (idx = 0; idx < count; idx++) { try { DetectParams detect = new DetectParams(); detect.Key = sensedEntities[idx].itemID; detect.Populate(m_CmdManager.m_ScriptEngine.World); detected.Add(detect); } catch (Exception) { // Ignore errors, the object has been deleted or the avatar has gone and // there was a problem in detect.Populate so nothing added to the list } if (detected.Count == maximumToReturn) break; } if (detected.Count == 0) { // To get here with zero in the list there must have been some sort of problem // like the object being deleted or the avatar leaving to have caused some // difficulty during the Populate above so fire a no_sensor event m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, new EventParams("no_sensor", new Object[0], new DetectParams[0])); } else { m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, new EventParams("sensor", new Object[] {new LSL_Types.LSLInteger(detected.Count) }, detected.ToArray())); } } } }
public static DetectParams FromDetectedObject(DetectedObject detobj) { DetectParams parms = new DetectParams(); parms.Key = detobj.keyUUID; parms.Group = detobj.groupUUID; parms.LinkNum = detobj.linkNum; parms.Name = detobj.nameStr; parms.Owner = detobj.ownerUUID; parms.Position = detobj.posVector; parms.Rotation = detobj.rotQuat; parms.Type = detobj.colliderType; parms.Velocity = detobj.velVector; return parms; }
private void OnObjectGrab(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { // Add to queue for all scripts in ObjectID object DetectParams[] det = new DetectParams[1]; det[0] = new DetectParams(); det[0].Key = remoteClient.AgentId; //det[0].Populate(World); if (originalID == 0) { SceneObjectPart part = CurrentRegion.Scene.GetSceneObjectPart(localID); if (part == null) return; det[0].LinkNum = part.LinkNum; } else { SceneObjectPart originalPart = CurrentRegion.Scene.GetSceneObjectPart(originalID); det[0].LinkNum = originalPart.LinkNum; } if (surfaceArgs != null) { det[0].SurfaceTouchArgs = surfaceArgs; } Shared.EventParams ep = new Shared.EventParams(localID, "touch_start", new Object[] {new LSL_Types.LSLInteger(1)}, det); CurrentRegion.Executors_Execute(ep); }
/// <summary> /// Add event to event execution queue /// </summary> /// <param name="localID">Region object ID</param> /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> /// <param name="param">Array of parameters to match event mask</param> public bool AddToObjectQueue(uint localID, string FunctionName, DetectParams[] qParams, params object[] param) { // Determine all scripts in Object and add to their queue //myScriptEngine.log.Info("[" + ScriptEngineName + "]: EventQueueManager Adding localID: " + localID + ", FunctionName: " + FunctionName); // Do we have any scripts in this object at all? If not, return if (m_ScriptEngine.m_ScriptManager.Scripts.ContainsKey(localID) == false) { //m_log.Debug("Event \String.Empty + FunctionName + "\" for localID: " + localID + ". No scripts found on this localID."); return false; } List<UUID> scriptKeys = m_ScriptEngine.m_ScriptManager.GetScriptKeys(localID); foreach (UUID itemID in scriptKeys) { // Add to each script in that object // TODO: Some scripts may not subscribe to this event. Should we NOT add it? Does it matter? AddToScriptQueue(localID, itemID, FunctionName, qParams, param); } return true; }