PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/Aurora/AuroraDotNetEngine/EventManager.cs

https://bitbucket.org/VirtualReality/async-sim-testing
C# | 1017 lines | 771 code | 119 blank | 127 comment | 204 complexity | daa7f4cd6b75e738d0ca5ddd209e144b 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. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID}))
  287. {
  288. d.Populate(part.ParentEntity.Scene);
  289. d.LinkNum = part.LinkNum;
  290. det.Add(d);
  291. }
  292. if (det.Count > 0)
  293. {
  294. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  295. if (datas == null || datas.Length == 0)
  296. {
  297. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  298. //if (datas == null || datas.Length == 0)
  299. return;
  300. }
  301. string functionName = "collision_start";
  302. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  303. foreach (ScriptData ID in datas)
  304. {
  305. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  306. }
  307. }
  308. }
  309. public void collision(ISceneChildEntity part, ColliderArgs col)
  310. {
  311. // Add to queue for all scripts in ObjectID object
  312. List<DetectParams> det = new List<DetectParams>();
  313. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID}))
  314. {
  315. d.Populate(part.ParentEntity.Scene);
  316. d.LinkNum = part.LinkNum;
  317. det.Add(d);
  318. }
  319. if (det.Count > 0)
  320. {
  321. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  322. if (datas == null || datas.Length == 0)
  323. {
  324. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  325. //if (datas == null || datas.Length == 0)
  326. return;
  327. }
  328. string functionName = "collision";
  329. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  330. foreach (ScriptData ID in datas)
  331. {
  332. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  333. }
  334. }
  335. }
  336. public void collision_end(ISceneChildEntity part, ColliderArgs col)
  337. {
  338. // Add to queue for all scripts in ObjectID object
  339. List<DetectParams> det = new List<DetectParams>();
  340. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams {Key = detobj.keyUUID}))
  341. {
  342. d.Populate(part.ParentEntity.Scene);
  343. d.LinkNum = part.LinkNum;
  344. det.Add(d);
  345. }
  346. if (det.Count > 0)
  347. {
  348. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  349. if (datas == null || datas.Length == 0)
  350. {
  351. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  352. //if (datas == null || datas.Length == 0)
  353. return;
  354. }
  355. string functionName = "collision_end";
  356. object[] param = new Object[] {new LSL_Types.LSLInteger(det.Count)};
  357. foreach (ScriptData ID in datas)
  358. {
  359. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  360. }
  361. }
  362. }
  363. public void land_collision_start(ISceneChildEntity part, ColliderArgs col)
  364. {
  365. List<DetectParams> det = new List<DetectParams>();
  366. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams
  367. {
  368. Position =
  369. new LSL_Types.Vector3(
  370. detobj.posVector.X,
  371. detobj.posVector.Y,
  372. detobj.posVector.Z),
  373. Key = detobj.keyUUID
  374. }))
  375. {
  376. d.Populate(part.ParentEntity.Scene);
  377. d.LinkNum = part.LinkNum;
  378. det.Add(d);
  379. }
  380. if (det.Count != 0)
  381. {
  382. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  383. if (datas == null || datas.Length == 0)
  384. {
  385. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  386. //if (datas == null || datas.Length == 0)
  387. return;
  388. }
  389. string functionName = "land_collision_start";
  390. object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)};
  391. foreach (ScriptData ID in datas)
  392. {
  393. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  394. }
  395. }
  396. }
  397. public void land_collision(ISceneChildEntity part, ColliderArgs col)
  398. {
  399. List<DetectParams> det = new List<DetectParams>();
  400. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams
  401. {
  402. Position =
  403. new LSL_Types.Vector3(
  404. detobj.posVector.X,
  405. detobj.posVector.Y,
  406. detobj.posVector.Z),
  407. Key = detobj.keyUUID
  408. }))
  409. {
  410. d.Populate(part.ParentEntity.Scene);
  411. d.LinkNum = part.LinkNum;
  412. det.Add(d);
  413. }
  414. if (det.Count != 0)
  415. {
  416. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  417. if (datas == null || datas.Length == 0)
  418. {
  419. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  420. //if (datas == null || datas.Length == 0)
  421. return;
  422. }
  423. string functionName = "land_collision";
  424. object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)};
  425. foreach (ScriptData ID in datas)
  426. {
  427. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  428. }
  429. }
  430. }
  431. public void land_collision_end(ISceneChildEntity part, ColliderArgs col)
  432. {
  433. List<DetectParams> det = new List<DetectParams>();
  434. foreach (DetectParams d in col.Colliders.Select(detobj => new DetectParams
  435. {
  436. Position =
  437. new LSL_Types.Vector3(
  438. detobj.posVector.X,
  439. detobj.posVector.Y,
  440. detobj.posVector.Z),
  441. Key = detobj.keyUUID
  442. }))
  443. {
  444. d.Populate(part.ParentEntity.Scene);
  445. d.LinkNum = part.LinkNum;
  446. det.Add(d);
  447. }
  448. if (det.Count != 0)
  449. {
  450. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  451. if (datas == null || datas.Length == 0)
  452. {
  453. //datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentGroup.RootPart.UUID);
  454. //if (datas == null || datas.Length == 0)
  455. return;
  456. }
  457. string functionName = "land_collision_end";
  458. object[] param = new Object[] {new LSL_Types.Vector3(det[0].Position)};
  459. foreach (ScriptData ID in datas)
  460. {
  461. m_scriptEngine.AddToScriptQueue(ID, functionName, det.ToArray(), EventPriority.FirstStart, param);
  462. }
  463. }
  464. }
  465. public void control(ISceneChildEntity part, UUID itemID, UUID agentID, uint held, uint change)
  466. {
  467. if (part == null)
  468. return;
  469. ScriptData ID = ScriptEngine.ScriptProtection.GetScript(part.UUID, itemID);
  470. if (ID == null)
  471. return;
  472. string functionName = "control";
  473. object[] param = new object[]
  474. {
  475. new LSL_Types.LSLString(agentID.ToString()),
  476. new LSL_Types.LSLInteger(held),
  477. new LSL_Types.LSLInteger(change)
  478. };
  479. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart, param);
  480. }
  481. public void email(uint localID, UUID itemID, string timeSent,
  482. string address, string subject, string message, int numLeft)
  483. {
  484. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  485. if (part == null)
  486. return;
  487. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  488. if (datas == null || datas.Length == 0)
  489. {
  490. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  491. if (datas == null || datas.Length == 0)
  492. return;
  493. }
  494. string functionName = "email";
  495. object[] param = new object[]
  496. {
  497. new LSL_Types.LSLString(timeSent),
  498. new LSL_Types.LSLString(address),
  499. new LSL_Types.LSLString(subject),
  500. new LSL_Types.LSLString(message),
  501. new LSL_Types.LSLInteger(numLeft)
  502. };
  503. foreach (ScriptData ID in datas)
  504. {
  505. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  506. param);
  507. }
  508. }
  509. public void at_target(uint localID, uint handle, Vector3 targetpos,
  510. Vector3 atpos)
  511. {
  512. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  513. if (part == null)
  514. return;
  515. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  516. if (datas == null || datas.Length == 0)
  517. {
  518. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  519. if (datas == null || datas.Length == 0)
  520. return;
  521. }
  522. string functionName = "at_target";
  523. object[] param = new object[]
  524. {
  525. new LSL_Types.LSLInteger(handle),
  526. new LSL_Types.Vector3(targetpos.X, targetpos.Y, targetpos.Z),
  527. new LSL_Types.Vector3(atpos.X, atpos.Y, atpos.Z)
  528. };
  529. foreach (ScriptData ID in datas)
  530. {
  531. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  532. param);
  533. }
  534. }
  535. public void not_at_target(uint localID)
  536. {
  537. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  538. if (part == null)
  539. return;
  540. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  541. if (datas == null || datas.Length == 0)
  542. {
  543. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  544. if (datas == null || datas.Length == 0)
  545. return;
  546. }
  547. string functionName = "not_at_target";
  548. object[] param = new object[0];
  549. foreach (ScriptData ID in datas)
  550. {
  551. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  552. param);
  553. }
  554. }
  555. public void at_rot_target(uint localID, uint handle, Quaternion targetrot,
  556. Quaternion atrot)
  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 = "at_rot_target";
  569. object[] param = new object[]
  570. {
  571. new LSL_Types.LSLInteger(handle),
  572. new LSL_Types.Quaternion(targetrot.X, targetrot.Y, targetrot.Z, targetrot.W),
  573. new LSL_Types.Quaternion(atrot.X, atrot.Y, atrot.Z, atrot.W)
  574. };
  575. foreach (ScriptData ID in datas)
  576. {
  577. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  578. param);
  579. }
  580. }
  581. public void not_at_rot_target(uint localID)
  582. {
  583. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  584. if (part == null)
  585. return;
  586. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  587. if (datas == null || datas.Length == 0)
  588. {
  589. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  590. if (datas == null || datas.Length == 0)
  591. return;
  592. }
  593. string functionName = "not_at_rot_target";
  594. object[] param = new object[0];
  595. foreach (ScriptData ID in datas)
  596. {
  597. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  598. param);
  599. }
  600. }
  601. public void attach(uint localID, UUID itemID, UUID avatar)
  602. {
  603. ISceneChildEntity part = m_scriptEngine.findPrim(localID);
  604. if (part == null)
  605. return;
  606. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  607. if (datas == null || datas.Length == 0)
  608. {
  609. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.UUID);
  610. if (datas == null || datas.Length == 0)
  611. return;
  612. }
  613. string functionName = "attach";
  614. object[] param = new object[]
  615. {
  616. new LSL_Types.LSLString(avatar.ToString())
  617. };
  618. foreach (ScriptData ID in datas)
  619. {
  620. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  621. param);
  622. }
  623. }
  624. public void moving_start(ISceneChildEntity part)
  625. {
  626. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  627. if (datas == null || datas.Length == 0)
  628. {
  629. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID);
  630. if (datas == null || datas.Length == 0)
  631. return;
  632. }
  633. string functionName = "moving_start";
  634. object[] param = new object[0];
  635. foreach (ScriptData ID in datas)
  636. {
  637. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  638. param);
  639. }
  640. }
  641. public void moving_end(ISceneChildEntity part)
  642. {
  643. ScriptData[] datas = ScriptEngine.ScriptProtection.GetScripts(part.UUID);
  644. if (datas == null || datas.Length == 0)
  645. {
  646. datas = ScriptEngine.ScriptProtection.GetScripts(part.ParentEntity.RootChild.UUID);
  647. if (datas == null || datas.Length == 0)
  648. return;
  649. }
  650. string functionName = "moving_end";
  651. object[] param = new object[0];
  652. foreach (ScriptData ID in datas)
  653. {
  654. m_scriptEngine.AddToScriptQueue(ID, functionName, new DetectParams[0], EventPriority.FirstStart,
  655. param);
  656. }
  657. }
  658. /// <summary>
  659. /// Start multiple scripts in the object
  660. /// </summary>
  661. /// <param name="part"></param>
  662. /// <param name="items"></param>
  663. /// <param name="startParam"></param>
  664. /// <param name="postOnRez"></param>
  665. /// <param name="stateSource"></param>
  666. /// <param name="rezzedFrom"></param>
  667. /// <param name="clearStateSaves"></param>
  668. public void rez_scripts(ISceneChildEntity part, TaskInventoryItem[] items,
  669. int startParam, bool postOnRez, StateSource stateSource, UUID rezzedFrom,
  670. bool clearStateSaves)
  671. {
  672. List<LUStruct> ItemsToStart =
  673. items.Select(
  674. item =>
  675. m_scriptEngine.StartScript(part, item.ItemID, startParam, postOnRez, stateSource, rezzedFrom,
  676. clearStateSaves))
  677. .Where(itemToQueue => itemToQueue.Action != LUType.Unknown)
  678. .ToList();
  679. if (ItemsToStart.Count != 0)
  680. m_scriptEngine.MaintenanceThread.AddScriptChange(ItemsToStart.ToArray(), LoadPriority.FirstStart);
  681. }
  682. /// <summary>
  683. /// 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
  684. /// </summary>
  685. /// <param name="ID"></param>
  686. /// <param name="FunctionName"></param>
  687. /// <param name="param"></param>
  688. /// <returns></returns>
  689. public bool CheckIfEventShouldFire(ScriptData ID, string FunctionName, object[] param)
  690. {
  691. lock (ID.ScriptEventLock)
  692. {
  693. if (ID.Loading)
  694. {
  695. //If the script is loading, enqueue all events
  696. return true;
  697. }
  698. //This will happen if the script doesn't compile correctly
  699. if (ID.Script == null)
  700. {
  701. MainConsole.Instance.Info("[AuroraDotNetEngine]: Could not load script from item '" +
  702. ID.InventoryItem.Name +
  703. "' to fire event " + FunctionName);
  704. return false;
  705. }
  706. scriptEvents eventType = (scriptEvents) Enum.Parse(typeof (scriptEvents), FunctionName);
  707. // this must be done even if there is no event method
  708. if (eventType == scriptEvents.touch_start)
  709. ID.RemoveTouchEvents = false;
  710. else if (eventType == scriptEvents.collision_start)
  711. ID.RemoveCollisionEvents = false;
  712. else if (eventType == scriptEvents.land_collision_start)
  713. ID.RemoveLandCollisionEvents = false;
  714. if (eventType == scriptEvents.state_entry)
  715. ID.ResetEvents();
  716. if ((ID.Script.GetStateEventFlags(ID.State) & (long) eventType) == 0)
  717. return false; //If the script doesn't contain the state, don't even bother queueing it
  718. //Make sure we can execute events at position
  719. if (!m_scriptEngine.PipeEventsForScript(ID.Part))
  720. return false;
  721. switch (eventType)
  722. {
  723. case scriptEvents.timer:
  724. if (ID.TimerInQueue)
  725. return false;
  726. ID.TimerInQueue = true;
  727. break;
  728. case scriptEvents.sensor:
  729. if (ID.SensorInQueue)
  730. return false;
  731. ID.SensorInQueue = true;
  732. break;
  733. case scriptEvents.no_sensor:
  734. if (ID.NoSensorInQueue)
  735. return false;
  736. ID.NoSensorInQueue = true;
  737. break;
  738. case scriptEvents.at_target:
  739. if (ID.AtTargetInQueue)
  740. return false;
  741. ID.AtTargetInQueue = true;
  742. break;
  743. case scriptEvents.not_at_target:
  744. if (ID.NotAtTargetInQueue)
  745. return false;
  746. ID.NotAtTargetInQueue = true;
  747. break;
  748. case scriptEvents.at_rot_target:
  749. if (ID.AtRotTargetInQueue)
  750. return false;
  751. ID.AtRotTargetInQueue = true;
  752. break;
  753. case scriptEvents.not_at_rot_target:
  754. if (ID.NotAtRotTargetInQueue)
  755. return false;
  756. ID.NotAtRotTargetInQueue = true;
  757. break;
  758. case scriptEvents.control:
  759. int held = ((LSL_Types.LSLInteger) param[1]).value;
  760. // int changed = ((LSL_Types.LSLInteger)data.Params[2]).value;
  761. // If the last message was a 0 (nothing held)
  762. // and this one is also nothing held, drop it
  763. //
  764. if (ID.LastControlLevel == held && held == 0)
  765. return true;
  766. // If there is one or more queued, then queue
  767. // only changed ones, else queue unconditionally
  768. //
  769. if (ID.ControlEventsInQueue > 0)
  770. {
  771. if (ID.LastControlLevel == held)
  772. return false;
  773. }
  774. break;
  775. case scriptEvents.collision:
  776. if (ID.CollisionInQueue || ID.RemoveCollisionEvents)
  777. return false;
  778. ID.CollisionInQueue = true;
  779. break;
  780. case scriptEvents.moving_start:
  781. if (ID.MovingInQueue) //Block all other moving_starts until moving_end is called
  782. return false;
  783. ID.MovingInQueue = true;
  784. break;
  785. case scriptEvents.moving_end:
  786. if (!ID.MovingInQueue) //If we get a moving_end after we have sent one event, don't fire another
  787. return false;
  788. break;
  789. case scriptEvents.collision_end:
  790. if (ID.RemoveCollisionEvents)
  791. return false;
  792. break;
  793. case scriptEvents.touch:
  794. if (ID.TouchInQueue || ID.RemoveTouchEvents)
  795. return false;
  796. ID.TouchInQueue = true;
  797. break;
  798. case scriptEvents.touch_end:
  799. if (ID.RemoveTouchEvents)
  800. return false;
  801. break;
  802. case scriptEvents.land_collision:
  803. if (ID.LandCollisionInQueue || ID.RemoveLandCollisionEvents)
  804. return false;
  805. ID.LandCollisionInQueue = true;
  806. break;
  807. case scriptEvents.land_collision_end:
  808. if (ID.RemoveLandCollisionEvents)
  809. return false;
  810. break;
  811. case scriptEvents.changed:
  812. Changed changed;
  813. if (param[0] is Changed)
  814. changed = (Changed) param[0];
  815. else
  816. changed = (Changed) (((LSL_Types.LSLInteger) param[0]).value);
  817. if (ID.ChangedInQueue.Contains(changed))
  818. return false;
  819. ID.ChangedInQueue.Add(changed);
  820. break;
  821. }
  822. }
  823. return true;
  824. }
  825. /// <summary>
  826. /// This removes the event from the queue and allows it to be fired again
  827. /// </summary>
  828. /// <param name="QIS"></param>
  829. public void EventComplete(QueueItemStruct QIS)
  830. {
  831. lock (QIS.ID.ScriptEventLock)
  832. {
  833. scriptEvents eventType = (scriptEvents) Enum.Parse(typeof (scriptEvents), QIS.functionName);
  834. switch (eventType)
  835. {
  836. case scriptEvents.timer:
  837. QIS.ID.TimerInQueue = false;
  838. break;
  839. case scriptEvents.control:
  840. if (QIS.ID.ControlEventsInQueue > 0)
  841. QIS.ID.ControlEventsInQueue--;
  842. break;
  843. case scriptEvents.collision:
  844. QIS.ID.CollisionInQueue = false;
  845. break;
  846. case scriptEvents.collision_end:
  847. QIS.ID.CollisionInQueue = false;
  848. break;
  849. case scriptEvents.moving_end:
  850. QIS.ID.MovingInQueue = false;
  851. break;
  852. case scriptEvents.touch:
  853. QIS.ID.TouchInQueue = false;
  854. break;
  855. case scriptEvents.touch_end:
  856. QIS.ID.TouchInQueue = false;
  857. break;
  858. case scriptEvents.land_collision:
  859. QIS.ID.LandCollisionInQueue = false;
  860. break;
  861. case scriptEvents.land_collision_end:
  862. QIS.ID.LandCollisionInQueue = false;
  863. break;
  864. case scriptEvents.sensor:
  865. QIS.ID.SensorInQueue = false;
  866. break;
  867. case scriptEvents.no_sensor:
  868. QIS.ID.NoSensorInQueue = false;
  869. break;
  870. case scriptEvents.at_target:
  871. QIS.ID.AtTargetInQueue = false;
  872. break;
  873. case scriptEvents.not_at_target:
  874. QIS.ID.NotAtTargetInQueue = false;
  875. break;
  876. case scriptEvents.at_rot_target:
  877. QIS.ID.AtRotTargetInQueue = false;
  878. break;
  879. case scriptEvents.not_at_rot_target:
  880. QIS.ID.NotAtRotTargetInQueue = false;
  881. break;
  882. case scriptEvents.changed:
  883. Changed changed;
  884. if (QIS.param[0] is Changed)
  885. {
  886. changed = (Changed) QIS.param[0];
  887. }
  888. else
  889. {
  890. changed = (Changed) (((LSL_Types.LSLInteger) QIS.param[0]).value);
  891. }
  892. QIS.ID.ChangedInQueue.Remove(changed);
  893. break;
  894. }
  895. }
  896. }
  897. }
  898. }