OSSL_Api.cs 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.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 OpenSim 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 System;
  28. using System.Collections;
  29. using System.Collections.Generic;
  30. using System.Runtime.Remoting.Lifetime;
  31. using System.Text;
  32. using OpenMetaverse;
  33. using Nini.Config;
  34. using OpenSim;
  35. using OpenSim.Framework;
  36. using OpenSim.Framework.Console;
  37. using OpenSim.Region.Environment.Interfaces;
  38. using OpenSim.Region.Environment.Scenes;
  39. using OpenSim.Region.ScriptEngine.Shared;
  40. using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
  41. using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
  42. using OpenSim.Region.ScriptEngine.Interfaces;
  43. using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
  44. using TPFlags = OpenSim.Framework.Constants.TeleportFlags;
  45. using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
  46. using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
  47. using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
  48. using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
  49. using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
  50. using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
  51. using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
  52. namespace OpenSim.Region.ScriptEngine.Shared.Api
  53. {
  54. //////////////////////////////////////////////////////////////
  55. //
  56. // Level description
  57. //
  58. // None - Function is no threat at all. It doesn't constitute
  59. // an threat to either users or the system and has no
  60. // known side effects
  61. //
  62. // Nuisance - Abuse of this command can cause a nuisance to the
  63. // region operator, such as log message spew
  64. //
  65. // VeryLow - Extreme levels ob abuse of this function can cause
  66. // impaired functioning of the region, or very gullible
  67. // users can be tricked into experiencing harmless effects
  68. //
  69. // Low - Intentional abuse can cause crashes or malfunction
  70. // under certain circumstances, which can easily be rectified,
  71. // or certain users can be tricked into certain situations
  72. // in an avoidable manner.
  73. //
  74. // Moderate - Intentional abuse can cause denial of service and crashes
  75. // with potential of data or state loss, or trusting users
  76. // can be tricked into embarrassing or uncomfortable
  77. // situationsa.
  78. //
  79. // High - Casual abuse can cause impaired functionality or temporary
  80. // denial of service conditions. Intentional abuse can easily
  81. // cause crashes with potential data loss, or can be used to
  82. // trick experienced and cautious users into unwanted situations,
  83. // or changes global data permanently and without undo ability
  84. //
  85. // VeryHigh - Even normal use may, depending on the number of instances,
  86. // or frequency of use, result in severe service impairment
  87. // or crash with loss of data, or can be used to cause
  88. // unwanted or harmful effects on users without giving the
  89. // user a means to avoid it.
  90. //
  91. // Severe - Even casual use is a danger to region stability, or function
  92. // allows console or OS command execution, or function allows
  93. // taking money without consent, or allows deletion or
  94. // modification of user data, or allows the compromise of
  95. // sensitive data by design.
  96. [Serializable]
  97. public class OSSL_Api : MarshalByRefObject, IOSSL_Api, IScriptApi
  98. {
  99. internal IScriptEngine m_ScriptEngine;
  100. internal ILSL_Api m_LSL_Api; // get a reference to the LSL API so we can call methods housed there
  101. internal SceneObjectPart m_host;
  102. internal uint m_localID;
  103. internal UUID m_itemID;
  104. internal bool m_OSFunctionsEnabled = false;
  105. internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
  106. internal float m_ScriptDelayFactor = 1.0f;
  107. internal float m_ScriptDistanceFactor = 1.0f;
  108. internal Dictionary<string, List<UUID> > m_FunctionPerms = new Dictionary<string, List<UUID> >();
  109. public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
  110. {
  111. m_ScriptEngine = ScriptEngine;
  112. m_host = host;
  113. m_localID = localID;
  114. m_itemID = itemID;
  115. if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
  116. m_OSFunctionsEnabled = true;
  117. m_ScriptDelayFactor =
  118. m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
  119. m_ScriptDistanceFactor =
  120. m_ScriptEngine.Config.GetFloat("ScriptDistanceLimitFactor", 1.0f);
  121. string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow");
  122. switch (risk)
  123. {
  124. case "None":
  125. m_MaxThreatLevel = ThreatLevel.None;
  126. break;
  127. case "VeryLow":
  128. m_MaxThreatLevel = ThreatLevel.VeryLow;
  129. break;
  130. case "Low":
  131. m_MaxThreatLevel = ThreatLevel.Low;
  132. break;
  133. case "Moderate":
  134. m_MaxThreatLevel = ThreatLevel.Moderate;
  135. break;
  136. case "High":
  137. m_MaxThreatLevel = ThreatLevel.High;
  138. break;
  139. case "VeryHigh":
  140. m_MaxThreatLevel = ThreatLevel.VeryHigh;
  141. break;
  142. case "Severe":
  143. m_MaxThreatLevel = ThreatLevel.Severe;
  144. break;
  145. default:
  146. break;
  147. }
  148. }
  149. //
  150. // Never expire this object
  151. //
  152. public override Object InitializeLifetimeService()
  153. {
  154. ILease lease = (ILease)base.InitializeLifetimeService();
  155. if (lease.CurrentState == LeaseState.Initial)
  156. {
  157. lease.InitialLeaseTime = TimeSpan.Zero;
  158. }
  159. return lease;
  160. }
  161. public Scene World
  162. {
  163. get { return m_ScriptEngine.World; }
  164. }
  165. internal void OSSLError(string msg)
  166. {
  167. throw new Exception("OSSL Runtime Error: " + msg);
  168. }
  169. public void CheckThreatLevel(ThreatLevel level, string function)
  170. {
  171. if (!m_OSFunctionsEnabled)
  172. OSSLError(String.Format("{0} permission denied. All OS functions are disabled.", function)); // throws
  173. if (!m_FunctionPerms.ContainsKey(function))
  174. {
  175. string perm = m_ScriptEngine.Config.GetString("Allow_"+function, "");
  176. if (perm == "")
  177. {
  178. m_FunctionPerms[function] = null; // a null value is default
  179. }
  180. else
  181. {
  182. bool allowed;
  183. if (bool.TryParse(perm, out allowed))
  184. {
  185. // Boolean given
  186. if (allowed)
  187. {
  188. m_FunctionPerms[function] = new List<UUID>();
  189. m_FunctionPerms[function].Add(UUID.Zero);
  190. }
  191. else
  192. m_FunctionPerms[function] = new List<UUID>(); // Empty list = none
  193. }
  194. else
  195. {
  196. m_FunctionPerms[function] = new List<UUID>();
  197. string[] ids = perm.Split(new char[] {','});
  198. foreach (string id in ids)
  199. {
  200. string current = id.Trim();
  201. UUID uuid;
  202. if (UUID.TryParse(current, out uuid))
  203. {
  204. if (uuid != UUID.Zero)
  205. m_FunctionPerms[function].Add(uuid);
  206. }
  207. }
  208. }
  209. }
  210. }
  211. // If the list is null, then the value was true / undefined
  212. // Threat level governs permissions in this case
  213. //
  214. // If the list is non-null, then it is a list of UUIDs allowed
  215. // to use that particular function. False causes an empty
  216. // list and therefore means "no one"
  217. //
  218. // To allow use by anyone, the list contains UUID.Zero
  219. //
  220. if (m_FunctionPerms[function] == null) // No list = true
  221. {
  222. if (level > m_MaxThreatLevel)
  223. OSSLError(
  224. String.Format(
  225. "{0} permission denied. Allowed threat level is {1} but function threat level is {2}.",
  226. function, m_MaxThreatLevel, level));
  227. }
  228. else
  229. {
  230. if (!m_FunctionPerms[function].Contains(UUID.Zero))
  231. {
  232. if (!m_FunctionPerms[function].Contains(m_host.OwnerID))
  233. OSSLError(
  234. String.Format("{0} permission denied. Prim owner is not in the list of users allowed to execute this function.",
  235. function));
  236. }
  237. }
  238. }
  239. protected void ScriptSleep(int delay)
  240. {
  241. delay = (int)((float)delay * m_ScriptDelayFactor);
  242. if (delay == 0)
  243. return;
  244. System.Threading.Thread.Sleep(delay);
  245. }
  246. //
  247. // OpenSim functions
  248. //
  249. public int osTerrainSetHeight(int x, int y, double val)
  250. {
  251. CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
  252. m_host.AddScriptLPS(1);
  253. if (x > 255 || x < 0 || y > 255 || y < 0)
  254. OSSLError("osTerrainSetHeight: Coordinate out of bounds");
  255. if (World.Permissions.CanTerraformLand(m_host.OwnerID, new Vector3(x, y, 0)))
  256. {
  257. World.Heightmap[x, y] = val;
  258. return 1;
  259. }
  260. else
  261. {
  262. return 0;
  263. }
  264. }
  265. public double osTerrainGetHeight(int x, int y)
  266. {
  267. CheckThreatLevel(ThreatLevel.None, "osTerrainGetHeight");
  268. m_host.AddScriptLPS(1);
  269. if (x > 255 || x < 0 || y > 255 || y < 0)
  270. OSSLError("osTerrainGetHeight: Coordinate out of bounds");
  271. return World.Heightmap[x, y];
  272. }
  273. public int osRegionRestart(double seconds)
  274. {
  275. // This is High here because region restart is not reliable
  276. // it may result in the region staying down or becoming
  277. // unstable. This should be changed to Low or VeryLow once
  278. // The underlying functionality is fixed, since the security
  279. // as such is sound
  280. //
  281. CheckThreatLevel(ThreatLevel.High, "osRegionRestart");
  282. m_host.AddScriptLPS(1);
  283. if (World.Permissions.CanIssueEstateCommand(m_host.OwnerID, false))
  284. {
  285. World.Restart((float)seconds);
  286. return 1;
  287. }
  288. else
  289. {
  290. return 0;
  291. }
  292. }
  293. public void osRegionNotice(string msg)
  294. {
  295. // This implementation provides absolutely no security
  296. // It's high griefing potential makes this classification
  297. // necessary
  298. //
  299. CheckThreatLevel(ThreatLevel.VeryHigh, "osRegionNotice");
  300. m_host.AddScriptLPS(1);
  301. World.SendGeneralAlert(msg);
  302. }
  303. public void osSetRot(UUID target, Quaternion rotation)
  304. {
  305. // This function has no security. It can be used to destroy
  306. // arbitrary builds the user would normally have no rights to
  307. //
  308. CheckThreatLevel(ThreatLevel.VeryHigh, "osSetRot");
  309. m_host.AddScriptLPS(1);
  310. if (World.Entities.ContainsKey(target))
  311. {
  312. World.Entities[target].Rotation = rotation;
  313. }
  314. else
  315. {
  316. OSSLError("osSetRot: Invalid target");
  317. }
  318. }
  319. public string osSetDynamicTextureURL(string dynamicID, string contentType, string url, string extraParams,
  320. int timer)
  321. {
  322. // This may be upgraded depending on the griefing or DOS
  323. // potential, or guarded with a delay
  324. //
  325. CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURL");
  326. m_host.AddScriptLPS(1);
  327. if (dynamicID == String.Empty)
  328. {
  329. IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
  330. UUID createdTexture =
  331. textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
  332. extraParams, timer);
  333. return createdTexture.ToString();
  334. }
  335. else
  336. {
  337. //TODO update existing dynamic textures
  338. }
  339. return UUID.Zero.ToString();
  340. }
  341. public string osSetDynamicTextureURLBlend(string dynamicID, string contentType, string url, string extraParams,
  342. int timer, int alpha)
  343. {
  344. CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureURLBlend");
  345. m_host.AddScriptLPS(1);
  346. if (dynamicID == String.Empty)
  347. {
  348. IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
  349. UUID createdTexture =
  350. textureManager.AddDynamicTextureURL(World.RegionInfo.RegionID, m_host.UUID, contentType, url,
  351. extraParams, timer, true, (byte) alpha);
  352. return createdTexture.ToString();
  353. }
  354. else
  355. {
  356. //TODO update existing dynamic textures
  357. }
  358. return UUID.Zero.ToString();
  359. }
  360. public string osSetDynamicTextureData(string dynamicID, string contentType, string data, string extraParams,
  361. int timer)
  362. {
  363. CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureData");
  364. m_host.AddScriptLPS(1);
  365. if (dynamicID == String.Empty)
  366. {
  367. IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
  368. if (textureManager != null)
  369. {
  370. if (extraParams == String.Empty)
  371. {
  372. extraParams = "256";
  373. }
  374. UUID createdTexture =
  375. textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
  376. extraParams, timer);
  377. return createdTexture.ToString();
  378. }
  379. }
  380. else
  381. {
  382. //TODO update existing dynamic textures
  383. }
  384. return UUID.Zero.ToString();
  385. }
  386. public string osSetDynamicTextureDataBlend(string dynamicID, string contentType, string data, string extraParams,
  387. int timer, int alpha)
  388. {
  389. CheckThreatLevel(ThreatLevel.VeryLow, "osSetDynamicTextureDataBlend");
  390. m_host.AddScriptLPS(1);
  391. if (dynamicID == String.Empty)
  392. {
  393. IDynamicTextureManager textureManager = World.RequestModuleInterface<IDynamicTextureManager>();
  394. if (textureManager != null)
  395. {
  396. if (extraParams == String.Empty)
  397. {
  398. extraParams = "256";
  399. }
  400. UUID createdTexture =
  401. textureManager.AddDynamicTextureData(World.RegionInfo.RegionID, m_host.UUID, contentType, data,
  402. extraParams, timer, true, (byte) alpha);
  403. return createdTexture.ToString();
  404. }
  405. }
  406. else
  407. {
  408. //TODO update existing dynamic textures
  409. }
  410. return UUID.Zero.ToString();
  411. }
  412. public bool osConsoleCommand(string command)
  413. {
  414. CheckThreatLevel(ThreatLevel.Severe, "osConsoleCommand");
  415. m_host.AddScriptLPS(1);
  416. if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
  417. {
  418. MainConsole.Instance.RunCommand(command);
  419. return true;
  420. }
  421. return false;
  422. }
  423. public void osSetPrimFloatOnWater(int floatYN)
  424. {
  425. CheckThreatLevel(ThreatLevel.VeryLow, "osSetPrimFloatOnWater");
  426. m_host.AddScriptLPS(1);
  427. if (m_host.ParentGroup != null)
  428. {
  429. if (m_host.ParentGroup.RootPart != null)
  430. {
  431. m_host.ParentGroup.RootPart.SetFloatOnWater(floatYN);
  432. }
  433. }
  434. }
  435. // Teleport functions
  436. public void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
  437. {
  438. // High because there is no security check. High griefer potential
  439. //
  440. CheckThreatLevel(ThreatLevel.High, "osTeleportAgent");
  441. m_host.AddScriptLPS(1);
  442. UUID agentId = new UUID();
  443. if (UUID.TryParse(agent, out agentId))
  444. {
  445. ScenePresence presence = World.GetScenePresence(agentId);
  446. if (presence != null)
  447. {
  448. // agent must be over owners land to avoid abuse
  449. if (m_host.OwnerID == World.GetLandOwner(presence.AbsolutePosition.X, presence.AbsolutePosition.Y))
  450. {
  451. presence.ControllingClient.SendTeleportLocationStart();
  452. World.RequestTeleportLocation(presence.ControllingClient, regionName,
  453. new Vector3((float)position.x, (float)position.y, (float)position.z),
  454. new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation);
  455. ScriptSleep(5000);
  456. }
  457. }
  458. }
  459. }
  460. public void osTeleportAgent(string agent, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat)
  461. {
  462. osTeleportAgent(agent, World.RegionInfo.RegionName, position, lookat);
  463. }
  464. // Adam's super super custom animation functions
  465. public void osAvatarPlayAnimation(string avatar, string animation)
  466. {
  467. CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation");
  468. UUID avatarID = (UUID)avatar;
  469. m_host.AddScriptLPS(1);
  470. if (World.Entities.ContainsKey((UUID)avatar) && World.Entities[avatarID] is ScenePresence)
  471. {
  472. ScenePresence target = (ScenePresence)World.Entities[avatarID];
  473. target.AddAnimation(animation);
  474. }
  475. }
  476. public void osAvatarStopAnimation(string avatar, string animation)
  477. {
  478. CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation");
  479. UUID avatarID = (UUID)avatar;
  480. m_host.AddScriptLPS(1);
  481. if (World.Entities.ContainsKey(avatarID) && World.Entities[avatarID] is ScenePresence)
  482. {
  483. ScenePresence target = (ScenePresence)World.Entities[avatarID];
  484. target.RemoveAnimation(animation);
  485. }
  486. }
  487. //Texture draw functions
  488. public string osMovePen(string drawList, int x, int y)
  489. {
  490. CheckThreatLevel(ThreatLevel.None, "osMovePen");
  491. m_host.AddScriptLPS(1);
  492. drawList += "MoveTo " + x + "," + y + ";";
  493. return drawList;
  494. }
  495. public string osDrawLine(string drawList, int startX, int startY, int endX, int endY)
  496. {
  497. CheckThreatLevel(ThreatLevel.None, "osDrawLine");
  498. m_host.AddScriptLPS(1);
  499. drawList += "MoveTo "+ startX+","+ startY +"; LineTo "+endX +","+endY +"; ";
  500. return drawList;
  501. }
  502. public string osDrawLine(string drawList, int endX, int endY)
  503. {
  504. CheckThreatLevel(ThreatLevel.None, "osDrawLine");
  505. m_host.AddScriptLPS(1);
  506. drawList += "LineTo " + endX + "," + endY + "; ";
  507. return drawList;
  508. }
  509. public string osDrawText(string drawList, string text)
  510. {
  511. CheckThreatLevel(ThreatLevel.None, "osDrawText");
  512. m_host.AddScriptLPS(1);
  513. drawList += "Text " + text + "; ";
  514. return drawList;
  515. }
  516. public string osDrawEllipse(string drawList, int width, int height)
  517. {
  518. CheckThreatLevel(ThreatLevel.None, "osDrawEllipse");
  519. m_host.AddScriptLPS(1);
  520. drawList += "Ellipse " + width + "," + height + "; ";
  521. return drawList;
  522. }
  523. public string osDrawRectangle(string drawList, int width, int height)
  524. {
  525. CheckThreatLevel(ThreatLevel.None, "osDrawRectangle");
  526. m_host.AddScriptLPS(1);
  527. drawList += "Rectangle " + width + "," + height + "; ";
  528. return drawList;
  529. }
  530. public string osDrawFilledRectangle(string drawList, int width, int height)
  531. {
  532. CheckThreatLevel(ThreatLevel.None, "osDrawFilledRectangle");
  533. m_host.AddScriptLPS(1);
  534. drawList += "FillRectangle " + width + "," + height + "; ";
  535. return drawList;
  536. }
  537. public string osSetFontSize(string drawList, int fontSize)
  538. {
  539. CheckThreatLevel(ThreatLevel.None, "osSetFontSize");
  540. m_host.AddScriptLPS(1);
  541. drawList += "FontSize "+ fontSize +"; ";
  542. return drawList;
  543. }
  544. public string osSetPenSize(string drawList, int penSize)
  545. {
  546. CheckThreatLevel(ThreatLevel.None, "osSetPenSize");
  547. m_host.AddScriptLPS(1);
  548. drawList += "PenSize " + penSize + "; ";
  549. return drawList;
  550. }
  551. public string osSetPenColour(string drawList, string colour)
  552. {
  553. CheckThreatLevel(ThreatLevel.None, "osSetPenColour");
  554. m_host.AddScriptLPS(1);
  555. drawList += "PenColour " + colour + "; ";
  556. return drawList;
  557. }
  558. public string osDrawImage(string drawList, int width, int height, string imageUrl)
  559. {
  560. CheckThreatLevel(ThreatLevel.None, "osDrawImage");
  561. m_host.AddScriptLPS(1);
  562. drawList +="Image " +width + "," + height+ ","+ imageUrl +"; " ;
  563. return drawList;
  564. }
  565. public void osSetStateEvents(int events)
  566. {
  567. // This function is a hack. There is no reason for it's existence
  568. // anymore, since state events now work properly.
  569. // It was probably added as a crutch or debugging aid, and
  570. // should be removed
  571. //
  572. CheckThreatLevel(ThreatLevel.High, "osSetStateEvents");
  573. m_host.SetScriptEvents(m_itemID, events);
  574. }
  575. public void osSetRegionWaterHeight(double height)
  576. {
  577. CheckThreatLevel(ThreatLevel.High, "osSetRegionWaterHeight");
  578. m_host.AddScriptLPS(1);
  579. //Check to make sure that the script's owner is the estate manager/master
  580. //World.Permissions.GenericEstatePermission(
  581. if (World.Permissions.IsGod(m_host.OwnerID))
  582. {
  583. World.EventManager.TriggerRequestChangeWaterHeight((float)height);
  584. }
  585. }
  586. public double osList2Double(LSL_Types.list src, int index)
  587. {
  588. // There is really no double type in OSSL. C# and other
  589. // have one, but the current implementation of LSL_Types.list
  590. // is not allowed to contain any.
  591. // This really should be removed.
  592. //
  593. CheckThreatLevel(ThreatLevel.None, "osList2Double");
  594. m_host.AddScriptLPS(1);
  595. if (index < 0)
  596. {
  597. index = src.Length + index;
  598. }
  599. if (index >= src.Length)
  600. {
  601. return 0.0;
  602. }
  603. return Convert.ToDouble(src.Data[index]);
  604. }
  605. public void osSetParcelMediaURL(string url)
  606. {
  607. // What actually is the difference to the LL function?
  608. //
  609. CheckThreatLevel(ThreatLevel.VeryLow, "osSetParcelMediaURL");
  610. m_host.AddScriptLPS(1);
  611. UUID landowner = World.GetLandOwner(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
  612. if (landowner == UUID.Zero)
  613. {
  614. return;
  615. }
  616. if (landowner != m_host.ObjectOwner)
  617. {
  618. return;
  619. }
  620. World.SetLandMediaURL(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y, url);
  621. }
  622. public string osGetScriptEngineName()
  623. {
  624. // This gets a "high" because knowing the engine may be used
  625. // to exploit engine-specific bugs or induce usage patterns
  626. // that trigger engine-specific failures.
  627. // Besides, public grid users aren't supposed to know.
  628. //
  629. CheckThreatLevel(ThreatLevel.High, "osGetScriptEngineName");
  630. m_host.AddScriptLPS(1);
  631. int scriptEngineNameIndex = 0;
  632. if (!String.IsNullOrEmpty(m_ScriptEngine.ScriptEngineName))
  633. {
  634. // parse off the "ScriptEngine."
  635. scriptEngineNameIndex = m_ScriptEngine.ScriptEngineName.IndexOf(".", scriptEngineNameIndex);
  636. scriptEngineNameIndex++; // get past delimiter
  637. int scriptEngineNameLength = m_ScriptEngine.ScriptEngineName.Length - scriptEngineNameIndex;
  638. // create char array then a string that is only the script engine name
  639. Char[] scriptEngineNameCharArray = m_ScriptEngine.ScriptEngineName.ToCharArray(scriptEngineNameIndex, scriptEngineNameLength);
  640. String scriptEngineName = new String(scriptEngineNameCharArray);
  641. return scriptEngineName;
  642. }
  643. else
  644. {
  645. return String.Empty;
  646. }
  647. }
  648. public string osGetSimulatorVersion()
  649. {
  650. // High because it can be used to target attacks to known weaknesses
  651. // This would allow a new class of griefer scripts that don't even
  652. // require their user to know what they are doing (see script
  653. // kiddie)
  654. //
  655. CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion");
  656. m_host.AddScriptLPS(1);
  657. return m_ScriptEngine.World.GetSimulatorVersion();
  658. }
  659. //for testing purposes only
  660. public void osSetParcelMediaTime(double time)
  661. {
  662. // This gets very high because I have no idea what it does.
  663. // If someone knows, please adjust. If it;s no longer needed,
  664. // please remove.
  665. //This sets the current time on a video. IE, it can be used to skip to a set time in the video. [MW]
  666. CheckThreatLevel(ThreatLevel.VeryHigh, "osSetParcelMediaTime");
  667. m_host.AddScriptLPS(1);
  668. World.ParcelMediaSetTime((float)time);
  669. }
  670. public Hashtable osParseJSON(string JSON)
  671. {
  672. CheckThreatLevel(ThreatLevel.None, "osParseJSON");
  673. m_host.AddScriptLPS(1);
  674. // see http://www.json.org/ for more details on JSON
  675. string currentKey=null;
  676. Stack objectStack = new Stack(); // objects in JSON can be nested so we need to keep a track of this
  677. Hashtable jsondata = new Hashtable(); // the hashtable to be returned
  678. int i=0;
  679. try
  680. {
  681. // iterate through the serialised stream of tokens and store at the right depth in the hashtable
  682. // the top level hashtable may contain more nested hashtables within it each containing an objects representation
  683. for (i=0;i<JSON.Length; i++)
  684. {
  685. // Console.WriteLine(""+JSON[i]);
  686. switch (JSON[i])
  687. {
  688. case '{':
  689. // create hashtable and add it to the stack or array if we are populating one, we can have a lot of nested objects in JSON
  690. Hashtable currentObject = new Hashtable();
  691. if (objectStack.Count==0) // the stack should only be empty for the first outer object
  692. {
  693. objectStack.Push(jsondata);
  694. }
  695. else if (objectStack.Peek().ToString()=="System.Collections.ArrayList")
  696. {
  697. // add it to the parent array
  698. ((ArrayList)objectStack.Peek()).Add(currentObject);
  699. objectStack.Push(currentObject);
  700. }
  701. else
  702. {
  703. // add it to the parent hashtable
  704. ((Hashtable)objectStack.Peek()).Add(currentKey,currentObject);
  705. objectStack.Push(currentObject);
  706. }
  707. // clear the key
  708. currentKey=null;
  709. break;
  710. case '}':
  711. // pop the hashtable off the stack
  712. objectStack.Pop();
  713. break;
  714. case '"':// string boundary
  715. string tokenValue="";
  716. i++; // move to next char
  717. // just loop through until the next quote mark storing the string, ignore quotes with pre-ceding \
  718. while (JSON[i]!='"')
  719. {
  720. tokenValue+=JSON[i];
  721. // handle escaped double quotes \"
  722. if (JSON[i]=='\\' && JSON[i+1]=='"')
  723. {
  724. tokenValue+=JSON[i+1];
  725. i++;
  726. }
  727. i++;
  728. }
  729. // ok we've got a string, if we've got an array on the top of the stack then we store it
  730. if (objectStack.Peek().ToString()=="System.Collections.ArrayList")
  731. {
  732. ((ArrayList)objectStack.Peek()).Add(tokenValue);
  733. }
  734. else if (currentKey==null) // no key stored and its not an array this must be a key so store it
  735. {
  736. currentKey = tokenValue;
  737. }
  738. else
  739. {
  740. // we have a key so lets store this value
  741. ((Hashtable)objectStack.Peek()).Add(currentKey,tokenValue);
  742. // now lets clear the key, we're done with it and moving on
  743. currentKey=null;
  744. }
  745. break;
  746. case ':':// key : value separator
  747. // just ignore
  748. break;
  749. case ' ':// spaces
  750. // just ignore
  751. break;
  752. case '[': // array start
  753. ArrayList currentArray = new ArrayList();
  754. if (objectStack.Peek().ToString()=="System.Collections.ArrayList")
  755. {
  756. ((ArrayList)objectStack.Peek()).Add(currentArray);
  757. }
  758. else
  759. {
  760. ((Hashtable)objectStack.Peek()).Add(currentKey,currentArray);
  761. // clear the key
  762. currentKey=null;
  763. }
  764. objectStack.Push(currentArray);
  765. break;
  766. case ',':// seperator
  767. // just ignore
  768. break;
  769. case ']'://Array end
  770. // pop the array off the stack
  771. objectStack.Pop();
  772. break;
  773. case 't': // we've found a character start not in quotes, it must be a boolean true
  774. if (objectStack.Peek().ToString()=="System.Collections.ArrayList")
  775. {
  776. ((ArrayList)objectStack.Peek()).Add(true);
  777. }
  778. else
  779. {
  780. ((Hashtable)objectStack.Peek()).Add(currentKey,true);
  781. currentKey=null;
  782. }
  783. //advance the counter to the letter 'e'
  784. i = i+3;
  785. break;
  786. case 'f': // we've found a character start not in quotes, it must be a boolean false
  787. if (objectStack.Peek().ToString()=="System.Collections.ArrayList")
  788. {
  789. ((ArrayList)objectStack.Peek()).Add(false);
  790. }
  791. else
  792. {
  793. ((Hashtable)objectStack.Peek()).Add(currentKey,false);
  794. currentKey=null;
  795. }
  796. //advance the counter to the letter 'e'
  797. i = i+4;
  798. break;
  799. case '\n':// carriage return
  800. // just ignore
  801. break;
  802. case '\r':// carriage return
  803. // just ignore
  804. break;
  805. default:
  806. // ok here we're catching all numeric types int,double,long we might want to spit these up mr accurately
  807. // but for now we'll just do them as strings
  808. string numberValue="";
  809. // just loop through until the next known marker quote mark storing the string
  810. while (JSON[i] != '"' && JSON[i] != ',' && JSON[i] != ']' && JSON[i] != '}' && JSON[i] != ' ')
  811. {
  812. numberValue+=""+JSON[i++];
  813. }
  814. i--; // we want to process this caracter that marked the end of this string in the main loop
  815. // ok we've got a string, if we've got an array on the top of the stack then we store it
  816. if (objectStack.Peek().ToString()=="System.Collections.ArrayList")
  817. {
  818. ((ArrayList)objectStack.Peek()).Add(numberValue);
  819. }
  820. else
  821. {
  822. // we have a key so lets store this value
  823. ((Hashtable)objectStack.Peek()).Add(currentKey,numberValue);
  824. // now lets clear the key, we're done with it and moving on
  825. currentKey=null;
  826. }
  827. break;
  828. }
  829. }
  830. }
  831. catch(Exception)
  832. {
  833. OSSLError("osParseJSON: The JSON string is not valid " + JSON) ;
  834. }
  835. return jsondata;
  836. }
  837. // send a message to to object identified by the given UUID, a script in the object must implement the dataserver function
  838. // the dataserver function is passed the ID of the calling function and a string message
  839. public void osMessageObject(LSL_Key objectUUID, string message)
  840. {
  841. CheckThreatLevel(ThreatLevel.Low, "osMessageObject");
  842. m_host.AddScriptLPS(1);
  843. object[] resobj = new object[] { new LSL_Types.LSLString(m_host.UUID.ToString()), new LSL_Types.LSLString(message) };
  844. SceneObjectPart sceneOP = World.GetSceneObjectPart(new UUID(objectUUID));
  845. m_ScriptEngine.PostObjectEvent(
  846. sceneOP.LocalId, new EventParams(
  847. "dataserver", resobj, new DetectParams[0]));
  848. }
  849. // This needs ThreatLevel high. It is an excellent griefer tool,
  850. // In a loop, it can cause asset bloat and DOS levels of asset
  851. // writes.
  852. //
  853. public void osMakeNotecard(string notecardName, LSL_Types.list contents)
  854. {
  855. CheckThreatLevel(ThreatLevel.High, "osMakeNotecard");
  856. m_host.AddScriptLPS(1);
  857. // Create new asset
  858. AssetBase asset = new AssetBase();
  859. asset.Name = notecardName;
  860. asset.Description = "Script Generated Notecard";
  861. asset.Type = 7;
  862. asset.FullID = UUID.Random();
  863. string notecardData = "";
  864. for (int i = 0; i < contents.Length; i++) {
  865. notecardData += contents.GetLSLStringItem(i) + "\n";
  866. }
  867. int textLength = notecardData.Length;
  868. notecardData = "Linden text version 2\n{\nLLEmbeddedItems version 1\n{\ncount 0\n}\nText length "
  869. + textLength.ToString() + "\n" + notecardData + "}\n";
  870. asset.Data = Encoding.ASCII.GetBytes(notecardData);
  871. World.AssetCache.AddAsset(asset);
  872. // Create Task Entry
  873. TaskInventoryItem taskItem=new TaskInventoryItem();
  874. taskItem.ResetIDs(m_host.UUID);
  875. taskItem.ParentID = m_host.UUID;
  876. taskItem.CreationDate = (uint)Util.UnixTimeSinceEpoch();
  877. taskItem.Name = asset.Name;
  878. taskItem.Description = asset.Description;
  879. taskItem.Type = 7;
  880. taskItem.InvType = 7;
  881. taskItem.OwnerID = m_host.OwnerID;
  882. taskItem.CreatorID = m_host.OwnerID;
  883. taskItem.BasePermissions = (uint)PermissionMask.All;
  884. taskItem.CurrentPermissions = (uint)PermissionMask.All;
  885. taskItem.EveryonePermissions = 0;
  886. taskItem.NextPermissions = (uint)PermissionMask.All;
  887. taskItem.GroupID = m_host.GroupID;
  888. taskItem.GroupPermissions = 0;
  889. taskItem.Flags = 0;
  890. taskItem.PermsGranter = UUID.Zero;
  891. taskItem.PermsMask = 0;
  892. taskItem.AssetID = asset.FullID;
  893. m_host.Inventory.AddInventoryItem(taskItem, false);
  894. }
  895. }
  896. }