PageRenderTime 66ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 3ms

/Aurora/AuroraDotNetEngine/APIs/LSL_Api.cs

https://bitbucket.org/VirtualReality/software-testing
C# | 11705 lines | 8971 code | 1635 blank | 1099 comment | 2545 complexity | d910892bba07447d3b6e84bd58f4441b MD5 | raw file

Large files files are truncated, but you can click here to view the full 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.DatabaseInterfaces;
  31. using Aurora.Framework.Modules;
  32. using Aurora.Framework.Physics;
  33. using Aurora.Framework.PresenceInfo;
  34. using Aurora.Framework.SceneInfo;
  35. using Aurora.Framework.SceneInfo.Entities;
  36. using Aurora.Framework.Serialization;
  37. using Aurora.Framework.Servers;
  38. using Aurora.Framework.Services;
  39. using Aurora.Framework.Services.ClassHelpers.Assets;
  40. using Aurora.Framework.Services.ClassHelpers.Inventory;
  41. using Aurora.Framework.Services.ClassHelpers.Profile;
  42. using Aurora.Framework.Utilities;
  43. using Aurora.ScriptEngine.AuroraDotNetEngine.APIs.Interfaces;
  44. using Aurora.ScriptEngine.AuroraDotNetEngine.Plugins;
  45. using Aurora.ScriptEngine.AuroraDotNetEngine.Runtime;
  46. using Nini.Config;
  47. using OpenMetaverse;
  48. using OpenMetaverse.Packets;
  49. using System;
  50. using System.Collections;
  51. using System.Collections.Generic;
  52. using System.Linq;
  53. using System.Runtime.Remoting.Lifetime;
  54. using System.Text;
  55. using System.Text.RegularExpressions;
  56. using System.Threading;
  57. using GridRegion = Aurora.Framework.Services.GridRegion;
  58. using LSL_Float = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.LSLFloat;
  59. using LSL_Integer = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.LSLInteger;
  60. using LSL_Key = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.LSLString;
  61. using LSL_List = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list;
  62. using LSL_Rotation = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Quaternion;
  63. using LSL_String = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.LSLString;
  64. using LSL_Vector = Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3;
  65. using PrimType = Aurora.Framework.SceneInfo.PrimType;
  66. using RegionFlags = Aurora.Framework.Services.RegionFlags;
  67. namespace Aurora.ScriptEngine.AuroraDotNetEngine.APIs
  68. {
  69. /// <summary>
  70. /// Contains all LSL ll-functions. This class will be in Default AppDomain.
  71. /// </summary>
  72. [Serializable]
  73. public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
  74. {
  75. protected IScriptModulePlugin m_ScriptEngine;
  76. protected ISceneChildEntity m_host;
  77. protected uint m_localID;
  78. protected UUID m_itemID;
  79. protected bool throwErrorOnNotImplemented = true;
  80. protected float m_ScriptDelayFactor = 1.0f;
  81. protected float m_ScriptDistanceFactor = 1.0f;
  82. protected float m_MinTimerInterval = 0.1f;
  83. protected DateTime m_timer = DateTime.Now;
  84. protected bool m_waitingForScriptAnswer = false;
  85. protected bool m_automaticLinkPermission = false;
  86. protected IMessageTransferModule m_TransferModule = null;
  87. protected int m_notecardLineReadCharsMax = 255;
  88. protected int m_scriptConsoleChannel = 0;
  89. protected bool m_scriptConsoleChannelEnabled = false;
  90. protected IUrlModule m_UrlModule = null;
  91. internal ScriptProtectionModule ScriptProtection;
  92. protected IWorldComm m_comms = null;
  93. // MUST be a ref type
  94. public class UserInfoCacheEntry
  95. {
  96. public int time;
  97. public UserAccount account;
  98. public UserInfo pinfo;
  99. }
  100. protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
  101. new Dictionary<UUID, UserInfoCacheEntry>();
  102. public void Initialize(IScriptModulePlugin ScriptEngine, ISceneChildEntity host, uint localID, UUID itemID,
  103. ScriptProtectionModule module)
  104. {
  105. m_ScriptEngine = ScriptEngine;
  106. m_host = host;
  107. m_localID = localID;
  108. m_itemID = itemID;
  109. ScriptProtection = module;
  110. m_ScriptDelayFactor =
  111. m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
  112. m_ScriptDistanceFactor =
  113. m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f);
  114. m_MinTimerInterval =
  115. m_ScriptEngine.Config.GetFloat("MinTimerInterval", 0.5f);
  116. m_automaticLinkPermission =
  117. m_ScriptEngine.Config.GetBoolean("AutomaticLinkPermission", false);
  118. m_notecardLineReadCharsMax =
  119. m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255);
  120. if (m_notecardLineReadCharsMax > 65535)
  121. m_notecardLineReadCharsMax = 65535;
  122. m_TransferModule =
  123. World.RequestModuleInterface<IMessageTransferModule>();
  124. m_UrlModule = World.RequestModuleInterface<IUrlModule>();
  125. m_comms = World.RequestModuleInterface<IWorldComm>();
  126. }
  127. public IScriptApi Copy()
  128. {
  129. return new LSL_Api();
  130. }
  131. public string Name
  132. {
  133. get { return "ll"; }
  134. }
  135. public string InterfaceName
  136. {
  137. get { return "ILSL_Api"; }
  138. }
  139. /// <summary>
  140. /// We don't have to add any assemblies here
  141. /// </summary>
  142. public string[] ReferencedAssemblies
  143. {
  144. get { return new string[0]; }
  145. }
  146. /// <summary>
  147. /// We use the default namespace, so we don't have any to add
  148. /// </summary>
  149. public string[] NamespaceAdditions
  150. {
  151. get { return new string[0]; }
  152. }
  153. public void Dispose()
  154. {
  155. }
  156. public override Object InitializeLifetimeService()
  157. {
  158. ILease lease = (ILease) base.InitializeLifetimeService();
  159. if (lease != null && lease.CurrentState == LeaseState.Initial)
  160. {
  161. lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
  162. // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
  163. // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
  164. }
  165. return lease;
  166. }
  167. protected virtual void ScriptSleep(int delay)
  168. {
  169. delay = (int) (delay*m_ScriptDelayFactor);
  170. if (delay == 0)
  171. return;
  172. Thread.Sleep(delay);
  173. }
  174. /// <summary>
  175. /// This is the new sleep implementation that allows for us to not freeze the script thread while we run
  176. /// </summary>
  177. /// <param name="delay"></param>
  178. /// <returns></returns>
  179. protected DateTime PScriptSleep(int delay)
  180. {
  181. double dly = (delay*m_ScriptDelayFactor);
  182. if (dly == 0.0)
  183. return DateTime.Now;
  184. DateTime timeToStopSleeping = DateTime.Now.AddMilliseconds(dly);
  185. return timeToStopSleeping;
  186. }
  187. public IScene World
  188. {
  189. get { return m_host.ParentEntity.Scene; }
  190. }
  191. public void state(string newState)
  192. {
  193. m_ScriptEngine.SetState(m_itemID, newState);
  194. throw new EventAbortException();
  195. }
  196. /// <summary>
  197. /// Reset the named script. The script must be present
  198. /// in the same prim.
  199. /// </summary>
  200. public void llResetScript()
  201. {
  202. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  203. if (m_UrlModule != null)
  204. {
  205. m_UrlModule.ScriptRemoved(m_itemID);
  206. }
  207. m_ScriptEngine.ResetScript(m_host.UUID, m_itemID, true);
  208. }
  209. public void llResetOtherScript(string name)
  210. {
  211. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  212. UUID item;
  213. if ((item = ScriptByName(name)) != UUID.Zero)
  214. m_ScriptEngine.ResetScript(m_host.UUID, item, false);
  215. else
  216. ShoutError("llResetOtherScript: script " + name + " not found");
  217. }
  218. public LSL_Integer llGetScriptState(string name)
  219. {
  220. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  221. return new LSL_Integer();
  222. UUID item;
  223. if ((item = ScriptByName(name)) != UUID.Zero)
  224. {
  225. return m_ScriptEngine.GetScriptRunningState(item) ? 1 : 0;
  226. }
  227. ShoutError("llGetScriptState: script " + name + " not found");
  228. // If we didn't find it, then it's safe to
  229. // assume it is not running.
  230. return 0;
  231. }
  232. public LSL_Key llGenerateKey()
  233. {
  234. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  235. return new LSL_Key();
  236. return UUID.Random().ToString();
  237. }
  238. public void llSetScriptState(string name, int run)
  239. {
  240. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  241. UUID item;
  242. // These functions are supposed to be robust,
  243. // so get the state one step at a time.
  244. if ((item = ScriptByName(name)) != UUID.Zero)
  245. {
  246. m_ScriptEngine.SetScriptRunningState(item, run == 1);
  247. }
  248. else
  249. {
  250. ShoutError("llSetScriptState: script " + name + " not found");
  251. }
  252. }
  253. public List<ISceneChildEntity> GetLinkParts(int linkType)
  254. {
  255. List<ISceneChildEntity> ret = new List<ISceneChildEntity> {m_host};
  256. if (linkType == ScriptBaseClass.LINK_SET)
  257. {
  258. if (m_host.ParentEntity != null)
  259. return new List<ISceneChildEntity>(m_host.ParentEntity.ChildrenEntities());
  260. return ret;
  261. }
  262. if (linkType == ScriptBaseClass.LINK_ROOT)
  263. {
  264. if (m_host.ParentEntity != null)
  265. {
  266. ret = new List<ISceneChildEntity> {m_host.ParentEntity.RootChild};
  267. return ret;
  268. }
  269. return ret;
  270. }
  271. if (linkType == ScriptBaseClass.LINK_ALL_OTHERS)
  272. {
  273. if (m_host.ParentEntity == null)
  274. return new List<ISceneChildEntity>();
  275. ret = new List<ISceneChildEntity>(m_host.ParentEntity.ChildrenEntities());
  276. if (ret.Contains(m_host))
  277. ret.Remove(m_host);
  278. return ret;
  279. }
  280. if (linkType == ScriptBaseClass.LINK_ALL_CHILDREN)
  281. {
  282. if (m_host.ParentEntity == null)
  283. return new List<ISceneChildEntity>();
  284. ret = new List<ISceneChildEntity>(m_host.ParentEntity.ChildrenEntities());
  285. if (ret.Contains(m_host.ParentEntity.RootChild))
  286. ret.Remove(m_host.ParentEntity.RootChild);
  287. return ret;
  288. }
  289. if (linkType == ScriptBaseClass.LINK_THIS)
  290. {
  291. return ret;
  292. }
  293. if (linkType < 0 || m_host.ParentEntity == null)
  294. return new List<ISceneChildEntity>();
  295. IEntity target = m_host.ParentEntity.GetLinkNumPart(linkType);
  296. if (target is ISceneChildEntity)
  297. {
  298. ret = new List<ISceneChildEntity> {target as ISceneChildEntity};
  299. }
  300. //No allowing scene presences to be found here
  301. return ret;
  302. }
  303. public List<IEntity> GetLinkPartsAndEntities(int linkType)
  304. {
  305. List<IEntity> ret = new List<IEntity> {m_host};
  306. if (linkType == ScriptBaseClass.LINK_SET)
  307. {
  308. if (m_host.ParentEntity != null)
  309. {
  310. List<ISceneChildEntity> parts = new List<ISceneChildEntity>(m_host.ParentEntity.ChildrenEntities());
  311. #if (!ISWIN)
  312. return parts.ConvertAll<IEntity>(new Converter<ISceneChildEntity, IEntity>(delegate(ISceneChildEntity part)
  313. {
  314. return (IEntity)part;
  315. }));
  316. #else
  317. return parts.ConvertAll(part => (IEntity) part);
  318. #endif
  319. }
  320. return ret;
  321. }
  322. if (linkType == ScriptBaseClass.LINK_ROOT)
  323. {
  324. if (m_host.ParentEntity != null)
  325. {
  326. ret = new List<IEntity> {m_host.ParentEntity.RootChild};
  327. return ret;
  328. }
  329. return ret;
  330. }
  331. if (linkType == ScriptBaseClass.LINK_ALL_OTHERS)
  332. {
  333. if (m_host.ParentEntity == null)
  334. return new List<IEntity>();
  335. List<ISceneChildEntity> sceneobjectparts =
  336. new List<ISceneChildEntity>(m_host.ParentEntity.ChildrenEntities());
  337. #if (!ISWIN)
  338. ret = sceneobjectparts.ConvertAll<IEntity>(new Converter<ISceneChildEntity, IEntity>(delegate(ISceneChildEntity part)
  339. {
  340. return (IEntity)part;
  341. }));
  342. #else
  343. ret = sceneobjectparts.ConvertAll(part => (IEntity) part);
  344. #endif
  345. if (ret.Contains(m_host))
  346. ret.Remove(m_host);
  347. return ret;
  348. }
  349. if (linkType == ScriptBaseClass.LINK_ALL_CHILDREN)
  350. {
  351. if (m_host.ParentEntity == null)
  352. return new List<IEntity>();
  353. List<ISceneChildEntity> children = new List<ISceneChildEntity>(m_host.ParentEntity.ChildrenEntities());
  354. #if (!ISWIN)
  355. ret = children.ConvertAll<IEntity>(new Converter<ISceneChildEntity, IEntity>(delegate(ISceneChildEntity part)
  356. {
  357. return (IEntity)part;
  358. }));
  359. #else
  360. ret = children.ConvertAll(part => (IEntity) part);
  361. #endif
  362. if (ret.Contains(m_host.ParentEntity.RootChild))
  363. ret.Remove(m_host.ParentEntity.RootChild);
  364. return ret;
  365. }
  366. if (linkType == ScriptBaseClass.LINK_THIS)
  367. {
  368. return ret;
  369. }
  370. if (linkType < 0 || m_host.ParentEntity == null)
  371. return new List<IEntity>();
  372. IEntity target = m_host.ParentEntity.GetLinkNumPart(linkType);
  373. if (target == null)
  374. return new List<IEntity>();
  375. ret = new List<IEntity> {target};
  376. return ret;
  377. }
  378. protected UUID InventorySelf()
  379. {
  380. UUID invItemID = new UUID();
  381. lock (m_host.TaskInventory)
  382. {
  383. foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
  384. {
  385. if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
  386. {
  387. invItemID = inv.Key;
  388. break;
  389. }
  390. }
  391. }
  392. return invItemID;
  393. }
  394. protected UUID InventoryKey(string name, int type)
  395. {
  396. lock (m_host.TaskInventory)
  397. {
  398. foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
  399. {
  400. if (inv.Value.Name == name)
  401. {
  402. if (inv.Value.Type != type)
  403. return UUID.Zero;
  404. return inv.Value.AssetID;
  405. }
  406. }
  407. }
  408. return UUID.Zero;
  409. }
  410. protected UUID InventoryKey(string name, bool throwExceptionIfDoesNotExist)
  411. {
  412. lock (m_host.TaskInventory)
  413. {
  414. foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
  415. {
  416. if (inv.Value.Name == name)
  417. {
  418. return inv.Value.AssetID;
  419. }
  420. }
  421. }
  422. if (throwExceptionIfDoesNotExist)
  423. {
  424. IChatModule chatModule = World.RequestModuleInterface<IChatModule>();
  425. if (chatModule != null)
  426. chatModule.SimChat("Could not find sound '" + name + "'.",
  427. ChatTypeEnum.DebugChannel, 2147483647, m_host.AbsolutePosition,
  428. m_host.Name, m_host.UUID, false, World);
  429. }
  430. return UUID.Zero;
  431. }
  432. /// <summary>
  433. /// accepts a valid UUID, -or- a name of an inventory item.
  434. /// Returns a valid UUID or UUID.Zero if key invalid and item not found
  435. /// in prim inventory.
  436. /// </summary>
  437. /// <param name="k"></param>
  438. /// <param name="throwExceptionIfDoesNotExist"></param>
  439. /// <returns></returns>
  440. protected UUID KeyOrName(string k, bool throwExceptionIfDoesNotExist)
  441. {
  442. UUID key = UUID.Zero;
  443. // if we can parse the string as a key, use it.
  444. if (UUID.TryParse(k, out key))
  445. {
  446. return key;
  447. }
  448. // else try to locate the name in inventory of object. found returns key,
  449. // not found returns UUID.Zero which will translate to the default particle texture
  450. return InventoryKey(k, throwExceptionIfDoesNotExist);
  451. }
  452. // convert a LSL_Rotation to a Quaternion
  453. protected Quaternion Rot2Quaternion(LSL_Rotation r)
  454. {
  455. Quaternion q = new Quaternion((float) r.x, (float) r.y, (float) r.z, (float) r.s);
  456. q.Normalize();
  457. return q;
  458. }
  459. //These are the implementations of the various ll-functions used by the LSL scripts.
  460. public LSL_Float llSin(double f)
  461. {
  462. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  463. return new LSL_Float();
  464. return Math.Sin(f);
  465. }
  466. public LSL_Float llCos(double f)
  467. {
  468. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  469. return new LSL_Float();
  470. return Math.Cos(f);
  471. }
  472. public LSL_Float llTan(double f)
  473. {
  474. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  475. return new LSL_Float();
  476. return Math.Tan(f);
  477. }
  478. public LSL_Float llAtan2(double x, double y)
  479. {
  480. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  481. return new LSL_Float();
  482. return Math.Atan2(x, y);
  483. }
  484. public LSL_Float llSqrt(double f)
  485. {
  486. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  487. return new LSL_Float();
  488. return Math.Sqrt(f);
  489. }
  490. public LSL_Float llPow(double fbase, double fexponent)
  491. {
  492. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  493. return new LSL_Float();
  494. return Math.Pow(fbase, fexponent);
  495. }
  496. public LSL_Integer llAbs(int i)
  497. {
  498. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  499. return new LSL_Integer();
  500. // changed to replicate LSL behaviour whereby minimum int value is returned untouched.
  501. if (i == Int32.MinValue)
  502. return i;
  503. return Math.Abs(i);
  504. }
  505. public LSL_Float llFabs(double f)
  506. {
  507. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  508. return new LSL_Float();
  509. return Math.Abs(f);
  510. }
  511. public LSL_Float llFrand(double mag)
  512. {
  513. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  514. return new LSL_Float();
  515. lock (Util.RandomClass)
  516. {
  517. return Util.RandomClass.NextDouble()*mag;
  518. }
  519. }
  520. public LSL_Integer llFloor(double f)
  521. {
  522. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  523. return new LSL_Integer();
  524. return (int) Math.Floor(f);
  525. }
  526. public LSL_Integer llCeil(double f)
  527. {
  528. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  529. return new LSL_Integer();
  530. return (int) Math.Ceiling(f);
  531. }
  532. // Xantor 01/May/2008 fixed midpointrounding (2.5 becomes 3.0 instead of 2.0, default = ToEven)
  533. public LSL_Integer llRound(double f)
  534. {
  535. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  536. return new LSL_Integer();
  537. double RoundedNumber = Math.Round(f, MidpointRounding.AwayFromZero);
  538. //Attempt to fix rounded numbers like -4.5 arounding away from zero
  539. if (f < 0)
  540. {
  541. if (f + 0.5 == RoundedNumber || f - 0.5 == RoundedNumber)
  542. {
  543. RoundedNumber += 1;
  544. }
  545. }
  546. return (int) RoundedNumber;
  547. }
  548. //This next group are vector operations involving squaring and square root. ckrinke
  549. public LSL_Float llVecMag(LSL_Vector v)
  550. {
  551. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  552. return new LSL_Float();
  553. return LSL_Vector.Mag(v);
  554. }
  555. public LSL_Vector llVecNorm(LSL_Vector v)
  556. {
  557. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  558. return new LSL_Vector();
  559. return LSL_Vector.Norm(v);
  560. }
  561. public LSL_Float llVecDist(LSL_Vector a, LSL_Vector b)
  562. {
  563. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  564. return new LSL_Float();
  565. double dx = a.x - b.x;
  566. double dy = a.y - b.y;
  567. double dz = a.z - b.z;
  568. return Math.Sqrt(dx*dx + dy*dy + dz*dz);
  569. }
  570. //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
  571. // Old implementation of llRot2Euler. Normalization not required as Atan2 function will
  572. // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
  573. public LSL_Vector llRot2Euler(LSL_Rotation r)
  574. {
  575. //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke
  576. LSL_Rotation t = new LSL_Rotation(r.x*r.x, r.y*r.y, r.z*r.z, r.s*r.s);
  577. double m = (t.x + t.y + t.z + t.s);
  578. if (m == 0) return new LSL_Vector();
  579. double n = 2*(r.y*r.s + r.x*r.z);
  580. double p = m*m - n*n;
  581. if (p > 0)
  582. return new LSL_Vector(Math.Atan2(2.0*(r.x*r.s - r.y*r.z), (-t.x - t.y + t.z + t.s)),
  583. Math.Atan2(n, Math.Sqrt(p)),
  584. Math.Atan2(2.0*(r.z*r.s - r.x*r.y), (t.x - t.y - t.z + t.s)));
  585. if (n > 0)
  586. return new LSL_Vector(0.0, Math.PI*0.5, Math.Atan2((r.z*r.s + r.x*r.y), 0.5 - t.x - t.z));
  587. return new LSL_Vector(0.0, -Math.PI*0.5, Math.Atan2((r.z*r.s + r.x*r.y), 0.5 - t.x - t.z));
  588. }
  589. /* From wiki:
  590. The Euler angle vector (in radians) is converted to a rotation by doing the rotations around the 3 axes
  591. in Z, Y, X order. So llEuler2Rot(<1.0, 2.0, 3.0> * DEG_TO_RAD) generates a rotation by taking the zero rotation,
  592. a vector pointing along the X axis, first rotating it 3 degrees around the global Z axis, then rotating the resulting
  593. vector 2 degrees around the global Y axis, and finally rotating that 1 degree around the global X axis.
  594. */
  595. /* How we arrived at this llEuler2Rot
  596. *
  597. * Experiment in SL to determine conventions:
  598. * llEuler2Rot(<PI,0,0>)=<1,0,0,0>
  599. * llEuler2Rot(<0,PI,0>)=<0,1,0,0>
  600. * llEuler2Rot(<0,0,PI>)=<0,0,1,0>
  601. *
  602. * Important facts about Quaternions
  603. * - multiplication is non-commutative (a*b != b*a)
  604. * - http://en.wikipedia.org/wiki/Quaternion#Basis_multiplication
  605. *
  606. * Above SL experiment gives (c1,c2,c3,s1,s2,s3 as defined in our llEuler2Rot):
  607. * Qx = c1+i*s1
  608. * Qy = c2+j*s2;
  609. * Qz = c3+k*s3;
  610. *
  611. * Rotations applied in order (from above) Z, Y, X
  612. * Q = (Qz * Qy) * Qx
  613. * ((c1+i*s1)*(c2+j*s2))*(c3+k*s3)
  614. * (c1*c2+i*s1*c2+j*c1*s2+ij*s1*s2)*(c3+k*s3)
  615. * (c1*c2+i*s1*c2+j*c1*s2+k*s1*s2)*(c3+k*s3)
  616. * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3+ik*s1*c2*s3+jk*c1*s2*s3+kk*s1*s2*s3
  617. * c1*c2*c3+i*s1*c2*c3+j*c1*s2*c3+k*s1*s2*c3+k*c1*c2*s3 -j*s1*c2*s3 +i*c1*s2*s3 -s1*s2*s3
  618. * regroup: x=i*(s1*c2*c3+c1*s2*s3)
  619. * y=j*(c1*s2*c3-s1*c2*s3)
  620. * z=k*(s1*s2*c3+c1*c2*s3)
  621. * s= c1*c2*c3-s1*s2*s3
  622. *
  623. * This implementation agrees with the functions found here:
  624. * http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions
  625. * And with the results in SL.
  626. *
  627. * It's also possible to calculate llEuler2Rot by direct multiplication of
  628. * the Qz, Qy, and Qx vectors (as above - and done in the "accurate" function
  629. * from the wiki).
  630. * Apparently in some cases this is better from a numerical precision perspective?
  631. */
  632. public LSL_Rotation llEuler2Rot(LSL_Vector v)
  633. {
  634. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  635. return new LSL_Rotation();
  636. double c1 = Math.Cos(v.x*0.5);
  637. double c2 = Math.Cos(v.y*0.5);
  638. double c3 = Math.Cos(v.z*0.5);
  639. double s1 = Math.Sin(v.x*0.5);
  640. double s2 = Math.Sin(v.y*0.5);
  641. double s3 = Math.Sin(v.z*0.5);
  642. double x = s1*c2*c3 + c1*s2*s3;
  643. double y = c1*s2*c3 - s1*c2*s3;
  644. double z = s1*s2*c3 + c1*c2*s3;
  645. double s = c1*c2*c3 - s1*s2*s3;
  646. return new LSL_Rotation(x, y, z, s);
  647. }
  648. public LSL_Rotation llAxes2Rot(LSL_Vector fwd, LSL_Vector left, LSL_Vector up)
  649. {
  650. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  651. return new LSL_Rotation();
  652. double s;
  653. double tr = fwd.x + left.y + up.z + 1.0;
  654. if (tr >= 1.0)
  655. {
  656. s = 0.5/Math.Sqrt(tr);
  657. return new LSL_Rotation(
  658. (left.z - up.y)*s,
  659. (up.x - fwd.z)*s,
  660. (fwd.y - left.x)*s,
  661. 0.25/s);
  662. }
  663. double max = (left.y > up.z) ? left.y : up.z;
  664. if (max < fwd.x)
  665. {
  666. s = Math.Sqrt(fwd.x - (left.y + up.z) + 1.0);
  667. double x = s*0.5;
  668. s = 0.5/s;
  669. return new LSL_Rotation(
  670. x,
  671. (fwd.y + left.x)*s,
  672. (up.x + fwd.z)*s,
  673. (left.z - up.y)*s);
  674. }
  675. if (max == left.y)
  676. {
  677. s = Math.Sqrt(left.y - (up.z + fwd.x) + 1.0);
  678. double y = s*0.5;
  679. s = 0.5/s;
  680. return new LSL_Rotation(
  681. (fwd.y + left.x)*s,
  682. y,
  683. (left.z + up.y)*s,
  684. (up.x - fwd.z)*s);
  685. }
  686. s = Math.Sqrt(up.z - (fwd.x + left.y) + 1.0);
  687. double z = s*0.5;
  688. s = 0.5/s;
  689. return new LSL_Rotation(
  690. (up.x + fwd.z)*s,
  691. (left.z + up.y)*s,
  692. z,
  693. (fwd.y - left.x)*s);
  694. }
  695. public LSL_Vector llRot2Fwd(LSL_Rotation r)
  696. {
  697. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  698. return new LSL_Vector();
  699. double m = r.x*r.x + r.y*r.y + r.z*r.z + r.s*r.s;
  700. // m is always greater than zero
  701. // if m is not equal to 1 then Rotation needs to be normalized
  702. if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
  703. {
  704. m = 1.0/Math.Sqrt(m);
  705. r.x *= m;
  706. r.y *= m;
  707. r.z *= m;
  708. r.s *= m;
  709. }
  710. // Fast Algebric Calculations instead of Vectors & Quaternions Product
  711. double x = r.x*r.x - r.y*r.y - r.z*r.z + r.s*r.s;
  712. double y = 2*(r.x*r.y + r.z*r.s);
  713. double z = 2*(r.x*r.z - r.y*r.s);
  714. return (new LSL_Vector(x, y, z));
  715. }
  716. public LSL_Vector llRot2Left(LSL_Rotation r)
  717. {
  718. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  719. return new LSL_Vector();
  720. double m = r.x*r.x + r.y*r.y + r.z*r.z + r.s*r.s;
  721. // m is always greater than zero
  722. // if m is not equal to 1 then Rotation needs to be normalized
  723. if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
  724. {
  725. m = 1.0/Math.Sqrt(m);
  726. r.x *= m;
  727. r.y *= m;
  728. r.z *= m;
  729. r.s *= m;
  730. }
  731. // Fast Algebric Calculations instead of Vectors & Quaternions Product
  732. double x = 2*(r.x*r.y - r.z*r.s);
  733. double y = -r.x*r.x + r.y*r.y - r.z*r.z + r.s*r.s;
  734. double z = 2*(r.x*r.s + r.y*r.z);
  735. return (new LSL_Vector(x, y, z));
  736. }
  737. public LSL_Vector llRot2Up(LSL_Rotation r)
  738. {
  739. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  740. return new LSL_Vector();
  741. double m = r.x*r.x + r.y*r.y + r.z*r.z + r.s*r.s;
  742. // m is always greater than zero
  743. // if m is not equal to 1 then Rotation needs to be normalized
  744. if (Math.Abs(1.0 - m) > 0.000001) // allow a little slop here for calculation precision
  745. {
  746. m = 1.0/Math.Sqrt(m);
  747. r.x *= m;
  748. r.y *= m;
  749. r.z *= m;
  750. r.s *= m;
  751. }
  752. // Fast Algebric Calculations instead of Vectors & Quaternions Product
  753. double x = 2*(r.x*r.z + r.y*r.s);
  754. double y = 2*(-r.x*r.s + r.y*r.z);
  755. double z = -r.x*r.x - r.y*r.y + r.z*r.z + r.s*r.s;
  756. return (new LSL_Vector(x, y, z));
  757. }
  758. public LSL_Rotation llRotBetween(LSL_Vector a, LSL_Vector b)
  759. {
  760. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  761. return new LSL_Rotation();
  762. //A and B should both be normalized
  763. LSL_Rotation rotBetween;
  764. // Check for zero vectors. If either is zero, return zero rotation. Otherwise,
  765. // continue calculation.
  766. if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f))
  767. {
  768. rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
  769. }
  770. else
  771. {
  772. a = LSL_Vector.Norm(a);
  773. b = LSL_Vector.Norm(b);
  774. double dotProduct = LSL_Vector.Dot(a, b);
  775. // There are two degenerate cases possible. These are for vectors 180 or
  776. // 0 degrees apart. These have to be detected and handled individually.
  777. //
  778. // Check for vectors 180 degrees apart.
  779. // A dot product of -1 would mean the angle between vectors is 180 degrees.
  780. if (dotProduct < -0.9999999f)
  781. {
  782. // First assume X axis is orthogonal to the vectors.
  783. LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f);
  784. orthoVector = orthoVector - a*(a.x/LSL_Vector.Dot(a, a));
  785. // Check for near zero vector. A very small non-zero number here will create
  786. // a rotation in an undesired direction.
  787. rotBetween = LSL_Vector.Mag(orthoVector) > 0.0001
  788. ? new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f)
  789. : new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
  790. }
  791. // Check for parallel vectors.
  792. // A dot product of 1 would mean the angle between vectors is 0 degrees.
  793. else if (dotProduct > 0.9999999f)
  794. {
  795. // Set zero rotation.
  796. rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
  797. }
  798. else
  799. {
  800. // All special checks have been performed so get the axis of rotation.
  801. LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
  802. // Quarternion s value is the length of the unit vector + dot product.
  803. double qs = 1.0 + dotProduct;
  804. rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
  805. // Normalize the rotation.
  806. double mag = LSL_Rotation.Mag(rotBetween);
  807. // We shouldn't have to worry about a divide by zero here. The qs value will be
  808. // non-zero because we already know if we're here, then the dotProduct is not -1 so
  809. // qs will not be zero. Also, we've already handled the input vectors being zero so the
  810. // crossProduct vector should also not be zero.
  811. rotBetween.x = rotBetween.x/mag;
  812. rotBetween.y = rotBetween.y/mag;
  813. rotBetween.z = rotBetween.z/mag;
  814. rotBetween.s = rotBetween.s/mag;
  815. // Check for undefined values and set zero rotation if any found. This code might not actually be required
  816. // any longer since zero vectors are checked for at the top.
  817. if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) ||
  818. Double.IsNaN(rotBetween.s))
  819. {
  820. rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
  821. }
  822. }
  823. }
  824. return rotBetween;
  825. }
  826. public void llWhisper(int channelID, string text)
  827. {
  828. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  829. if (text.Length > 1023)
  830. text = text.Substring(0, 1023);
  831. IChatModule chatModule = World.RequestModuleInterface<IChatModule>();
  832. if (chatModule != null)
  833. chatModule.SimChat(text, ChatTypeEnum.Whisper, channelID,
  834. m_host.ParentEntity.RootChild.AbsolutePosition, m_host.Name, m_host.UUID, false,
  835. World);
  836. if (m_comms != null)
  837. m_comms.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
  838. }
  839. public void llSay(int channelID, object m_text)
  840. {
  841. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  842. string text = m_text.ToString();
  843. if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
  844. {
  845. MainConsole.Instance.Debug(text);
  846. }
  847. else
  848. {
  849. if (text.Length > 1023)
  850. text = text.Substring(0, 1023);
  851. IChatModule chatModule = World.RequestModuleInterface<IChatModule>();
  852. if (chatModule != null)
  853. chatModule.SimChat(text, ChatTypeEnum.Say, channelID,
  854. m_host.ParentEntity.RootChild.AbsolutePosition, m_host.Name, m_host.UUID, false,
  855. World);
  856. if (m_comms != null)
  857. m_comms.DeliverMessage(ChatTypeEnum.Say, channelID, m_host.Name, m_host.UUID, text);
  858. }
  859. }
  860. public void llShout(int channelID, string text)
  861. {
  862. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  863. if (text.Length > 1023)
  864. text = text.Substring(0, 1023);
  865. IChatModule chatModule = World.RequestModuleInterface<IChatModule>();
  866. if (chatModule != null)
  867. chatModule.SimChat(text, ChatTypeEnum.Shout, channelID,
  868. m_host.ParentEntity.RootChild.AbsolutePosition, m_host.Name, m_host.UUID, true, World);
  869. if (m_comms != null)
  870. m_comms.DeliverMessage(ChatTypeEnum.Shout, channelID, m_host.Name, m_host.UUID, text);
  871. }
  872. public void llRegionSay(int channelID, string text)
  873. {
  874. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  875. if (text.Length > 1023)
  876. text = text.Substring(0, 1023);
  877. if (channelID == 0) //0 isn't normally allowed, so check against a higher threat level
  878. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.Moderate, "LSL", m_host, "LSL", m_itemID)) return;
  879. IChatModule chatModule = World.RequestModuleInterface<IChatModule>();
  880. if (chatModule != null)
  881. chatModule.SimChat(text, ChatTypeEnum.Region, channelID,
  882. m_host.ParentEntity.RootChild.AbsolutePosition, m_host.Name, m_host.UUID, false,
  883. World);
  884. if (m_comms != null)
  885. m_comms.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID, text);
  886. }
  887. public void llRegionSayTo(LSL_Key toID, int channelID, string text)
  888. {
  889. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  890. IChatModule chatModule = World.RequestModuleInterface<IChatModule>();
  891. if (text.Length > 1023)
  892. text = text.Substring(0, 1023);
  893. if (channelID == 0)
  894. {
  895. IScenePresence presence = World.GetScenePresence(UUID.Parse(toID.m_string));
  896. if (presence != null)
  897. {
  898. if (chatModule != null)
  899. chatModule.TrySendChatMessage(presence, m_host.AbsolutePosition, m_host.AbsolutePosition,
  900. m_host.UUID, m_host.Name, ChatTypeEnum.Say, text,
  901. ChatSourceType.Object, 10000);
  902. }
  903. }
  904. if (m_comms != null)
  905. m_comms.DeliverMessage(ChatTypeEnum.Region, channelID, m_host.Name, m_host.UUID,
  906. UUID.Parse(toID.m_string), text);
  907. }
  908. public LSL_Integer llListen(int channelID, string name, string ID, string msg)
  909. {
  910. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  911. return new LSL_Integer();
  912. UUID keyID;
  913. UUID.TryParse(ID, out keyID);
  914. if (m_comms != null)
  915. return m_comms.Listen(m_itemID, m_host.UUID, channelID, name, keyID, msg);
  916. return -1;
  917. }
  918. public void llListenControl(int number, int active)
  919. {
  920. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  921. if (m_comms != null)
  922. m_comms.ListenControl(m_itemID, number, active);
  923. }
  924. public void llListenRemove(int number)
  925. {
  926. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  927. if (m_comms != null)
  928. m_comms.ListenRemove(m_itemID, number);
  929. }
  930. public void llSensor(string name, string id, int type, double range, double arc)
  931. {
  932. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  933. UUID keyID = UUID.Zero;
  934. UUID.TryParse(id, out keyID);
  935. SensorRepeatPlugin sensorPlugin = (SensorRepeatPlugin) m_ScriptEngine.GetScriptPlugin("SensorRepeat");
  936. sensorPlugin.SenseOnce(m_host.UUID, m_itemID, name, keyID, type, range, arc, m_host);
  937. }
  938. public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate)
  939. {
  940. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  941. UUID keyID = UUID.Zero;
  942. UUID.TryParse(id, out keyID);
  943. SensorRepeatPlugin sensorPlugin = (SensorRepeatPlugin) m_ScriptEngine.GetScriptPlugin("SensorRepeat");
  944. sensorPlugin.SetSenseRepeatEvent(m_host.UUID, m_itemID, name, keyID, type, range, arc, rate, m_host);
  945. }
  946. public void llSensorRemove()
  947. {
  948. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;
  949. SensorRepeatPlugin sensorPlugin = (SensorRepeatPlugin) m_ScriptEngine.GetScriptPlugin("SensorRepeat");
  950. sensorPlugin.RemoveScript(m_host.UUID, m_itemID);
  951. }
  952. public string resolveName(UUID objecUUID)
  953. {
  954. // try avatar username surname
  955. UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.AllScopeIDs, objecUUID);
  956. if (account != null)
  957. return account.Name;
  958. // try an scene object
  959. ISceneChildEntity SOP = World.GetSceneObjectPart(objecUUID);
  960. if (SOP != null)
  961. return SOP.Name;
  962. IEntity SensedObject;
  963. if (!World.Entities.TryGetValue(objecUUID, out SensedObject))
  964. {
  965. IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
  966. if (groups != null)
  967. {
  968. GroupRecord gr = groups.GetGroupRecord(objecUUID);
  969. if (gr != null)
  970. return gr.GroupName;
  971. }
  972. return String.Empty;
  973. }
  974. return SensedObject.Name;
  975. }
  976. public LSL_String llDetectedName(int number)
  977. {
  978. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  979. return new LSL_String();
  980. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  981. if (detectedParams == null)
  982. return String.Empty;
  983. return detectedParams.Name;
  984. }
  985. public LSL_String llDetectedKey(int number)
  986. {
  987. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  988. return new LSL_String();
  989. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  990. if (detectedParams == null)
  991. return String.Empty;
  992. return detectedParams.Key.ToString();
  993. }
  994. public LSL_String llDetectedOwner(int number)
  995. {
  996. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  997. return new LSL_String();
  998. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  999. if (detectedParams == null)
  1000. return String.Empty;
  1001. return detectedParams.Owner.ToString();
  1002. }
  1003. public LSL_Integer llDetectedType(int number)
  1004. {
  1005. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  1006. return new LSL_Integer();
  1007. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  1008. if (detectedParams == null)
  1009. return 0;
  1010. return new LSL_Integer(detectedParams.Type);
  1011. }
  1012. public LSL_Vector llDetectedPos(int number)
  1013. {
  1014. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  1015. return new LSL_Vector();
  1016. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  1017. if (detectedParams == null)
  1018. return new LSL_Vector();
  1019. return detectedParams.Position;
  1020. }
  1021. public LSL_Vector llDetectedVel(int number)
  1022. {
  1023. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  1024. return new LSL_Vector();
  1025. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  1026. if (detectedParams == null)
  1027. return new LSL_Vector();
  1028. return detectedParams.Velocity;
  1029. }
  1030. public LSL_Vector llDetectedGrab(int number)
  1031. {
  1032. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  1033. return new LSL_Vector();
  1034. DetectParams parms = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  1035. if (parms == null)
  1036. return new LSL_Vector(0, 0, 0);
  1037. return parms.OffsetPos;
  1038. }
  1039. public LSL_Rotation llDetectedRot(int number)
  1040. {
  1041. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  1042. return new LSL_Rotation();
  1043. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  1044. if (detectedParams == null)
  1045. return new LSL_Rotation();
  1046. return detectedParams.Rotation;
  1047. }
  1048. public LSL_Integer llDetectedGroup(int number)
  1049. {
  1050. if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
  1051. return new LSL_Integer();
  1052. DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_host.UUID, m_itemID, number);
  1053. if (detectedParams == null)
  1054. ret

Large files files are truncated, but you can click here to view the full file