public void touch(ISceneChildEntity part, ISceneChildEntity child, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { Dictionary <UUID, DetectParams> det = new Dictionary <UUID, DetectParams>(); if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) { det = new Dictionary <UUID, DetectParams>(); } // Add to queue for all scripts in ObjectID object DetectParams detparam = new DetectParams(); detparam = new DetectParams { Key = remoteClient.AgentId, OffsetPos = new LSL_Types.Vector3(offsetPos.X, offsetPos.Y, offsetPos.Z) }; detparam.Populate(part.ParentEntity.Scene); detparam.LinkNum = child.LinkNum; if (surfaceArgs != null) { detparam.SurfaceTouchArgs = surfaceArgs; } det[remoteClient.AgentId] = detparam; CoalescedTouchEvents[part.LocalId] = det; ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { return; } string functionName = "touch"; object[] param = new Object[] { new LSL_Types.LSLInteger(det.Count) }; foreach (ScriptData ID in datas) { m_scriptEngine.AddToScriptQueue(ID, functionName, new List <DetectParams>(det.Values).ToArray(), EventPriority.FirstStart, param); } }
public void touch_end(ISceneChildEntity part, ISceneChildEntity child, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { Dictionary <UUID, DetectParams> det = new Dictionary <UUID, DetectParams>(); if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) { det = new Dictionary <UUID, DetectParams>(); } // Add to queue for all scripts in ObjectID object DetectParams detparam = new DetectParams(); detparam = new DetectParams(); detparam.Key = remoteClient.AgentId; detparam.Populate(m_scriptEngine.findPrimsScene(part.LocalId)); detparam.LinkNum = child.LinkNum; if (surfaceArgs != null) { detparam.SurfaceTouchArgs = surfaceArgs; } det[remoteClient.AgentId] = detparam; CoalescedTouchEvents[part.LocalId] = det; ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { return; } string functionName = "touch_end"; object[] param = new Object[] { new LSL_Types.LSLInteger(1) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) { m_scriptEngine.AddToScriptQueue(ID, functionName, new List <DetectParams>(det.Values).ToArray(), ID.VersionID, param); } } //Remove us from the det param list det.Remove(remoteClient.AgentId); CoalescedTouchEvents[part.LocalId] = det; }
public void land_collision_end(ISceneChildEntity part, ColliderArgs col) { List <DetectParams> det = new List <DetectParams>(); foreach (DetectedObject detobj in col.Colliders) { DetectParams d = new DetectParams(); d.Position = new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z); d.Key = detobj.keyUUID; d.Populate(part.ParentEntity.Scene); d.LinkNum = part.LinkNum; det.Add(d); } if (det.Count != 0) { ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); //if (datas == null || datas.Length == 0) return; } string functionName = "land_collision_end"; object[] param = new Object[] { new LSL_Types.Vector3(det[0].Position) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) { m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), ID.VersionID, param); } } } }
public void collision_start(ISceneChildEntity part, 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(part.ParentEntity.Scene); d.LinkNum = part.LinkNum; det.Add(d); } if (det.Count > 0) { ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); //if (datas == null || datas.Length == 0) return; } string functionName = "collision_start"; object[] param = new Object[] { new LSL_Types.LSLInteger(det.Count) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) { m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), ID.VersionID, param); } } } }
public void touch_end (ISceneChildEntity part, ISceneChildEntity child, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>(); if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) det = new Dictionary<UUID, DetectParams>(); // Add to queue for all scripts in ObjectID object DetectParams detparam = new DetectParams(); detparam = new DetectParams(); detparam.Key = remoteClient.AgentId; detparam.Populate(m_scriptEngine.findPrimsScene(part.LocalId)); detparam.LinkNum = child.LinkNum; if (surfaceArgs != null) detparam.SurfaceTouchArgs = surfaceArgs; det[remoteClient.AgentId] = detparam; CoalescedTouchEvents[part.LocalId] = det; ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) return; string functionName = "touch_end"; object[] param = new Object[] { new LSL_Types.LSLInteger (det.Count) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), EventPriority.FirstStart, param); } //Remove us from the det param list det.Remove(remoteClient.AgentId); CoalescedTouchEvents[part.LocalId] = det; }
public void AddEventSchQueue(ScriptData ID, string FunctionName, DetectParams[] qParams, EventPriority priority, params object[] param) { QueueItemStruct QIS; if (ID == null || ID.Script == null || ID.IgnoreNew) return; if (!ID.SetEventParams(FunctionName, qParams)) // check events delay rules return; QIS = new QueueItemStruct { EventsProcData = new ScriptEventsProcData(), ID = ID, functionName = FunctionName, llDetectParams = qParams, param = param, VersionID = Interlocked.Read(ref ID.VersionID), State = ID.State, CurrentlyAt = null }; ScriptEvents.Enqueue(QIS); long threadCount = Interlocked.Read(ref scriptThreadpool.nthreads); if (threadCount == 0 || threadCount < (ScriptEvents.Count + (SleepingScriptEventCount/2))*EventPerformance) { scriptThreadpool.QueueEvent(eventLoop, 2); } }
public EventParams(string eventName, Object[] eventParams, DetectParams[] detectParams) { EventName = eventName; Params = eventParams; DetectParams = detectParams; }
public void AddEventSchQueue(ScriptData ID, string FunctionName, DetectParams[] qParams, int VersionID, params object[] param) { QueueItemStruct QIS = new QueueItemStruct(); QIS.ID = ID; QIS.functionName = FunctionName; QIS.llDetectParams = qParams; QIS.param = param; QIS.VersionID = VersionID; QIS.State = ID.State; AddEventSchQIS(QIS); }
public bool SetEventParams(string functionName, DetectParams[] qParams) { if (Suspended || !Running) return false; //No suspended scripts... if (qParams.Length > 0) LastDetectParams = qParams; if ( /*functionName == "control" || */functionName == "state_entry" || functionName == "on_rez" || functionName == "link_message") { //For vehicles, otherwise breaks them. DO NOT REMOVE UNLESS YOU FIND A BETTER WAY TO FIX return true; } long NowTicks = Util.EnvironmentTickCount(); if (EventDelayTicks != 0) { if (NowTicks < NextEventTimeTicks) return false; NextEventTimeTicks = NowTicks + EventDelayTicks; } switch (functionName) { //Times pulled from http://wiki.secondlife.com/wiki/LSL_Delay case "touch": //Limits for 0.1 seconds case "touch_start": case "touch_end": if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(TouchEventDelayTicks * TicksPerMillisecond); break; case "timer": //Settable timer limiter if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(TimerEventDelayTicks * TicksPerMillisecond); break; case "collision": //Collision limiters taken off of reporting from WhiteStar in mantis 0004513 case "collision_start": case "collision_end": case "land_collision": case "land_collision_start": case "land_collision_end": if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(CollisionEventDelayTicks * TicksPerMillisecond); break; case "control": if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(0.5f * TicksPerMillisecond); break; default: //Default is 0.05 seconds for event limiting if (!NextEventDelay.ContainsKey(functionName)) break; //If it doesn't exist, we don't limit it if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(DefaultEventDelayTicks * TicksPerMillisecond); break; } //Add the event to the stats ScriptScore++; m_ScriptEngine.ScriptEPS++; return true; }
/// <summary> /// Posts the event to the given object. /// </summary> /// <param name="ID"></param> /// <param name="FunctionName"></param> /// <param name="qParams"></param> /// <param name="param"></param> /// <returns></returns> public bool AddToScriptQueue(ScriptData ID, string FunctionName, DetectParams[] qParams, int VersionID, EventPriority priority, params object[] param) { // Create a structure and add data QueueItemStruct QIS = new QueueItemStruct(); QIS.ID = ID; QIS.functionName = FunctionName; QIS.llDetectParams = qParams; QIS.param = param; QIS.VersionID = VersionID; QIS.State = ID.State; MaintenanceThread.AddEvent(QIS, priority); return true; }
/// <summary> /// Posts event to all objects in the group. /// </summary> /// <param name="localID">Region object ID</param> /// <param name="FunctionName">Name of the function, will be state + "_event_" + FunctionName</param> /// <param name="VersionID">Version ID of the script. Note: If it is -1, the version ID will be detected automatically</param> /// <param name="param">Array of parameters to match event mask</param> public bool AddToObjectQueue(UUID partID, string FunctionName, DetectParams[] qParams, int VersionID, params object[] param) { // Determine all scripts in Object and add to their queue ScriptData[] datas = ScriptProtection.GetScripts(partID); if (datas == null) //No scripts to post to... so it is firing all the events it needs to return true; foreach (ScriptData ID in datas) { if (VersionID == -1) VersionID = ID.VersionID; // Add to each script in that object AddToScriptQueue(ID, FunctionName, qParams, VersionID, EventPriority.FirstStart, param); } return true; }
public void AddEventSchQueue(ScriptData ID, string FunctionName, DetectParams[] qParams, EventPriority priority, params object[] param) { QueueItemStruct QIS; if (ID == null || ID.Script == null || ID.IgnoreNew) return; if (!ID.SetEventParams(FunctionName, qParams)) // check events delay rules return; QIS = new QueueItemStruct(); QIS.EventsProcData = new ScriptEventsProcData (); QIS.ID = ID; QIS.functionName = FunctionName; QIS.llDetectParams = qParams; QIS.param = param; QIS.VersionID = Interlocked.Read(ref ID.VersionID); QIS.State = ID.State; QIS.CurrentlyAt = null; lock (ScriptEvents) { ScriptEvents.Enqueue (QIS); ScriptEventCount++; #if Debug m_log.Warn (ScriptEventCount + ", " + QIS.functionName); #endif } long threadCount = Interlocked.Read (ref scriptThreadpool.nthreads); if (threadCount == 0 || threadCount < (ScriptEventCount + (SleepingScriptEventCount / 2)) * EventPerformance) { scriptThreadpool.QueueEvent (eventLoop, 2); } }
public void touch(ISceneChildEntity part, ISceneChildEntity child, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>(); if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) det = new Dictionary<UUID, DetectParams>(); // Add to queue for all scripts in ObjectID object DetectParams detparam = new DetectParams(); detparam = new DetectParams { Key = remoteClient.AgentId, OffsetPos = new LSL_Types.Vector3(offsetPos.X, offsetPos.Y, offsetPos.Z) }; detparam.Populate(part.ParentEntity.Scene); detparam.LinkNum = child.LinkNum; if (surfaceArgs != null) detparam.SurfaceTouchArgs = surfaceArgs; det[remoteClient.AgentId] = detparam; CoalescedTouchEvents[part.LocalId] = det; ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) return; string functionName = "touch"; object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)}; #if (!ISWIN) foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) { m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), EventPriority.FirstStart, param); } } #else foreach (ScriptData ID in datas.Where(ID => CheckIfEventShouldFire(ID, functionName, param))) { m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), EventPriority.FirstStart, param); } #endif }
public void AddEventSchQueue(ScriptData ID, string FunctionName, DetectParams[] qParams, int VersionID, EventPriority priority, params object[] param) { QueueItemStruct QIS; if (ID == null || ID.EventsProcData.IgnoreNew) return; if (!ID.SetEventParams(FunctionName, qParams)) // check events delay rules return; QIS = new QueueItemStruct(); QIS.ID = ID; QIS.functionName = FunctionName; QIS.llDetectParams = qParams; QIS.param = param; QIS.VersionID = VersionID; QIS.State = ID.State; QIS.CurrentlyAt = null; lock (ID.EventsProcData) { ID.EventsProcDataLocked = true; if (ID.EventsProcData.EventsQueue.Count > 100) { ID.EventsProcDataLocked = false; return; } ID.EventsProcData.EventsQueue.Enqueue(QIS); lock (ScriptIDs) { if (!ScriptIDs.Contains(ID)) { ID.EventsProcData.State = (int)ScriptEventsState.Idle; ID.EventsProcData.thread = null; ScriptIDs.AddLast(ID); NScriptIDs++; ID.InEventsProcData = true; } } } ID.EventsProcDataLocked = false; lock (WorkersLock) { if (WorkersLock.nWorkers < MaxScriptThreads) { Scriptthreadpool.QueueEvent(loop, 2); } } }
/// <summary> /// Handles piping the proper stuff to The script engine for touching /// Including DetectedParams /// </summary> /// <param name="localID"></param> /// <param name="originalID"></param> /// <param name="offsetPos"></param> /// <param name="remoteClient"></param> /// <param name="surfaceArgs"></param> public void touch_start(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) { // Add to queue for all scripts in ObjectID object Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>(); if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det)) det = new Dictionary<UUID, DetectParams>(); DetectParams detparam = new DetectParams(); detparam.Key = remoteClient.AgentId; detparam.Populate(part.ParentGroup.Scene); detparam.LinkNum = part.LinkNum; if (surfaceArgs != null) { detparam.SurfaceTouchArgs = surfaceArgs; } det[remoteClient.AgentId] = detparam; CoalescedTouchEvents[part.LocalId] = det; ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) return; string functionName = "touch_start"; object[] param = new Object[] { new LSL_Types.LSLInteger(1) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(), ID.VersionID, EventPriority.FirstStart, param); } }
public void collision_start (ISceneChildEntity part, 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(part.ParentEntity.Scene); d.LinkNum = part.LinkNum; det.Add(d); } if (det.Count > 0) { ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); //if (datas == null || datas.Length == 0) return; } string functionName = "collision_start"; object[] param = new Object[] { new LSL_Types.LSLInteger(det.Count) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); } } }
public void land_collision_end (ISceneChildEntity part, ColliderArgs col) { List<DetectParams> det = new List<DetectParams>(); foreach (DetectedObject detobj in col.Colliders) { DetectParams d = new DetectParams(); d.Position = new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z); d.Key = detobj.keyUUID; d.Populate(part.ParentEntity.Scene); d.LinkNum = part.LinkNum; det.Add(d); } if (det.Count != 0) { ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID); if (datas == null || datas.Length == 0) { //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID); //if (datas == null || datas.Length == 0) return; } string functionName = "land_collision_end"; object[] param = new Object[] { new LSL_Types.Vector3(det[0].Position) }; foreach (ScriptData ID in datas) { if (CheckIfEventShouldFire(ID, functionName, param)) m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param); } } }
public bool SetEventParams(string functionName, DetectParams[] qParams) { if (qParams.Length > 0) LastDetectParams = qParams; if (functionName == "control") { //For vehicles, otherwise breaks them. DO NOT REMOVE UNLESS YOU FIND A BETTER WAY TO FIX return true; } long NowTicks = Environment.TickCount; if (EventDelayTicks != 0) { if (NowTicks < NextEventTimeTicks) return false; NextEventTimeTicks = NowTicks + EventDelayTicks; } switch (functionName) { //Times pulled from http://wiki.secondlife.com/wiki/LSL_Delay case "touch": //Limits for 0.1 seconds case "touch_start": case "touch_end": if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(TouchEventDelayTicks * 100); break; case "timer": //Settable timer limiter if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(TimerEventDelayTicks * 100); break; case "collision": //Collision limiters taken off of reporting from WhiteStar in mantis 0004513 case "collision_start": case "collision_end": case "land_collision": case "land_collision_start": case "land_collision_end": if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(CollisionEventDelayTicks * 100); break; default: //Default is 0.05 seconds for event limiting if (NowTicks < NextEventDelay[functionName]) return false; NextEventDelay[functionName] = NowTicks + (long)(DefaultEventDelayTicks * 100); break; } //Add the event to the stats part.ParentGroup.AddScriptEPS(1); return true; }