/Aurora/AuroraDotNetEngine/EventManager.cs

https://bitbucket.org/VirtualReality/software-testing · C# · 1096 lines · 854 code · 115 blank · 127 comment · 206 complexity · 1ac814aedd96c3964977b1323e7ededd MD5 · raw file

  1. /*
  2. * Copyright (c) Contributors, http://aurora-sim.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the Aurora-Sim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using Aurora.Framework;
  28. using Aurora.Framework.ClientInterfaces;
  29. using Aurora.Framework.ConsoleFramework;
  30. using Aurora.Framework.Modules;
  31. using Aurora.Framework.PresenceInfo;
  32. using Aurora.Framework.SceneInfo;
  33. using Aurora.Framework.SceneInfo.Entities;
  34. using Aurora.Framework.Utilities;
  35. using OpenMetaverse;
  36. using System;
  37. using System.Collections.Generic;
  38. using System.Linq;
  39. namespace Aurora.ScriptEngine.AuroraDotNetEngine
  40. {
  41. /// <summary>
  42. /// Prepares events so they can be directly executed upon a script by EventQueueManager, then queues it.
  43. /// </summary>
  44. public class EventManager
  45. {
  46. //
  47. // This class it the link between an event inside OpenSim and
  48. // the corresponding event in a user script being executed.
  49. //
  50. // For example when an user touches an object then the
  51. // "scene.EventManager.OnObjectGrab" event is fired
  52. // inside OpenSim.
  53. // We hook up to this event and queue a touch_start in
  54. // the event queue with the proper LSL parameters.
  55. //
  56. // You can check debug C# dump of an LSL script if you need to
  57. // verify what exact parameters are needed.
  58. //
  59. private readonly Dictionary<uint, Dictionary<UUID, DetectParams>> CoalescedTouchEvents =
  60. new Dictionary<uint, Dictionary<UUID, DetectParams>>();
  61. private readonly ScriptEngine m_scriptEngine;
  62. public EventManager(ScriptEngine _ScriptEngine)
  63. {
  64. m_scriptEngine = _ScriptEngine;
  65. }
  66. public void HookUpRegionEvents(IScene Scene)
  67. {
  68. //MainConsole.Instance.Info("[" + myScriptEngine.ScriptEngineName +
  69. // "]: Hooking up to server events");
  70. Scene.EventManager.OnObjectGrab +=
  71. touch_start;
  72. Scene.EventManager.OnObjectGrabbing +=
  73. touch;
  74. Scene.EventManager.OnObjectDeGrab +=
  75. touch_end;
  76. Scene.EventManager.OnScriptChangedEvent +=
  77. changed;
  78. Scene.EventManager.OnScriptAtTargetEvent +=
  79. at_target;
  80. Scene.EventManager.OnScriptNotAtTargetEvent +=
  81. not_at_target;
  82. Scene.EventManager.OnScriptAtRotTargetEvent +=
  83. at_rot_target;
  84. Scene.EventManager.OnScriptNotAtRotTargetEvent +=
  85. not_at_rot_target;
  86. Scene.EventManager.OnScriptControlEvent +=
  87. control;
  88. Scene.EventManager.OnScriptColliderStart +=
  89. collision_start;
  90. Scene.EventManager.OnScriptColliding +=
  91. collision;
  92. Scene.EventManager.OnScriptCollidingEnd +=
  93. collision_end;
  94. Scene.EventManager.OnScriptLandColliderStart +=
  95. land_collision_start;
  96. Scene.EventManager.OnScriptLandColliding +=
  97. land_collision;
  98. Scene.EventManager.OnScriptLandColliderEnd +=
  99. land_collision_end;
  100. Scene.EventManager.OnAttach += attach;
  101. Scene.EventManager.OnScriptMovingStartEvent += moving_start;
  102. Scene.EventManager.OnScriptMovingEndEvent += moving_end;
  103. Scene.EventManager.OnRezScripts += rez_scripts;
  104. IMoneyModule money =
  105. Scene.RequestModuleInterface<IMoneyModule>();
  106. if (money != null)
  107. {
  108. money.OnObjectPaid += HandleObjectPaid;
  109. money.OnPostObjectPaid += HandlePostObjectPaid;
  110. }
  111. }
  112. //private void HandleObjectPaid(UUID objectID, UUID agentID, int amount)
  113. private bool HandleObjectPaid(UUID objectID, UUID agentID, int amount)
  114. {
  115. //bool ret = false;
  116. //ISceneChildEntity part = m_scriptEngine.findPrim(objectID);
  117. //if (part == null)
  118. // return;
  119. //MainConsole.Instance.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount);
  120. //if (part.ParentGroup != null)
  121. // part = part.ParentGroup.RootPart;
  122. //if (part != null)
  123. //{
  124. // money(part.LocalId, agentID, amount);
  125. //}
  126. //if (part != null)
  127. //{
  128. // MainConsole.Instance.Debug("Paid: " + objectID + " from " + agentID + ", amount " + amount);
  129. // if (part.ParentEntity != null) part = part.ParentEntity.RootChild;
  130. // if (part != null)
  131. // {
  132. // ret = money(part.LocalId, agentID, amount);
  133. // }
  134. //}
  135. //return ret;
  136. return true;
  137. }
  138. private bool HandlePostObjectPaid(uint localID, ulong regionHandle, UUID agentID, int amount)
  139. {
  140. return money(localID, agentID, amount);
  141. }
  142. public void changed(ISceneChildEntity part, uint change)
  143. {
  144. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  145. if (datas == null || datas.Length == 0)
  146. {
  147. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID);
  148. if (datas == null || datas.Length == 0)
  149. return;
  150. }
  151. string functionName = "changed";
  152. object[] param = new Object[] {new LSL_Types.LSLInteger(change)};
  153. foreach (ScriptData ID in datas)
  154. {
  155. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  156. param);
  157. }
  158. }
  159. /// <summary>
  160. /// Handles piping the proper stuff to The script engine for touching
  161. /// Including DetectedParams
  162. /// </summary>
  163. /// <param name="part"></param>
  164. /// <param name="child"></param>
  165. /// <param name="offsetPos"></param>
  166. /// <param name="remoteClient"></param>
  167. /// <param name="surfaceArgs"></param>
  168. public void touch_start(ISceneChildEntity part, ISceneChildEntity child, Vector3 offsetPos,
  169. IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
  170. {
  171. // Add to queue for all scripts in ObjectID object
  172. Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>();
  173. if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det))
  174. det = new Dictionary<UUID, DetectParams>();
  175. DetectParams detparam = new DetectParams {Key = remoteClient.AgentId};
  176. detparam.Populate(part.ParentEntity.Scene);
  177. detparam.LinkNum = child.LinkNum;
  178. if (surfaceArgs != null)
  179. {
  180. detparam.SurfaceTouchArgs = surfaceArgs;
  181. }
  182. det[remoteClient.AgentId] = detparam;
  183. CoalescedTouchEvents[part.LocalId] = det;
  184. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  185. if (datas == null || datas.Length == 0)
  186. return;
  187. string functionName = "touch_start";
  188. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  189. foreach (ScriptData ID in datas)
  190. {
  191. m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(),
  192. EventPriority.FirstStart, param);
  193. }
  194. }
  195. public void touch(ISceneChildEntity part, ISceneChildEntity child, Vector3 offsetPos,
  196. IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs)
  197. {
  198. Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>();
  199. if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det))
  200. det = new Dictionary<UUID, DetectParams>();
  201. // Add to queue for all scripts in ObjectID object
  202. DetectParams detparam = new DetectParams();
  203. detparam = new DetectParams
  204. {
  205. Key = remoteClient.AgentId,
  206. OffsetPos = new LSL_Types.Vector3(offsetPos.X,
  207. offsetPos.Y,
  208. offsetPos.Z)
  209. };
  210. detparam.Populate(part.ParentEntity.Scene);
  211. detparam.LinkNum = child.LinkNum;
  212. if (surfaceArgs != null)
  213. detparam.SurfaceTouchArgs = surfaceArgs;
  214. det[remoteClient.AgentId] = detparam;
  215. CoalescedTouchEvents[part.LocalId] = det;
  216. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  217. if (datas == null || datas.Length == 0)
  218. return;
  219. string functionName = "touch";
  220. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  221. foreach (ScriptData ID in datas)
  222. {
  223. m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(),
  224. EventPriority.FirstStart, param);
  225. }
  226. }
  227. public void touch_end(ISceneChildEntity part, ISceneChildEntity child, IClientAPI remoteClient,
  228. SurfaceTouchEventArgs surfaceArgs)
  229. {
  230. Dictionary<UUID, DetectParams> det = new Dictionary<UUID, DetectParams>();
  231. if (!CoalescedTouchEvents.TryGetValue(part.LocalId, out det))
  232. det = new Dictionary<UUID, DetectParams>();
  233. // Add to queue for all scripts in ObjectID object
  234. DetectParams detparam = new DetectParams();
  235. detparam = new DetectParams {Key = remoteClient.AgentId};
  236. detparam.Populate(part.ParentEntity.Scene);
  237. detparam.LinkNum = child.LinkNum;
  238. if (surfaceArgs != null)
  239. detparam.SurfaceTouchArgs = surfaceArgs;
  240. det[remoteClient.AgentId] = detparam;
  241. CoalescedTouchEvents[part.LocalId] = det;
  242. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  243. if (datas == null || datas.Length == 0)
  244. return;
  245. string functionName = "touch_end";
  246. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  247. foreach (ScriptData ID in datas)
  248. {
  249. m_scriptEngine.AddToScriptQueue(ID, functionName, new List<DetectParams>(det.Values).ToArray(),
  250. EventPriority.FirstStart, param);
  251. }
  252. //Remove us from the det param list
  253. det.Remove(remoteClient.AgentId);
  254. CoalescedTouchEvents[part.LocalId] = det;
  255. }
  256. //public void money(uint localID, UUID agentID, int amount)
  257. public bool money(uint localID, UUID agentID, int amount)
  258. {
  259. bool ret = false;
  260. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  261. if (part == null) return ret;
  262. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  263. if (datas == null || datas.Length == 0)
  264. {
  265. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  266. if (datas == null || datas.Length == 0) return ret;
  267. }
  268. string functionName = "money";
  269. object[] param = new object[]
  270. {
  271. new LSL_Types.LSLString(agentID.ToString()),
  272. new LSL_Types.LSLInteger(amount)
  273. };
  274. foreach (ScriptData ID in datas)
  275. {
  276. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  277. param);
  278. ret = true;
  279. }
  280. return ret;
  281. }
  282. public void collision_start(ISceneChildEntity part, ColliderArgs col)
  283. {
  284. // Add to queue for all scripts in ObjectID object
  285. List<DetectParams> det = new List<DetectParams>();
  286. #if (!ISWIN)
  287. foreach (DetectedObject detobj in col.Colliders)
  288. {
  289. DetectParams d = new DetectParams { Key = detobj.keyUUID };
  290. d.Populate(part.ParentEntity.Scene);
  291. d.LinkNum = part.LinkNum;
  292. det.Add(d);
  293. }
  294. #else
  295. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID}))
  296. {
  297. d.Populate(part.ParentEntity.Scene);
  298. d.LinkNum = part.LinkNum;
  299. det.Add(d);
  300. }
  301. #endif
  302. if (det.Count > 0)
  303. {
  304. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  305. if (datas == null || datas.Length == 0)
  306. {
  307. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  308. //if (datas == null || datas.Length == 0)
  309. return;
  310. }
  311. string functionName = "collision_start";
  312. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  313. foreach (ScriptData ID in datas)
  314. {
  315. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  316. }
  317. }
  318. }
  319. public void collision(ISceneChildEntity part, ColliderArgs col)
  320. {
  321. // Add to queue for all scripts in ObjectID object
  322. List<DetectParams> det = new List<DetectParams>();
  323. #if (!ISWIN)
  324. foreach (DetectedObject detobj in col.Colliders)
  325. {
  326. DetectParams d = new DetectParams { Key = detobj.keyUUID };
  327. d.Populate(part.ParentEntity.Scene);
  328. d.LinkNum = part.LinkNum;
  329. det.Add(d);
  330. }
  331. #else
  332. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID}))
  333. {
  334. d.Populate(part.ParentEntity.Scene);
  335. d.LinkNum = part.LinkNum;
  336. det.Add(d);
  337. }
  338. #endif
  339. if (det.Count > 0)
  340. {
  341. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  342. if (datas == null || datas.Length == 0)
  343. {
  344. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  345. //if (datas == null || datas.Length == 0)
  346. return;
  347. }
  348. string functionName = "collision";
  349. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  350. foreach (ScriptData ID in datas)
  351. {
  352. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  353. }
  354. }
  355. }
  356. public void collision_end(ISceneChildEntity part, ColliderArgs col)
  357. {
  358. // Add to queue for all scripts in ObjectID object
  359. List<DetectParams> det = new List<DetectParams>();
  360. #if (!ISWIN)
  361. foreach (DetectedObject detobj in col.Colliders)
  362. {
  363. DetectParams d = new DetectParams { Key = detobj.keyUUID };
  364. d.Populate(part.ParentEntity.Scene);
  365. d.LinkNum = part.LinkNum;
  366. det.Add(d);
  367. }
  368. #else
  369. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID}))
  370. {
  371. d.Populate(part.ParentEntity.Scene);
  372. d.LinkNum = part.LinkNum;
  373. det.Add(d);
  374. }
  375. #endif
  376. if (det.Count > 0)
  377. {
  378. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  379. if (datas == null || datas.Length == 0)
  380. {
  381. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  382. //if (datas == null || datas.Length == 0)
  383. return;
  384. }
  385. string functionName = "collision_end";
  386. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  387. foreach (ScriptData ID in datas)
  388. {
  389. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  390. }
  391. }
  392. }
  393. public void land_collision_start(ISceneChildEntity part, ColliderArgs col)
  394. {
  395. List<DetectParams> det = new List<DetectParams>();
  396. #if (!ISWIN)
  397. foreach (DetectedObject detobj in col.Colliders)
  398. {
  399. DetectParams d = new DetectParams
  400. {
  401. Position =
  402. new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y,
  403. detobj.posVector.Z),
  404. Key = detobj.keyUUID
  405. };
  406. d.Populate(part.ParentEntity.Scene);
  407. d.LinkNum = part.LinkNum;
  408. det.Add(d);
  409. }
  410. #else
  411. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams
  412. {
  413. Position =
  414. new LSL_Types.Vector3(
  415. detobj.posVector.X,
  416. detobj.posVector.Y,
  417. detobj.posVector.Z),
  418. Key = detobj.keyUUID
  419. }))
  420. {
  421. d.Populate(part.ParentEntity.Scene);
  422. d.LinkNum = part.LinkNum;
  423. det.Add(d);
  424. }
  425. #endif
  426. if (det.Count != 0)
  427. {
  428. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  429. if (datas == null || datas.Length == 0)
  430. {
  431. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  432. //if (datas == null || datas.Length == 0)
  433. return;
  434. }
  435. string functionName = "land_collision_start";
  436. object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)};
  437. foreach (ScriptData ID in datas)
  438. {
  439. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  440. }
  441. }
  442. }
  443. public void land_collision(ISceneChildEntity part, ColliderArgs col)
  444. {
  445. List<DetectParams> det = new List<DetectParams>();
  446. #if (!ISWIN)
  447. foreach (DetectedObject detobj in col.Colliders)
  448. {
  449. DetectParams d = new DetectParams
  450. {
  451. Position = new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z),
  452. Key = detobj.keyUUID
  453. };
  454. d.Populate(part.ParentEntity.Scene);
  455. d.LinkNum = part.LinkNum;
  456. det.Add(d);
  457. }
  458. #else
  459. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams
  460. {
  461. Position =
  462. new LSL_Types.Vector3(
  463. detobj.posVector.X,
  464. detobj.posVector.Y,
  465. detobj.posVector.Z),
  466. Key = detobj.keyUUID
  467. }))
  468. {
  469. d.Populate(part.ParentEntity.Scene);
  470. d.LinkNum = part.LinkNum;
  471. det.Add(d);
  472. }
  473. #endif
  474. if (det.Count != 0)
  475. {
  476. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  477. if (datas == null || datas.Length == 0)
  478. {
  479. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  480. //if (datas == null || datas.Length == 0)
  481. return;
  482. }
  483. string functionName = "land_collision";
  484. object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)};
  485. foreach (ScriptData ID in datas)
  486. {
  487. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  488. }
  489. }
  490. }
  491. public void land_collision_end(ISceneChildEntity part, ColliderArgs col)
  492. {
  493. List<DetectParams> det = new List<DetectParams>();
  494. #if (!ISWIN)
  495. foreach (DetectedObject detobj in col.Colliders)
  496. {
  497. DetectParams d = new DetectParams
  498. {
  499. Position = new LSL_Types.Vector3(detobj.posVector.X, detobj.posVector.Y, detobj.posVector.Z),
  500. Key = detobj.keyUUID
  501. };
  502. d.Populate(part.ParentEntity.Scene);
  503. d.LinkNum = part.LinkNum;
  504. det.Add(d);
  505. }
  506. #else
  507. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams
  508. {
  509. Position =
  510. new LSL_Types.Vector3(
  511. detobj.posVector.X,
  512. detobj.posVector.Y,
  513. detobj.posVector.Z),
  514. Key = detobj.keyUUID
  515. }))
  516. {
  517. d.Populate(part.ParentEntity.Scene);
  518. d.LinkNum = part.LinkNum;
  519. det.Add(d);
  520. }
  521. #endif
  522. if (det.Count != 0)
  523. {
  524. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  525. if (datas == null || datas.Length == 0)
  526. {
  527. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  528. //if (datas == null || datas.Length == 0)
  529. return;
  530. }
  531. string functionName = "land_collision_end";
  532. object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)};
  533. foreach (ScriptData ID in datas)
  534. {
  535. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  536. }
  537. }
  538. }
  539. public void control(ISceneChildEntity part, UUID itemID, UUID agentID, uint held, uint change)
  540. {
  541. if (part == null)
  542. return;
  543. ScriptData ID = ScriptEngine.ScriptProtection.GetScript(part.UUID, itemID);
  544. if (ID == null)
  545. return;
  546. string functionName = "control";
  547. object[] param = new object[]
  548. {
  549. new LSL_Types.LSLString(agentID.ToString()),
  550. new LSL_Types.LSLInteger(held),
  551. new LSL_Types.LSLInteger(change)
  552. };
  553. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, param);
  554. }
  555. public void email(uint localID, UUID itemID, string timeSent,
  556. string address, string subject, string message, int numLeft)
  557. {
  558. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  559. if (part == null)
  560. return;
  561. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  562. if (datas == null || datas.Length == 0)
  563. {
  564. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  565. if (datas == null || datas.Length == 0)
  566. return;
  567. }
  568. string functionName = "email";
  569. object[] param = new object[]
  570. {
  571. new LSL_Types.LSLString(timeSent),
  572. new LSL_Types.LSLString(address),
  573. new LSL_Types.LSLString(subject),
  574. new LSL_Types.LSLString(message),
  575. new LSL_Types.LSLInteger(numLeft)
  576. };
  577. foreach (ScriptData ID in datas)
  578. {
  579. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  580. param);
  581. }
  582. }
  583. public void at_target(uint localID, uint handle, Vector3 targetpos,
  584. Vector3 atpos)
  585. {
  586. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  587. if (part == null)
  588. return;
  589. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  590. if (datas == null || datas.Length == 0)
  591. {
  592. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  593. if (datas == null || datas.Length == 0)
  594. return;
  595. }
  596. string functionName = "at_target";
  597. object[] param = new object[]
  598. {
  599. new LSL_Types.LSLInteger(handle),
  600. new LSL_Types.Vector3(targetpos.X, targetpos.Y, targetpos.Z),
  601. new LSL_Types.Vector3(atpos.X, atpos.Y, atpos.Z)
  602. };
  603. foreach (ScriptData ID in datas)
  604. {
  605. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  606. param);
  607. }
  608. }
  609. public void not_at_target(uint localID)
  610. {
  611. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  612. if (part == null)
  613. return;
  614. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  615. if (datas == null || datas.Length == 0)
  616. {
  617. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  618. if (datas == null || datas.Length == 0)
  619. return;
  620. }
  621. string functionName = "not_at_target";
  622. object[] param = new object[0];
  623. foreach (ScriptData ID in datas)
  624. {
  625. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  626. param);
  627. }
  628. }
  629. public void at_rot_target(uint localID, uint handle, Quaternion targetrot,
  630. Quaternion atrot)
  631. {
  632. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  633. if (part == null)
  634. return;
  635. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  636. if (datas == null || datas.Length == 0)
  637. {
  638. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  639. if (datas == null || datas.Length == 0)
  640. return;
  641. }
  642. string functionName = "at_rot_target";
  643. object[] param = new object[]
  644. {
  645. new LSL_Types.LSLInteger(handle),
  646. new LSL_Types.Quaternion(targetrot.X, targetrot.Y, targetrot.Z, targetrot.W),
  647. new LSL_Types.Quaternion(atrot.X, atrot.Y, atrot.Z, atrot.W)
  648. };
  649. foreach (ScriptData ID in datas)
  650. {
  651. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  652. param);
  653. }
  654. }
  655. public void not_at_rot_target(uint localID)
  656. {
  657. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  658. if (part == null)
  659. return;
  660. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  661. if (datas == null || datas.Length == 0)
  662. {
  663. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  664. if (datas == null || datas.Length == 0)
  665. return;
  666. }
  667. string functionName = "not_at_rot_target";
  668. object[] param = new object[0];
  669. foreach (ScriptData ID in datas)
  670. {
  671. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  672. param);
  673. }
  674. }
  675. public void attach(uint localID, UUID itemID, UUID avatar)
  676. {
  677. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  678. if (part == null)
  679. return;
  680. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  681. if (datas == null || datas.Length == 0)
  682. {
  683. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  684. if (datas == null || datas.Length == 0)
  685. return;
  686. }
  687. string functionName = "attach";
  688. object[] param = new object[]
  689. {
  690. new LSL_Types.LSLString(avatar.ToString())
  691. };
  692. foreach (ScriptData ID in datas)
  693. {
  694. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  695. param);
  696. }
  697. }
  698. public void moving_start(ISceneChildEntity part)
  699. {
  700. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  701. if (datas == null || datas.Length == 0)
  702. {
  703. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID);
  704. if (datas == null || datas.Length == 0)
  705. return;
  706. }
  707. string functionName = "moving_start";
  708. object[] param = new object[0];
  709. foreach (ScriptData ID in datas)
  710. {
  711. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  712. param);
  713. }
  714. }
  715. public void moving_end(ISceneChildEntity part)
  716. {
  717. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  718. if (datas == null || datas.Length == 0)
  719. {
  720. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID);
  721. if (datas == null || datas.Length == 0)
  722. return;
  723. }
  724. string functionName = "moving_end";
  725. object[] param = new object[0];
  726. foreach (ScriptData ID in datas)
  727. {
  728. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  729. param);
  730. }
  731. }
  732. /// <summary>
  733. /// Start multiple scripts in the object
  734. /// </summary>
  735. /// <param name="part"></param>
  736. /// <param name="items"></param>
  737. /// <param name="startParam"></param>
  738. /// <param name="postOnRez"></param>
  739. /// <param name="stateSource"></param>
  740. /// <param name="rezzedFrom"></param>
  741. /// <param name="clearStateSaves"></param>
  742. public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items,
  743. int startParam, bool postOnRez, StateSource stateSource, UUID rezzedFrom,
  744. bool clearStateSaves)
  745. {
  746. #if (!ISWIN)
  747. List<LUStruct> ItemsToStart = new List<LUStruct>();
  748. foreach (TaskInventoryItem item in items)
  749. {
  750. LUStruct itemToQueue = m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom, clearStateSaves);
  751. if (itemToQueue.Action != LUType.Unknown) ItemsToStart.Add(itemToQueue);
  752. }
  753. #else
  754. List<LUStruct> ItemsToStart =
  755. items.Select(
  756. item =>
  757. m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom,
  758. clearStateSaves))
  759. .Where(itemToQueue => itemToQueue.Action != LUType.Unknown)
  760. .ToList();
  761. #endif
  762. if (ItemsToStart.Count != 0)
  763. m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray(), LoadPriority.FirstStart);
  764. }
  765. /// <summary>
  766. /// This checks the minimum amount of time between script firings as well as control events, making sure that events do NOT fire after scripts reset, close or restart, etc
  767. /// </summary>
  768. /// <param name="ID"></param>
  769. /// <param name="FunctionName"></param>
  770. /// <param name="param"></param>
  771. /// <returns></returns>
  772. public bool CheckIfEventShouldFire(ScriptData ID, string FunctionName, object[] param)
  773. {
  774. lock (ID.ScriptEventLock)
  775. {
  776. if (ID.Loading)
  777. {
  778. //If the script is loading, enqueue all events
  779. return true;
  780. }
  781. //This will happen if the script doesn't compile correctly
  782. if (ID.Script == null)
  783. {
  784. MainConsole.Instance.Info("[AuroraDotNetEngine]: Could not load script from item '" +
  785. ID.InventoryItem.Name +
  786. "' to fire event " + FunctionName);
  787. return false;
  788. }
  789. scriptEvents eventType = (scriptEvents) Enum.Parse(typeof (scriptEvents), FunctionName);
  790. // this must be done even if there is no event method
  791. if (eventType == scriptEvents.touch_start)
  792. ID.RemoveTouchEvents = false;
  793. else if (eventType == scriptEvents.collision_start)
  794. ID.RemoveCollisionEvents = false;
  795. else if (eventType == scriptEvents.land_collision_start)
  796. ID.RemoveLandCollisionEvents = false;
  797. if (eventType == scriptEvents.state_entry)
  798. ID.ResetEvents();
  799. if ((ID.Script.GetStateEventFlags(ID.State) & (long) eventType) == 0)
  800. return false; //If the script doesn't contain the state, don't even bother queueing it
  801. //Make sure we can execute events at position
  802. if (!m_scriptEngine.PipeEventsForScript(ID.Part))
  803. return false;
  804. switch (eventType)
  805. {
  806. case scriptEvents.timer:
  807. if (ID.TimerInQueue)
  808. return false;
  809. ID.TimerInQueue = true;
  810. break;
  811. case scriptEvents.sensor:
  812. if (ID.SensorInQueue)
  813. return false;
  814. ID.SensorInQueue = true;
  815. break;
  816. case scriptEvents.no_sensor:
  817. if (ID.NoSensorInQueue)
  818. return false;
  819. ID.NoSensorInQueue = true;
  820. break;
  821. case scriptEvents.at_target:
  822. if (ID.AtTargetInQueue)
  823. return false;
  824. ID.AtTargetInQueue = true;
  825. break;
  826. case scriptEvents.not_at_target:
  827. if (ID.NotAtTargetInQueue)
  828. return false;
  829. ID.NotAtTargetInQueue = true;
  830. break;
  831. case scriptEvents.at_rot_target:
  832. if (ID.AtRotTargetInQueue)
  833. return false;
  834. ID.AtRotTargetInQueue = true;
  835. break;
  836. case scriptEvents.not_at_rot_target:
  837. if (ID.NotAtRotTargetInQueue)
  838. return false;
  839. ID.NotAtRotTargetInQueue = true;
  840. break;
  841. case scriptEvents.control:
  842. int held = ((LSL_Types.LSLInteger) param[1]).value;
  843. // int changed = ((LSL_Types.LSLInteger)data.Params[2]).value;
  844. // If the last message was a 0 (nothing held)
  845. // and this one is also nothing held, drop it
  846. //
  847. if (ID.LastControlLevel == held && held == 0)
  848. return true;
  849. // If there is one or more queued, then queue
  850. // only changed ones, else queue unconditionally
  851. //
  852. if (ID.ControlEventsInQueue > 0)
  853. {
  854. if (ID.LastControlLevel == held)
  855. return false;
  856. }
  857. break;
  858. case scriptEvents.collision:
  859. if (ID.CollisionInQueue || ID.RemoveCollisionEvents)
  860. return false;
  861. ID.CollisionInQueue = true;
  862. break;
  863. case scriptEvents.moving_start:
  864. if (ID.MovingInQueue) //Block all other moving_starts until moving_end is called
  865. return false;
  866. ID.MovingInQueue = true;
  867. break;
  868. case scriptEvents.moving_end:
  869. if (!ID.MovingInQueue) //If we get a moving_end after we have sent one event, don't fire another
  870. return false;
  871. break;
  872. case scriptEvents.collision_end:
  873. if (ID.RemoveCollisionEvents)
  874. return false;
  875. break;
  876. case scriptEvents.touch:
  877. if (ID.TouchInQueue || ID.RemoveTouchEvents)
  878. return false;
  879. ID.TouchInQueue = true;
  880. break;
  881. case scriptEvents.touch_end:
  882. if (ID.RemoveTouchEvents)
  883. return false;
  884. break;
  885. case scriptEvents.land_collision:
  886. if (ID.LandCollisionInQueue || ID.RemoveLandCollisionEvents)
  887. return false;
  888. ID.LandCollisionInQueue = true;
  889. break;
  890. case scriptEvents.land_collision_end:
  891. if (ID.RemoveLandCollisionEvents)
  892. return false;
  893. break;
  894. case scriptEvents.changed:
  895. Changed changed;
  896. if (param[0] is Changed)
  897. changed = (Changed) param[0];
  898. else
  899. changed = (Changed) (((LSL_Types.LSLInteger) param[0]).value);
  900. if (ID.ChangedInQueue.Contains(changed))
  901. return false;
  902. ID.ChangedInQueue.Add(changed);
  903. break;
  904. }
  905. }
  906. return true;
  907. }
  908. /// <summary>
  909. /// This removes the event from the queue and allows it to be fired again
  910. /// </summary>
  911. /// <param name="QIS"></param>
  912. public void EventComplete(QueueItemStruct QIS)
  913. {
  914. lock (QIS.ID.ScriptEventLock)
  915. {
  916. scriptEvents eventType = (scriptEvents) Enum.Parse(typeof (scriptEvents), QIS.functionName);
  917. switch (eventType)
  918. {
  919. case scriptEvents.timer:
  920. QIS.ID.TimerInQueue = false;
  921. break;
  922. case scriptEvents.control:
  923. if (QIS.ID.ControlEventsInQueue > 0)
  924. QIS.ID.ControlEventsInQueue--;
  925. break;
  926. case scriptEvents.collision:
  927. QIS.ID.CollisionInQueue = false;
  928. break;
  929. case scriptEvents.collision_end:
  930. QIS.ID.CollisionInQueue = false;
  931. break;
  932. case scriptEvents.moving_end:
  933. QIS.ID.MovingInQueue = false;
  934. break;
  935. case scriptEvents.touch:
  936. QIS.ID.TouchInQueue = false;
  937. break;
  938. case scriptEvents.touch_end:
  939. QIS.ID.TouchInQueue = false;
  940. break;
  941. case scriptEvents.land_collision:
  942. QIS.ID.LandCollisionInQueue = false;
  943. break;
  944. case scriptEvents.land_collision_end:
  945. QIS.ID.LandCollisionInQueue = false;
  946. break;
  947. case scriptEvents.sensor:
  948. QIS.ID.SensorInQueue = false;
  949. break;
  950. case scriptEvents.no_sensor:
  951. QIS.ID.NoSensorInQueue = false;
  952. break;
  953. case scriptEvents.at_target:
  954. QIS.ID.AtTargetInQueue = false;
  955. break;
  956. case scriptEvents.not_at_target:
  957. QIS.ID.NotAtTargetInQueue = false;
  958. break;
  959. case scriptEvents.at_rot_target:
  960. QIS.ID.AtRotTargetInQueue = false;
  961. break;
  962. case scriptEvents.not_at_rot_target:
  963. QIS.ID.NotAtRotTargetInQueue = false;
  964. break;
  965. case scriptEvents.changed:
  966. Changed changed;
  967. if (QIS.param[0] is Changed)
  968. {
  969. changed = (Changed) QIS.param[0];
  970. }
  971. else
  972. {
  973. changed = (Changed) (((LSL_Types.LSLInteger) QIS.param[0]).value);
  974. }
  975. QIS.ID.ChangedInQueue.Remove(changed);
  976. break;
  977. }
  978. }
  979. }
  980. }
  981. }