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.cs834
1 files changed, 499 insertions, 335 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 53c6e5c..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;
1880 part.ScheduleFullUpdate();
1881 } 1931 }
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;
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 {
@@ -3332,7 +3400,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3332 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3400 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3333 3401
3334 if (attachmentsModule != null) 3402 if (attachmentsModule != null)
3335 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false); 3403 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3336 else 3404 else
3337 return false; 3405 return false;
3338 } 3406 }
@@ -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
4191 // parse for sitting avatare-names
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
4200 int totalprims = m_host.ParentGroup.PrimCount + nametable.Count;
4201 if (totalprims > m_host.ParentGroup.PrimCount)
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 4243
4214 // Single prim 4244 ISceneEntity entity = GetLinkEntity(linknum);
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 4245
4223 // Link set 4246 if (entity != null)
4224 SceneObjectPart part = null; 4247 return entity.Name;
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
@@ -4724,7 +4729,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4724 UUID av = new UUID(); 4729 UUID av = new UUID();
4725 if (!UUID.TryParse(agent,out av)) 4730 if (!UUID.TryParse(agent,out av))
4726 { 4731 {
4727 //LSLError("First parameter to llDialog needs to be a key");
4728 return; 4732 return;
4729 } 4733 }
4730 4734
@@ -4765,7 +4769,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4765 return; 4769 return;
4766 } 4770 }
4767 // TODO: Parameter check logic required. 4771 // TODO: Parameter check logic required.
4768 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4772 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4769 m_host.CollisionSoundVolume = (float)impact_volume; 4773 m_host.CollisionSoundVolume = (float)impact_volume;
4770 m_host.CollisionSoundType = 1; 4774 m_host.CollisionSoundType = 1;
4771 } 4775 }
@@ -4890,7 +4894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4890 { 4894 {
4891 if (pushrestricted) 4895 if (pushrestricted)
4892 { 4896 {
4893 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4897 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4894 4898
4895 // 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
4896 if (targetlandObj == null) 4900 if (targetlandObj == null)
@@ -4905,7 +4909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4905 } 4909 }
4906 else 4910 else
4907 { 4911 {
4908 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos.X, PusheePos.Y); 4912 ILandObject targetlandObj = World.LandChannel.GetLandObject(PusheePos);
4909 if (targetlandObj == null) 4913 if (targetlandObj == null)
4910 { 4914 {
4911 // 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
@@ -4935,6 +4939,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4935 } 4939 }
4936 } 4940 }
4937 } 4941 }
4942
4938 if (pushAllowed) 4943 if (pushAllowed)
4939 { 4944 {
4940 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4945 float distance = (PusheePos - m_host.AbsolutePosition).Length();
@@ -4964,17 +4969,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4964 applied_linear_impulse *= scaling_factor; 4969 applied_linear_impulse *= scaling_factor;
4965 4970
4966 } 4971 }
4972
4967 if (pusheeIsAvatar) 4973 if (pusheeIsAvatar)
4968 { 4974 {
4969 if (pusheeav != null) 4975 if (pusheeav != null)
4970 { 4976 {
4971 if (pusheeav.PhysicsActor != null) 4977 PhysicsActor pa = pusheeav.PhysicsActor;
4978
4979 if (pa != null)
4972 { 4980 {
4973 if (local != 0) 4981 if (local != 0)
4974 { 4982 {
4975 applied_linear_impulse *= m_host.GetWorldRotation(); 4983 applied_linear_impulse *= m_host.GetWorldRotation();
4976 } 4984 }
4977 pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true); 4985
4986 pa.AddForce(applied_linear_impulse, true);
4978 } 4987 }
4979 } 4988 }
4980 } 4989 }
@@ -5324,8 +5333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5324 public LSL_Vector llGetCenterOfMass() 5333 public LSL_Vector llGetCenterOfMass()
5325 { 5334 {
5326 m_host.AddScriptLPS(1); 5335 m_host.AddScriptLPS(1);
5327 Vector3 center = m_host.GetCenterOfMass(); 5336
5328 return new LSL_Vector(center.X,center.Y,center.Z); 5337 return new LSL_Vector(m_host.GetCenterOfMass());
5329 } 5338 }
5330 5339
5331 public LSL_List llListSort(LSL_List src, int stride, int ascending) 5340 public LSL_List llListSort(LSL_List src, int stride, int ascending)
@@ -5466,7 +5475,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5466 // 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
5467 // At the time of patching, LSL_Key is currently LSL_String, 5476 // At the time of patching, LSL_Key is currently LSL_String,
5468 // 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
5469 // for completion and should LSL_Key ever be implemented 5478 // for completion and should LSL_Key ever be implemented
5470 // as it's own struct 5479 // as it's own struct
5471 else if (!(src.Data[index] is LSL_String || 5480 else if (!(src.Data[index] is LSL_String ||
5472 src.Data[index] is LSL_Key || 5481 src.Data[index] is LSL_Key ||
@@ -5603,8 +5612,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5603 { 5612 {
5604 m_host.AddScriptLPS(1); 5613 m_host.AddScriptLPS(1);
5605 5614
5606 return string.Join(", ", 5615 return string.Join(", ",
5607 (new List<object>(src.Data)).ConvertAll<string>(o => 5616 (new List<object>(src.Data)).ConvertAll<string>(o =>
5608 { 5617 {
5609 return o.ToString(); 5618 return o.ToString();
5610 }).ToArray()); 5619 }).ToArray());
@@ -5852,9 +5861,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5852 } 5861 }
5853 5862
5854 /// <summary> 5863 /// <summary>
5855 /// Insert the list identified by <src> into the 5864 /// Insert the list identified by <paramref name="src"/> into the
5856 /// list designated by <dest> such that the first 5865 /// list designated by <paramref name="dest"/> such that the first
5857 /// new element has the index specified by <index> 5866 /// new element has the index specified by <paramref name="index"/>
5858 /// </summary> 5867 /// </summary>
5859 5868
5860 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)
@@ -6182,12 +6191,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6182 } 6191 }
6183 6192
6184 ILandObject land; 6193 ILandObject land;
6185 Vector3 pos;
6186 UUID id = UUID.Zero; 6194 UUID id = UUID.Zero;
6195
6187 if (parcel || parcelOwned) 6196 if (parcel || parcelOwned)
6188 { 6197 {
6189 pos = m_host.ParentGroup.RootPart.GetWorldPosition(); 6198 land = World.LandChannel.GetLandObject(m_host.ParentGroup.RootPart.GetWorldPosition());
6190 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6191 if (land == null) 6199 if (land == null)
6192 { 6200 {
6193 id = UUID.Zero; 6201 id = UUID.Zero;
@@ -6213,20 +6221,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6213 { 6221 {
6214 if (!regionWide) 6222 if (!regionWide)
6215 { 6223 {
6216 pos = ssp.AbsolutePosition; 6224 land = World.LandChannel.GetLandObject(ssp.AbsolutePosition);
6217 land = World.LandChannel.GetLandObject(pos.X, pos.Y);
6218 if (land != null) 6225 if (land != null)
6219 { 6226 {
6220 if (parcelOwned && land.LandData.OwnerID == id || 6227 if (parcelOwned && land.LandData.OwnerID == id ||
6221 parcel && land.LandData.GlobalID == id) 6228 parcel && land.LandData.GlobalID == id)
6222 { 6229 {
6223 result.Add(ssp.UUID.ToString()); 6230 result.Add(new LSL_Key(ssp.UUID.ToString()));
6224 } 6231 }
6225 } 6232 }
6226 } 6233 }
6227 else 6234 else
6228 { 6235 {
6229 result.Add(ssp.UUID.ToString()); 6236 result.Add(new LSL_Key(ssp.UUID.ToString()));
6230 } 6237 }
6231 } 6238 }
6232 // Maximum of 100 results 6239 // Maximum of 100 results
@@ -6330,7 +6337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6330 if (m_SoundModule != null) 6337 if (m_SoundModule != null)
6331 { 6338 {
6332 m_SoundModule.TriggerSoundLimited(m_host.UUID, 6339 m_SoundModule.TriggerSoundLimited(m_host.UUID,
6333 KeyOrName(sound, AssetType.Sound), volume, 6340 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume,
6334 bottom_south_west, top_north_east); 6341 bottom_south_west, top_north_east);
6335 } 6342 }
6336 } 6343 }
@@ -6345,14 +6352,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6345 if (presence != null) 6352 if (presence != null)
6346 { 6353 {
6347 // agent must be over the owners land 6354 // agent must be over the owners land
6348 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition.X, presence.AbsolutePosition.Y); 6355 ILandObject land = World.LandChannel.GetLandObject(presence.AbsolutePosition);
6349 if (land == null) 6356 if (land == null)
6350 return; 6357 return;
6351 6358
6352 if (m_host.OwnerID == land.LandData.OwnerID) 6359 if (m_host.OwnerID == land.LandData.OwnerID)
6353 { 6360 {
6354 Vector3 pos = World.GetNearestAllowedPosition(presence, land); 6361 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6355 presence.TeleportWithMomentum(pos, null); 6362 presence.TeleportWithMomentum(p, null);
6356 presence.ControllingClient.SendAlertMessage("You have been ejected from this land"); 6363 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
6357 } 6364 }
6358 } 6365 }
@@ -6374,19 +6381,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6374 ScenePresence presence = World.GetScenePresence(key); 6381 ScenePresence presence = World.GetScenePresence(key);
6375 if (presence != null) // object is an avatar 6382 if (presence != null) // object is an avatar
6376 { 6383 {
6377 if (m_host.OwnerID 6384 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
6378 == World.LandChannel.GetLandObject(
6379 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
6380 return 1; 6385 return 1;
6381 } 6386 }
6382 else // object is not an avatar 6387 else // object is not an avatar
6383 { 6388 {
6384 SceneObjectPart obj = World.GetSceneObjectPart(key); 6389 SceneObjectPart obj = World.GetSceneObjectPart(key);
6390
6385 if (obj != null) 6391 if (obj != null)
6386 if (m_host.OwnerID 6392 {
6387 == World.LandChannel.GetLandObject( 6393 if (m_host.OwnerID == World.LandChannel.GetLandObject(obj.AbsolutePosition).LandData.OwnerID)
6388 obj.AbsolutePosition.X, obj.AbsolutePosition.Y).LandData.OwnerID)
6389 return 1; 6394 return 1;
6395 }
6390 } 6396 }
6391 } 6397 }
6392 6398
@@ -6494,8 +6500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6494 // 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
6495 // or 6501 // or
6496 // if the object is owned by a person with estate access. 6502 // if the object is owned by a person with estate access.
6497 6503 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition);
6498 ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y);
6499 if (parcel != null) 6504 if (parcel != null)
6500 { 6505 {
6501 if (m_host.OwnerID == parcel.LandData.OwnerID || 6506 if (m_host.OwnerID == parcel.LandData.OwnerID ||
@@ -6507,14 +6512,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6507 } 6512 }
6508 } 6513 }
6509 } 6514 }
6510
6511 } 6515 }
6512
6513 } 6516 }
6514 6517
6515 public LSL_Vector llGroundSlope(LSL_Vector offset) 6518 public LSL_Vector llGroundSlope(LSL_Vector offset)
6516 { 6519 {
6517 m_host.AddScriptLPS(1); 6520 m_host.AddScriptLPS(1);
6521
6518 //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.
6519 LSL_Vector vsn = llGroundNormal(offset); 6523 LSL_Vector vsn = llGroundNormal(offset);
6520 6524
@@ -6525,7 +6529,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6525 vsl.Normalize(); 6529 vsl.Normalize();
6526 //Normalization might be overkill here 6530 //Normalization might be overkill here
6527 6531
6528 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;
6529 } 6537 }
6530 6538
6531 public LSL_Vector llGroundNormal(LSL_Vector offset) 6539 public LSL_Vector llGroundNormal(LSL_Vector offset)
@@ -6575,7 +6583,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6575 //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
6576 //this normalization may be overkill 6584 //this normalization may be overkill
6577 6585
6578 return new LSL_Vector(vsn.X, vsn.Y, vsn.Z); 6586 return new LSL_Vector(vsn);
6579 } 6587 }
6580 6588
6581 public LSL_Vector llGroundContour(LSL_Vector offset) 6589 public LSL_Vector llGroundContour(LSL_Vector offset)
@@ -6687,6 +6695,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6687 ps.BurstSpeedMax = 1.0f; 6695 ps.BurstSpeedMax = 1.0f;
6688 ps.BurstRate = 0.1f; 6696 ps.BurstRate = 0.1f;
6689 ps.PartMaxAge = 10.0f; 6697 ps.PartMaxAge = 10.0f;
6698 ps.BurstPartCount = 1;
6690 return ps; 6699 return ps;
6691 } 6700 }
6692 6701
@@ -6710,8 +6719,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6710 6719
6711 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) 6720 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6712 { 6721 {
6713
6714
6715 if (rules.Length == 0) 6722 if (rules.Length == 0)
6716 { 6723 {
6717 part.RemoveParticleSystem(); 6724 part.RemoveParticleSystem();
@@ -6802,7 +6809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6802 break; 6809 break;
6803 6810
6804 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE: 6811 case (int)ScriptBaseClass.PSYS_SRC_TEXTURE:
6805 prules.Texture = KeyOrName(rules.GetLSLStringItem(i + 1)); 6812 prules.Texture = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, rules.GetLSLStringItem(i + 1));
6806 break; 6813 break;
6807 6814
6808 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE: 6815 case (int)ScriptBaseClass.PSYS_SRC_BURST_RATE:
@@ -6947,7 +6954,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6947 m_host.OwnerID, m_host.Name, destID, 6954 m_host.OwnerID, m_host.Name, destID,
6948 (byte)InstantMessageDialog.TaskInventoryOffered, 6955 (byte)InstantMessageDialog.TaskInventoryOffered,
6949 false, string.Format("'{0}'", category), 6956 false, string.Format("'{0}'", category),
6950// 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
6951// 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),
6952 folderID, false, pos, 6959 folderID, false, pos,
6953 bucket, false); 6960 bucket, false);
@@ -7066,12 +7073,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7066 public LSL_String llAvatarOnLinkSitTarget(int linknum) 7073 public LSL_String llAvatarOnLinkSitTarget(int linknum)
7067 { 7074 {
7068 m_host.AddScriptLPS(1); 7075 m_host.AddScriptLPS(1);
7069 if(linknum == ScriptBaseClass.LINK_SET || 7076 if(linknum == ScriptBaseClass.LINK_SET ||
7070 linknum == ScriptBaseClass.LINK_ALL_CHILDREN || 7077 linknum == ScriptBaseClass.LINK_ALL_CHILDREN ||
7071 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString(); 7078 linknum == ScriptBaseClass.LINK_ALL_OTHERS) return UUID.Zero.ToString();
7072 7079
7073 List<SceneObjectPart> parts = GetLinkParts(linknum); 7080 List<SceneObjectPart> parts = GetLinkParts(linknum);
7074 if (parts.Count == 0) return UUID.Zero.ToString(); 7081 if (parts.Count == 0) return UUID.Zero.ToString();
7075 return parts[0].SitTargetAvatar.ToString(); 7082 return parts[0].SitTargetAvatar.ToString();
7076 } 7083 }
7077 7084
@@ -7080,7 +7087,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7080 { 7087 {
7081 m_host.AddScriptLPS(1); 7088 m_host.AddScriptLPS(1);
7082 UUID key; 7089 UUID key;
7083 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 7090 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
7091
7084 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7092 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
7085 { 7093 {
7086 int expires = 0; 7094 int expires = 0;
@@ -7222,20 +7230,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7222 } 7230 }
7223 if (buttons.Length > 12) 7231 if (buttons.Length > 12)
7224 { 7232 {
7225 LSLError("No more than 12 buttons can be shown"); 7233 ShoutError("button list too long, must be 12 or fewer entries");
7226 return;
7227 } 7234 }
7228 string[] buts = new string[buttons.Length]; 7235 int length = buttons.Length;
7229 for (int i = 0; i < buttons.Length; i++) 7236 if (length > 12)
7237 length = 12;
7238
7239 string[] buts = new string[length];
7240 for (int i = 0; i < length; i++)
7230 { 7241 {
7231 if (buttons.Data[i].ToString() == String.Empty) 7242 if (buttons.Data[i].ToString() == String.Empty)
7232 { 7243 {
7233 LSLError("button label cannot be blank"); 7244 ShoutError("button label cannot be blank");
7234 return; 7245 return;
7235 } 7246 }
7236 if (buttons.Data[i].ToString().Length > 24) 7247 if (buttons.Data[i].ToString().Length > 24)
7237 { 7248 {
7238 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters"); 7249 ShoutError("button label cannot be longer than 24 characters");
7239 return; 7250 return;
7240 } 7251 }
7241 buts[i] = buttons.Data[i].ToString(); 7252 buts[i] = buttons.Data[i].ToString();
@@ -7371,6 +7382,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7371 public void llCloseRemoteDataChannel(string channel) 7382 public void llCloseRemoteDataChannel(string channel)
7372 { 7383 {
7373 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
7374 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 7392 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
7375 if (xmlrpcMod != null) 7393 if (xmlrpcMod != null)
7376 xmlrpcMod.CloseXMLRPCChannel((UUID)channel); 7394 xmlrpcMod.CloseXMLRPCChannel((UUID)channel);
@@ -7450,7 +7468,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7450 hollow = 0.70f; 7468 hollow = 0.70f;
7451 } 7469 }
7452 } 7470 }
7453 // Otherwise, hollow is limited to 95%. 7471 // Otherwise, hollow is limited to 95%.
7454 else 7472 else
7455 { 7473 {
7456 if (hollow > 0.95f) 7474 if (hollow > 0.95f)
@@ -7744,9 +7762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7744 UUID sculptId; 7762 UUID sculptId;
7745 7763
7746 if (!UUID.TryParse(map, out sculptId)) 7764 if (!UUID.TryParse(map, out sculptId))
7747 { 7765 sculptId = ScriptUtils.GetAssetIdFromItemName(m_host, map, (int)AssetType.Texture);
7748 sculptId = InventoryKey(map, (int)AssetType.Texture);
7749 }
7750 7766
7751 if (sculptId == UUID.Zero) 7767 if (sculptId == UUID.Zero)
7752 return; 7768 return;
@@ -7843,7 +7859,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7843 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType; 7859 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7844 physdata.Density = part.Density; 7860 physdata.Density = part.Density;
7845 physdata.Friction = part.Friction; 7861 physdata.Friction = part.Friction;
7846 physdata.Bounce = part.Bounciness; 7862 physdata.Bounce = part.Restitution;
7847 physdata.GravitationModifier = part.GravityModifier; 7863 physdata.GravitationModifier = part.GravityModifier;
7848 7864
7849 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0) 7865 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
@@ -8236,7 +8252,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8236 8252
8237 ExtraPhysicsData physdata = new ExtraPhysicsData(); 8253 ExtraPhysicsData physdata = new ExtraPhysicsData();
8238 physdata.Density = part.Density; 8254 physdata.Density = part.Density;
8239 physdata.Bounce = part.Bounciness; 8255 physdata.Bounce = part.Restitution;
8240 physdata.GravitationModifier = part.GravityModifier; 8256 physdata.GravitationModifier = part.GravityModifier;
8241 physdata.PhysShapeType = (PhysShapeType)shape_type; 8257 physdata.PhysShapeType = (PhysShapeType)shape_type;
8242 8258
@@ -8509,7 +8525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8509 { 8525 {
8510 m_host.AddScriptLPS(1); 8526 m_host.AddScriptLPS(1);
8511 8527
8512 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8528 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8513 8529
8514 if (land.LandData.OwnerID != m_host.OwnerID) 8530 if (land.LandData.OwnerID != m_host.OwnerID)
8515 return; 8531 return;
@@ -8523,7 +8539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8523 { 8539 {
8524 m_host.AddScriptLPS(1); 8540 m_host.AddScriptLPS(1);
8525 8541
8526 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 8542 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
8527 8543
8528 if (land.LandData.OwnerID != m_host.OwnerID) 8544 if (land.LandData.OwnerID != m_host.OwnerID)
8529 return String.Empty; 8545 return String.Empty;
@@ -8534,8 +8550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8534 public LSL_Vector llGetRootPosition() 8550 public LSL_Vector llGetRootPosition()
8535 { 8551 {
8536 m_host.AddScriptLPS(1); 8552 m_host.AddScriptLPS(1);
8537 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition.X, m_host.ParentGroup.AbsolutePosition.Y, 8553
8538 m_host.ParentGroup.AbsolutePosition.Z); 8554 return new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8539 } 8555 }
8540 8556
8541 /// <summary> 8557 /// <summary>
@@ -8558,13 +8574,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8558 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 8574 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
8559 q = avatar.CameraRotation; // Mouselook 8575 q = avatar.CameraRotation; // Mouselook
8560 else 8576 else
8561 q = avatar.Rotation; // Currently infrequently updated so may be inaccurate 8577 q = avatar.GetWorldRotation(); // Currently infrequently updated so may be inaccurate
8562 else 8578 else
8563 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
8564 } 8580 }
8565 else 8581 else
8566 q = m_host.ParentGroup.GroupRotation; // just the group rotation 8582 q = m_host.ParentGroup.GroupRotation; // just the group rotation
8567 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 8583
8584 return new LSL_Rotation(q);
8568 } 8585 }
8569 8586
8570 public LSL_String llGetObjectDesc() 8587 public LSL_String llGetObjectDesc()
@@ -8731,8 +8748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8731 8748
8732 public LSL_Vector llGetGeometricCenter() 8749 public LSL_Vector llGetGeometricCenter()
8733 { 8750 {
8734 Vector3 tmp = m_host.GetGeometricCenter(); 8751 return new LSL_Vector(m_host.GetGeometricCenter());
8735 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
8736 } 8752 }
8737 8753
8738 public LSL_List llGetPrimitiveParams(LSL_List rules) 8754 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -8839,9 +8855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8839 break; 8855 break;
8840 8856
8841 case (int)ScriptBaseClass.PRIM_SIZE: 8857 case (int)ScriptBaseClass.PRIM_SIZE:
8842 res.Add(new LSL_Vector(part.Scale.X, 8858 res.Add(new LSL_Vector(part.Scale));
8843 part.Scale.Y,
8844 part.Scale.Z));
8845 break; 8859 break;
8846 8860
8847 case (int)ScriptBaseClass.PRIM_ROTATION: 8861 case (int)ScriptBaseClass.PRIM_ROTATION:
@@ -8909,16 +8923,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8909 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));
8910 8924
8911 // float revolutions 8925 // float revolutions
8912 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);
8913 // Slightly inaccurate, because an unsigned byte is being used to represent 8927 // Slightly inaccurate, because an unsigned byte is being used to represent
8914 // 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
8915 // SL does it). 8929 // SL does it).
8916 // 8930 //
8917 // Using these formulas to store and retrieve PathRevolutions, it is not 8931 // Using these formulas to store and retrieve PathRevolutions, it is not
8918 // 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
8919 // 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
8920 // 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
8921 // 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
8922 // 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.
8923 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value 8937 // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value
8924 // 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
@@ -9202,9 +9216,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9202 case (int)ScriptBaseClass.PRIM_DESC: 9216 case (int)ScriptBaseClass.PRIM_DESC:
9203 res.Add(new LSL_String(part.Description)); 9217 res.Add(new LSL_String(part.Description));
9204 break; 9218 break;
9205
9206 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9219 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9207 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));
9208 break; 9221 break;
9209 9222
9210 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9223 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
@@ -10236,6 +10249,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10236 return UUID.Zero.ToString(); 10249 return UUID.Zero.ToString();
10237 } 10250 }
10238 } 10251 }
10252
10239 public LSL_String llRequestURL() 10253 public LSL_String llRequestURL()
10240 { 10254 {
10241 m_host.AddScriptLPS(1); 10255 m_host.AddScriptLPS(1);
@@ -10387,7 +10401,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10387 10401
10388 // 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
10389 // 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.
10390 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10404 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10391 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 10405 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return;
10392 10406
10393 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)?
@@ -10710,22 +10724,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10710 m_host.AddScriptLPS(1); 10724 m_host.AddScriptLPS(1);
10711 10725
10712 if (m_item.PermsGranter == UUID.Zero) 10726 if (m_item.PermsGranter == UUID.Zero)
10713 return new LSL_Vector(); 10727 return Vector3.Zero;
10714 10728
10715 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10729 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10716 { 10730 {
10717 ShoutError("No permissions to track the camera"); 10731 ShoutError("No permissions to track the camera");
10718 return new LSL_Vector(); 10732 return Vector3.Zero;
10719 } 10733 }
10720 10734
10721// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10735// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10722 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10736 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10723 if (presence != null) 10737 if (presence != null)
10724 { 10738 {
10725 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10739 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
10726 return pos; 10740 return pos;
10727 } 10741 }
10728 return new LSL_Vector(); 10742
10743 return Vector3.Zero;
10729 } 10744 }
10730 10745
10731 public LSL_Rotation llGetCameraRot() 10746 public LSL_Rotation llGetCameraRot()
@@ -10733,22 +10748,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10733 m_host.AddScriptLPS(1); 10748 m_host.AddScriptLPS(1);
10734 10749
10735 if (m_item.PermsGranter == UUID.Zero) 10750 if (m_item.PermsGranter == UUID.Zero)
10736 return new LSL_Rotation(); 10751 return Quaternion.Identity;
10737 10752
10738 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10753 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10739 { 10754 {
10740 ShoutError("No permissions to track the camera"); 10755 ShoutError("No permissions to track the camera");
10741 return new LSL_Rotation(); 10756 return Quaternion.Identity;
10742 } 10757 }
10743 10758
10744// ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10759// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10745 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); 10760 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10746 if (presence != null) 10761 if (presence != null)
10747 { 10762 {
10748 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10763 return new LSL_Rotation(presence.CameraRotation);
10749 } 10764 }
10750 10765
10751 return new LSL_Rotation(); 10766 return Quaternion.Identity;
10752 } 10767 }
10753 10768
10754 /// <summary> 10769 /// <summary>
@@ -10829,7 +10844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10829 { 10844 {
10830 m_host.AddScriptLPS(1); 10845 m_host.AddScriptLPS(1);
10831 UUID key; 10846 UUID key;
10832 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10847 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10833 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10848 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10834 { 10849 {
10835 int expires = 0; 10850 int expires = 0;
@@ -10870,7 +10885,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10870 { 10885 {
10871 m_host.AddScriptLPS(1); 10886 m_host.AddScriptLPS(1);
10872 UUID key; 10887 UUID key;
10873 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10888 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10874 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10889 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed))
10875 { 10890 {
10876 if (UUID.TryParse(avatar, out key)) 10891 if (UUID.TryParse(avatar, out key))
@@ -10897,7 +10912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10897 { 10912 {
10898 m_host.AddScriptLPS(1); 10913 m_host.AddScriptLPS(1);
10899 UUID key; 10914 UUID key;
10900 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 10915 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10901 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10916 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned))
10902 { 10917 {
10903 if (UUID.TryParse(avatar, out key)) 10918 if (UUID.TryParse(avatar, out key))
@@ -11129,9 +11144,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11129 IHttpRequestModule httpScriptMod = 11144 IHttpRequestModule httpScriptMod =
11130 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>(); 11145 m_ScriptEngine.World.RequestModuleInterface<IHttpRequestModule>();
11131 List<string> param = new List<string>(); 11146 List<string> param = new List<string>();
11132 foreach (object o in parameters.Data) 11147 bool ok;
11148 Int32 flag;
11149
11150 for (int i = 0; i < parameters.Data.Length; i += 2)
11133 { 11151 {
11134 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 }
11135 } 11201 }
11136 11202
11137 Vector3 position = m_host.AbsolutePosition; 11203 Vector3 position = m_host.AbsolutePosition;
@@ -11263,7 +11329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11263 public void llResetLandBanList() 11329 public void llResetLandBanList()
11264 { 11330 {
11265 m_host.AddScriptLPS(1); 11331 m_host.AddScriptLPS(1);
11266 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11332 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11267 if (land.OwnerID == m_host.OwnerID) 11333 if (land.OwnerID == m_host.OwnerID)
11268 { 11334 {
11269 foreach (LandAccessEntry entry in land.ParcelAccessList) 11335 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11280,7 +11346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11280 public void llResetLandPassList() 11346 public void llResetLandPassList()
11281 { 11347 {
11282 m_host.AddScriptLPS(1); 11348 m_host.AddScriptLPS(1);
11283 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).LandData; 11349 LandData land = World.LandChannel.GetLandObject(m_host.AbsolutePosition).LandData;
11284 if (land.OwnerID == m_host.OwnerID) 11350 if (land.OwnerID == m_host.OwnerID)
11285 { 11351 {
11286 foreach (LandAccessEntry entry in land.ParcelAccessList) 11352 foreach (LandAccessEntry entry in land.ParcelAccessList)
@@ -11297,12 +11363,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11297 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)
11298 { 11364 {
11299 m_host.AddScriptLPS(1); 11365 m_host.AddScriptLPS(1);
11300 11366
11301 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y); 11367 ILandObject lo = World.LandChannel.GetLandObject((float)pos.x, (float)pos.y);
11302 11368
11303 if (lo == null) 11369 if (lo == null)
11304 return 0; 11370 return 0;
11305 11371
11306 IPrimCounts pc = lo.PrimCounts; 11372 IPrimCounts pc = lo.PrimCounts;
11307 11373
11308 if (sim_wide != ScriptBaseClass.FALSE) 11374 if (sim_wide != ScriptBaseClass.FALSE)
@@ -11332,7 +11398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11332 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP) 11398 else if (category == ScriptBaseClass.PARCEL_COUNT_TEMP)
11333 return 0; // counts not implemented yet 11399 return 0; // counts not implemented yet
11334 } 11400 }
11335 11401
11336 return 0; 11402 return 0;
11337 } 11403 }
11338 11404
@@ -11517,6 +11583,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11517 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11583 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11518 ret.Add(new LSL_Float(0)); 11584 ret.Add(new LSL_Float(0));
11519 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;
11520 default: 11615 default:
11521 // Invalid or unhandled constant. 11616 // Invalid or unhandled constant.
11522 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11617 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -11608,6 +11703,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11608 // The value returned in SL for normal prims is prim count 11703 // The value returned in SL for normal prims is prim count
11609 ret.Add(new LSL_Float(obj.PhysicsCost)); 11704 ret.Add(new LSL_Float(obj.PhysicsCost));
11610 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;
11611 default: 11752 default:
11612 // Invalid or unhandled constant. 11753 // Invalid or unhandled constant.
11613 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL)); 11754 ret.Add(new LSL_Integer(ScriptBaseClass.OBJECT_UNKNOWN_DETAIL));
@@ -11618,7 +11759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11618 return ret; 11759 return ret;
11619 } 11760 }
11620 } 11761 }
11621 11762
11622 return new LSL_List(); 11763 return new LSL_List();
11623 } 11764 }
11624 11765
@@ -11687,14 +11828,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11687 return UUID.Zero.ToString(); 11828 return UUID.Zero.ToString();
11688 } 11829 }
11689 11830
11831 string reqIdentifier = UUID.Random().ToString();
11832
11690 // was: UUID tid = tid = AsyncCommands. 11833 // was: UUID tid = tid = AsyncCommands.
11691 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);
11692 11835
11693 if (NotecardCache.IsCached(assetID)) 11836 if (NotecardCache.IsCached(assetID))
11694 { 11837 {
11695 AsyncCommands. 11838 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(assetID).ToString());
11696 DataserverPlugin.DataserverReply(assetID.ToString(), 11839
11697 NotecardCache.GetLines(assetID).ToString());
11698 ScriptSleep(100); 11840 ScriptSleep(100);
11699 return tid.ToString(); 11841 return tid.ToString();
11700 } 11842 }
@@ -11710,9 +11852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11710 string data = Encoding.UTF8.GetString(a.Data); 11852 string data = Encoding.UTF8.GetString(a.Data);
11711 //m_log.Debug(data); 11853 //m_log.Debug(data);
11712 NotecardCache.Cache(id, data); 11854 NotecardCache.Cache(id, data);
11713 AsyncCommands. 11855 AsyncCommands.DataserverPlugin.DataserverReply(reqIdentifier, NotecardCache.GetLines(id).ToString());
11714 DataserverPlugin.DataserverReply(id.ToString(),
11715 NotecardCache.GetLines(id).ToString());
11716 }); 11856 });
11717 11857
11718 ScriptSleep(100); 11858 ScriptSleep(100);
@@ -11741,13 +11881,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11741 return UUID.Zero.ToString(); 11881 return UUID.Zero.ToString();
11742 } 11882 }
11743 11883
11884 string reqIdentifier = UUID.Random().ToString();
11885
11744 // was: UUID tid = tid = AsyncCommands. 11886 // was: UUID tid = tid = AsyncCommands.
11745 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);
11746 11888
11747 if (NotecardCache.IsCached(assetID)) 11889 if (NotecardCache.IsCached(assetID))
11748 { 11890 {
11749 AsyncCommands.DataserverPlugin.DataserverReply(assetID.ToString(), 11891 AsyncCommands.DataserverPlugin.DataserverReply(
11750 NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax)); 11892 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11893
11751 ScriptSleep(100); 11894 ScriptSleep(100);
11752 return tid.ToString(); 11895 return tid.ToString();
11753 } 11896 }
@@ -11763,8 +11906,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11763 string data = Encoding.UTF8.GetString(a.Data); 11906 string data = Encoding.UTF8.GetString(a.Data);
11764 //m_log.Debug(data); 11907 //m_log.Debug(data);
11765 NotecardCache.Cache(id, data); 11908 NotecardCache.Cache(id, data);
11766 AsyncCommands.DataserverPlugin.DataserverReply(id.ToString(), 11909 AsyncCommands.DataserverPlugin.DataserverReply(
11767 NotecardCache.GetLine(id, line, m_notecardLineReadCharsMax)); 11910 reqIdentifier, NotecardCache.GetLine(assetID, line, m_notecardLineReadCharsMax));
11768 }); 11911 });
11769 11912
11770 ScriptSleep(100); 11913 ScriptSleep(100);
@@ -11799,7 +11942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11799 11942
11800 LSL_List result = new LSL_List(); 11943 LSL_List result = new LSL_List();
11801 11944
11802 if (obj != null && obj.OwnerID != m_host.OwnerID) 11945 if (obj != null && obj.OwnerID == m_host.OwnerID)
11803 { 11946 {
11804 LSL_List remaining = GetPrimParams(obj, rules, ref result); 11947 LSL_List remaining = GetPrimParams(obj, rules, ref result);
11805 11948
@@ -11903,7 +12046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11903 World.ForEachScenePresence(delegate(ScenePresence sp) 12046 World.ForEachScenePresence(delegate(ScenePresence sp)
11904 { 12047 {
11905 Vector3 ac = sp.AbsolutePosition - rayStart; 12048 Vector3 ac = sp.AbsolutePosition - rayStart;
11906 Vector3 bc = sp.AbsolutePosition - rayEnd; 12049// Vector3 bc = sp.AbsolutePosition - rayEnd;
11907 12050
11908 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));
11909 12052
@@ -11991,9 +12134,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11991 radius = Math.Abs(maxY); 12134 radius = Math.Abs(maxY);
11992 if (Math.Abs(maxZ) > radius) 12135 if (Math.Abs(maxZ) > radius)
11993 radius = Math.Abs(maxZ); 12136 radius = Math.Abs(maxZ);
11994 12137 radius = radius*1.413f;
11995 Vector3 ac = group.AbsolutePosition - rayStart; 12138 Vector3 ac = group.AbsolutePosition - rayStart;
11996 Vector3 bc = group.AbsolutePosition - rayEnd; 12139// Vector3 bc = group.AbsolutePosition - rayEnd;
11997 12140
11998 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));
11999 12142
@@ -12006,11 +12149,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12006 if (d2 > 0) 12149 if (d2 > 0)
12007 return; 12150 return;
12008 12151
12152 ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
12009 EntityIntersection intersection = group.TestIntersection(ray, true, false); 12153 EntityIntersection intersection = group.TestIntersection(ray, true, false);
12010 // Miss. 12154 // Miss.
12011 if (!intersection.HitTF) 12155 if (!intersection.HitTF)
12012 return; 12156 return;
12013 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
12014 ContactResult result = new ContactResult (); 12166 ContactResult result = new ContactResult ();
12015 result.ConsumerID = group.LocalId; 12167 result.ConsumerID = group.LocalId;
12016// result.Depth = intersection.distance; 12168// result.Depth = intersection.distance;
@@ -12226,7 +12378,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12226 if (checkNonPhysical) 12378 if (checkNonPhysical)
12227 rayfilter |= RayFilterFlags.nonphysical; 12379 rayfilter |= RayFilterFlags.nonphysical;
12228 if (detectPhantom) 12380 if (detectPhantom)
12229 rayfilter |= RayFilterFlags.LSLPhanton; 12381 rayfilter |= RayFilterFlags.LSLPhantom;
12230 12382
12231 Vector3 direction = dir * ( 1/dist); 12383 Vector3 direction = dir * ( 1/dist);
12232 12384
@@ -12284,8 +12436,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12284 if (checkPhysical || checkNonPhysical || detectPhantom) 12436 if (checkPhysical || checkNonPhysical || detectPhantom)
12285 { 12437 {
12286 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12438 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12287 foreach (ContactResult r in objectHits) 12439 for (int iter = 0; iter < objectHits.Length; iter++)
12288 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 }
12289 } 12445 }
12290 } 12446 }
12291 12447
@@ -12346,7 +12502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12346 else 12502 else
12347 { 12503 {
12348 ScenePresence sp = World.GetScenePresence(result.ConsumerID); 12504 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
12349 /// It it a boy? a girl? 12505 /// It it a boy? a girl?
12350 if (sp != null) 12506 if (sp != null)
12351 itemID = sp.UUID; 12507 itemID = sp.UUID;
12352 } 12508 }
@@ -12358,7 +12514,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12358 list.Add(new LSL_Integer(linkNum)); 12514 list.Add(new LSL_Integer(linkNum));
12359 12515
12360 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 12516 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
12361 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z)); 12517 list.Add(new LSL_Vector(result.Normal));
12362 12518
12363 values++; 12519 values++;
12364 if (values >= count) 12520 if (values >= count)
@@ -13233,7 +13389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13233 13389
13234 public static void Cache(UUID assetID, string text) 13390 public static void Cache(UUID assetID, string text)
13235 { 13391 {
13236 CacheCheck(); 13392 CheckCache();
13237 13393
13238 lock (m_Notecards) 13394 lock (m_Notecards)
13239 { 13395 {
@@ -13271,7 +13427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13271 /// Get a notecard line. 13427 /// Get a notecard line.
13272 /// </summary> 13428 /// </summary>
13273 /// <param name="assetID"></param> 13429 /// <param name="assetID"></param>
13274 /// <param name="line">Lines start at index 0</param> 13430 /// <param name="lineNumber">Lines start at index 0</param>
13275 /// <returns></returns> 13431 /// <returns></returns>
13276 public static string GetLine(UUID assetID, int lineNumber) 13432 public static string GetLine(UUID assetID, int lineNumber)
13277 { 13433 {
@@ -13300,9 +13456,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13300 /// Get a notecard line. 13456 /// Get a notecard line.
13301 /// </summary> 13457 /// </summary>
13302 /// <param name="assetID"></param> 13458 /// <param name="assetID"></param>
13303 /// <param name="line">Lines start at index 0</param> 13459 /// <param name="lineNumber">Lines start at index 0</param>
13304 /// <param name="maxLength">Maximum length of the returned line. Longer lines will be truncated</para> 13460 /// <param name="maxLength">
13305 /// <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>
13306 public static string GetLine(UUID assetID, int lineNumber, int maxLength) 13467 public static string GetLine(UUID assetID, int lineNumber, int maxLength)
13307 { 13468 {
13308 string line = GetLine(assetID, lineNumber); 13469 string line = GetLine(assetID, lineNumber);
@@ -13313,13 +13474,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
13313 return line; 13474 return line;
13314 } 13475 }
13315 13476
13316 public static void CacheCheck() 13477 public static void CheckCache()
13317 { 13478 {
13318 foreach (UUID key in new List<UUID>(m_Notecards.Keys)) 13479 lock (m_Notecards)
13319 { 13480 {
13320 Notecard nc = m_Notecards[key]; 13481 foreach (UUID key in new List<UUID>(m_Notecards.Keys))
13321 if (nc.lastRef.AddSeconds(30) < DateTime.Now) 13482 {
13322 m_Notecards.Remove(key); 13483 Notecard nc = m_Notecards[key];
13484 if (nc.lastRef.AddSeconds(30) < DateTime.Now)
13485 m_Notecards.Remove(key);
13486 }
13323 } 13487 }
13324 } 13488 }
13325 } 13489 }