aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs275
1 files changed, 272 insertions, 3 deletions
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
index 33c6511..5013ab8 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
@@ -31,8 +31,11 @@ using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Threading; 32using System.Threading;
33using libsecondlife; 33using libsecondlife;
34using Axiom.Math;
34using OpenSim.Region.Environment.Interfaces; 35using OpenSim.Region.Environment.Interfaces;
35using OpenSim.Region.Environment.Modules; 36using OpenSim.Region.Environment.Modules;
37using OpenSim.Region.Environment.Scenes;
38using OpenSim.Framework;
36 39
37namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase 40namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
38{ 41{
@@ -46,6 +49,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
46 49
47 private ScriptEngine m_ScriptEngine; 50 private ScriptEngine m_ScriptEngine;
48 51
52 public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents =
53 new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>();
54 private Object SenseLock = new Object();
55
49 public AsyncLSLCommandManager(ScriptEngine _ScriptEngine) 56 public AsyncLSLCommandManager(ScriptEngine _ScriptEngine)
50 { 57 {
51 m_ScriptEngine = _ScriptEngine; 58 m_ScriptEngine = _ScriptEngine;
@@ -128,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
128 CheckXMLRPCRequests(); 135 CheckXMLRPCRequests();
129 // Check Listeners 136 // Check Listeners
130 CheckListeners(); 137 CheckListeners();
138 // Check Sensors
139 CheckSenseRepeaterEvents();
131 } 140 }
132 141
133 /// <summary> 142 /// <summary>
@@ -154,6 +163,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
154 163
155 xmlrpc.CancelSRDRequests(itemID); 164 xmlrpc.CancelSRDRequests(itemID);
156 165
166 // Remove Sensors
167 UnSetSenseRepeaterEvents(localID, itemID);
168
157 } 169 }
158 170
159 #region TIMER 171 #region TIMER
@@ -253,6 +265,262 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
253 } 265 }
254 266
255 #endregion 267 #endregion
268 #region SENSOR
269
270 //
271 // SenseRepeater and Sensors
272 //
273 private class SenseRepeatClass
274 {
275 public uint localID;
276 public LLUUID itemID;
277 public double interval;
278 public DateTime next;
279
280 public string name;
281 public LLUUID keyID;
282 public int type;
283 public double range;
284 public double arc;
285 public SceneObjectPart host;
286 }
287
288 private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
289 private object SenseRepeatListLock = new object();
290
291 public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID,
292 string name, LLUUID keyID, int type, double range, double arc, double sec,SceneObjectPart host)
293 {
294 Console.WriteLine("SetSensorEvent");
295
296 // Always remove first, in case this is a re-set
297 UnSetSenseRepeaterEvents(m_localID, m_itemID);
298 if (sec == 0) // Disabling timer
299 return;
300
301 // Add to timer
302 SenseRepeatClass ts = new SenseRepeatClass();
303 ts.localID = m_localID;
304 ts.itemID = m_itemID;
305 ts.interval = sec;
306 ts.name = name;
307 ts.keyID = keyID;
308 ts.type = type;
309 ts.range = range;
310 ts.arc = arc;
311 ts.host = host;
312
313 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
314 lock (SenseRepeatListLock)
315 {
316 SenseRepeaters.Add(ts);
317 }
318 }
319
320 public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID)
321 {
322 // Remove from timer
323 lock (SenseRepeatListLock)
324 {
325 List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
326 foreach (SenseRepeatClass ts in SenseRepeaters)
327 {
328 if (ts.localID != m_localID && ts.itemID != m_itemID)
329 {
330 NewSensors.Add(ts);
331 }
332 }
333 SenseRepeaters.Clear();
334 SenseRepeaters = NewSensors;
335 }
336 }
337
338 public void CheckSenseRepeaterEvents()
339 {
340 // Nothing to do here?
341 if (SenseRepeaters.Count == 0)
342 return;
343
344 lock (SenseRepeatListLock)
345 {
346 // Go through all timers
347 foreach (SenseRepeatClass ts in SenseRepeaters)
348 {
349 // Time has passed?
350 if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
351 {
352 SensorSweep(ts);
353 // set next interval
354 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
355 }
356 }
357 } // lock
358 }
359
360 public void SenseOnce(uint m_localID, LLUUID m_itemID,
361 string name, LLUUID keyID, int type, double range, double arc, SceneObjectPart host)
362 {
363 // Add to timer
364 SenseRepeatClass ts = new SenseRepeatClass();
365 ts.localID = m_localID;
366 ts.itemID = m_itemID;
367 ts.interval = 0;
368 ts.name = name;
369 ts.keyID = keyID;
370 ts.type = type;
371 ts.range = range;
372 ts.arc = arc;
373 ts.host = host;
374 SensorSweep(ts);
375 }
376
377 public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID)
378 {
379 lock (SenseLock)
380 {
381 Dictionary<LLUUID, LSL_Types.list> Obj = null;
382 if (!SenseEvents.TryGetValue(m_localID, out Obj))
383 {
384 m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing localID: " + m_localID);
385 return null;
386 }
387 lock (Obj)
388 {
389 // Get script
390 LSL_Types.list SenseList = null;
391 if (!Obj.TryGetValue(m_itemID, out SenseList))
392 {
393 m_ScriptEngine.Log.Info("[AsyncLSL]: GetSensorList missing itemID: " + m_itemID);
394 return null;
395 }
396 return SenseList;
397 }
398 }
399
400 }
401
402 private void SensorSweep(SenseRepeatClass ts)
403 {
404 //m_ScriptEngine.Log.Info("[AsyncLSL]:Enter SensorSweep");
405 SceneObjectPart SensePoint =ts.host;
406
407 if (SensePoint == null)
408 {
409 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep (SensePoint == null) for "+ts.itemID.ToString());
410 return;
411 }
412 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep Scan");
413
414 LLVector3 sensorPos = SensePoint.AbsolutePosition;
415 LLVector3 regionPos = new LLVector3(m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
416 LLVector3 fromRegionPos = sensorPos + regionPos;
417
418 LLQuaternion q = SensePoint.RotationOffset;
419 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
420 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
421 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
422
423 // Here we should do some smart culling ...
424 // math seems quicker than strings so try that first
425 LSL_Types.list SensedObjects = new LSL_Types.list();
426 LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0);
427
428 foreach (EntityBase ent in m_ScriptEngine.World.Entities.Values)
429 {
430
431 LLVector3 toRegionPos = ent.AbsolutePosition + regionPos;
432 double dis = Math.Abs((double) Util.GetDistanceTo(toRegionPos, fromRegionPos));
433 if (dis <= ts.range)
434 {
435 // In Range, is it the right Type ?
436 int objtype = 0;
437
438 if (m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor
439 if (ent.Velocity.Equals(ZeroVector))
440 objtype |= 0x04; // passive non-moving
441 else
442 objtype |= 0x02; // active moving
443 if (ent is IScript) objtype |= 0x08; // Scripted. It COULD have one hidden ...
444
445 if ( ((ts.type & objtype) != 0 ) ||((ts.type & objtype) == ts.type ))
446 {
447 // docs claim AGENT|ACTIVE should find agent objects OR active objects
448 // so the bitwise AND with object type should be non-zero
449
450 // Right type too, what about the other params , key and name ?
451 bool keep = true;
452 if (ts.arc != Math.PI)
453 {
454 // not omni-directional. Can you see it ?
455 // vec forward_dir = llRot2Fwd(llGetRot())
456 // vec obj_dir = toRegionPos-fromRegionPos
457 // dot=dot(forward_dir,obj_dir)
458 // mag_fwd = mag(forward_dir)
459 // mag_obj = mag(obj_dir)
460 // ang = acos( dot /(mag_fwd*mag_obj))
461 double ang_obj = 0;
462 try
463 {
464 LLVector3 diff =toRegionPos - fromRegionPos;
465 LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
466 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
467 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
468 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
469 }
470 catch
471 {
472 }
473
474 if (ang_obj > ts.arc) keep = false;
475 }
476
477 if (keep && (ts.name.Length > 0) && (ts.name != ent.Name))
478 {
479 keep = false;
480 }
481
482 if (keep && (ts.keyID != null) && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID))
483 {
484 keep = false;
485 }
486 if (keep==true) SensedObjects.Add(ent.UUID);
487 }
488 }
489 }
490 //m_ScriptEngine.Log.Info("[AsyncLSL]: Enter SensorSweep SenseLock");
491
492 lock (SenseLock)
493 {
494 // Create object if it doesn't exist
495 if (SenseEvents.ContainsKey(ts.localID) == false)
496 {
497 SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>());
498 }
499 // clear if previous traces exist
500 Dictionary<LLUUID, LSL_Types.list> Obj;
501 SenseEvents.TryGetValue(ts.localID, out Obj);
502 if (Obj.ContainsKey(ts.itemID) == true)
503 Obj.Remove(ts.itemID);
504
505 // note list may be zero length
506 Obj.Add(ts.itemID, SensedObjects);
507
508 if (SensedObjects.Length == 0)
509 {
510 // send a "no_sensor"
511 // Add it to queue
512 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "no_sensor", EventQueueManager.llDetectNull,
513 new object[] {});
514 }
515 else
516 {
517
518 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(ts.localID, ts.itemID, "sensor", EventQueueManager.llDetectNull,
519 new object[] { SensedObjects.Length });
520 }
521 }
522 }
523 #endregion
256 524
257 #region HTTP REQUEST 525 #region HTTP REQUEST
258 526
@@ -271,7 +539,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
271 539
272 while (httpInfo != null) 540 while (httpInfo != null)
273 { 541 {
274 //Console.WriteLine("PICKED HTTP REQ:" + httpInfo.response_body + httpInfo.status); 542 //m_ScriptEngine.Log.Info("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
275 543
276 // Deliver data to prim's remote_data handler 544 // Deliver data to prim's remote_data handler
277 // 545 //
@@ -291,7 +559,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
291 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 559 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
292 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj 560 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
293 ); 561 );
294 562 //Thread.Sleep(2500);
295 } 563 }
296 564
297 httpInfo = iHttpReq.GetNextCompletedRequest(); 565 httpInfo = iHttpReq.GetNextCompletedRequest();
@@ -381,7 +649,8 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
381 //Deliver data to prim's listen handler 649 //Deliver data to prim's listen handler
382 object[] resobj = new object[] 650 object[] resobj = new object[]
383 { 651 {
384 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() 652 //lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
653 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetSourceItemID().ToString(), lInfo.GetMessage()
385 }; 654 };
386 655
387 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 656 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(