aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs812
1 files changed, 487 insertions, 325 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7be64eb..bc35272 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -48,6 +48,7 @@ using OpenSim.Region.Framework.Interfaces;
48using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization; 49using OpenSim.Region.Framework.Scenes.Serialization;
50using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
51using OpenSim.Region.Framework.Scenes.Scripting;
51using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
52using OpenSim.Region.ScriptEngine.Shared; 53using OpenSim.Region.ScriptEngine.Shared;
53using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 54using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
@@ -70,6 +71,8 @@ using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
71using System.Reflection; 72using System.Reflection;
72using Timer = System.Timers.Timer; 73using Timer = System.Timers.Timer;
74using System.Linq;
75using PermissionMask = OpenSim.Framework.PermissionMask;
73 76
74namespace OpenSim.Region.ScriptEngine.Shared.Api 77namespace OpenSim.Region.ScriptEngine.Shared.Api
75{ 78{
@@ -87,10 +90,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
87 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 90 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
88 { 91 {
89 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 92 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
93
90 protected IScriptEngine m_ScriptEngine; 94 protected IScriptEngine m_ScriptEngine;
91 protected SceneObjectPart m_host; 95 protected SceneObjectPart m_host;
92 96
93 /// <summary> 97 /// <summary>
98 /// Used for script sleeps when we are using co-operative script termination.
99 /// </summary>
100 /// <remarks>null if co-operative script termination is not active</remarks>
101 WaitHandle m_coopSleepHandle;
102
103 /// <summary>
94 /// The item that hosts this script 104 /// The item that hosts this script
95 /// </summary> 105 /// </summary>
96 protected TaskInventoryItem m_item; 106 protected TaskInventoryItem m_item;
@@ -100,6 +110,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
100 protected float m_ScriptDelayFactor = 1.0f; 110 protected float m_ScriptDelayFactor = 1.0f;
101 protected float m_ScriptDistanceFactor = 1.0f; 111 protected float m_ScriptDistanceFactor = 1.0f;
102 protected float m_MinTimerInterval = 0.5f; 112 protected float m_MinTimerInterval = 0.5f;
113 protected float m_recoilScaleFactor = 0.0f;
103 114
104 protected DateTime m_timer = DateTime.Now; 115 protected DateTime m_timer = DateTime.Now;
105 protected bool m_waitingForScriptAnswer = false; 116 protected bool m_waitingForScriptAnswer = false;
@@ -140,34 +151,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 {"TURNLEFT", "Turning Left"}, 151 {"TURNLEFT", "Turning Left"},
141 {"TURNRIGHT", "Turning Right"} 152 {"TURNRIGHT", "Turning Right"}
142 }; 153 };
154 //An array of HTTP/1.1 headers that are not allowed to be used
155 //as custom headers by llHTTPRequest.
156 private string[] HttpStandardHeaders =
157 {
158 "Accept", "Accept-Charset", "Accept-Encoding", "Accept-Language",
159 "Accept-Ranges", "Age", "Allow", "Authorization", "Cache-Control",
160 "Connection", "Content-Encoding", "Content-Language",
161 "Content-Length", "Content-Location", "Content-MD5",
162 "Content-Range", "Content-Type", "Date", "ETag", "Expect",
163 "Expires", "From", "Host", "If-Match", "If-Modified-Since",
164 "If-None-Match", "If-Range", "If-Unmodified-Since", "Last-Modified",
165 "Location", "Max-Forwards", "Pragma", "Proxy-Authenticate",
166 "Proxy-Authorization", "Range", "Referer", "Retry-After", "Server",
167 "TE", "Trailer", "Transfer-Encoding", "Upgrade", "User-Agent",
168 "Vary", "Via", "Warning", "WWW-Authenticate"
169 };
143 170
144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 171 public void Initialize(
172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
145 { 173 {
146/*
147 m_ShoutSayTimer = new Timer(1000);
148 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
149 m_ShoutSayTimer.AutoReset = true;
150 m_ShoutSayTimer.Start();
151*/
152 m_lastSayShoutCheck = DateTime.UtcNow; 174 m_lastSayShoutCheck = DateTime.UtcNow;
153 175
154 m_ScriptEngine = ScriptEngine; 176 m_ScriptEngine = scriptEngine;
155 m_host = host; 177 m_host = host;
156 m_item = item; 178 m_item = item;
157 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false); 179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
180 m_coopSleepHandle = coopSleepHandle;
158 181
159 LoadLimits(); // read script limits from config. 182 LoadConfig();
160 183
161 m_TransferModule = 184 m_TransferModule =
162 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 185 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
163 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 186 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
164 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>(); 187 m_SoundModule = m_ScriptEngine.World.RequestModuleInterface<ISoundModule>();
165 188
166 AsyncCommands = new AsyncCommandManager(ScriptEngine); 189 AsyncCommands = new AsyncCommandManager(m_ScriptEngine);
167 } 190 }
168 191
169 /* load configuration items that affect script, object and run-time behavior. */ 192 /// <summary>
170 private void LoadLimits() 193 /// Load configuration items that affect script, object and run-time behavior. */
194 /// </summary>
195 private void LoadConfig()
171 { 196 {
172 m_ScriptDelayFactor = 197 m_ScriptDelayFactor =
173 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 198 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -181,12 +206,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
181 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255); 206 m_ScriptEngine.Config.GetInt("NotecardLineReadCharsMax", 255);
182 if (m_notecardLineReadCharsMax > 65535) 207 if (m_notecardLineReadCharsMax > 65535)
183 m_notecardLineReadCharsMax = 65535; 208 m_notecardLineReadCharsMax = 65535;
209
184 // load limits for particular subsystems. 210 // load limits for particular subsystems.
185 IConfig SMTPConfig; 211 IConfig SMTPConfig;
186 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) { 212 if ((SMTPConfig = m_ScriptEngine.ConfigSource.Configs["SMTP"]) != null) {
187 // there's an smtp config, so load in the snooze time. 213 // there's an smtp config, so load in the snooze time.
188 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME); 214 EMAIL_PAUSE_TIME = SMTPConfig.GetInt("email_pause_time", EMAIL_PAUSE_TIME);
189 } 215 }
216
217 // Rezzing an object with a velocity can create recoil. This feature seems to have been
218 // removed from recent versions of SL. The code computes recoil (vel*mass) and scales
219 // it by this factor. May be zero to turn off recoil all together.
220 m_recoilScaleFactor = m_ScriptEngine.Config.GetFloat("RecoilScaleFactor", m_recoilScaleFactor);
190 } 221 }
191 222
192 public override Object InitializeLifetimeService() 223 public override Object InitializeLifetimeService()
@@ -207,7 +238,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
207 delay = (int)((float)delay * m_ScriptDelayFactor); 238 delay = (int)((float)delay * m_ScriptDelayFactor);
208 if (delay == 0) 239 if (delay == 0)
209 return; 240 return;
210 System.Threading.Thread.Sleep(delay); 241
242 Sleep(delay);
243 }
244
245 protected virtual void Sleep(int delay)
246 {
247 if (m_coopSleepHandle == null)
248 System.Threading.Thread.Sleep(delay);
249 else
250 CheckForCoopTermination(delay);
251 }
252
253 /// <summary>
254 /// Check for co-operative termination.
255 /// </summary>
256 /// <param name='delay'>If called with 0, then just the check is performed with no wait.</param>
257 protected virtual void CheckForCoopTermination(int delay)
258 {
259 if (m_coopSleepHandle.WaitOne(delay))
260 throw new ScriptCoopStopException();
211 } 261 }
212 262
213 public Scene World 263 public Scene World
@@ -339,6 +389,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
339 } 389 }
340 } 390 }
341 391
392 /// <summary>
393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
394 /// </summary>
395 /// <remarks>
396 /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then
397 /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset.
398 /// The ScenePresences receive linknums in the order in which they sat.
399 /// </remarks>
400 /// <returns>
401 /// The link entity. null if not found.
402 /// </returns>
403 /// <param name='linknum'>
404 /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4).
405 /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned.
406 /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any
407 /// positive integer is given in this case then null is returned.
408 /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
409 /// of entities, then the entity which corresponds to that linknum is returned.
410 /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
411 /// null is returned.
412 /// </param>
413 public ISceneEntity GetLinkEntity(int linknum)
414 {
415 if (linknum < 0)
416 {
417 if (linknum == ScriptBaseClass.LINK_THIS)
418 return m_host;
419 else
420 return null;
421 }
422
423 int actualPrimCount = m_host.ParentGroup.PrimCount;
424 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
425 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
426
427 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
428 // prim that has any avatars sat upon it (in which case the root prim is link 1).
429 if (linknum == 0)
430 {
431 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
432 return m_host;
433
434 return null;
435 }
436 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
437 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
438 else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
439 {
440 if (sittingAvatarIds.Count > 0)
441 return m_host.ParentGroup.RootPart;
442 else
443 return null;
444 }
445 else if (linknum <= adjustedPrimCount)
446 {
447 if (linknum <= actualPrimCount)
448 {
449 return m_host.ParentGroup.GetLinkNumPart(linknum);
450 }
451 else
452 {
453 ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
454 if (sp != null)
455 return sp;
456 else
457 return null;
458 }
459 }
460 else
461 {
462 return null;
463 }
464 }
465
342 public List<SceneObjectPart> GetLinkParts(int linkType) 466 public List<SceneObjectPart> GetLinkParts(int linkType)
343 { 467 {
344 return GetLinkParts(m_host, linkType); 468 return GetLinkParts(m_host, linkType);
@@ -392,79 +516,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
392 } 516 }
393 } 517 }
394 518
395 protected UUID InventoryKey(string name, int type)
396 {
397 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name);
398
399 if (item != null && item.Type == type)
400 return item.AssetID;
401 else
402 return UUID.Zero;
403 }
404
405 /// <summary>
406 /// accepts a valid UUID, -or- a name of an inventory item.
407 /// Returns a valid UUID or UUID.Zero if key invalid and item not found
408 /// in prim inventory.
409 /// </summary>
410 /// <param name="k"></param>
411 /// <returns></returns>
412 protected UUID KeyOrName(string k)
413 {
414 UUID key;
415
416 // if we can parse the string as a key, use it.
417 // else try to locate the name in inventory of object. found returns key,
418 // not found returns UUID.Zero
419 if (!UUID.TryParse(k, out key))
420 {
421 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k);
422
423 if (item != null)
424 key = item.AssetID;
425 else
426 key = UUID.Zero;
427 }
428
429 return key;
430 }
431
432 /// <summary>
433 /// Return the UUID of the asset matching the specified key or name
434 /// and asset type.
435 /// </summary>
436 /// <param name="k"></param>
437 /// <param name="type"></param>
438 /// <returns></returns>
439 protected UUID KeyOrName(string k, AssetType type)
440 {
441 UUID key;
442
443 if (!UUID.TryParse(k, out key))
444 {
445 TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k);
446 if (item != null && item.Type == (int)type)
447 key = item.AssetID;
448 }
449 else
450 {
451 lock (m_host.TaskInventory)
452 {
453 foreach (KeyValuePair<UUID, TaskInventoryItem> item in m_host.TaskInventory)
454 {
455 if (item.Value.Type == (int)type && item.Value.Name == k)
456 {
457 key = item.Value.ItemID;
458 break;
459 }
460 }
461 }
462 }
463
464
465 return key;
466 }
467
468 //These are the implementations of the various ll-functions used by the LSL scripts. 519 //These are the implementations of the various ll-functions used by the LSL scripts.
469 public LSL_Float llSin(double f) 520 public LSL_Float llSin(double f)
470 { 521 {
@@ -1483,19 +1534,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1483 return 0; 1534 return 0;
1484 1535
1485 case ScriptBaseClass.STATUS_ROTATE_X: 1536 case ScriptBaseClass.STATUS_ROTATE_X:
1486 if (m_host.GetAxisRotation(2) == 2) 1537 // if (m_host.GetAxisRotation(2) != 0)
1538 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_X) != 0)
1487 return 1; 1539 return 1;
1488 else 1540 else
1489 return 0; 1541 return 0;
1490 1542
1491 case ScriptBaseClass.STATUS_ROTATE_Y: 1543 case ScriptBaseClass.STATUS_ROTATE_Y:
1492 if (m_host.GetAxisRotation(4) == 4) 1544 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Y) != 0)
1493 return 1; 1545 return 1;
1494 else 1546 else
1495 return 0; 1547 return 0;
1496 1548
1497 case ScriptBaseClass.STATUS_ROTATE_Z: 1549 case ScriptBaseClass.STATUS_ROTATE_Z:
1498 if (m_host.GetAxisRotation(8) == 8) 1550 if (m_host.GetAxisRotation((int)SceneObjectGroup.axisSelect.STATUS_ROTATE_Z) != 0)
1499 return 1; 1551 return 1;
1500 else 1552 else
1501 return 0; 1553 return 0;
@@ -1715,7 +1767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 if (tex.FaceTextures[i] != null) 1767 if (tex.FaceTextures[i] != null)
1716 { 1768 {
1717 tex.FaceTextures[i].Shiny = sval; 1769 tex.FaceTextures[i].Shiny = sval;
1718 tex.FaceTextures[i].Bump = bump;; 1770 tex.FaceTextures[i].Bump = bump;
1719 } 1771 }
1720 tex.DefaultTexture.Shiny = sval; 1772 tex.DefaultTexture.Shiny = sval;
1721 tex.DefaultTexture.Bump = bump; 1773 tex.DefaultTexture.Bump = bump;
@@ -1838,7 +1890,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); 1890 texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f);
1839 tex.DefaultTexture.RGBA = texcolor; 1891 tex.DefaultTexture.RGBA = texcolor;
1840 } 1892 }
1841 1893
1842 part.UpdateTextureEntry(tex.GetBytes()); 1894 part.UpdateTextureEntry(tex.GetBytes());
1843 return; 1895 return;
1844 } 1896 }
@@ -1875,10 +1927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 part.Shape.FlexiForceX = (float)Force.x; 1927 part.Shape.FlexiForceX = (float)Force.x;
1876 part.Shape.FlexiForceY = (float)Force.y; 1928 part.Shape.FlexiForceY = (float)Force.y;
1877 part.Shape.FlexiForceZ = (float)Force.z; 1929 part.Shape.FlexiForceZ = (float)Force.z;
1878 part.Shape.PathCurve = 0x80; 1930 part.Shape.PathCurve = (byte)Extrusion.Flexible;
1879 part.ParentGroup.HasGroupChanged = true; 1931 }
1880 part.ScheduleFullUpdate(); 1932 else
1933 {
1934 // Other values not set, they do not seem to be sent to the viewer
1935 // Setting PathCurve appears to be what actually toggles the check box and turns Flexi on and off
1936 part.Shape.PathCurve = (byte)Extrusion.Straight;
1937 part.Shape.FlexiEntry = false;
1881 } 1938 }
1939 part.ParentGroup.HasGroupChanged = true;
1940 part.ScheduleFullUpdate();
1882 } 1941 }
1883 1942
1884 /// <summary> 1943 /// <summary>
@@ -1954,7 +2013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1954 rgb.x = texcolor.R; 2013 rgb.x = texcolor.R;
1955 rgb.y = texcolor.G; 2014 rgb.y = texcolor.G;
1956 rgb.z = texcolor.B; 2015 rgb.z = texcolor.B;
1957 2016
1958 return rgb; 2017 return rgb;
1959 } 2018 }
1960 else 2019 else
@@ -1996,12 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1996 2055
1997 UUID textureID = new UUID(); 2056 UUID textureID = new UUID();
1998 2057
1999 textureID = InventoryKey(texture, (int)AssetType.Texture); 2058 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
2000 if (textureID == UUID.Zero) 2059 if (textureID == UUID.Zero)
2001 { 2060 {
2002 if (!UUID.TryParse(texture, out textureID)) 2061 if (!UUID.TryParse(texture, out textureID))
2003 return; 2062 return;
2004 } 2063 }
2005 2064
2006 Primitive.TextureEntry tex = part.Shape.Textures; 2065 Primitive.TextureEntry tex = part.Shape.Textures;
2007 2066
@@ -2207,7 +2266,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2207 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND. 2266 // IF YOU GET REGION CROSSINGS WORKING WITH THIS FUNCTION, REPLACE THE WORKAROUND.
2208 // 2267 //
2209 // This workaround is to prevent silent failure of this function. 2268 // This workaround is to prevent silent failure of this function.
2210 // According to the specification on the SL Wiki, providing a position outside of the 2269 // According to the specification on the SL Wiki, providing a position outside of the
2211 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize) 2270 if (pos.x < 0 || pos.x > Constants.RegionSize || pos.y < 0 || pos.y > Constants.RegionSize)
2212 { 2271 {
2213 return 0; 2272 return 0;
@@ -2442,7 +2501,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2442 { 2501 {
2443 return llGetRootRotation(); 2502 return llGetRootRotation();
2444 } 2503 }
2445 2504
2446 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2447 Quaternion q = m_host.GetWorldRotation(); 2506 Quaternion q = m_host.GetWorldRotation();
2448 2507
@@ -2474,14 +2533,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2474 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 2533 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2475 q = avatar.CameraRotation; // Mouselook 2534 q = avatar.CameraRotation; // Mouselook
2476 else 2535 else
2477 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 2536 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
2478 } 2537 }
2479 else 2538 else
2480 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case 2539 q = part.ParentGroup.GroupRotation; // Likely never get here but just in case
2481 } 2540 }
2482 else 2541 else
2483 q = part.ParentGroup.GroupRotation; // just the group rotation 2542 q = part.ParentGroup.GroupRotation; // just the group rotation
2484 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2543
2544 return new LSL_Rotation(q);
2485 } 2545 }
2486 2546
2487 q = part.GetWorldRotation(); 2547 q = part.GetWorldRotation();
@@ -2605,8 +2665,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2605 public LSL_Vector llGetTorque() 2665 public LSL_Vector llGetTorque()
2606 { 2666 {
2607 m_host.AddScriptLPS(1); 2667 m_host.AddScriptLPS(1);
2608 Vector3 torque = m_host.ParentGroup.GetTorque(); 2668
2609 return new LSL_Vector(torque.X,torque.Y,torque.Z); 2669 return new LSL_Vector(m_host.ParentGroup.GetTorque());
2610 } 2670 }
2611 2671
2612 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local) 2672 public void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local)
@@ -2639,13 +2699,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2639 vel = m_host.ParentGroup.RootPart.Velocity; 2699 vel = m_host.ParentGroup.RootPart.Velocity;
2640 } 2700 }
2641 2701
2642 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2702 return new LSL_Vector(vel);
2643 } 2703 }
2644 2704
2645 public LSL_Vector llGetAccel() 2705 public LSL_Vector llGetAccel()
2646 { 2706 {
2647 m_host.AddScriptLPS(1); 2707 m_host.AddScriptLPS(1);
2648 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2708
2709 return new LSL_Vector(m_host.Acceleration);
2649 } 2710 }
2650 2711
2651 public void llSetAngularVelocity(LSL_Vector avel, int local) 2712 public void llSetAngularVelocity(LSL_Vector avel, int local)
@@ -2712,7 +2773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2712 if (m_SoundModule != null) 2773 if (m_SoundModule != null)
2713 { 2774 {
2714 m_SoundModule.SendSound(m_host.UUID, 2775 m_SoundModule.SendSound(m_host.UUID,
2715 KeyOrName(sound, AssetType.Sound), volume, false, 0, 2776 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
2716 0, false, false); 2777 0, false, false);
2717 } 2778 }
2718 } 2779 }
@@ -2722,7 +2783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2722 m_host.AddScriptLPS(1); 2783 m_host.AddScriptLPS(1);
2723 if (m_SoundModule != null) 2784 if (m_SoundModule != null)
2724 { 2785 {
2725 m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound), 2786 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2726 volume, 20, false); 2787 volume, 20, false);
2727 } 2788 }
2728 } 2789 }
@@ -2732,7 +2793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 m_host.AddScriptLPS(1); 2793 m_host.AddScriptLPS(1);
2733 if (m_SoundModule != null) 2794 if (m_SoundModule != null)
2734 { 2795 {
2735 m_SoundModule.LoopSound(m_host.UUID, KeyOrName(sound), 2796 m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound),
2736 volume, 20, true); 2797 volume, 20, true);
2737 } 2798 }
2738 } 2799 }
@@ -2754,7 +2815,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2754 if (m_SoundModule != null) 2815 if (m_SoundModule != null)
2755 { 2816 {
2756 m_SoundModule.SendSound(m_host.UUID, 2817 m_SoundModule.SendSound(m_host.UUID,
2757 KeyOrName(sound, AssetType.Sound), volume, false, 0, 2818 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
2758 0, true, false); 2819 0, true, false);
2759 } 2820 }
2760 } 2821 }
@@ -2766,7 +2827,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2766 if (m_SoundModule != null) 2827 if (m_SoundModule != null)
2767 { 2828 {
2768 m_SoundModule.SendSound(m_host.UUID, 2829 m_SoundModule.SendSound(m_host.UUID,
2769 KeyOrName(sound, AssetType.Sound), volume, true, 0, 0, 2830 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, true, 0, 0,
2770 false, false); 2831 false, false);
2771 } 2832 }
2772 } 2833 }
@@ -2783,7 +2844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2783 { 2844 {
2784 m_host.AddScriptLPS(1); 2845 m_host.AddScriptLPS(1);
2785 if (m_SoundModule != null) 2846 if (m_SoundModule != null)
2786 m_SoundModule.PreloadSound(m_host.UUID, KeyOrName(sound), 0); 2847 m_SoundModule.PreloadSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), 0);
2787 ScriptSleep(1000); 2848 ScriptSleep(1000);
2788 } 2849 }
2789 2850
@@ -3141,11 +3202,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3141 3202
3142 PhysicsActor pa = new_group.RootPart.PhysActor; 3203 PhysicsActor pa = new_group.RootPart.PhysActor;
3143 3204
3205 //Recoil.
3144 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3206 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
3145 { 3207 {
3146 float groupmass = new_group.GetMass(); 3208 float groupmass = new_group.GetMass();
3147 vel *= -groupmass; 3209 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
3148 llApplyImpulse(vel, 0); 3210 if (recoil != Vector3.Zero)
3211 {
3212 llApplyImpulse(recoil, 0);
3213 }
3149 } 3214 }
3150 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3215 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3151 return; 3216 return;
@@ -3220,7 +3285,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3220 { 3285 {
3221// m_log.Info("llSleep snoozing " + sec + "s."); 3286// m_log.Info("llSleep snoozing " + sec + "s.");
3222 m_host.AddScriptLPS(1); 3287 m_host.AddScriptLPS(1);
3223 Thread.Sleep((int)(sec * 1000)); 3288
3289 Sleep((int)(sec * 1000));
3224 } 3290 }
3225 3291
3226 public LSL_Float llGetMass() 3292 public LSL_Float llGetMass()
@@ -3268,7 +3334,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3268 3334
3269 if (!UUID.TryParse(id, out objectID)) 3335 if (!UUID.TryParse(id, out objectID))
3270 objectID = UUID.Zero; 3336 objectID = UUID.Zero;
3271 3337
3272 if (objectID == UUID.Zero && name == "") 3338 if (objectID == UUID.Zero && name == "")
3273 return; 3339 return;
3274 3340
@@ -3322,7 +3388,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 /// <summary> 3388 /// <summary>
3323 /// Attach the object containing this script to the avatar that owns it. 3389 /// Attach the object containing this script to the avatar that owns it.
3324 /// </summary> 3390 /// </summary>
3325 /// <param name='attachment'>The attachment point (e.g. ATTACH_CHEST)</param> 3391 /// <param name='attachmentPoint'>
3392 /// The attachment point (e.g. <see cref="OpenSim.Region.ScriptEngine.Shared.ScriptBase.ScriptBaseClass.ATTACH_CHEST">ATTACH_CHEST</see>)
3393 /// </param>
3326 /// <returns>true if the attach suceeded, false if it did not</returns> 3394 /// <returns>true if the attach suceeded, false if it did not</returns>
3327 public bool AttachToAvatar(int attachmentPoint) 3395 public bool AttachToAvatar(int attachmentPoint)
3328 { 3396 {
@@ -3473,20 +3541,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 msg.offline = (byte)0; //offline; 3541 msg.offline = (byte)0; //offline;
3474 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID; 3542 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3475 msg.Position = new Vector3(m_host.AbsolutePosition); 3543 msg.Position = new Vector3(m_host.AbsolutePosition);
3476 msg.RegionID = World.RegionInfo.RegionID.Guid; 3544 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3477 msg.binaryBucket 3545
3546 Vector3 pos = m_host.AbsolutePosition;
3547 msg.binaryBucket
3478 = Util.StringToBytes256( 3548 = Util.StringToBytes256(
3479 "{0}/{1}/{2}/{3}", 3549 "{0}/{1}/{2}/{3}",
3480 World.RegionInfo.RegionName, 3550 World.RegionInfo.RegionName,
3481 (int)Math.Floor(m_host.AbsolutePosition.X), 3551 (int)Math.Floor(pos.X),
3482 (int)Math.Floor(m_host.AbsolutePosition.Y), 3552 (int)Math.Floor(pos.Y),
3483 (int)Math.Floor(m_host.AbsolutePosition.Z)); 3553 (int)Math.Floor(pos.Z));
3484 3554
3485 if (m_TransferModule != null) 3555 if (m_TransferModule != null)
3486 { 3556 {
3487 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 3557 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3488 } 3558 }
3489 3559
3490 ScriptSleep(2000); 3560 ScriptSleep(2000);
3491 } 3561 }
3492 3562
@@ -3611,7 +3681,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3611 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3681 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3612 { 3682 {
3613 m_host.AddScriptLPS(1); 3683 m_host.AddScriptLPS(1);
3614 3684
3615 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3685 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3616 // set the rotation of the object, copy that behavior 3686 // set the rotation of the object, copy that behavior
3617 PhysicsActor pa = m_host.PhysActor; 3687 PhysicsActor pa = m_host.PhysActor;
@@ -3653,7 +3723,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3653 if (presence != null) 3723 if (presence != null)
3654 { 3724 {
3655 // Do NOT try to parse UUID, animations cannot be triggered by ID 3725 // Do NOT try to parse UUID, animations cannot be triggered by ID
3656 UUID animID = InventoryKey(anim, (int)AssetType.Animation); 3726 UUID animID = ScriptUtils.GetAssetIdFromItemName(m_host, anim, (int)AssetType.Animation);
3657 if (animID == UUID.Zero) 3727 if (animID == UUID.Zero)
3658 presence.Animator.AddAnimation(anim, m_host.UUID); 3728 presence.Animator.AddAnimation(anim, m_host.UUID);
3659 else 3729 else
@@ -3675,12 +3745,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3675 3745
3676 if (presence != null) 3746 if (presence != null)
3677 { 3747 {
3678 UUID animID = KeyOrName(anim); 3748 UUID animID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, anim);
3679 3749
3680 if (animID == UUID.Zero) 3750 if (animID == UUID.Zero)
3681 presence.Animator.RemoveAnimation(anim); 3751 presence.Animator.RemoveAnimation(anim);
3682 else 3752 else
3683 presence.Animator.RemoveAnimation(animID); 3753 presence.Animator.RemoveAnimation(animID, true);
3684 } 3754 }
3685 } 3755 }
3686 } 3756 }
@@ -3753,21 +3823,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3753 } 3823 }
3754 else 3824 else
3755 { 3825 {
3756 bool sitting = false; 3826 if (m_host.ParentGroup.GetSittingAvatars().Contains(agentID))
3757 if (m_host.SitTargetAvatar == agentID)
3758 {
3759 sitting = true;
3760 }
3761 else
3762 {
3763 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3764 {
3765 if (p.SitTargetAvatar == agentID)
3766 sitting = true;
3767 }
3768 }
3769
3770 if (sitting)
3771 { 3827 {
3772 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3828 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3773 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3829 implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
@@ -3809,7 +3865,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3809 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 3865 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
3810 if (npcModule != null && npcModule.IsNPC(agentID, World)) 3866 if (npcModule != null && npcModule.IsNPC(agentID, World))
3811 { 3867 {
3812 if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID) 3868 if (npcModule.CheckPermissions(agentID, m_host.OwnerID))
3813 { 3869 {
3814 lock (m_host.TaskInventory) 3870 lock (m_host.TaskInventory)
3815 { 3871 {
@@ -4184,62 +4240,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4184 public LSL_String llGetLinkName(int linknum) 4240 public LSL_String llGetLinkName(int linknum)
4185 { 4241 {
4186 m_host.AddScriptLPS(1); 4242 m_host.AddScriptLPS(1);
4187 // simplest case, this prims link number
4188 if (linknum == m_host.LinkNum || linknum == ScriptBaseClass.LINK_THIS)
4189 return m_host.Name;
4190 4243
4191 // parse for sitting avatare-names 4244 ISceneEntity entity = GetLinkEntity(linknum);
4192 List<String> nametable = new List<String>();
4193 World.ForEachRootScenePresence(delegate(ScenePresence presence)
4194 {
4195 SceneObjectPart sitPart = presence.ParentPart;
4196 if (sitPart != null && m_host.ParentGroup.ContainsPart(sitPart.LocalId))
4197 nametable.Add(presence.ControllingClient.Name);
4198 });
4199 4245
4200 int totalprims = m_host.ParentGroup.PrimCount + nametable.Count; 4246 if (entity != null)
4201 if (totalprims > m_host.ParentGroup.PrimCount) 4247 return entity.Name;
4202 {
4203 // sitting Avatar-Name with negativ linknum / SinglePrim
4204 if (linknum < 0 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1)
4205 return nametable[0];
4206 // Prim-Name / SinglePrim Sitting Avatar
4207 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1)
4208 return m_host.Name;
4209 // LinkNumber > of Real PrimSet = AvatarName
4210 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
4211 return nametable[totalprims - linknum];
4212 }
4213
4214 // Single prim
4215 if (m_host.LinkNum == 0)
4216 {
4217 if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT)
4218 return m_host.Name;
4219 else
4220 return UUID.Zero.ToString();
4221 }
4222
4223 // Link set
4224 SceneObjectPart part = null;
4225 if (m_host.LinkNum == 1) // this is the Root prim
4226 {
4227 if (linknum < 0)
4228 part = m_host.ParentGroup.GetLinkNumPart(2);
4229 else
4230 part = m_host.ParentGroup.GetLinkNumPart(linknum);
4231 }
4232 else // this is a child prim
4233 {
4234 if (linknum < 2)
4235 part = m_host.ParentGroup.GetLinkNumPart(1);
4236 else
4237 part = m_host.ParentGroup.GetLinkNumPart(linknum);
4238 }
4239 if (part != null)
4240 return part.Name;
4241 else 4248 else
4242 return UUID.Zero.ToString(); 4249 return ScriptBaseClass.NULL_KEY;
4243 } 4250 }
4244 4251
4245 public LSL_Integer llGetInventoryNumber(int type) 4252 public LSL_Integer llGetInventoryNumber(int type)
@@ -4604,8 +4611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4604 if (presence.UserLevel >= 200) return; 4611 if (presence.UserLevel >= 200) return;
4605 4612
4606 // agent must be over the owners land 4613 // agent must be over the owners land
4607 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4614 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4608 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4609 { 4615 {
4610 if (!World.TeleportClientHome(agentId, presence.ControllingClient)) 4616 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4611 { 4617 {
@@ -4621,6 +4627,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4621 } 4627 }
4622 } 4628 }
4623 } 4629 }
4630
4624 ScriptSleep(5000); 4631 ScriptSleep(5000);
4625 } 4632 }
4626 4633
@@ -4641,8 +4648,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4641 destination = World.RegionInfo.RegionName; 4648 destination = World.RegionInfo.RegionName;
4642 4649
4643 // agent must be over the owners land 4650 // agent must be over the owners land
4644 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4651 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4645 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4646 { 4652 {
4647 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4653 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4648 } 4654 }
@@ -4673,8 +4679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4673 if (presence.GodLevel >= 200) return; 4679 if (presence.GodLevel >= 200) return;
4674 4680
4675 // agent must be over the owners land 4681 // agent must be over the owners land
4676 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4682 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4677 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4678 { 4683 {
4679 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4684 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4680 } 4685 }
@@ -4691,7 +4696,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4691 4696
4692 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt) 4697 private void DoLLTeleport(ScenePresence sp, string destination, Vector3 targetPos, Vector3 targetLookAt)
4693 { 4698 {
4694 UUID assetID = KeyOrName(destination); 4699 UUID assetID = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, destination);
4695 4700
4696 // The destinaion is not an asset ID and also doesn't name a landmark. 4701 // The destinaion is not an asset ID and also doesn't name a landmark.
4697 // Use it as a sim name 4702 // Use it as a sim name
@@ -4764,7 +4769,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4764 return; 4769 return;
4765 } 4770 }
4766 // TODO: Parameter check logic required. 4771 // TODO: Parameter check logic required.
4767 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4772 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4768 m_host.CollisionSoundVolume = (float)impact_volume; 4773 m_host.CollisionSoundVolume = (float)impact_volume;
4769 m_host.CollisionSoundType = 1; 4774 m_host.CollisionSoundType = 1;
4770 } 4775 }
@@ -4889,7 +4894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4889 { 4894 {
4890 if (pushrestricted) 4895 if (pushrestricted)
4891 { 4896 {
4892 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4897 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4893 4898
4894 // We didn't find the parcel but region is push restricted so assume it is NOT ok 4899 // We didn't find the parcel but region is push restricted so assume it is NOT ok
4895 if (targetlandObj == null) 4900 if (targetlandObj == null)
@@ -4904,7 +4909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4904 } 4909 }
4905 else 4910 else
4906 { 4911 {
4907 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4912 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4908 if (targetlandObj == null) 4913 if (targetlandObj == null)
4909 { 4914 {
4910 // We didn't find the parcel but region isn't push restricted so assume it's ok 4915 // We didn't find the parcel but region isn't push restricted so assume it's ok
@@ -4934,6 +4939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4934 } 4939 }
4935 } 4940 }
4936 } 4941 }
4942
4937 if (pushAllowed) 4943 if (pushAllowed)
4938 { 4944 {
4939 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4945 float distance = (PusheePos - m_host.AbsolutePosition).Length();
@@ -4963,17 +4969,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4963 applied_linear_impulse *= scaling_factor; 4969 applied_linear_impulse *= scaling_factor;
4964 4970
4965 } 4971 }
4972
4966 if (pusheeIsAvatar) 4973 if (pusheeIsAvatar)
4967 { 4974 {
4968 if (pusheeav != null) 4975 if (pusheeav != null)
4969 { 4976 {
4970 if (pusheeav.PhysicsActor != null) 4977 PhysicsActor pa = pusheeav.PhysicsActor;
4978
4979 if (pa != null)
4971 { 4980 {
4972 if (local != 0) 4981 if (local != 0)
4973 { 4982 {
4974 applied_linear_impulse *= m_host.GetWorldRotation(); 4983 applied_linear_impulse *= m_host.GetWorldRotation();
4975 } 4984 }
4976 pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true); 4985
4986 pa.AddForce(applied_linear_impulse, true);
4977 } 4987 }
4978 } 4988 }
4979 } 4989 }
@@ -5323,8 +5333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5323 public LSL_Vector llGetCenterOfMass() 5333 public LSL_Vector llGetCenterOfMass()
5324 { 5334 {
5325 m_host.AddScriptLPS(1); 5335 m_host.AddScriptLPS(1);
5326 Vector3 center = m_host.GetCenterOfMass(); 5336
5327 return new LSL_Vector(center.X,center.Y,center.Z); 5337 return new LSL_Vector(m_host.GetCenterOfMass());
5328 } 5338 }
5329 5339
5330 public LSL_List llListSort(LSL_List src, int stride, int ascending) 5340 public LSL_List llListSort(LSL_List src, int stride, int ascending)
@@ -5465,7 +5475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5465 // SL spits out an empty string for types other than key & string 5475 // SL spits out an empty string for types other than key & string
5466 // At the time of patching, LSL_Key is currently LSL_String, 5476 // At the time of patching, LSL_Key is currently LSL_String,
5467 // so the OR check may be a little redundant, but it's being done 5477 // so the OR check may be a little redundant, but it's being done
5468 // for completion and should LSL_Key ever be implemented 5478 // for completion and should LSL_Key ever be implemented
5469 // as it's own struct 5479 // as it's own struct
5470 else if (!(src.Data[index] is LSL_String || 5480 else if (!(src.Data[index] is LSL_String ||
5471 src.Data[index] is LSL_Key || 5481 src.Data[index] is LSL_Key ||
@@ -5602,8 +5612,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5602 { 5612 {
5603 m_host.AddScriptLPS(1); 5613 m_host.AddScriptLPS(1);
5604 5614
5605 return string.Join(", ", 5615 return string.Join(", ",
5606 (new List<object>(src.Data)).ConvertAll<string>(o => 5616 (new List<object>(src.Data)).ConvertAll<string>(o =>
5607 { 5617 {
5608 return o.ToString(); 5618 return o.ToString();
5609 }).ToArray()); 5619 }).ToArray());
@@ -5851,9 +5861,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5851 } 5861 }
5852 5862
5853 /// <summary> 5863 /// <summary>
5854 /// Insert the list identified by <src> into the 5864 /// Insert the list identified by <paramref name="src"/> into the
5855 /// list designated by <dest> such that the first 5865 /// list designated by <paramref name="dest"/> such that the first
5856 /// new element has the index specified by <index> 5866 /// new element has the index specified by <paramref name="index"/>
5857 /// </summary> 5867 /// </summary>
5858 5868
5859 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index) 5869 public LSL_List llListInsertList(LSL_List dest, LSL_List src, int index)
@@ -6181,12 +6191,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6181 } 6191 }
6182 6192
6183 ILandObject land; 6193 ILandObject land;
6184 Vector3 pos;
6185 UUID id = UUID.Zero; 6194 UUID id = UUID.Zero;
6195
6186 if (parcel || parcelOwned) 6196 if (parcel || parcelOwned)
6187 { 6197 {
6188 pos = m_host.ParentGroup.RootPart.GetWorldPosition(); 6198 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
6189 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6190 if (land == null) 6199 if (land == null)
6191 { 6200 {
6192 id = UUID.Zero; 6201 id = UUID.Zero;
@@ -6212,20 +6221,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6212 { 6221 {
6213 if (!regionWide) 6222 if (!regionWide)
6214 { 6223 {
6215 pos = ssp.AbsolutePosition; 6224 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
6216 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6217 if (land != null) 6225 if (land != null)
6218 { 6226 {
6219 if (parcelOwned && land.LandData.OwnerID == id || 6227 if (parcelOwned && land.LandData.OwnerID == id ||
6220 parcel && land.LandData.GlobalID == id) 6228 parcel && land.LandData.GlobalID == id)
6221 { 6229 {
6222 result.Add(ssp.UUID.ToString()); 6230 result.Add(new LSL_Key(ssp.UUID.ToString()));
6223 } 6231 }
6224 } 6232 }
6225 } 6233 }
6226 else 6234 else
6227 { 6235 {
6228 result.Add(ssp.UUID.ToString()); 6236 result.Add(new LSL_Key(ssp.UUID.ToString()));
6229 } 6237 }
6230 } 6238 }
6231 // Maximum of 100 results 6239 // Maximum of 100 results
@@ -6329,7 +6337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6329 if (m_SoundModule != null) 6337 if (m_SoundModule != null)
6330 { 6338 {
6331 m_SoundModule.TriggerSoundLimited(m_host.UUID, 6339 m_SoundModule.TriggerSoundLimited(m_host.UUID,
6332 KeyOrName(sound, AssetType.Sound), volume, 6340 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume,
6333 bottom_south_west, top_north_east); 6341 bottom_south_west, top_north_east);
6334 } 6342 }
6335 } 6343 }
@@ -6344,14 +6352,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6344 if (presence != null) 6352 if (presence != null)
6345 { 6353 {
6346 // agent must be over the owners land 6354 // agent must be over the owners land
6347 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); 6355 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
6348 if (land == null) 6356 if (land == null)
6349 return; 6357 return;
6350 6358
6351 if (m_host.OwnerID == land.LandData.OwnerID) 6359 if (m_host.OwnerID == land.LandData.OwnerID)
6352 { 6360 {
6353 Vector3 pos = World.GetNearestAllowedPosition(presence, land); 6361 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6354 presence.TeleportWithMomentum(pos, null); 6362 presence.TeleportWithMomentum(p, null);
6355 presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); 6363 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6356 } 6364 }
6357 } 6365 }
@@ -6373,19 +6381,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6373 ScenePresence presence = World.GetScenePresence(key); 6381 ScenePresence presence = World.GetScenePresence(key);
6374 if (presence != null) // object is an avatar 6382 if (presence != null) // object is an avatar
6375 { 6383 {
6376 if (m_host.OwnerID 6384 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
6377 == World.LandChannel.GetLandObject(
6378 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
6379 return 1; 6385 return 1;
6380 } 6386 }
6381 else // object is not an avatar 6387 else // object is not an avatar
6382 { 6388 {
6383 SceneObjectPart obj = World.GetSceneObjectPart(key); 6389 SceneObjectPart obj = World.GetSceneObjectPart(key);
6390
6384 if (obj != null) 6391 if (obj != null)
6385 if (m_host.OwnerID 6392 {
6386 == World.LandChannel.GetLandObject( 6393 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
6387 obj.AbsolutePosition.X, obj.AbsolutePosition.Y).LandData.OwnerID)
6388 return 1; 6394 return 1;
6395 }
6389 } 6396 }
6390 } 6397 }
6391 6398
@@ -6493,8 +6500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6493 // if the land is group owned and the object is group owned by the same group 6500 // if the land is group owned and the object is group owned by the same group
6494 // or 6501 // or
6495 // if the object is owned by a person with estate access. 6502 // if the object is owned by a person with estate access.
6496 6503 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
6497 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y);
6498 if (parcel != null) 6504 if (parcel != null)
6499 { 6505 {
6500 if (m_host.OwnerID == parcel.LandData.OwnerID || 6506 if (m_host.OwnerID == parcel.LandData.OwnerID ||
@@ -6506,14 +6512,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6506 } 6512 }
6507 } 6513 }
6508 } 6514 }
6509
6510 } 6515 }
6511
6512 } 6516 }
6513 6517
6514 public LSL_Vector llGroundSlope(LSL_Vector offset) 6518 public LSL_Vector llGroundSlope(LSL_Vector offset)
6515 { 6519 {
6516 m_host.AddScriptLPS(1); 6520 m_host.AddScriptLPS(1);
6521
6517 //Get the slope normal. This gives us the equation of the plane tangent to the slope. 6522 //Get the slope normal. This gives us the equation of the plane tangent to the slope.
6518 LSL_Vector vsn = llGroundNormal(offset); 6523 LSL_Vector vsn = llGroundNormal(offset);
6519 6524
@@ -6524,7 +6529,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6524 vsl.Normalize(); 6529 vsl.Normalize();
6525 //Normalization might be overkill here 6530 //Normalization might be overkill here
6526 6531
6527 return new LSL_Vector(vsl.X, vsl.Y, vsl.Z); 6532 vsn.x = vsl.X;
6533 vsn.y = vsl.Y;
6534 vsn.z = vsl.Z;
6535
6536 return vsn;
6528 } 6537 }
6529 6538
6530 public LSL_Vector llGroundNormal(LSL_Vector offset) 6539 public LSL_Vector llGroundNormal(LSL_Vector offset)
@@ -6574,7 +6583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6574 //I believe the crossproduct of two normalized vectors is a normalized vector so 6583 //I believe the crossproduct of two normalized vectors is a normalized vector so
6575 //this normalization may be overkill 6584 //this normalization may be overkill
6576 6585
6577 return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); 6586 return new LSL_Vector(vsn);
6578 } 6587 }
6579 6588
6580 public LSL_Vector llGroundContour(LSL_Vector offset) 6589 public LSL_Vector llGroundContour(LSL_Vector offset)
@@ -6686,6 +6695,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6686 ps.BurstSpeedMax = 1.0f; 6695 ps.BurstSpeedMax = 1.0f;
6687 ps.BurstRate = 0.1f; 6696 ps.BurstRate = 0.1f;
6688 ps.PartMaxAge = 10.0f; 6697 ps.PartMaxAge = 10.0f;
6698 ps.BurstPartCount = 1;
6689 return ps; 6699 return ps;
6690 } 6700 }
6691 6701
@@ -6709,8 +6719,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6709 6719
6710 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) 6720 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6711 { 6721 {
6712
6713
6714 if (rules.Length == 0) 6722 if (rules.Length == 0)
6715 { 6723 {
6716 part.RemoveParticleSystem(); 6724 part.RemoveParticleSystem();
@@ -6801,7 +6809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6801 break; 6809 break;
6802 6810
6803 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: 6811 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE:
6804 prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); 6812 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1));
6805 break; 6813 break;
6806 6814
6807 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: 6815 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE:
@@ -6946,7 +6954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6946 m_host.OwnerID, m_host.Name, destID, 6954 m_host.OwnerID, m_host.Name, destID,
6947 (byte)InstantMessageDialog.TaskInventoryOffered, 6955 (byte)InstantMessageDialog.TaskInventoryOffered,
6948 false, string.Format("'{0}'", category), 6956 false, string.Format("'{0}'", category),
6949// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06 6957// We won't go so far as to add a SLURL, but this is the format used by LL as of 2012-10-06
6950// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z), 6958// false, string.Format("'{0}' ( http://slurl.com/secondlife/{1}/{2}/{3}/{4} )", category, World.Name, (int)pos.X, (int)pos.Y, (int)pos.Z),
6951 folderID, false, pos, 6959 folderID, false, pos,
6952 bucket, false); 6960 bucket, false);
@@ -7065,12 +7073,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7065 public LSL_String llAvatarOnLinkSitTarget(int linknum) 7073 public LSL_String llAvatarOnLinkSitTarget(int linknum)
7066 { 7074 {
7067 m_host.AddScriptLPS(1); 7075 m_host.AddScriptLPS(1);
7068 if(linknum == ScriptBaseClass.LINK_SET || 7076 if(linknum == ScriptBaseClass.LINK_SET ||
7069 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 7077 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
7070 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 7078 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
7071 7079
7072 List<SceneObjectPart> parts = GetLinkParts(linknum); 7080 List<SceneObjectPart> parts = GetLinkParts(linknum);
7073 if (parts.Count == 0) return UUID.Zero.ToString(); 7081 if (parts.Count == 0) return UUID.Zero.ToString();
7074 return parts[0].SitTargetAvatar.ToString(); 7082 return parts[0].SitTargetAvatar.ToString();
7075 } 7083 }
7076 7084
@@ -7079,7 +7087,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7079 { 7087 {
7080 m_host.AddScriptLPS(1); 7088 m_host.AddScriptLPS(1);
7081 UUID key; 7089 UUID key;
7082 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 7090 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7091
7083 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7092 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
7084 { 7093 {
7085 int expires = 0; 7094 int expires = 0;
@@ -7373,6 +7382,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7373 public void llCloseRemoteDataChannel(string channel) 7382 public void llCloseRemoteDataChannel(string channel)
7374 { 7383 {
7375 m_host.AddScriptLPS(1); 7384 m_host.AddScriptLPS(1);
7385
7386 IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface<IXmlRpcRouter>();
7387 if (xmlRpcRouter != null)
7388 {
7389 xmlRpcRouter.UnRegisterReceiver(channel, m_item.ItemID);
7390 }
7391
7376 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 7392 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7377 if (xmlrpcMod != null) 7393 if (xmlrpcMod != null)
7378 xmlrpcMod.CloseXMLRPCChannel((UUID)channel); 7394 xmlrpcMod.CloseXMLRPCChannel((UUID)channel);
@@ -7452,7 +7468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7452 hollow = 0.70f; 7468 hollow = 0.70f;
7453 } 7469 }
7454 } 7470 }
7455 // Otherwise, hollow is limited to 95%. 7471 // Otherwise, hollow is limited to 95%.
7456 else 7472 else
7457 { 7473 {
7458 if (hollow > 0.95f) 7474 if (hollow > 0.95f)
@@ -7746,9 +7762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7746 UUID sculptId; 7762 UUID sculptId;
7747 7763
7748 if (!UUID.TryParse(map, out sculptId)) 7764 if (!UUID.TryParse(map, out sculptId))
7749 { 7765 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture);
7750 sculptId = InventoryKey(map, (int)AssetType.Texture);
7751 }
7752 7766
7753 if (sculptId == UUID.Zero) 7767 if (sculptId == UUID.Zero)
7754 return; 7768 return;
@@ -8511,7 +8525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8511 { 8525 {
8512 m_host.AddScriptLPS(1); 8526 m_host.AddScriptLPS(1);
8513 8527
8514 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8528 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8515 8529
8516 if (land.LandData.OwnerID != m_host.OwnerID) 8530 if (land.LandData.OwnerID != m_host.OwnerID)
8517 return; 8531 return;
@@ -8525,7 +8539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8525 { 8539 {
8526 m_host.AddScriptLPS(1); 8540 m_host.AddScriptLPS(1);
8527 8541
8528 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8542 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8529 8543
8530 if (land.LandData.OwnerID != m_host.OwnerID) 8544 if (land.LandData.OwnerID != m_host.OwnerID)
8531 return String.Empty; 8545 return String.Empty;
@@ -8536,8 +8550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8536 public LSL_Vector llGetRootPosition() 8550 public LSL_Vector llGetRootPosition()
8537 { 8551 {
8538 m_host.AddScriptLPS(1); 8552 m_host.AddScriptLPS(1);
8539 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y, 8553
8540 m_host.ParentGroup.AbsolutePosition.Z); 8554 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8541 } 8555 }
8542 8556
8543 /// <summary> 8557 /// <summary>
@@ -8560,13 +8574,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8560 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 8574 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
8561 q = avatar.CameraRotation; // Mouselook 8575 q = avatar.CameraRotation; // Mouselook
8562 else 8576 else
8563 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 8577 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
8564 else 8578 else
8565 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case 8579 q = m_host.ParentGroup.GroupRotation; // Likely never get here but just in case
8566 } 8580 }
8567 else 8581 else
8568 q = m_host.ParentGroup.GroupRotation; // just the group rotation 8582 q = m_host.ParentGroup.GroupRotation; // just the group rotation
8569 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 8583
8584 return new LSL_Rotation(q);
8570 } 8585 }
8571 8586
8572 public LSL_String llGetObjectDesc() 8587 public LSL_String llGetObjectDesc()
@@ -8733,8 +8748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8733 8748
8734 public LSL_Vector llGetGeometricCenter() 8749 public LSL_Vector llGetGeometricCenter()
8735 { 8750 {
8736 Vector3 tmp = m_host.GetGeometricCenter(); 8751 return new LSL_Vector(m_host.GetGeometricCenter());
8737 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
8738 } 8752 }
8739 8753
8740 public LSL_List llGetPrimitiveParams(LSL_List rules) 8754 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8841,9 +8855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8841 break; 8855 break;
8842 8856
8843 case (int)ScriptBaseClass.PRIM_SIZE: 8857 case (int)ScriptBaseClass.PRIM_SIZE:
8844 res.Add(new LSL_Vector(part.Scale.X, 8858 res.Add(new LSL_Vector(part.Scale));
8845 part.Scale.Y,
8846 part.Scale.Z));
8847 break; 8859 break;
8848 8860
8849 case (int)ScriptBaseClass.PRIM_ROTATION: 8861 case (int)ScriptBaseClass.PRIM_ROTATION:
@@ -8911,16 +8923,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8911 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); 8923 res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
8912 8924
8913 // float revolutions 8925 // float revolutions
8914 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); 8926 res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d);
8915 // Slightly inaccurate, because an unsigned byte is being used to represent 8927 // Slightly inaccurate, because an unsigned byte is being used to represent
8916 // the entire range of floating-point values from 1.0 through 4.0 (which is how 8928 // the entire range of floating-point values from 1.0 through 4.0 (which is how
8917 // SL does it). 8929 // SL does it).
8918 // 8930 //
8919 // Using these formulas to store and retrieve PathRevolutions, it is not 8931 // Using these formulas to store and retrieve PathRevolutions, it is not
8920 // possible to use all values between 1.00 and 4.00. For instance, you can't 8932 // possible to use all values between 1.00 and 4.00. For instance, you can't
8921 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you 8933 // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you
8922 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them 8934 // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them
8923 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar 8935 // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar
8924 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. 8936 // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11.
8925 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value 8937 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8926 // such as 1.10. So, SL must store and retreive the actual user input rather 8938 // such as 1.10. So, SL must store and retreive the actual user input rather
@@ -9204,9 +9216,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9204 case (int)ScriptBaseClass.PRIM_DESC: 9216 case (int)ScriptBaseClass.PRIM_DESC:
9205 res.Add(new LSL_String(part.Description)); 9217 res.Add(new LSL_String(part.Description));
9206 break; 9218 break;
9207
9208 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9219 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9209 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9220 res.Add(new LSL_Rotation(part.RotationOffset));
9210 break; 9221 break;
9211 9222
9212 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9223 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
@@ -10238,6 +10249,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10238 return UUID.Zero.ToString(); 10249 return UUID.Zero.ToString();
10239 } 10250 }
10240 } 10251 }
10252
10241 public LSL_String llRequestURL() 10253 public LSL_String llRequestURL()
10242 { 10254 {
10243 m_host.AddScriptLPS(1); 10255 m_host.AddScriptLPS(1);
@@ -10389,7 +10401,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10389 10401
10390 // according to the docs, this command only works if script owner and land owner are the same 10402 // according to the docs, this command only works if script owner and land owner are the same
10391 // lets add estate owners and gods, too, and use the generic permission check. 10403 // lets add estate owners and gods, too, and use the generic permission check.
10392 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10404 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10393 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 10405 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
10394 10406
10395 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 10407 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
@@ -10712,22 +10724,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10712 m_host.AddScriptLPS(1); 10724 m_host.AddScriptLPS(1);
10713 10725
10714 if (m_item.PermsGranter == UUID.Zero) 10726 if (m_item.PermsGranter == UUID.Zero)
10715 return new LSL_Vector(); 10727 return Vector3.Zero;
10716 10728
10717 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10729 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10718 { 10730 {
10719 ShoutError("No permissions to track the camera"); 10731 ShoutError("No permissions to track the camera");
10720 return new LSL_Vector(); 10732 return Vector3.Zero;
10721 } 10733 }
10722 10734
10723// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10735// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10724 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10736 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10725 if (presence != null) 10737 if (presence != null)
10726 { 10738 {
10727 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10739 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
10728 return pos; 10740 return pos;
10729 } 10741 }
10730 return new LSL_Vector(); 10742
10743 return Vector3.Zero;
10731 } 10744 }
10732 10745
10733 public LSL_Rotation llGetCameraRot() 10746 public LSL_Rotation llGetCameraRot()
@@ -10735,22 +10748,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10735 m_host.AddScriptLPS(1); 10748 m_host.AddScriptLPS(1);
10736 10749
10737 if (m_item.PermsGranter == UUID.Zero) 10750 if (m_item.PermsGranter == UUID.Zero)
10738 return new LSL_Rotation(); 10751 return Quaternion.Identity;
10739 10752
10740 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10753 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10741 { 10754 {
10742 ShoutError("No permissions to track the camera"); 10755 ShoutError("No permissions to track the camera");
10743 return new LSL_Rotation(); 10756 return Quaternion.Identity;
10744 } 10757 }
10745 10758
10746// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10759// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10747 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10760 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10748 if (presence != null) 10761 if (presence != null)
10749 { 10762 {
10750 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10763 return new LSL_Rotation(presence.CameraRotation);
10751 } 10764 }
10752 10765
10753 return new LSL_Rotation(); 10766 return Quaternion.Identity;
10754 } 10767 }
10755 10768
10756 /// <summary> 10769 /// <summary>
@@ -10831,7 +10844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10831 { 10844 {
10832 m_host.AddScriptLPS(1); 10845 m_host.AddScriptLPS(1);
10833 UUID key; 10846 UUID key;
10834 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10847 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10835 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10848 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10836 { 10849 {
10837 int expires = 0; 10850 int expires = 0;
@@ -10872,7 +10885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10872 { 10885 {
10873 m_host.AddScriptLPS(1); 10886 m_host.AddScriptLPS(1);
10874 UUID key; 10887 UUID key;
10875 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10888 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10876 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10889 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10877 { 10890 {
10878 if (UUID.TryParse(avatar, out key)) 10891 if (UUID.TryParse(avatar, out key))
@@ -10899,7 +10912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10899 { 10912 {
10900 m_host.AddScriptLPS(1); 10913 m_host.AddScriptLPS(1);
10901 UUID key; 10914 UUID key;
10902 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10915 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10903 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10916 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10904 { 10917 {
10905 if (UUID.TryParse(avatar, out key)) 10918 if (UUID.TryParse(avatar, out key))
@@ -11131,9 +11144,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11131 IHttpRequestModule httpScriptMod = 11144 IHttpRequestModule httpScriptMod =
11132 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); 11145 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
11133 List<string> param = new List<string>(); 11146 List<string> param = new List<string>();
11134 foreach (object o in parameters.Data) 11147 bool ok;
11148 Int32 flag;
11149
11150 for (int i = 0; i < parameters.Data.Length; i += 2)
11135 { 11151 {
11136 param.Add(o.ToString()); 11152 ok = Int32.TryParse(parameters.Data[i].ToString(), out flag);
11153 if (!ok || flag < 0 ||
11154 flag > (int)HttpRequestConstants.HTTP_PRAGMA_NO_CACHE)
11155 {
11156 throw new ScriptException("Parameter " + i.ToString() + " is an invalid flag");
11157 }
11158
11159 param.Add(parameters.Data[i].ToString()); //Add parameter flag
11160
11161 if (flag != (int)HttpRequestConstants.HTTP_CUSTOM_HEADER)
11162 {
11163 param.Add(parameters.Data[i+1].ToString()); //Add parameter value
11164 }
11165 else
11166 {
11167 //Parameters are in pairs and custom header takes
11168 //arguments in pairs so adjust for header marker.
11169 ++i;
11170
11171 //Maximum of 8 headers are allowed based on the
11172 //Second Life documentation for llHTTPRequest.
11173 for (int count = 1; count <= 8; ++count)
11174 {
11175 //Enough parameters remaining for (another) header?
11176 if (parameters.Data.Length - i < 2)
11177 {
11178 //There must be at least one name/value pair for custom header
11179 if (count == 1)
11180 throw new ScriptException("Missing name/value for custom header at parameter " + i.ToString());
11181 break;
11182 }
11183
11184 if (HttpStandardHeaders.Contains(parameters.Data[i].ToString(), StringComparer.OrdinalIgnoreCase))
11185 throw new ScriptException("Name is invalid as a custom header at parameter " + i.ToString());
11186
11187 param.Add(parameters.Data[i].ToString());
11188 param.Add(parameters.Data[i+1].ToString());
11189
11190 //Have we reached the end of the list of headers?
11191 //End is marked by a string with a single digit.
11192 if (i+2 >= parameters.Data.Length ||
11193 Char.IsDigit(parameters.Data[i].ToString()[0]))
11194 {
11195 break;
11196 }
11197
11198 i += 2;
11199 }
11200 }
11137 } 11201 }
11138 11202
11139 Vector3 position = m_host.AbsolutePosition; 11203 Vector3 position = m_host.AbsolutePosition;
@@ -11265,7 +11329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11265 public void llResetLandBanList() 11329 public void llResetLandBanList()
11266 { 11330 {
11267 m_host.AddScriptLPS(1); 11331 m_host.AddScriptLPS(1);
11268 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11332 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11269 if (land.OwnerID == m_host.OwnerID) 11333 if (land.OwnerID == m_host.OwnerID)
11270 { 11334 {
11271 foreach (LandAccessEntry entry in land.ParcelAccessList) 11335 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11282,7 +11346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11282 public void llResetLandPassList() 11346 public void llResetLandPassList()
11283 { 11347 {
11284 m_host.AddScriptLPS(1); 11348 m_host.AddScriptLPS(1);
11285 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11349 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11286 if (land.OwnerID == m_host.OwnerID) 11350 if (land.OwnerID == m_host.OwnerID)
11287 { 11351 {
11288 foreach (LandAccessEntry entry in land.ParcelAccessList) 11352 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11299,12 +11363,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11299 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 11363 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
11300 { 11364 {
11301 m_host.AddScriptLPS(1); 11365 m_host.AddScriptLPS(1);
11302 11366
11303 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 11367 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
11304 11368
11305 if (lo == null) 11369 if (lo == null)
11306 return 0; 11370 return 0;
11307 11371
11308 IPrimCounts pc = lo.PrimCounts; 11372 IPrimCounts pc = lo.PrimCounts;
11309 11373
11310 if (sim_wide != ScriptBaseClass.FALSE) 11374 if (sim_wide != ScriptBaseClass.FALSE)
@@ -11334,7 +11398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11334 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) 11398 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
11335 return 0; // counts not implemented yet 11399 return 0; // counts not implemented yet
11336 } 11400 }
11337 11401
11338 return 0; 11402 return 0;
11339 } 11403 }
11340 11404
@@ -11519,6 +11583,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11519 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11583 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11520 ret.Add(new LSL_Float(0)); 11584 ret.Add(new LSL_Float(0));
11521 break; 11585 break;
11586 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11587 ret.Add(new LSL_Float(0));
11588 break;
11589 case ScriptBaseClass.OBJECT_ROOT:
11590 SceneObjectPart p = av.ParentPart;
11591 if (p != null)
11592 {
11593 ret.Add(new LSL_String(p.ParentGroup.RootPart.UUID.ToString()));
11594 }
11595 else
11596 {
11597 ret.Add(new LSL_String(id));
11598 }
11599 break;
11600 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11601 ret.Add(new LSL_Integer(0));
11602 break;
11603 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE: // Pathfinding
11604 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_AVATAR));
11605 break;
11606 case ScriptBaseClass.OBJECT_PHYSICS:
11607 ret.Add(new LSL_Integer(0));
11608 break;
11609 case ScriptBaseClass.OBJECT_PHANTOM:
11610 ret.Add(new LSL_Integer(0));
11611 break;
11612 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11613 ret.Add(new LSL_Integer(0));
11614 break;
11522 default: 11615 default:
11523 // Invalid or unhandled constant. 11616 // Invalid or unhandled constant.
11524 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11617 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -11610,6 +11703,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11610 // The value returned in SL for normal prims is prim count 11703 // The value returned in SL for normal prims is prim count
11611 ret.Add(new LSL_Float(obj.PhysicsCost)); 11704 ret.Add(new LSL_Float(obj.PhysicsCost));
11612 break; 11705 break;
11706 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11707 ret.Add(new LSL_Float(0));
11708 break;
11709 case ScriptBaseClass.OBJECT_ROOT:
11710 ret.Add(new LSL_String(obj.ParentGroup.RootPart.UUID.ToString()));
11711 break;
11712 case ScriptBaseClass.OBJECT_ATTACHED_POINT:
11713 ret.Add(new LSL_Integer(obj.ParentGroup.AttachmentPoint));
11714 break;
11715 case ScriptBaseClass.OBJECT_PATHFINDING_TYPE:
11716 byte pcode = obj.Shape.PCode;
11717 if (obj.ParentGroup.AttachmentPoint != 0
11718 || pcode == (byte)PCode.Grass
11719 || pcode == (byte)PCode.Tree
11720 || pcode == (byte)PCode.NewTree)
11721 {
11722 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_OTHER));
11723 }
11724 else
11725 {
11726 ret.Add(new LSL_Integer(ScriptBaseClass.OPT_LEGACY_LINKSET));
11727 }
11728 break;
11729 case ScriptBaseClass.OBJECT_PHYSICS:
11730 if (obj.ParentGroup.AttachmentPoint != 0)
11731 {
11732 ret.Add(new LSL_Integer(0)); // Always false if attached
11733 }
11734 else
11735 {
11736 ret.Add(new LSL_Integer(obj.ParentGroup.UsesPhysics ? 1 : 0));
11737 }
11738 break;
11739 case ScriptBaseClass.OBJECT_PHANTOM:
11740 if (obj.ParentGroup.AttachmentPoint != 0)
11741 {
11742 ret.Add(new LSL_Integer(0)); // Always false if attached
11743 }
11744 else
11745 {
11746 ret.Add(new LSL_Integer(obj.ParentGroup.IsPhantom ? 1 : 0));
11747 }
11748 break;
11749 case ScriptBaseClass.OBJECT_TEMP_ON_REZ:
11750 ret.Add(new LSL_Integer(obj.ParentGroup.IsTemporary ? 1 : 0));
11751 break;
11613 default: 11752 default:
11614 // Invalid or unhandled constant. 11753 // Invalid or unhandled constant.
11615 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11754 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -11620,7 +11759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11620 return ret; 11759 return ret;
11621 } 11760 }
11622 } 11761 }
11623 11762
11624 return new LSL_List(); 11763 return new LSL_List();
11625 } 11764 }
11626 11765
@@ -11689,14 +11828,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11689 return UUID.Zero.ToString(); 11828 return UUID.Zero.ToString();
11690 } 11829 }
11691 11830
11831 string reqIdentifier = UUID.Random().ToString();
11832
11692 // was: UUID tid = tid = AsyncCommands. 11833 // was: UUID tid = tid = AsyncCommands.
11693 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); 11834 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11694 11835
11695 if (NotecardCache.IsCached(assetID)) 11836 if (NotecardCache.IsCached(assetID))
11696 { 11837 {
11697 AsyncCommands. 11838 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString());
11698 DataserverPlugin.DataserverReply(assetID.ToString(), 11839
11699 NotecardCache.GetLines(assetID).ToString());
11700 ScriptSleep(100); 11840 ScriptSleep(100);
11701 return tid.ToString(); 11841 return tid.ToString();
11702 } 11842 }
@@ -11712,9 +11852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11712 string data = Encoding.UTF8.GetString(a.Data); 11852 string data = Encoding.UTF8.GetString(a.Data);
11713 //m_log.Debug(data); 11853 //m_log.Debug(data);
11714 NotecardCache.Cache(id, data); 11854 NotecardCache.Cache(id, data);
11715 AsyncCommands. 11855 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
11716 DataserverPlugin.DataserverReply(id.ToString(),
11717 NotecardCache.GetLines(id).ToString());
11718 }); 11856 });
11719 11857
11720 ScriptSleep(100); 11858 ScriptSleep(100);
@@ -11743,13 +11881,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11743 return UUID.Zero.ToString(); 11881 return UUID.Zero.ToString();
11744 } 11882 }
11745 11883
11884 string reqIdentifier = UUID.Random().ToString();
11885
11746 // was: UUID tid = tid = AsyncCommands. 11886 // was: UUID tid = tid = AsyncCommands.
11747 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, assetID.ToString()); 11887 UUID tid = AsyncCommands.DataserverPlugin.RegisterRequest(m_host.LocalId, m_item.ItemID, reqIdentifier);
11748 11888
11749 if (NotecardCache.IsCached(assetID)) 11889 if (NotecardCache.IsCached(assetID))
11750 { 11890 {
11751 AsyncCommands.DataserverPlugin.DataserverReply(assetID.ToString(), 11891 AsyncCommands.DataserverPlugin.DataserverReply(
11752 NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11892 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11893
11753 ScriptSleep(100); 11894 ScriptSleep(100);
11754 return tid.ToString(); 11895 return tid.ToString();
11755 } 11896 }
@@ -11765,8 +11906,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11765 string data = Encoding.UTF8.GetString(a.Data); 11906 string data = Encoding.UTF8.GetString(a.Data);
11766 //m_log.Debug(data); 11907 //m_log.Debug(data);
11767 NotecardCache.Cache(id, data); 11908 NotecardCache.Cache(id, data);
11768 AsyncCommands.DataserverPlugin.DataserverReply(id.ToString(), 11909 AsyncCommands.DataserverPlugin.DataserverReply(
11769 NotecardCache.GetLine(id, line, m_notecardLineReadCharsMax)); 11910 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11770 }); 11911 });
11771 11912
11772 ScriptSleep(100); 11913 ScriptSleep(100);
@@ -11801,7 +11942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11801 11942
11802 LSL_List result = new LSL_List(); 11943 LSL_List result = new LSL_List();
11803 11944
11804 if (obj != null && obj.OwnerID != m_host.OwnerID) 11945 if (obj != null && obj.OwnerID == m_host.OwnerID)
11805 { 11946 {
11806 LSL_List remaining = GetPrimParams(obj, rules, ref result); 11947 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11807 11948
@@ -11905,7 +12046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11905 World.ForEachScenePresence(delegate(ScenePresence sp) 12046 World.ForEachScenePresence(delegate(ScenePresence sp)
11906 { 12047 {
11907 Vector3 ac = sp.AbsolutePosition - rayStart; 12048 Vector3 ac = sp.AbsolutePosition - rayStart;
11908 Vector3 bc = sp.AbsolutePosition - rayEnd; 12049// Vector3 bc = sp.AbsolutePosition - rayEnd;
11909 12050
11910 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 12051 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11911 12052
@@ -11993,9 +12134,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11993 radius = Math.Abs(maxY); 12134 radius = Math.Abs(maxY);
11994 if (Math.Abs(maxZ) > radius) 12135 if (Math.Abs(maxZ) > radius)
11995 radius = Math.Abs(maxZ); 12136 radius = Math.Abs(maxZ);
11996 12137 radius = radius*1.413f;
11997 Vector3 ac = group.AbsolutePosition - rayStart; 12138 Vector3 ac = group.AbsolutePosition - rayStart;
11998 Vector3 bc = group.AbsolutePosition - rayEnd; 12139// Vector3 bc = group.AbsolutePosition - rayEnd;
11999 12140
12000 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd)); 12141 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
12001 12142
@@ -12008,11 +12149,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12008 if (d2 > 0) 12149 if (d2 > 0)
12009 return; 12150 return;
12010 12151
12152 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
12011 EntityIntersection intersection = group.TestIntersection(ray, true, false); 12153 EntityIntersection intersection = group.TestIntersection(ray, true, false);
12012 // Miss. 12154 // Miss.
12013 if (!intersection.HitTF) 12155 if (!intersection.HitTF)
12014 return; 12156 return;
12015 12157
12158 Vector3 b1 = group.AbsolutePosition + new Vector3(minX, minY, minZ);
12159 Vector3 b2 = group.AbsolutePosition + new Vector3(maxX, maxY, maxZ);
12160 //m_log.DebugFormat("[LLCASTRAY]: min<{0},{1},{2}>, max<{3},{4},{5}> = hitp<{6},{7},{8}>", b1.X,b1.Y,b1.Z,b2.X,b2.Y,b2.Z,intersection.ipoint.X,intersection.ipoint.Y,intersection.ipoint.Z);
12161 if (!(intersection.ipoint.X >= b1.X && intersection.ipoint.X <= b2.X &&
12162 intersection.ipoint.Y >= b1.Y && intersection.ipoint.Y <= b2.Y &&
12163 intersection.ipoint.Z >= b1.Z && intersection.ipoint.Z <= b2.Z))
12164 return;
12165
12016 ContactResult result = new ContactResult (); 12166 ContactResult result = new ContactResult ();
12017 result.ConsumerID = group.LocalId; 12167 result.ConsumerID = group.LocalId;
12018// result.Depth = intersection.distance; 12168// result.Depth = intersection.distance;
@@ -12228,7 +12378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12228 if (checkNonPhysical) 12378 if (checkNonPhysical)
12229 rayfilter |= RayFilterFlags.nonphysical; 12379 rayfilter |= RayFilterFlags.nonphysical;
12230 if (detectPhantom) 12380 if (detectPhantom)
12231 rayfilter |= RayFilterFlags.LSLPhanton; 12381 rayfilter |= RayFilterFlags.LSLPhantom;
12232 12382
12233 Vector3 direction = dir * ( 1/dist); 12383 Vector3 direction = dir * ( 1/dist);
12234 12384
@@ -12286,8 +12436,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12286 if (checkPhysical || checkNonPhysical || detectPhantom) 12436 if (checkPhysical || checkNonPhysical || detectPhantom)
12287 { 12437 {
12288 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12438 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12289 foreach (ContactResult r in objectHits) 12439 for (int iter = 0; iter < objectHits.Length; iter++)
12290 results.Add(r); 12440 {
12441 // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler.
12442 objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart);
12443 results.Add(objectHits[iter]);
12444 }
12291 } 12445 }
12292 } 12446 }
12293 12447
@@ -12348,7 +12502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12348 else 12502 else
12349 { 12503 {
12350 ScenePresence sp = World.GetScenePresence(result.ConsumerID); 12504 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
12351 /// It it a boy? a girl? 12505 /// It it a boy? a girl?
12352 if (sp != null) 12506 if (sp != null)
12353 itemID = sp.UUID; 12507 itemID = sp.UUID;
12354 } 12508 }
@@ -12360,7 +12514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12360 list.Add(new LSL_Integer(linkNum)); 12514 list.Add(new LSL_Integer(linkNum));
12361 12515
12362 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 12516 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
12363 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); 12517 list.Add(new LSL_Vector(result.Normal));
12364 12518
12365 values++; 12519 values++;
12366 if (values >= count) 12520 if (values >= count)
@@ -13235,7 +13389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13235 13389
13236 public static void Cache(UUID assetID, string text) 13390 public static void Cache(UUID assetID, string text)
13237 { 13391 {
13238 CacheCheck(); 13392 CheckCache();
13239 13393
13240 lock (m_Notecards) 13394 lock (m_Notecards)
13241 { 13395 {
@@ -13273,7 +13427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13273 /// Get a notecard line. 13427 /// Get a notecard line.
13274 /// </summary> 13428 /// </summary>
13275 /// <param name="assetID"></param> 13429 /// <param name="assetID"></param>
13276 /// <param name="line">Lines start at index 0</param> 13430 /// <param name="lineNumber">Lines start at index 0</param>
13277 /// <returns></returns> 13431 /// <returns></returns>
13278 public static string GetLine(UUID assetID, int lineNumber) 13432 public static string GetLine(UUID assetID, int lineNumber)
13279 { 13433 {
@@ -13302,9 +13456,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13302 /// Get a notecard line. 13456 /// Get a notecard line.
13303 /// </summary> 13457 /// </summary>
13304 /// <param name="assetID"></param> 13458 /// <param name="assetID"></param>
13305 /// <param name="line">Lines start at index 0</param> 13459 /// <param name="lineNumber">Lines start at index 0</param>
13306 /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para> 13460 /// <param name="maxLength">
13307 /// <returns></returns> 13461 /// Maximum length of the returned line.
13462 /// </param>
13463 /// <returns>
13464 /// If the line length is longer than <paramref name="maxLength"/>,
13465 /// the return string will be truncated.
13466 /// </returns>
13308 public static string GetLine(UUID assetID, int lineNumber, int maxLength) 13467 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
13309 { 13468 {
13310 string line = GetLine(assetID, lineNumber); 13469 string line = GetLine(assetID, lineNumber);
@@ -13315,13 +13474,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13315 return line; 13474 return line;
13316 } 13475 }
13317 13476
13318 public static void CacheCheck() 13477 public static void CheckCache()
13319 { 13478 {
13320 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 13479 lock (m_Notecards)
13321 { 13480 {
13322 Notecard nc = m_Notecards[key]; 13481 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
13323 if (nc.lastRef.AddSeconds(30) < DateTime.Now) 13482 {
13324 m_Notecards.Remove(key); 13483 Notecard nc = m_Notecards[key];
13484 if (nc.lastRef.AddSeconds(30) < DateTime.Now)
13485 m_Notecards.Remove(key);
13486 }
13325 } 13487 }
13326 } 13488 }
13327 } 13489 }