aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3407
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs159
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs22
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs24
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs65
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs173
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
20 files changed, 3121 insertions, 1156 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..6879ebb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 if (xmlrpc != null)
321 {
322 xmlrpc.DeleteChannels(itemID);
323 xmlrpc.CancelSRDRequests(itemID);
324 }
325
326 // Remove Sensors
327 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
328
329 }
330
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 331 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 332 {
310 List<Object> data = new List<Object>(); 333 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..fce8ff8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 969243c..3f0af6d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using System.Linq; 74using System.Linq;
71using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
72 76
@@ -115,11 +119,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
115 protected int m_notecardLineReadCharsMax = 255; 119 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 120 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 121 protected bool m_scriptConsoleChannelEnabled = false;
122 protected bool m_debuggerSafe = false;
118 protected IUrlModule m_UrlModule = null; 123 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 125 new Dictionary<UUID, UserInfoCacheEntry>();
126 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 127 protected ISoundModule m_SoundModule = null;
122 128
129// protected Timer m_ShoutSayTimer;
130 protected int m_SayShoutCount = 0;
131 DateTime m_lastSayShoutCheck;
132
133 private Dictionary<string, string> MovementAnimationsForLSL =
134 new Dictionary<string, string> {
135 {"FLY", "Flying"},
136 {"FLYSLOW", "FlyingSlow"},
137 {"HOVER_UP", "Hovering Up"},
138 {"HOVER_DOWN", "Hovering Down"},
139 {"HOVER", "Hovering"},
140 {"LAND", "Landing"},
141 {"FALLDOWN", "Falling Down"},
142 {"PREJUMP", "PreJumping"},
143 {"JUMP", "Jumping"},
144 {"STANDUP", "Standing Up"},
145 {"SOFT_LAND", "Soft Landing"},
146 {"STAND", "Standing"},
147 {"CROUCHWALK", "CrouchWalking"},
148 {"RUN", "Running"},
149 {"WALK", "Walking"},
150 {"CROUCH", "Crouching"},
151 {"TURNLEFT", "Turning Left"},
152 {"TURNRIGHT", "Turning Right"}
153 };
123 //An array of HTTP/1.1 headers that are not allowed to be used 154 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 155 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 156 private string[] HttpStandardHeaders =
@@ -140,9 +171,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 public void Initialize( 171 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 173 {
174 m_lastSayShoutCheck = DateTime.UtcNow;
175
143 m_ScriptEngine = scriptEngine; 176 m_ScriptEngine = scriptEngine;
144 m_host = host; 177 m_host = host;
145 m_item = item; 178 m_item = item;
179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 m_coopSleepHandle = coopSleepHandle; 180 m_coopSleepHandle = coopSleepHandle;
147 181
148 LoadConfig(); 182 LoadConfig();
@@ -231,6 +265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
231 get { return m_ScriptEngine.World; } 265 get { return m_ScriptEngine.World; }
232 } 266 }
233 267
268 [DebuggerNonUserCode]
234 public void state(string newState) 269 public void state(string newState)
235 { 270 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 271 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -240,6 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 /// Reset the named script. The script must be present 275 /// Reset the named script. The script must be present
241 /// in the same prim. 276 /// in the same prim.
242 /// </summary> 277 /// </summary>
278 [DebuggerNonUserCode]
243 public void llResetScript() 279 public void llResetScript()
244 { 280 {
245 m_host.AddScriptLPS(1); 281 m_host.AddScriptLPS(1);
@@ -302,6 +338,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
302 } 338 }
303 } 339 }
304 340
341 public List<ScenePresence> GetLinkAvatars(int linkType)
342 {
343 List<ScenePresence> ret = new List<ScenePresence>();
344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
345 return ret;
346
347 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
348
349 switch (linkType)
350 {
351 case ScriptBaseClass.LINK_SET:
352 return avs;
353
354 case ScriptBaseClass.LINK_ROOT:
355 return ret;
356
357 case ScriptBaseClass.LINK_ALL_OTHERS:
358 return avs;
359
360 case ScriptBaseClass.LINK_ALL_CHILDREN:
361 return avs;
362
363 case ScriptBaseClass.LINK_THIS:
364 return ret;
365
366 default:
367 if (linkType < 0)
368 return ret;
369
370 int partCount = m_host.ParentGroup.GetPartCount();
371
372 if (linkType <= partCount)
373 {
374 return ret;
375 }
376 else
377 {
378 linkType = linkType - partCount;
379 if (linkType > avs.Count)
380 {
381 return ret;
382 }
383 else
384 {
385 ret.Add(avs[linkType-1]);
386 return ret;
387 }
388 }
389 }
390 }
391
305 /// <summary> 392 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 394 /// </summary>
@@ -384,6 +471,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 471 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 472 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 473 List<SceneObjectPart> ret = new List<SceneObjectPart>();
474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
475 return ret;
387 ret.Add(part); 476 ret.Add(part);
388 477
389 switch (linkType) 478 switch (linkType)
@@ -537,31 +626,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
537 626
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 627 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539 628
540 /// <summary> 629 // Utility function for llRot2Euler
541 /// Convert an LSL rotation to a Euler vector. 630
542 /// </summary> 631 // normalize an angle between -PI and PI (-180 to +180 degrees)
543 /// <remarks> 632 protected double NormalizeAngle(double angle)
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks>
547 /// <param name="r"></param>
548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 633 {
551 m_host.AddScriptLPS(1); 634 if (angle > -Math.PI && angle < Math.PI)
635 return angle;
552 636
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 637 int numPis = (int)(Math.PI / angle);
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 638 double remainder = angle - Math.PI * numPis;
555 if (m == 0.0) return new LSL_Vector(); 639 if (numPis % 2 == 1)
556 double x = Math.Atan2(-v.y, v.z); 640 return Math.PI - angle;
557 double sin = v.x / m; 641 return remainder;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 642 }
559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
562 double z = Math.Atan2(v.y, v.x);
563 643
564 return new LSL_Vector(x, y, z); 644 public LSL_Vector llRot2Euler(LSL_Rotation q1)
645 {
646 m_host.AddScriptLPS(1);
647 LSL_Vector eul = new LSL_Vector();
648
649 double sqw = q1.s*q1.s;
650 double sqx = q1.x*q1.x;
651 double sqy = q1.z*q1.z;
652 double sqz = q1.y*q1.y;
653 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
654 double test = q1.x*q1.z + q1.y*q1.s;
655 if (test > 0.4999*unit) { // singularity at north pole
656 eul.z = 2 * Math.Atan2(q1.x,q1.s);
657 eul.y = Math.PI/2;
658 eul.x = 0;
659 return eul;
660 }
661 if (test < -0.4999*unit) { // singularity at south pole
662 eul.z = -2 * Math.Atan2(q1.x,q1.s);
663 eul.y = -Math.PI/2;
664 eul.x = 0;
665 return eul;
666 }
667 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
668 eul.y = Math.Asin(2*test/unit);
669 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
670 return eul;
565 } 671 }
566 672
567 /* From wiki: 673 /* From wiki:
@@ -614,18 +720,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
614 m_host.AddScriptLPS(1); 720 m_host.AddScriptLPS(1);
615 721
616 double x,y,z,s; 722 double x,y,z,s;
617 723 v.x *= 0.5;
618 double c1 = Math.Cos(v.x * 0.5); 724 v.y *= 0.5;
619 double c2 = Math.Cos(v.y * 0.5); 725 v.z *= 0.5;
620 double c3 = Math.Cos(v.z * 0.5); 726 double c1 = Math.Cos(v.x);
621 double s1 = Math.Sin(v.x * 0.5); 727 double c2 = Math.Cos(v.y);
622 double s2 = Math.Sin(v.y * 0.5); 728 double c1c2 = c1 * c2;
623 double s3 = Math.Sin(v.z * 0.5); 729 double s1 = Math.Sin(v.x);
624 730 double s2 = Math.Sin(v.y);
625 x = s1 * c2 * c3 + c1 * s2 * s3; 731 double s1s2 = s1 * s2;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 732 double c1s2 = c1 * s2;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 733 double s1c2 = s1 * c2;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 734 double c3 = Math.Cos(v.z);
735 double s3 = Math.Sin(v.z);
736
737 x = s1c2 * c3 + c1s2 * s3;
738 y = c1s2 * c3 - s1c2 * s3;
739 z = s1s2 * c3 + c1c2 * s3;
740 s = c1c2 * c3 - s1s2 * s3;
629 741
630 return new LSL_Rotation(x, y, z, s); 742 return new LSL_Rotation(x, y, z, s);
631 } 743 }
@@ -763,77 +875,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
763 { 875 {
764 //A and B should both be normalized 876 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 878 /* This method is more accurate than the SL one, and thus causes problems
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 879 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
768 // continue calculation. 880
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 881 double dotProduct = LSL_Vector.Dot(a, b);
770 { 882 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 883 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
772 } 884 double angle = Math.Acos(dotProduct / magProduct);
773 else 885 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
774 { 886 double s = Math.Sin(angle / 2);
775 a = LSL_Vector.Norm(a); 887
776 b = LSL_Vector.Norm(b); 888 double x = axis.x * s;
777 double dotProduct = LSL_Vector.Dot(a, b); 889 double y = axis.y * s;
778 // There are two degenerate cases possible. These are for vectors 180 or 890 double z = axis.z * s;
779 // 0 degrees apart. These have to be detected and handled individually. 891 double w = Math.Cos(angle / 2);
780 // 892
781 // Check for vectors 180 degrees apart. 893 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
783 if (dotProduct < -0.9999999f) 895
784 { 896 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
785 // First assume X axis is orthogonal to the vectors. 897 */
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 898
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 899 // This method mimics the 180 errors found in SL
788 // Check for near zero vector. A very small non-zero number here will create 900 // See www.euclideanspace.com... angleBetween
789 // a rotation in an undesired direction. 901 LSL_Vector vec_a = a;
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 902 LSL_Vector vec_b = b;
791 { 903
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 904 // Eliminate zero length
793 } 905 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
794 // If the magnitude of the vector was near zero, then assume the X axis is not 906 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
795 // orthogonal and use the Z axis instead. 907 if (vec_a_mag < 0.00001 ||
796 else 908 vec_b_mag < 0.00001)
797 { 909 {
798 // Set 180 z rotation. 910 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 911 }
800 } 912
801 } 913 // Normalize
802 // Check for parallel vectors. 914 vec_a = llVecNorm(vec_a);
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 915 vec_b = llVecNorm(vec_b);
804 else if (dotProduct > 0.9999999f) 916
805 { 917 // Calculate axis and rotation angle
806 // Set zero rotation. 918 LSL_Vector axis = vec_a % vec_b;
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 919 LSL_Float cos_theta = vec_a * vec_b;
808 } 920
809 else 921 // Check if parallel
810 { 922 if (cos_theta > 0.99999)
811 // All special checks have been performed so get the axis of rotation. 923 {
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 924 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 // Quarternion s value is the length of the unit vector + dot product. 925 }
814 double qs = 1.0 + dotProduct; 926
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 927 // Check if anti-parallel
816 // Normalize the rotation. 928 else if (cos_theta < -0.99999)
817 double mag = LSL_Rotation.Mag(rotBetween); 929 {
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 930 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 931 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 932 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
821 // crossProduct vector should also not be zero. 933 }
822 rotBetween.x = rotBetween.x / mag; 934 else // other rotation
823 rotBetween.y = rotBetween.y / mag; 935 {
824 rotBetween.z = rotBetween.z / mag; 936 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
825 rotBetween.s = rotBetween.s / mag; 937 axis = llVecNorm(axis);
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 938 double x, y, z, s, t;
827 // any longer since zero vectors are checked for at the top. 939 s = Math.Cos(theta);
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 940 t = Math.Sin(theta);
829 { 941 x = axis.x * t;
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 942 y = axis.y * t;
831 } 943 z = axis.z * t;
832 } 944 return new LSL_Rotation(x,y,z,s);
833 } 945 }
834 return rotBetween; 946 }
835 } 947
836
837 public void llWhisper(int channelID, string text) 948 public void llWhisper(int channelID, string text)
838 { 949 {
839 m_host.AddScriptLPS(1); 950 m_host.AddScriptLPS(1);
@@ -849,10 +960,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 960 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 961 }
851 962
963 private void CheckSayShoutTime()
964 {
965 DateTime now = DateTime.UtcNow;
966 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
967 {
968 m_lastSayShoutCheck = now;
969 m_SayShoutCount = 0;
970 }
971 else
972 m_SayShoutCount++;
973 }
974
852 public void llSay(int channelID, string text) 975 public void llSay(int channelID, string text)
853 { 976 {
854 m_host.AddScriptLPS(1); 977 m_host.AddScriptLPS(1);
855 978
979 if (channelID == 0)
980// m_SayShoutCount++;
981 CheckSayShoutTime();
982
983 if (m_SayShoutCount >= 11)
984 ScriptSleep(2000);
985
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 986 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 987 {
858 Console.WriteLine(text); 988 Console.WriteLine(text);
@@ -875,6 +1005,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 { 1005 {
876 m_host.AddScriptLPS(1); 1006 m_host.AddScriptLPS(1);
877 1007
1008 if (channelID == 0)
1009// m_SayShoutCount++;
1010 CheckSayShoutTime();
1011
1012 if (m_SayShoutCount >= 11)
1013 ScriptSleep(2000);
1014
878 if (text.Length > 1023) 1015 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 1016 text = text.Substring(0, 1023);
880 1017
@@ -906,22 +1043,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
906 1043
907 public void llRegionSayTo(string target, int channel, string msg) 1044 public void llRegionSayTo(string target, int channel, string msg)
908 { 1045 {
1046 string error = String.Empty;
1047
909 if (msg.Length > 1023) 1048 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 1049 msg = msg.Substring(0, 1023);
911 1050
912 m_host.AddScriptLPS(1); 1051 m_host.AddScriptLPS(1);
913 1052
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 {
916 return;
917 }
918
919 UUID TargetID; 1053 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 1054 UUID.TryParse(target, out TargetID);
921 1055
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1056 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 1057 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1058 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1059 LSLError(error);
925 } 1060 }
926 1061
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1062 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1177,10 +1312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 return detectedParams.TouchUV; 1312 return detectedParams.TouchUV;
1178 } 1313 }
1179 1314
1315 [DebuggerNonUserCode]
1180 public virtual void llDie() 1316 public virtual void llDie()
1181 { 1317 {
1182 m_host.AddScriptLPS(1); 1318 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1319 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1184 } 1320 }
1185 1321
1186 public LSL_Float llGround(LSL_Vector offset) 1322 public LSL_Float llGround(LSL_Vector offset)
@@ -1251,6 +1387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1251 1387
1252 public void llSetStatus(int status, int value) 1388 public void llSetStatus(int status, int value)
1253 { 1389 {
1390 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1391 return;
1254 m_host.AddScriptLPS(1); 1392 m_host.AddScriptLPS(1);
1255 1393
1256 int statusrotationaxis = 0; 1394 int statusrotationaxis = 0;
@@ -1274,6 +1412,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1274 if (!allow) 1412 if (!allow)
1275 return; 1413 return;
1276 1414
1415 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1416 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1417 return;
1418
1277 m_host.ScriptSetPhysicsStatus(true); 1419 m_host.ScriptSetPhysicsStatus(true);
1278 } 1420 }
1279 else 1421 else
@@ -1474,6 +1616,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1474 { 1616 {
1475 m_host.AddScriptLPS(1); 1617 m_host.AddScriptLPS(1);
1476 1618
1619 SetColor(m_host, color, face);
1620 }
1621
1622 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1626
1627 Primitive.TextureEntry tex = part.Shape.Textures;
1628 Color4 texcolor;
1629 if (face >= 0 && face < GetNumberOfSides(part))
1630 {
1631 texcolor = tex.CreateFace((uint)face).RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.FaceTextures[face].RGBA = texcolor;
1636 part.UpdateTextureEntry(tex.GetBytes());
1637 return;
1638 }
1639 else if (face == ScriptBaseClass.ALL_SIDES)
1640 {
1641 for (uint i = 0; i < GetNumberOfSides(part); i++)
1642 {
1643 if (tex.FaceTextures[i] != null)
1644 {
1645 texcolor = tex.FaceTextures[i].RGBA;
1646 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1647 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1648 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1649 tex.FaceTextures[i].RGBA = texcolor;
1650 }
1651 texcolor = tex.DefaultTexture.RGBA;
1652 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1653 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1654 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1655 tex.DefaultTexture.RGBA = texcolor;
1656 }
1657 part.UpdateTextureEntry(tex.GetBytes());
1658 return;
1659 }
1660
1477 if (face == ScriptBaseClass.ALL_SIDES) 1661 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1662 face = SceneObjectPart.ALL_SIDES;
1479 1663
@@ -1482,6 +1666,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1482 1666
1483 public void SetTexGen(SceneObjectPart part, int face,int style) 1667 public void SetTexGen(SceneObjectPart part, int face,int style)
1484 { 1668 {
1669 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1670 return;
1671
1485 Primitive.TextureEntry tex = part.Shape.Textures; 1672 Primitive.TextureEntry tex = part.Shape.Textures;
1486 MappingType textype; 1673 MappingType textype;
1487 textype = MappingType.Default; 1674 textype = MappingType.Default;
@@ -1512,6 +1699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1512 1699
1513 public void SetGlow(SceneObjectPart part, int face, float glow) 1700 public void SetGlow(SceneObjectPart part, int face, float glow)
1514 { 1701 {
1702 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1703 return;
1704
1515 Primitive.TextureEntry tex = part.Shape.Textures; 1705 Primitive.TextureEntry tex = part.Shape.Textures;
1516 if (face >= 0 && face < GetNumberOfSides(part)) 1706 if (face >= 0 && face < GetNumberOfSides(part))
1517 { 1707 {
@@ -1537,6 +1727,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1537 1727
1538 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1728 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1539 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1540 1732
1541 Shininess sval = new Shininess(); 1733 Shininess sval = new Shininess();
1542 1734
@@ -1587,6 +1779,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1587 1779
1588 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1780 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1589 { 1781 {
1782 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1783 return;
1784
1590 Primitive.TextureEntry tex = part.Shape.Textures; 1785 Primitive.TextureEntry tex = part.Shape.Textures;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1786 if (face >= 0 && face < GetNumberOfSides(part))
1592 { 1787 {
@@ -1647,13 +1842,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1647 m_host.AddScriptLPS(1); 1842 m_host.AddScriptLPS(1);
1648 1843
1649 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1844 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1650 1845 if (parts.Count > 0)
1651 foreach (SceneObjectPart part in parts) 1846 {
1652 SetAlpha(part, alpha, face); 1847 try
1848 {
1849 foreach (SceneObjectPart part in parts)
1850 SetAlpha(part, alpha, face);
1851 }
1852 finally
1853 {
1854 }
1855 }
1653 } 1856 }
1654 1857
1655 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1858 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1656 { 1859 {
1860 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1861 return;
1862
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1863 Primitive.TextureEntry tex = part.Shape.Textures;
1658 Color4 texcolor; 1864 Color4 texcolor;
1659 if (face >= 0 && face < GetNumberOfSides(part)) 1865 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1706,7 +1912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1706 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1912 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1707 float wind, float tension, LSL_Vector Force) 1913 float wind, float tension, LSL_Vector Force)
1708 { 1914 {
1709 if (part == null) 1915 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1710 return; 1916 return;
1711 1917
1712 if (flexi) 1918 if (flexi)
@@ -1747,7 +1953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1747 /// <param name="falloff"></param> 1953 /// <param name="falloff"></param>
1748 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1954 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1749 { 1955 {
1750 if (part == null) 1956 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1751 return; 1957 return;
1752 1958
1753 if (light) 1959 if (light)
@@ -1780,11 +1986,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1986 Primitive.TextureEntry tex = part.Shape.Textures;
1781 Color4 texcolor; 1987 Color4 texcolor;
1782 LSL_Vector rgb = new LSL_Vector(); 1988 LSL_Vector rgb = new LSL_Vector();
1989 int nsides = GetNumberOfSides(part);
1990
1783 if (face == ScriptBaseClass.ALL_SIDES) 1991 if (face == ScriptBaseClass.ALL_SIDES)
1784 { 1992 {
1785 int i; 1993 int i;
1786 1994 for (i = 0; i < nsides; i++)
1787 for (i = 0 ; i < GetNumberOfSides(part); i++)
1788 { 1995 {
1789 texcolor = tex.GetFace((uint)i).RGBA; 1996 texcolor = tex.GetFace((uint)i).RGBA;
1790 rgb.x += texcolor.R; 1997 rgb.x += texcolor.R;
@@ -1792,14 +1999,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 rgb.z += texcolor.B; 1999 rgb.z += texcolor.B;
1793 } 2000 }
1794 2001
1795 rgb.x /= (float)GetNumberOfSides(part); 2002 float invnsides = 1.0f / (float)nsides;
1796 rgb.y /= (float)GetNumberOfSides(part); 2003
1797 rgb.z /= (float)GetNumberOfSides(part); 2004 rgb.x *= invnsides;
2005 rgb.y *= invnsides;
2006 rgb.z *= invnsides;
1798 2007
1799 return rgb; 2008 return rgb;
1800 } 2009 }
1801 2010 if (face >= 0 && face < nsides)
1802 if (face >= 0 && face < GetNumberOfSides(part))
1803 { 2011 {
1804 texcolor = tex.GetFace((uint)face).RGBA; 2012 texcolor = tex.GetFace((uint)face).RGBA;
1805 rgb.x = texcolor.R; 2013 rgb.x = texcolor.R;
@@ -1826,15 +2034,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1826 m_host.AddScriptLPS(1); 2034 m_host.AddScriptLPS(1);
1827 2035
1828 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2036 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1829 2037 if (parts.Count > 0)
1830 foreach (SceneObjectPart part in parts) 2038 {
1831 SetTexture(part, texture, face); 2039 try
1832 2040 {
2041 foreach (SceneObjectPart part in parts)
2042 SetTexture(part, texture, face);
2043 }
2044 finally
2045 {
2046 }
2047 }
1833 ScriptSleep(200); 2048 ScriptSleep(200);
1834 } 2049 }
1835 2050
1836 protected void SetTexture(SceneObjectPart part, string texture, int face) 2051 protected void SetTexture(SceneObjectPart part, string texture, int face)
1837 { 2052 {
2053 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2054 return;
2055
1838 UUID textureID = new UUID(); 2056 UUID textureID = new UUID();
1839 2057
1840 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2058 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1879,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1879 2097
1880 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2098 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1881 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1882 Primitive.TextureEntry tex = part.Shape.Textures; 2103 Primitive.TextureEntry tex = part.Shape.Textures;
1883 if (face >= 0 && face < GetNumberOfSides(part)) 2104 if (face >= 0 && face < GetNumberOfSides(part))
1884 { 2105 {
@@ -1915,6 +2136,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1915 2136
1916 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2137 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1917 { 2138 {
2139 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2140 return;
2141
1918 Primitive.TextureEntry tex = part.Shape.Textures; 2142 Primitive.TextureEntry tex = part.Shape.Textures;
1919 if (face >= 0 && face < GetNumberOfSides(part)) 2143 if (face >= 0 && face < GetNumberOfSides(part))
1920 { 2144 {
@@ -1951,6 +2175,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 2175
1952 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2176 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1953 { 2177 {
2178 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2179 return;
2180
1954 Primitive.TextureEntry tex = part.Shape.Textures; 2181 Primitive.TextureEntry tex = part.Shape.Textures;
1955 if (face >= 0 && face < GetNumberOfSides(part)) 2182 if (face >= 0 && face < GetNumberOfSides(part))
1956 { 2183 {
@@ -2092,7 +2319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2092 return end; 2319 return end;
2093 } 2320 }
2094 2321
2095 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2322 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2096 { 2323 {
2097 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2324 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2098 return fromPos; 2325 return fromPos;
@@ -2108,9 +2335,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2108 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2335 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2109 targetPos.z = ground; 2336 targetPos.z = ground;
2110 } 2337 }
2111 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2338 if (adjust)
2339 return SetPosAdjust(fromPos, targetPos);
2112 2340
2113 return real_vec; 2341 return targetPos;
2114 } 2342 }
2115 2343
2116 /// <summary> 2344 /// <summary>
@@ -2121,27 +2349,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2121 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2349 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2122 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2350 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2123 { 2351 {
2124 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2352 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2353 return;
2354
2125 LSL_Vector currentPos = GetPartLocalPos(part); 2355 LSL_Vector currentPos = GetPartLocalPos(part);
2356 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2126 2357
2127 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2128 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2129 2358
2130 if (part.ParentGroup.RootPart == part) 2359 if (part.ParentGroup.RootPart == part)
2131 { 2360 {
2132 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2133 targetPos.z = ground;
2134 SceneObjectGroup parent = part.ParentGroup; 2361 SceneObjectGroup parent = part.ParentGroup;
2135 parent.UpdateGroupPosition(!adjust ? targetPos : 2362 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2136 SetPosAdjust(currentPos, targetPos)); 2363 return;
2364 Util.FireAndForget(delegate(object x) {
2365 parent.UpdateGroupPosition((Vector3)toPos);
2366 });
2137 } 2367 }
2138 else 2368 else
2139 { 2369 {
2140 part.OffsetPosition = !adjust ? targetPos : 2370 part.OffsetPosition = (Vector3)toPos;
2141 SetPosAdjust(currentPos, targetPos); 2371// SceneObjectGroup parent = part.ParentGroup;
2142 SceneObjectGroup parent = part.ParentGroup; 2372// parent.HasGroupChanged = true;
2143 parent.HasGroupChanged = true; 2373// parent.ScheduleGroupForTerseUpdate();
2144 parent.ScheduleGroupForTerseUpdate(); 2374 part.ScheduleTerseUpdate();
2145 } 2375 }
2146 } 2376 }
2147 2377
@@ -2170,13 +2400,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2170 else 2400 else
2171 { 2401 {
2172 if (part.ParentGroup.IsAttachment) 2402 if (part.ParentGroup.IsAttachment)
2173 {
2174 pos = part.AttachedPos; 2403 pos = part.AttachedPos;
2175 }
2176 else 2404 else
2177 {
2178 pos = part.AbsolutePosition; 2405 pos = part.AbsolutePosition;
2179 }
2180 } 2406 }
2181 2407
2182// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2408// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2188,8 +2414,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 { 2414 {
2189 m_host.AddScriptLPS(1); 2415 m_host.AddScriptLPS(1);
2190 2416
2417
2418 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2419 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2420 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2421 // RootPart != null should shortcircuit
2422
2191 // try to let this work as in SL... 2423 // try to let this work as in SL...
2192 if (m_host.ParentID == 0) 2424 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2193 { 2425 {
2194 // special case: If we are root, rotate complete SOG to new rotation 2426 // special case: If we are root, rotate complete SOG to new rotation
2195 SetRot(m_host, rot); 2427 SetRot(m_host, rot);
@@ -2216,25 +2448,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2448
2217 protected void SetRot(SceneObjectPart part, Quaternion rot) 2449 protected void SetRot(SceneObjectPart part, Quaternion rot)
2218 { 2450 {
2219 part.UpdateRotation(rot); 2451 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2220 // Update rotation does not move the object in the physics scene if it's a linkset. 2452 return;
2221 2453
2222//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2454 bool isroot = (part == part.ParentGroup.RootPart);
2223// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2455 bool isphys;
2224 2456
2225 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2226 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2227 // It's perfectly okay when the object is not an active physical body though.
2228 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2229 // but only if the object is not physial and active. This is important for rotating doors.
2230 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2231 // scene
2232 PhysicsActor pa = part.PhysActor; 2457 PhysicsActor pa = part.PhysActor;
2233 2458
2234 if (pa != null && !pa.IsPhysical) 2459 // keep using physactor ideia of isphysical
2460 // it should be SOP ideia of that
2461 // not much of a issue with ubitODE
2462 if (pa != null && pa.IsPhysical)
2463 isphys = true;
2464 else
2465 isphys = false;
2466
2467 // SL doesn't let scripts rotate root of physical linksets
2468 if (isroot && isphys)
2469 return;
2470
2471 part.UpdateRotation(rot);
2472
2473 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2474 // so do a nasty update of parts positions if is a root part rotation
2475 if (isroot && pa != null) // with if above implies non physical root part
2235 { 2476 {
2236 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2477 part.ParentGroup.ResetChildPrimPhysicsPositions();
2237 } 2478 }
2479 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2480 {
2481 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2482 if (sittingavas.Count > 0)
2483 {
2484 foreach (ScenePresence av in sittingavas)
2485 {
2486 if (isroot || part.LocalId == av.ParentID)
2487 av.SendTerseUpdateToAllClients();
2488 }
2489 }
2490 }
2238 } 2491 }
2239 2492
2240 /// <summary> 2493 /// <summary>
@@ -2251,6 +2504,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2251 2504
2252 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2253 Quaternion q = m_host.GetWorldRotation(); 2506 Quaternion q = m_host.GetWorldRotation();
2507
2508 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2509 {
2510 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2511 if (avatar != null)
2512 {
2513 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2514 q = avatar.CameraRotation * q; // Mouselook
2515 else
2516 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2517 }
2518 }
2519
2254 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2520 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2255 } 2521 }
2256 2522
@@ -2278,14 +2544,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2278 return new LSL_Rotation(q); 2544 return new LSL_Rotation(q);
2279 } 2545 }
2280 2546
2281 return new LSL_Rotation(part.GetWorldRotation()); 2547 q = part.GetWorldRotation();
2548 if (part.ParentGroup.AttachmentPoint != 0)
2549 {
2550 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2551 if (avatar != null)
2552 {
2553 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2554 q = avatar.CameraRotation * q; // Mouselook
2555 else
2556 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2557 }
2558 }
2559
2560 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2282 } 2561 }
2283 2562
2284 public LSL_Rotation llGetLocalRot() 2563 public LSL_Rotation llGetLocalRot()
2285 { 2564 {
2286 m_host.AddScriptLPS(1); 2565 return GetPartLocalRot(m_host);
2566 }
2287 2567
2288 return new LSL_Rotation(m_host.RotationOffset); 2568 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2569 {
2570 m_host.AddScriptLPS(1);
2571 Quaternion rot = part.RotationOffset;
2572 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2289 } 2573 }
2290 2574
2291 public void llSetForce(LSL_Vector force, int local) 2575 public void llSetForce(LSL_Vector force, int local)
@@ -2365,16 +2649,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2365 m_host.ApplyImpulse(v, local != 0); 2649 m_host.ApplyImpulse(v, local != 0);
2366 } 2650 }
2367 2651
2652
2368 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2653 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2369 { 2654 {
2370 m_host.AddScriptLPS(1); 2655 m_host.AddScriptLPS(1);
2371 m_host.ApplyAngularImpulse(force, local != 0); 2656 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2372 } 2657 }
2373 2658
2374 public void llSetTorque(LSL_Vector torque, int local) 2659 public void llSetTorque(LSL_Vector torque, int local)
2375 { 2660 {
2376 m_host.AddScriptLPS(1); 2661 m_host.AddScriptLPS(1);
2377 m_host.SetAngularImpulse(torque, local != 0); 2662 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2378 } 2663 }
2379 2664
2380 public LSL_Vector llGetTorque() 2665 public LSL_Vector llGetTorque()
@@ -2391,20 +2676,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2391 llSetTorque(torque, local); 2676 llSetTorque(torque, local);
2392 } 2677 }
2393 2678
2679 public void llSetVelocity(LSL_Vector vel, int local)
2680 {
2681 m_host.AddScriptLPS(1);
2682 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2683 }
2684
2394 public LSL_Vector llGetVel() 2685 public LSL_Vector llGetVel()
2395 { 2686 {
2396 m_host.AddScriptLPS(1); 2687 m_host.AddScriptLPS(1);
2397 2688
2398 Vector3 vel; 2689 Vector3 vel = Vector3.Zero;
2399 2690
2400 if (m_host.ParentGroup.IsAttachment) 2691 if (m_host.ParentGroup.IsAttachment)
2401 { 2692 {
2402 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2693 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2403 vel = avatar.Velocity; 2694 if (avatar != null)
2695 vel = avatar.Velocity;
2404 } 2696 }
2405 else 2697 else
2406 { 2698 {
2407 vel = m_host.Velocity; 2699 vel = m_host.ParentGroup.RootPart.Velocity;
2408 } 2700 }
2409 2701
2410 return new LSL_Vector(vel); 2702 return new LSL_Vector(vel);
@@ -2417,11 +2709,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2417 return new LSL_Vector(m_host.Acceleration); 2709 return new LSL_Vector(m_host.Acceleration);
2418 } 2710 }
2419 2711
2420 public LSL_Vector llGetOmega() 2712 public void llSetAngularVelocity(LSL_Vector avel, int local)
2421 { 2713 {
2422 m_host.AddScriptLPS(1); 2714 m_host.AddScriptLPS(1);
2715 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2716 }
2423 2717
2424 return new LSL_Vector(m_host.AngularVelocity); 2718 public LSL_Vector llGetOmega()
2719 {
2720 m_host.AddScriptLPS(1);
2721 Vector3 avel = m_host.AngularVelocity;
2722 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2425 } 2723 }
2426 2724
2427 public LSL_Float llGetTimeOfDay() 2725 public LSL_Float llGetTimeOfDay()
@@ -2780,7 +3078,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2780 return src.ToLower(); 3078 return src.ToLower();
2781 } 3079 }
2782 3080
2783 public void llGiveMoney(string destination, int amount) 3081 public LSL_Integer llGiveMoney(string destination, int amount)
2784 { 3082 {
2785 Util.FireAndForget(x => 3083 Util.FireAndForget(x =>
2786 { 3084 {
@@ -2811,9 +3109,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2811 return; 3109 return;
2812 } 3110 }
2813 3111
3112 string reason;
2814 money.ObjectGiveMoney( 3113 money.ObjectGiveMoney(
2815 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3114 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
2816 }); 3115 });
3116
3117 return 0;
2817 } 3118 }
2818 3119
2819 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3120 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2892,13 +3193,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2892 new_group.RootPart.UUID.ToString()) }, 3193 new_group.RootPart.UUID.ToString()) },
2893 new DetectParams[0])); 3194 new DetectParams[0]));
2894 3195
2895 float groupmass = new_group.GetMass(); 3196 // do recoil
3197 SceneObjectGroup hostgrp = m_host.ParentGroup;
3198 if (hostgrp == null)
3199 return;
3200
3201 if (hostgrp.IsAttachment) // don't recoil avatars
3202 return;
2896 3203
2897 PhysicsActor pa = new_group.RootPart.PhysActor; 3204 PhysicsActor pa = new_group.RootPart.PhysActor;
2898 3205
2899 //Recoil. 3206 //Recoil.
2900 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3207 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2901 { 3208 {
3209 float groupmass = new_group.GetMass();
2902 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3210 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2903 if (recoil != Vector3.Zero) 3211 if (recoil != Vector3.Zero)
2904 { 3212 {
@@ -2906,6 +3214,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2906 } 3214 }
2907 } 3215 }
2908 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3216 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3217 return;
3218
2909 }); 3219 });
2910 3220
2911 //ScriptSleep((int)((groupmass * velmag) / 10)); 3221 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2920,35 +3230,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2920 public void llLookAt(LSL_Vector target, double strength, double damping) 3230 public void llLookAt(LSL_Vector target, double strength, double damping)
2921 { 3231 {
2922 m_host.AddScriptLPS(1); 3232 m_host.AddScriptLPS(1);
2923 // Determine where we are looking from
2924 LSL_Vector from = llGetPos();
2925
2926 // Work out the normalised vector from the source to the target
2927 LSL_Vector delta = llVecNorm(target - from);
2928 LSL_Vector angle = new LSL_Vector(0,0,0);
2929 3233
2930 // Calculate the yaw 3234 // Get the normalized vector to the target
2931 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3235 LSL_Vector d1 = llVecNorm(target - llGetPos());
2932 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
2933 3236
2934 // Calculate pitch 3237 // Get the bearing (yaw)
2935 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3238 LSL_Vector a1 = new LSL_Vector(0,0,0);
3239 a1.z = llAtan2(d1.y, d1.x);
2936 3240
2937 // we need to convert from a vector describing 3241 // Get the elevation (pitch)
2938 // the angles of rotation in radians into rotation value 3242 LSL_Vector a2 = new LSL_Vector(0,0,0);
2939 LSL_Rotation rot = llEuler2Rot(angle); 3243 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2940 3244
2941 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3245 LSL_Rotation r1 = llEuler2Rot(a1);
2942 // set the rotation of the object, copy that behavior 3246 LSL_Rotation r2 = llEuler2Rot(a2);
2943 PhysicsActor pa = m_host.PhysActor; 3247 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2944 3248
2945 if (strength == 0 || pa == null || !pa.IsPhysical) 3249 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2946 { 3250 {
2947 llSetRot(rot); 3251 // Do nothing if either value is 0 (this has been checked in SL)
3252 if (strength <= 0.0 || damping <= 0.0)
3253 return;
3254
3255 llSetRot(r3 * r2 * r1);
2948 } 3256 }
2949 else 3257 else
2950 { 3258 {
2951 m_host.StartLookAt(rot, (float)strength, (float)damping); 3259 if (strength == 0)
3260 {
3261 llSetRot(r3 * r2 * r1);
3262 return;
3263 }
3264
3265 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2952 } 3266 }
2953 } 3267 }
2954 3268
@@ -2995,17 +3309,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 } 3309 }
2996 else 3310 else
2997 { 3311 {
2998 if (m_host.IsRoot) 3312 // new SL always returns object mass
2999 { 3313// if (m_host.IsRoot)
3314// {
3000 return m_host.ParentGroup.GetMass(); 3315 return m_host.ParentGroup.GetMass();
3001 } 3316// }
3002 else 3317// else
3003 { 3318// {
3004 return m_host.GetMass(); 3319// return m_host.GetMass();
3005 } 3320// }
3006 } 3321 }
3007 } 3322 }
3008 3323
3324
3325 public LSL_Float llGetMassMKS()
3326 {
3327 return 100f * llGetMass();
3328 }
3329
3009 public void llCollisionFilter(string name, string id, int accept) 3330 public void llCollisionFilter(string name, string id, int accept)
3010 { 3331 {
3011 m_host.AddScriptLPS(1); 3332 m_host.AddScriptLPS(1);
@@ -3053,8 +3374,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3053 { 3374 {
3054 // Unregister controls from Presence 3375 // Unregister controls from Presence
3055 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3376 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3056 // Remove Take Control permission.
3057 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3058 } 3377 }
3059 } 3378 }
3060 } 3379 }
@@ -3082,7 +3401,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3401 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3083 3402
3084 if (attachmentsModule != null) 3403 if (attachmentsModule != null)
3085 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3404 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3086 else 3405 else
3087 return false; 3406 return false;
3088 } 3407 }
@@ -3112,9 +3431,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 { 3431 {
3113 m_host.AddScriptLPS(1); 3432 m_host.AddScriptLPS(1);
3114 3433
3115// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3116// return;
3117
3118 if (m_item.PermsGranter != m_host.OwnerID) 3434 if (m_item.PermsGranter != m_host.OwnerID)
3119 return; 3435 return;
3120 3436
@@ -3157,6 +3473,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3157 3473
3158 public void llInstantMessage(string user, string message) 3474 public void llInstantMessage(string user, string message)
3159 { 3475 {
3476 UUID result;
3477 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3478 {
3479 ShoutError("An invalid key was passed to llInstantMessage");
3480 ScriptSleep(2000);
3481 return;
3482 }
3483
3484
3160 m_host.AddScriptLPS(1); 3485 m_host.AddScriptLPS(1);
3161 3486
3162 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3487 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3171,14 +3496,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3171 UUID friendTransactionID = UUID.Random(); 3496 UUID friendTransactionID = UUID.Random();
3172 3497
3173 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3498 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3174 3499
3175 GridInstantMessage msg = new GridInstantMessage(); 3500 GridInstantMessage msg = new GridInstantMessage();
3176 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3501 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3177 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3502 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3178 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3503 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3179// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3504// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3180// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3505// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3181 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3506// DateTime dt = DateTime.UtcNow;
3507//
3508// // Ticks from UtcNow, but make it look like local. Evil, huh?
3509// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3510//
3511// try
3512// {
3513// // Convert that to the PST timezone
3514// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3515// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3516// }
3517// catch
3518// {
3519// // No logging here, as it could be VERY spammy
3520// }
3521//
3522// // And make it look local again to fool the unix time util
3523// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3524
3525 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3526
3182 //if (client != null) 3527 //if (client != null)
3183 //{ 3528 //{
3184 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3529 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3192,10 +3537,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 msg.message = message.Substring(0, 1024); 3537 msg.message = message.Substring(0, 1024);
3193 else 3538 else
3194 msg.message = message; 3539 msg.message = message;
3195 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3540 msg.dialog = (byte)19; // MessageFromObject
3196 msg.fromGroup = false;// fromGroup; 3541 msg.fromGroup = false;// fromGroup;
3197 msg.offline = (byte)0; //offline; 3542 msg.offline = (byte)0; //offline;
3198 msg.ParentEstateID = 0; //ParentEstateID; 3543 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3199 msg.Position = new Vector3(m_host.AbsolutePosition); 3544 msg.Position = new Vector3(m_host.AbsolutePosition);
3200 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3545 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3201 3546
@@ -3227,7 +3572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3227 } 3572 }
3228 3573
3229 emailModule.SendEmail(m_host.UUID, address, subject, message); 3574 emailModule.SendEmail(m_host.UUID, address, subject, message);
3230 llSleep(EMAIL_PAUSE_TIME); 3575 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3231 } 3576 }
3232 3577
3233 public void llGetNextEmail(string address, string subject) 3578 public void llGetNextEmail(string address, string subject)
@@ -3473,7 +3818,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3818 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3474 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3819 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3475 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3820 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3821 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3476 ScriptBaseClass.PERMISSION_ATTACH; 3822 ScriptBaseClass.PERMISSION_ATTACH;
3823
3477 } 3824 }
3478 else 3825 else
3479 { 3826 {
@@ -3490,15 +3837,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3490 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3837 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3491 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3838 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3492 } 3839 }
3840 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3841 {
3842 implicitPerms = perm;
3843 }
3493 } 3844 }
3494 3845
3495 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3846 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3496 { 3847 {
3497 lock (m_host.TaskInventory) 3848 m_host.TaskInventory.LockItemsForWrite(true);
3498 { 3849 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3499 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3850 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3500 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3851 m_host.TaskInventory.LockItemsForWrite(false);
3501 }
3502 3852
3503 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3853 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3504 "run_time_permissions", new Object[] { 3854 "run_time_permissions", new Object[] {
@@ -3541,11 +3891,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3541 3891
3542 if (!m_waitingForScriptAnswer) 3892 if (!m_waitingForScriptAnswer)
3543 { 3893 {
3544 lock (m_host.TaskInventory) 3894 m_host.TaskInventory.LockItemsForWrite(true);
3545 { 3895 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3546 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3896 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3547 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3897 m_host.TaskInventory.LockItemsForWrite(false);
3548 }
3549 3898
3550 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3899 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3551 m_waitingForScriptAnswer=true; 3900 m_waitingForScriptAnswer=true;
@@ -3574,14 +3923,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3574 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3923 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3575 llReleaseControls(); 3924 llReleaseControls();
3576 3925
3577 lock (m_host.TaskInventory) 3926 m_host.TaskInventory.LockItemsForWrite(true);
3578 { 3927 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3579 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3928 m_host.TaskInventory.LockItemsForWrite(false);
3580 } 3929
3581 3930 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3582 m_ScriptEngine.PostScriptEvent( 3931 "run_time_permissions", new Object[] {
3583 m_item.ItemID, 3932 new LSL_Integer(answer) },
3584 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3933 new DetectParams[0]));
3585 } 3934 }
3586 3935
3587 public LSL_String llGetPermissionsKey() 3936 public LSL_String llGetPermissionsKey()
@@ -3620,14 +3969,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3620 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3969 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3621 { 3970 {
3622 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3971 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3623 3972 if (parts.Count > 0)
3624 foreach (SceneObjectPart part in parts) 3973 {
3625 part.SetFaceColorAlpha(face, color, null); 3974 try
3975 {
3976 foreach (SceneObjectPart part in parts)
3977 part.SetFaceColorAlpha(face, color, null);
3978 }
3979 finally
3980 {
3981 }
3982 }
3626 } 3983 }
3627 3984
3628 public void llCreateLink(string target, int parent) 3985 public void llCreateLink(string target, int parent)
3629 { 3986 {
3630 m_host.AddScriptLPS(1); 3987 m_host.AddScriptLPS(1);
3988
3631 UUID targetID; 3989 UUID targetID;
3632 3990
3633 if (!UUID.TryParse(target, out targetID)) 3991 if (!UUID.TryParse(target, out targetID))
@@ -3733,10 +4091,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3733 // Restructuring Multiple Prims. 4091 // Restructuring Multiple Prims.
3734 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4092 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3735 parts.Remove(parentPrim.RootPart); 4093 parts.Remove(parentPrim.RootPart);
3736 foreach (SceneObjectPart part in parts) 4094 if (parts.Count > 0)
3737 { 4095 {
3738 parentPrim.DelinkFromGroup(part.LocalId, true); 4096 try
4097 {
4098 foreach (SceneObjectPart part in parts)
4099 {
4100 parentPrim.DelinkFromGroup(part.LocalId, true);
4101 }
4102 }
4103 finally
4104 {
4105 }
3739 } 4106 }
4107
3740 parentPrim.HasGroupChanged = true; 4108 parentPrim.HasGroupChanged = true;
3741 parentPrim.ScheduleGroupForFullUpdate(); 4109 parentPrim.ScheduleGroupForFullUpdate();
3742 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4110 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3745,12 +4113,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3745 { 4113 {
3746 SceneObjectPart newRoot = parts[0]; 4114 SceneObjectPart newRoot = parts[0];
3747 parts.Remove(newRoot); 4115 parts.Remove(newRoot);
3748 foreach (SceneObjectPart part in parts) 4116
4117 try
3749 { 4118 {
3750 // Required for linking 4119 foreach (SceneObjectPart part in parts)
3751 part.ClearUpdateSchedule(); 4120 {
3752 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4121 part.ClearUpdateSchedule();
4122 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4123 }
3753 } 4124 }
4125 finally
4126 {
4127 }
4128
4129
3754 newRoot.ParentGroup.HasGroupChanged = true; 4130 newRoot.ParentGroup.HasGroupChanged = true;
3755 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4131 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3756 } 4132 }
@@ -3770,6 +4146,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3770 public void llBreakAllLinks() 4146 public void llBreakAllLinks()
3771 { 4147 {
3772 m_host.AddScriptLPS(1); 4148 m_host.AddScriptLPS(1);
4149
4150 TaskInventoryItem item = m_item;
4151
4152 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4153 && !m_automaticLinkPermission)
4154 {
4155 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4156 return;
4157 }
4158
3773 SceneObjectGroup parentPrim = m_host.ParentGroup; 4159 SceneObjectGroup parentPrim = m_host.ParentGroup;
3774 if (parentPrim.AttachmentPoint != 0) 4160 if (parentPrim.AttachmentPoint != 0)
3775 return; // Fail silently if attached 4161 return; // Fail silently if attached
@@ -3789,13 +4175,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3789 public LSL_String llGetLinkKey(int linknum) 4175 public LSL_String llGetLinkKey(int linknum)
3790 { 4176 {
3791 m_host.AddScriptLPS(1); 4177 m_host.AddScriptLPS(1);
4178 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4179 if (part != null)
4180 {
4181 return part.UUID.ToString();
4182 }
4183 else
4184 {
4185 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4186 {
4187 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3792 4188
3793 ISceneEntity entity = GetLinkEntity(linknum); 4189 if (linknum < 0)
4190 return UUID.Zero.ToString();
3794 4191
3795 if (entity != null) 4192 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3796 return entity.UUID.ToString(); 4193 if (avatars.Count > linknum)
3797 else 4194 {
3798 return ScriptBaseClass.NULL_KEY; 4195 return avatars[linknum].UUID.ToString();
4196 }
4197 }
4198 return UUID.Zero.ToString();
4199 }
3799 } 4200 }
3800 4201
3801 /// <summary> 4202 /// <summary>
@@ -3854,17 +4255,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3854 m_host.AddScriptLPS(1); 4255 m_host.AddScriptLPS(1);
3855 int count = 0; 4256 int count = 0;
3856 4257
3857 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3858 { 4260 {
3859 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Type == type || type == -1)
3860 { 4262 {
3861 if (inv.Value.Type == type || type == -1) 4263 count = count + 1;
3862 {
3863 count = count + 1;
3864 }
3865 } 4264 }
3866 } 4265 }
3867 4266
4267 m_host.TaskInventory.LockItemsForRead(false);
3868 return count; 4268 return count;
3869 } 4269 }
3870 4270
@@ -3873,16 +4273,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3873 m_host.AddScriptLPS(1); 4273 m_host.AddScriptLPS(1);
3874 ArrayList keys = new ArrayList(); 4274 ArrayList keys = new ArrayList();
3875 4275
3876 lock (m_host.TaskInventory) 4276 m_host.TaskInventory.LockItemsForRead(true);
4277 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3877 { 4278 {
3878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4279 if (inv.Value.Type == type || type == -1)
3879 { 4280 {
3880 if (inv.Value.Type == type || type == -1) 4281 keys.Add(inv.Value.Name);
3881 {
3882 keys.Add(inv.Value.Name);
3883 }
3884 } 4282 }
3885 } 4283 }
4284 m_host.TaskInventory.LockItemsForRead(false);
3886 4285
3887 if (keys.Count == 0) 4286 if (keys.Count == 0)
3888 { 4287 {
@@ -3920,7 +4319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3920 if (item == null) 4319 if (item == null)
3921 { 4320 {
3922 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4321 llSay(0, String.Format("Could not find object '{0}'", inventory));
3923 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4322 return;
4323// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3924 } 4324 }
3925 4325
3926 UUID objId = item.ItemID; 4326 UUID objId = item.ItemID;
@@ -3948,33 +4348,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3948 return; 4348 return;
3949 } 4349 }
3950 } 4350 }
4351
3951 // destination is an avatar 4352 // destination is an avatar
3952 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4353 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3953 4354
3954 if (agentItem == null) 4355 if (agentItem == null)
3955 return; 4356 return;
3956 4357
3957 if (m_TransferModule != null) 4358 byte[] bucket = new byte[1];
3958 { 4359 bucket[0] = (byte)item.Type;
3959 byte[] bucket = new byte[1]; 4360 //byte[] objBytes = agentItem.ID.GetBytes();
3960 bucket[0] = (byte)item.Type; 4361 //Array.Copy(objBytes, 0, bucket, 1, 16);
3961 4362
3962 GridInstantMessage msg = new GridInstantMessage(World, 4363 GridInstantMessage msg = new GridInstantMessage(World,
3963 m_host.OwnerID, m_host.Name, destId, 4364 m_host.OwnerID, m_host.Name, destId,
3964 (byte)InstantMessageDialog.TaskInventoryOffered, 4365 (byte)InstantMessageDialog.TaskInventoryOffered,
3965 false, item.Name+". "+m_host.Name+" is located at "+ 4366 false, item.Name+". "+m_host.Name+" is located at "+
3966 World.RegionInfo.RegionName+" "+ 4367 World.RegionInfo.RegionName+" "+
3967 m_host.AbsolutePosition.ToString(), 4368 m_host.AbsolutePosition.ToString(),
3968 agentItem.ID, true, m_host.AbsolutePosition, 4369 agentItem.ID, true, m_host.AbsolutePosition,
3969 bucket, true); 4370 bucket, true);
3970 4371
3971 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4372 ScenePresence sp;
3972 }
3973 4373
4374 if (World.TryGetScenePresence(destId, out sp))
4375 {
4376 sp.ControllingClient.SendInstantMessage(msg);
4377 }
4378 else
4379 {
4380 if (m_TransferModule != null)
4381 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4382 }
4383
4384 //This delay should only occur when giving inventory to avatars.
3974 ScriptSleep(3000); 4385 ScriptSleep(3000);
3975 } 4386 }
3976 } 4387 }
3977 4388
4389 [DebuggerNonUserCode]
3978 public void llRemoveInventory(string name) 4390 public void llRemoveInventory(string name)
3979 { 4391 {
3980 m_host.AddScriptLPS(1); 4392 m_host.AddScriptLPS(1);
@@ -4029,109 +4441,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4029 { 4441 {
4030 m_host.AddScriptLPS(1); 4442 m_host.AddScriptLPS(1);
4031 4443
4032 UUID uuid = (UUID)id; 4444 UUID uuid;
4033 PresenceInfo pinfo = null; 4445 if (UUID.TryParse(id, out uuid))
4034 UserAccount account;
4035
4036 UserInfoCacheEntry ce;
4037 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4038 { 4446 {
4039 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4447 PresenceInfo pinfo = null;
4040 if (account == null) 4448 UserAccount account;
4449
4450 UserInfoCacheEntry ce;
4451 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4041 { 4452 {
4042 m_userInfoCache[uuid] = null; // Cache negative 4453 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4043 return UUID.Zero.ToString(); 4454 if (account == null)
4044 } 4455 {
4456 m_userInfoCache[uuid] = null; // Cache negative
4457 return UUID.Zero.ToString();
4458 }
4045 4459
4046 4460
4047 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4461 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4048 if (pinfos != null && pinfos.Length > 0) 4462 if (pinfos != null && pinfos.Length > 0)
4049 {
4050 foreach (PresenceInfo p in pinfos)
4051 { 4463 {
4052 if (p.RegionID != UUID.Zero) 4464 foreach (PresenceInfo p in pinfos)
4053 { 4465 {
4054 pinfo = p; 4466 if (p.RegionID != UUID.Zero)
4467 {
4468 pinfo = p;
4469 }
4055 } 4470 }
4056 } 4471 }
4057 }
4058 4472
4059 ce = new UserInfoCacheEntry(); 4473 ce = new UserInfoCacheEntry();
4060 ce.time = Util.EnvironmentTickCount(); 4474 ce.time = Util.EnvironmentTickCount();
4061 ce.account = account; 4475 ce.account = account;
4062 ce.pinfo = pinfo; 4476 ce.pinfo = pinfo;
4063 } 4477 m_userInfoCache[uuid] = ce;
4064 else 4478 }
4065 { 4479 else
4066 if (ce == null) 4480 {
4067 return UUID.Zero.ToString(); 4481 if (ce == null)
4482 return UUID.Zero.ToString();
4068 4483
4069 account = ce.account; 4484 account = ce.account;
4070 pinfo = ce.pinfo; 4485 pinfo = ce.pinfo;
4071 } 4486 }
4072 4487
4073 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4488 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4074 {
4075 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4076 if (pinfos != null && pinfos.Length > 0)
4077 { 4489 {
4078 foreach (PresenceInfo p in pinfos) 4490 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4491 if (pinfos != null && pinfos.Length > 0)
4079 { 4492 {
4080 if (p.RegionID != UUID.Zero) 4493 foreach (PresenceInfo p in pinfos)
4081 { 4494 {
4082 pinfo = p; 4495 if (p.RegionID != UUID.Zero)
4496 {
4497 pinfo = p;
4498 }
4083 } 4499 }
4084 } 4500 }
4085 } 4501 else
4086 else 4502 pinfo = null;
4087 pinfo = null;
4088 4503
4089 ce.time = Util.EnvironmentTickCount(); 4504 ce.time = Util.EnvironmentTickCount();
4090 ce.pinfo = pinfo; 4505 ce.pinfo = pinfo;
4091 } 4506 }
4092 4507
4093 string reply = String.Empty; 4508 string reply = String.Empty;
4094 4509
4095 switch (data) 4510 switch (data)
4096 { 4511 {
4097 case 1: // DATA_ONLINE (0|1) 4512 case 1: // DATA_ONLINE (0|1)
4098 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4513 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4099 reply = "1"; 4514 reply = "1";
4100 else 4515 else
4101 reply = "0"; 4516 reply = "0";
4102 break; 4517 break;
4103 case 2: // DATA_NAME (First Last) 4518 case 2: // DATA_NAME (First Last)
4104 reply = account.FirstName + " " + account.LastName; 4519 reply = account.FirstName + " " + account.LastName;
4105 break; 4520 break;
4106 case 3: // DATA_BORN (YYYY-MM-DD) 4521 case 3: // DATA_BORN (YYYY-MM-DD)
4107 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4522 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4108 born = born.AddSeconds(account.Created); 4523 born = born.AddSeconds(account.Created);
4109 reply = born.ToString("yyyy-MM-dd"); 4524 reply = born.ToString("yyyy-MM-dd");
4110 break; 4525 break;
4111 case 4: // DATA_RATING (0,0,0,0,0,0) 4526 case 4: // DATA_RATING (0,0,0,0,0,0)
4112 reply = "0,0,0,0,0,0"; 4527 reply = "0,0,0,0,0,0";
4113 break; 4528 break;
4114 case 7: // DATA_USERLEVEL (integer) 4529 case 8: // DATA_PAYINFO (0|1|2|3)
4115 reply = account.UserLevel.ToString(); 4530 reply = "0";
4116 break; 4531 break;
4117 case 8: // DATA_PAYINFO (0|1|2|3) 4532 default:
4118 reply = "0"; 4533 return UUID.Zero.ToString(); // Raise no event
4119 break; 4534 }
4120 default:
4121 return UUID.Zero.ToString(); // Raise no event
4122 }
4123 4535
4124 UUID rq = UUID.Random(); 4536 UUID rq = UUID.Random();
4125 4537
4126 UUID tid = AsyncCommands. 4538 UUID tid = AsyncCommands.
4127 DataserverPlugin.RegisterRequest(m_host.LocalId, 4539 DataserverPlugin.RegisterRequest(m_host.LocalId,
4128 m_item.ItemID, rq.ToString()); 4540 m_item.ItemID, rq.ToString());
4129 4541
4130 AsyncCommands. 4542 AsyncCommands.
4131 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4543 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4132 4544
4133 ScriptSleep(100); 4545 ScriptSleep(100);
4134 return tid.ToString(); 4546 return tid.ToString();
4547 }
4548 else
4549 {
4550 ShoutError("Invalid UUID passed to llRequestAgentData.");
4551 }
4552 return "";
4135 } 4553 }
4136 4554
4137 public LSL_String llRequestInventoryData(string name) 4555 public LSL_String llRequestInventoryData(string name)
@@ -4188,12 +4606,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4188 if (UUID.TryParse(agent, out agentId)) 4606 if (UUID.TryParse(agent, out agentId))
4189 { 4607 {
4190 ScenePresence presence = World.GetScenePresence(agentId); 4608 ScenePresence presence = World.GetScenePresence(agentId);
4191 if (presence != null) 4609 if (presence != null && presence.PresenceType != PresenceType.Npc)
4192 { 4610 {
4611 // agent must not be a god
4612 if (presence.UserLevel >= 200) return;
4613
4193 // agent must be over the owners land 4614 // agent must be over the owners land
4194 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4615 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4195 { 4616 {
4196 World.TeleportClientHome(agentId, presence.ControllingClient); 4617 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4618 {
4619 // They can't be teleported home for some reason
4620 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4621 if (regionInfo != null)
4622 {
4623 World.RequestTeleportLocation(
4624 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4625 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4626 }
4627 }
4197 } 4628 }
4198 } 4629 }
4199 } 4630 }
@@ -4211,20 +4642,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4211 ScenePresence presence = World.GetScenePresence(agentId); 4642 ScenePresence presence = World.GetScenePresence(agentId);
4212 if (presence != null && presence.PresenceType != PresenceType.Npc) 4643 if (presence != null && presence.PresenceType != PresenceType.Npc)
4213 { 4644 {
4214 // agent must not be a god
4215 if (presence.GodLevel >= 200) return;
4216
4217 if (destination == String.Empty) 4645 if (destination == String.Empty)
4218 destination = World.RegionInfo.RegionName; 4646 destination = World.RegionInfo.RegionName;
4219 4647
4220 // agent must be over the owners land 4648 if (m_item.PermsGranter == agentId)
4221 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4649 {
4650 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4651 {
4652 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4653 }
4654 }
4655
4656 // agent must be wearing the object
4657 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4222 { 4658 {
4223 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4659 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4224 } 4660 }
4225 else // or must be wearing the prim 4661 else
4226 { 4662 {
4227 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4663 // agent must not be a god
4664 if (presence.GodLevel >= 200) return;
4665
4666 // agent must be over the owners land
4667 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4668 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4669 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4228 { 4670 {
4229 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4671 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4230 } 4672 }
@@ -4238,24 +4680,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4238 m_host.AddScriptLPS(1); 4680 m_host.AddScriptLPS(1);
4239 UUID agentId = new UUID(); 4681 UUID agentId = new UUID();
4240 4682
4241 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4683 ulong regionHandle = Utils.UIntsToLong((uint)(global_coords.x / 256) * 256, (uint)(global_coords.y / 256) * 256);
4242 4684
4243 if (UUID.TryParse(agent, out agentId)) 4685 if (UUID.TryParse(agent, out agentId))
4244 { 4686 {
4687 // This function is owner only!
4688 if (m_host.OwnerID != agentId)
4689 return;
4690
4245 ScenePresence presence = World.GetScenePresence(agentId); 4691 ScenePresence presence = World.GetScenePresence(agentId);
4692
4693 // Can't TP sitting avatars
4694 if (presence.ParentID != 0) // Sitting
4695 return;
4696
4246 if (presence != null && presence.PresenceType != PresenceType.Npc) 4697 if (presence != null && presence.PresenceType != PresenceType.Npc)
4247 { 4698 {
4248 // agent must not be a god 4699 if (m_item.PermsGranter == agentId)
4249 if (presence.GodLevel >= 200) return;
4250
4251 // agent must be over the owners land
4252 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4253 { 4700 {
4254 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4701 // If attached using llAttachToAvatarTemp, cowardly refuse
4255 } 4702 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
4256 else // or must be wearing the prim 4703 return;
4257 { 4704
4258 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4705 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4259 { 4706 {
4260 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4707 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4261 } 4708 }
@@ -4299,7 +4746,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4299 UUID av = new UUID(); 4746 UUID av = new UUID();
4300 if (!UUID.TryParse(agent,out av)) 4747 if (!UUID.TryParse(agent,out av))
4301 { 4748 {
4302 LSLError("First parameter to llDialog needs to be a key");
4303 return; 4749 return;
4304 } 4750 }
4305 4751
@@ -4332,9 +4778,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4332 { 4778 {
4333 m_host.AddScriptLPS(1); 4779 m_host.AddScriptLPS(1);
4334 4780
4781 if(impact_sound == "")
4782 {
4783 m_host.CollisionSoundVolume = (float)impact_volume;
4784 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4785 m_host.CollisionSoundType = 0;
4786 return;
4787 }
4335 // TODO: Parameter check logic required. 4788 // TODO: Parameter check logic required.
4336 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4789 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4337 m_host.CollisionSoundVolume = (float)impact_volume; 4790 m_host.CollisionSoundVolume = (float)impact_volume;
4791 m_host.CollisionSoundType = 1;
4338 } 4792 }
4339 4793
4340 public LSL_String llGetAnimation(string id) 4794 public LSL_String llGetAnimation(string id)
@@ -4348,14 +4802,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4348 4802
4349 if (m_host.RegionHandle == presence.RegionHandle) 4803 if (m_host.RegionHandle == presence.RegionHandle)
4350 { 4804 {
4351 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4352
4353 if (presence != null) 4805 if (presence != null)
4354 { 4806 {
4355 AnimationSet currentAnims = presence.Animator.Animations; 4807 if (presence.SitGround)
4356 string currentAnimationState = String.Empty; 4808 return "Sitting on Ground";
4357 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4809 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4358 return currentAnimationState; 4810 return "Sitting";
4811
4812 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4813 string lslMovementAnimation;
4814
4815 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4816 return lslMovementAnimation;
4359 } 4817 }
4360 } 4818 }
4361 4819
@@ -4503,7 +4961,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4503 { 4961 {
4504 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4962 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4505 float distance_term = distance * distance * distance; // Script Energy 4963 float distance_term = distance * distance * distance; // Script Energy
4506 float pusher_mass = m_host.GetMass(); 4964 // use total object mass and not part
4965 float pusher_mass = m_host.ParentGroup.GetMass();
4507 4966
4508 float PUSH_ATTENUATION_DISTANCE = 17f; 4967 float PUSH_ATTENUATION_DISTANCE = 17f;
4509 float PUSH_ATTENUATION_SCALE = 5f; 4968 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4757,6 +5216,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4757 { 5216 {
4758 return item.AssetID.ToString(); 5217 return item.AssetID.ToString();
4759 } 5218 }
5219 m_host.TaskInventory.LockItemsForRead(false);
4760 5220
4761 return UUID.Zero.ToString(); 5221 return UUID.Zero.ToString();
4762 } 5222 }
@@ -4909,14 +5369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4909 { 5369 {
4910 m_host.AddScriptLPS(1); 5370 m_host.AddScriptLPS(1);
4911 5371
4912 if (src == null) 5372 return src.Length;
4913 {
4914 return 0;
4915 }
4916 else
4917 {
4918 return src.Length;
4919 }
4920 } 5373 }
4921 5374
4922 public LSL_Integer llList2Integer(LSL_List src, int index) 5375 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4987,7 +5440,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4987 else if (src.Data[index] is LSL_Float) 5440 else if (src.Data[index] is LSL_Float)
4988 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5441 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4989 else if (src.Data[index] is LSL_String) 5442 else if (src.Data[index] is LSL_String)
4990 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5443 {
5444 string str = ((LSL_String) src.Data[index]).m_string;
5445 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5446 if (m != Match.Empty)
5447 {
5448 str = m.Value;
5449 double d = 0.0;
5450 if (!Double.TryParse(str, out d))
5451 return 0.0;
5452
5453 return d;
5454 }
5455 return 0.0;
5456 }
4991 return Convert.ToDouble(src.Data[index]); 5457 return Convert.ToDouble(src.Data[index]);
4992 } 5458 }
4993 catch (FormatException) 5459 catch (FormatException)
@@ -5029,7 +5495,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5029 // for completion and should LSL_Key ever be implemented 5495 // for completion and should LSL_Key ever be implemented
5030 // as it's own struct 5496 // as it's own struct
5031 else if (!(src.Data[index] is LSL_String || 5497 else if (!(src.Data[index] is LSL_String ||
5032 src.Data[index] is LSL_Key)) 5498 src.Data[index] is LSL_Key ||
5499 src.Data[index] is String))
5033 { 5500 {
5034 return ""; 5501 return "";
5035 } 5502 }
@@ -5287,7 +5754,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5287 } 5754 }
5288 } 5755 }
5289 } 5756 }
5290 else { 5757 else
5758 {
5291 object[] array = new object[src.Length]; 5759 object[] array = new object[src.Length];
5292 Array.Copy(src.Data, 0, array, 0, src.Length); 5760 Array.Copy(src.Data, 0, array, 0, src.Length);
5293 result = new LSL_List(array); 5761 result = new LSL_List(array);
@@ -5394,7 +5862,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5394 public LSL_Integer llGetRegionAgentCount() 5862 public LSL_Integer llGetRegionAgentCount()
5395 { 5863 {
5396 m_host.AddScriptLPS(1); 5864 m_host.AddScriptLPS(1);
5397 return new LSL_Integer(World.GetRootAgentCount()); 5865
5866 int count = 0;
5867 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5868 count++;
5869 });
5870
5871 return new LSL_Integer(count);
5398 } 5872 }
5399 5873
5400 public LSL_Vector llGetRegionCorner() 5874 public LSL_Vector llGetRegionCorner()
@@ -5635,6 +6109,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5635 flags |= ScriptBaseClass.AGENT_AWAY; 6109 flags |= ScriptBaseClass.AGENT_AWAY;
5636 } 6110 }
5637 6111
6112 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6113 UUID[] anims = agent.Animator.GetAnimationArray();
6114 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6115 {
6116 flags |= ScriptBaseClass.AGENT_BUSY;
6117 }
6118
5638 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6119 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5639 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6120 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5640 { 6121 {
@@ -5682,6 +6163,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5682 flags |= ScriptBaseClass.AGENT_SITTING; 6163 flags |= ScriptBaseClass.AGENT_SITTING;
5683 } 6164 }
5684 6165
6166 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6167 {
6168 flags |= ScriptBaseClass.AGENT_MALE;
6169 }
6170
5685 return flags; 6171 return flags;
5686 } 6172 }
5687 6173
@@ -5827,9 +6313,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5827 6313
5828 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6314 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5829 6315
5830 foreach (SceneObjectPart part in parts) 6316 try
6317 {
6318 foreach (SceneObjectPart part in parts)
6319 {
6320 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6321 }
6322 }
6323 finally
5831 { 6324 {
5832 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5833 } 6325 }
5834 } 6326 }
5835 6327
@@ -5883,13 +6375,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5883 6375
5884 if (m_host.OwnerID == land.LandData.OwnerID) 6376 if (m_host.OwnerID == land.LandData.OwnerID)
5885 { 6377 {
5886 World.TeleportClientHome(agentID, presence.ControllingClient); 6378 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6379 presence.TeleportWithMomentum(p, null);
6380 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5887 } 6381 }
5888 } 6382 }
5889 } 6383 }
5890 ScriptSleep(5000); 6384 ScriptSleep(5000);
5891 } 6385 }
5892 6386
6387 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6388 {
6389 return ParseString2List(str, separators, in_spacers, false);
6390 }
6391
5893 public LSL_Integer llOverMyLand(string id) 6392 public LSL_Integer llOverMyLand(string id)
5894 { 6393 {
5895 m_host.AddScriptLPS(1); 6394 m_host.AddScriptLPS(1);
@@ -5942,26 +6441,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5942 } 6441 }
5943 else 6442 else
5944 { 6443 {
5945 agentSize = GetAgentSize(avatar); 6444// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6445 Vector3 s = avatar.Appearance.AvatarSize;
6446 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5946 } 6447 }
5947
5948 return agentSize; 6448 return agentSize;
5949 } 6449 }
5950 6450
5951 public LSL_Integer llSameGroup(string agent) 6451 public LSL_Integer llSameGroup(string id)
5952 { 6452 {
5953 m_host.AddScriptLPS(1); 6453 m_host.AddScriptLPS(1);
5954 UUID agentId = new UUID(); 6454 UUID uuid = new UUID();
5955 if (!UUID.TryParse(agent, out agentId)) 6455 if (!UUID.TryParse(id, out uuid))
5956 return new LSL_Integer(0); 6456 return new LSL_Integer(0);
5957 ScenePresence presence = World.GetScenePresence(agentId); 6457
5958 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6458 // Check if it's a group key
5959 return new LSL_Integer(0); 6459 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5960 IClientAPI client = presence.ControllingClient;
5961 if (m_host.GroupID == client.ActiveGroupId)
5962 return new LSL_Integer(1); 6460 return new LSL_Integer(1);
5963 else 6461
6462 // We got passed a UUID.Zero
6463 if (uuid == UUID.Zero)
6464 return new LSL_Integer(0);
6465
6466 // Handle the case where id names an avatar
6467 ScenePresence presence = World.GetScenePresence(uuid);
6468 if (presence != null)
6469 {
6470 if (presence.IsChildAgent)
6471 return new LSL_Integer(0);
6472
6473 IClientAPI client = presence.ControllingClient;
6474 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6475 return new LSL_Integer(1);
6476
6477 return new LSL_Integer(0);
6478 }
6479
6480 // Handle object case
6481 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6482 if (part != null)
6483 {
6484 // This will handle both deed and non-deed and also the no
6485 // group case
6486 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6487 return new LSL_Integer(1);
6488
5964 return new LSL_Integer(0); 6489 return new LSL_Integer(0);
6490 }
6491
6492 return new LSL_Integer(0);
5965 } 6493 }
5966 6494
5967 public void llUnSit(string id) 6495 public void llUnSit(string id)
@@ -6520,6 +7048,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6520 7048
6521 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7049 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6522 { 7050 {
7051 // LSL quaternions can normalize to 0, normal Quaternions can't.
7052 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7053 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7054
6523 part.SitTargetPosition = offset; 7055 part.SitTargetPosition = offset;
6524 part.SitTargetOrientation = rot; 7056 part.SitTargetOrientation = rot;
6525 part.ParentGroup.HasGroupChanged = true; 7057 part.ParentGroup.HasGroupChanged = true;
@@ -6574,7 +7106,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6574 UUID key; 7106 UUID key;
6575 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 7107 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
6576 7108
6577 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 7109 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
6578 { 7110 {
6579 int expires = 0; 7111 int expires = 0;
6580 if (hours != 0) 7112 if (hours != 0)
@@ -6706,30 +7238,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6706 UUID av = new UUID(); 7238 UUID av = new UUID();
6707 if (!UUID.TryParse(avatar,out av)) 7239 if (!UUID.TryParse(avatar,out av))
6708 { 7240 {
6709 LSLError("First parameter to llDialog needs to be a key"); 7241 //LSLError("First parameter to llDialog needs to be a key");
6710 return; 7242 return;
6711 } 7243 }
6712 if (buttons.Length < 1) 7244 if (buttons.Length < 1)
6713 { 7245 {
6714 LSLError("No less than 1 button can be shown"); 7246 buttons.Add("OK");
6715 return;
6716 } 7247 }
6717 if (buttons.Length > 12) 7248 if (buttons.Length > 12)
6718 { 7249 {
6719 LSLError("No more than 12 buttons can be shown"); 7250 ShoutError("button list too long, must be 12 or fewer entries");
6720 return;
6721 } 7251 }
6722 string[] buts = new string[buttons.Length]; 7252 int length = buttons.Length;
6723 for (int i = 0; i < buttons.Length; i++) 7253 if (length > 12)
7254 length = 12;
7255
7256 string[] buts = new string[length];
7257 for (int i = 0; i < length; i++)
6724 { 7258 {
6725 if (buttons.Data[i].ToString() == String.Empty) 7259 if (buttons.Data[i].ToString() == String.Empty)
6726 { 7260 {
6727 LSLError("button label cannot be blank"); 7261 ShoutError("button label cannot be blank");
6728 return; 7262 return;
6729 } 7263 }
6730 if (buttons.Data[i].ToString().Length > 24) 7264 if (buttons.Data[i].ToString().Length > 24)
6731 { 7265 {
6732 LSLError("button label cannot be longer than 24 characters"); 7266 ShoutError("button label cannot be longer than 24 characters");
6733 return; 7267 return;
6734 } 7268 }
6735 buts[i] = buttons.Data[i].ToString(); 7269 buts[i] = buttons.Data[i].ToString();
@@ -6796,9 +7330,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6796 return; 7330 return;
6797 } 7331 }
6798 7332
6799 // the rest of the permission checks are done in RezScript, so check the pin there as well 7333 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6800 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7334 if (dest != null)
7335 {
7336 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7337 {
7338 // the rest of the permission checks are done in RezScript, so check the pin there as well
7339 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6801 7340
7341 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7342 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7343 }
7344 }
6802 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7345 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6803 ScriptSleep(3000); 7346 ScriptSleep(3000);
6804 } 7347 }
@@ -6872,19 +7415,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6872 public LSL_String llMD5String(string src, int nonce) 7415 public LSL_String llMD5String(string src, int nonce)
6873 { 7416 {
6874 m_host.AddScriptLPS(1); 7417 m_host.AddScriptLPS(1);
6875 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7418 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6876 } 7419 }
6877 7420
6878 public LSL_String llSHA1String(string src) 7421 public LSL_String llSHA1String(string src)
6879 { 7422 {
6880 m_host.AddScriptLPS(1); 7423 m_host.AddScriptLPS(1);
6881 return Util.SHA1Hash(src).ToLower(); 7424 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6882 } 7425 }
6883 7426
6884 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7427 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6885 { 7428 {
6886 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7429 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6887 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7430 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7431 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7432 return shapeBlock;
6888 7433
6889 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7434 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6890 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7435 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6989,6 +7534,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6989 // Prim type box, cylinder and prism. 7534 // Prim type box, cylinder and prism.
6990 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7535 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6991 { 7536 {
7537 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7538 return;
7539
6992 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7540 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6993 ObjectShapePacket.ObjectDataBlock shapeBlock; 7541 ObjectShapePacket.ObjectDataBlock shapeBlock;
6994 7542
@@ -7042,6 +7590,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7042 // Prim type sphere. 7590 // Prim type sphere.
7043 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7591 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7044 { 7592 {
7593 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7594 return;
7595
7045 ObjectShapePacket.ObjectDataBlock shapeBlock; 7596 ObjectShapePacket.ObjectDataBlock shapeBlock;
7046 7597
7047 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7598 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7083,6 +7634,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7083 // Prim type torus, tube and ring. 7634 // Prim type torus, tube and ring.
7084 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7635 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
7085 { 7636 {
7637 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7638 return;
7639
7086 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7640 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7087 ObjectShapePacket.ObjectDataBlock shapeBlock; 7641 ObjectShapePacket.ObjectDataBlock shapeBlock;
7088 7642
@@ -7218,6 +7772,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7218 // Prim type sculpt. 7772 // Prim type sculpt.
7219 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7773 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7220 { 7774 {
7775 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7776 return;
7777
7221 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7778 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7222 UUID sculptId; 7779 UUID sculptId;
7223 7780
@@ -7240,7 +7797,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7240 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7797 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7241 { 7798 {
7242 // default 7799 // default
7243 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7800 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7244 } 7801 }
7245 7802
7246 part.Shape.SetSculptProperties((byte)type, sculptId); 7803 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7257,48 +7814,142 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7257 ScriptSleep(200); 7814 ScriptSleep(200);
7258 } 7815 }
7259 7816
7260 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7817 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7261 { 7818 {
7262 m_host.AddScriptLPS(1); 7819 m_host.AddScriptLPS(1);
7263 7820
7264 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7821 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7822 }
7265 7823
7266 ScriptSleep(200); 7824 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7825 {
7826 List<object> parts = new List<object>();
7827 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7828 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7829 foreach (SceneObjectPart p in prims)
7830 parts.Add(p);
7831 foreach (ScenePresence p in avatars)
7832 parts.Add(p);
7833
7834 LSL_List remaining = null;
7835 uint rulesParsed = 0;
7836
7837 if (parts.Count > 0)
7838 {
7839 foreach (object part in parts)
7840 {
7841 if (part is SceneObjectPart)
7842 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7843 else
7844 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7845 }
7846
7847 while ((object)remaining != null && remaining.Length > 2)
7848 {
7849 linknumber = remaining.GetLSLIntegerItem(0);
7850 rules = remaining.GetSublist(1, -1);
7851 parts.Clear();
7852 prims = GetLinkParts(linknumber);
7853 avatars = GetLinkAvatars(linknumber);
7854 foreach (SceneObjectPart p in prims)
7855 parts.Add(p);
7856 foreach (ScenePresence p in avatars)
7857 parts.Add(p);
7858
7859 remaining = null;
7860 foreach (object part in parts)
7861 {
7862 if (part is SceneObjectPart)
7863 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7864 else
7865 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7866 }
7867 }
7868 }
7267 } 7869 }
7268 7870
7269 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7871 public LSL_List llGetPhysicsMaterial()
7270 { 7872 {
7271 m_host.AddScriptLPS(1); 7873 LSL_List result = new LSL_List();
7272 7874
7273 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7875 result.Add(new LSL_Float(m_host.GravityModifier));
7876 result.Add(new LSL_Float(m_host.Restitution));
7877 result.Add(new LSL_Float(m_host.Friction));
7878 result.Add(new LSL_Float(m_host.Density));
7879
7880 return result;
7274 } 7881 }
7275 7882
7276 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7883 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7884 float material_density, float material_friction,
7885 float material_restitution, float material_gravity_modifier)
7277 { 7886 {
7278 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7887 ExtraPhysicsData physdata = new ExtraPhysicsData();
7888 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7889 physdata.Density = part.Density;
7890 physdata.Friction = part.Friction;
7891 physdata.Bounce = part.Restitution;
7892 physdata.GravitationModifier = part.GravityModifier;
7279 7893
7280 LSL_List remaining = null; 7894 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7281 uint rulesParsed = 0; 7895 physdata.Density = material_density;
7896 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7897 physdata.Friction = material_friction;
7898 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7899 physdata.Bounce = material_restitution;
7900 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7901 physdata.GravitationModifier = material_gravity_modifier;
7282 7902
7283 foreach (SceneObjectPart part in parts) 7903 part.UpdateExtraPhysics(physdata);
7284 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7904 }
7285 7905
7286 while (remaining != null && remaining.Length > 2) 7906 public void llSetPhysicsMaterial(int material_bits,
7287 { 7907 float material_gravity_modifier, float material_restitution,
7288 linknumber = remaining.GetLSLIntegerItem(0); 7908 float material_friction, float material_density)
7289 rules = remaining.GetSublist(1, -1); 7909 {
7290 parts = GetLinkParts(linknumber); 7910 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7911 }
7291 7912
7292 foreach (SceneObjectPart part in parts) 7913 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7293 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7914 {
7915 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7916 llSetLinkPrimitiveParamsFast(linknumber, rules);
7917 ScriptSleep(200);
7918 }
7919
7920 // vector up using libomv (c&p from sop )
7921 // vector up rotated by r
7922 private Vector3 Zrot(Quaternion r)
7923 {
7924 double x, y, z, m;
7925
7926 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7927 if (Math.Abs(1.0 - m) > 0.000001)
7928 {
7929 m = 1.0 / Math.Sqrt(m);
7930 r.X *= (float)m;
7931 r.Y *= (float)m;
7932 r.Z *= (float)m;
7933 r.W *= (float)m;
7294 } 7934 }
7935
7936 x = 2 * (r.X * r.Z + r.Y * r.W);
7937 y = 2 * (-r.X * r.W + r.Y * r.Z);
7938 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7939
7940 return new Vector3((float)x, (float)y, (float)z);
7295 } 7941 }
7296 7942
7297 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7943 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7298 { 7944 {
7945 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7946 return null;
7947
7299 int idx = 0; 7948 int idx = 0;
7300 int idxStart = 0; 7949 int idxStart = 0;
7301 7950
7951 SceneObjectGroup parentgrp = part.ParentGroup;
7952
7302 bool positionChanged = false; 7953 bool positionChanged = false;
7303 LSL_Vector currentPosition = GetPartLocalPos(part); 7954 LSL_Vector currentPosition = GetPartLocalPos(part);
7304 7955
@@ -7323,8 +7974,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7323 return null; 7974 return null;
7324 7975
7325 v=rules.GetVector3Item(idx++); 7976 v=rules.GetVector3Item(idx++);
7977 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7978 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7979 else
7980 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7326 positionChanged = true; 7981 positionChanged = true;
7327 currentPosition = GetSetPosTarget(part, v, currentPosition);
7328 7982
7329 break; 7983 break;
7330 case (int)ScriptBaseClass.PRIM_SIZE: 7984 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7341,7 +7995,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7341 7995
7342 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7996 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7343 // try to let this work as in SL... 7997 // try to let this work as in SL...
7344 if (part.ParentID == 0) 7998 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7345 { 7999 {
7346 // special case: If we are root, rotate complete SOG to new rotation 8000 // special case: If we are root, rotate complete SOG to new rotation
7347 SetRot(part, q); 8001 SetRot(part, q);
@@ -7601,7 +8255,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7601 return null; 8255 return null;
7602 8256
7603 string ph = rules.Data[idx++].ToString(); 8257 string ph = rules.Data[idx++].ToString();
7604 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8258 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7605 8259
7606 break; 8260 break;
7607 8261
@@ -7635,12 +8289,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7635 8289
7636 break; 8290 break;
7637 8291
8292 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8293 if (remain < 5)
8294 return null;
8295
8296 int material_bits = rules.GetLSLIntegerItem(idx++);
8297 float material_density = (float)rules.GetLSLFloatItem(idx++);
8298 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8299 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8300 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8301
8302 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8303
8304 break;
8305
7638 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8306 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7639 if (remain < 1) 8307 if (remain < 1)
7640 return null; 8308 return null;
7641 string temp = rules.Data[idx++].ToString(); 8309 string temp = rules.Data[idx++].ToString();
7642 8310
7643 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8311 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7644 8312
7645 break; 8313 break;
7646 8314
@@ -7714,14 +8382,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7714 if (part.ParentGroup.RootPart == part) 8382 if (part.ParentGroup.RootPart == part)
7715 { 8383 {
7716 SceneObjectGroup parent = part.ParentGroup; 8384 SceneObjectGroup parent = part.ParentGroup;
7717 parent.UpdateGroupPosition(currentPosition); 8385 Util.FireAndForget(delegate(object x) {
8386 parent.UpdateGroupPosition(currentPosition);
8387 });
7718 } 8388 }
7719 else 8389 else
7720 { 8390 {
7721 part.OffsetPosition = currentPosition; 8391 part.OffsetPosition = currentPosition;
7722 SceneObjectGroup parent = part.ParentGroup; 8392// SceneObjectGroup parent = part.ParentGroup;
7723 parent.HasGroupChanged = true; 8393// parent.HasGroupChanged = true;
7724 parent.ScheduleGroupForTerseUpdate(); 8394// parent.ScheduleGroupForTerseUpdate();
8395 part.ScheduleTerseUpdate();
7725 } 8396 }
7726 } 8397 }
7727 } 8398 }
@@ -7759,10 +8430,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7759 8430
7760 public LSL_String llXorBase64Strings(string str1, string str2) 8431 public LSL_String llXorBase64Strings(string str1, string str2)
7761 { 8432 {
7762 m_host.AddScriptLPS(1); 8433 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7763 Deprecated("llXorBase64Strings"); 8434
7764 ScriptSleep(300); 8435 ScriptSleep(300);
7765 return String.Empty; 8436 m_host.AddScriptLPS(1);
8437
8438 if (str1 == String.Empty)
8439 return String.Empty;
8440 if (str2 == String.Empty)
8441 return str1;
8442
8443 int len = str2.Length;
8444 if ((len % 4) != 0) // LL is EVIL!!!!
8445 {
8446 while (str2.EndsWith("="))
8447 str2 = str2.Substring(0, str2.Length - 1);
8448
8449 len = str2.Length;
8450 int mod = len % 4;
8451
8452 if (mod == 1)
8453 str2 = str2.Substring(0, str2.Length - 1);
8454 else if (mod == 2)
8455 str2 += "==";
8456 else if (mod == 3)
8457 str2 += "=";
8458 }
8459
8460 byte[] data1;
8461 byte[] data2;
8462 try
8463 {
8464 data1 = Convert.FromBase64String(str1);
8465 data2 = Convert.FromBase64String(str2);
8466 }
8467 catch (Exception)
8468 {
8469 return new LSL_String(String.Empty);
8470 }
8471
8472 // For cases where the decoded length of s2 is greater
8473 // than the decoded length of s1, simply perform a normal
8474 // decode and XOR
8475 //
8476 if (data2.Length >= data1.Length)
8477 {
8478 for (int pos = 0 ; pos < data1.Length ; pos++ )
8479 data1[pos] ^= data2[pos];
8480
8481 return Convert.ToBase64String(data1);
8482 }
8483
8484 // Remove padding
8485 while (str1.EndsWith("="))
8486 str1 = str1.Substring(0, str1.Length - 1);
8487 while (str2.EndsWith("="))
8488 str2 = str2.Substring(0, str2.Length - 1);
8489
8490 byte[] d1 = new byte[str1.Length];
8491 byte[] d2 = new byte[str2.Length];
8492
8493 for (int i = 0 ; i < str1.Length ; i++)
8494 {
8495 int idx = b64.IndexOf(str1.Substring(i, 1));
8496 if (idx == -1)
8497 idx = 0;
8498 d1[i] = (byte)idx;
8499 }
8500
8501 for (int i = 0 ; i < str2.Length ; i++)
8502 {
8503 int idx = b64.IndexOf(str2.Substring(i, 1));
8504 if (idx == -1)
8505 idx = 0;
8506 d2[i] = (byte)idx;
8507 }
8508
8509 string output = String.Empty;
8510
8511 for (int pos = 0 ; pos < d1.Length ; pos++)
8512 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8513
8514 while (output.Length % 3 > 0)
8515 output += "=";
8516
8517 return output;
7766 } 8518 }
7767 8519
7768 public void llRemoteDataSetRegion() 8520 public void llRemoteDataSetRegion()
@@ -7887,8 +8639,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7887 public LSL_Integer llGetNumberOfPrims() 8639 public LSL_Integer llGetNumberOfPrims()
7888 { 8640 {
7889 m_host.AddScriptLPS(1); 8641 m_host.AddScriptLPS(1);
7890 8642 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7891 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8643
8644 return m_host.ParentGroup.PrimCount + avatarCount;
7892 } 8645 }
7893 8646
7894 /// <summary> 8647 /// <summary>
@@ -7903,55 +8656,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7903 m_host.AddScriptLPS(1); 8656 m_host.AddScriptLPS(1);
7904 UUID objID = UUID.Zero; 8657 UUID objID = UUID.Zero;
7905 LSL_List result = new LSL_List(); 8658 LSL_List result = new LSL_List();
8659
8660 // If the ID is not valid, return null result
7906 if (!UUID.TryParse(obj, out objID)) 8661 if (!UUID.TryParse(obj, out objID))
7907 { 8662 {
7908 result.Add(new LSL_Vector()); 8663 result.Add(new LSL_Vector());
7909 result.Add(new LSL_Vector()); 8664 result.Add(new LSL_Vector());
7910 return result; 8665 return result;
7911 } 8666 }
8667
8668 // Check if this is an attached prim. If so, replace
8669 // the UUID with the avatar UUID and report it's bounding box
8670 SceneObjectPart part = World.GetSceneObjectPart(objID);
8671 if (part != null && part.ParentGroup.IsAttachment)
8672 objID = part.ParentGroup.AttachedAvatar;
8673
8674 // Find out if this is an avatar ID. If so, return it's box
7912 ScenePresence presence = World.GetScenePresence(objID); 8675 ScenePresence presence = World.GetScenePresence(objID);
7913 if (presence != null) 8676 if (presence != null)
7914 { 8677 {
7915 if (presence.ParentID == 0) // not sat on an object 8678 // As per LSL Wiki, there is no difference between sitting
8679 // and standing avatar since server 1.36
8680 LSL_Vector lower;
8681 LSL_Vector upper;
8682
8683 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8684
8685 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8686 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8687/*
7916 { 8688 {
7917 LSL_Vector lower; 8689 // This is for ground sitting avatars
7918 LSL_Vector upper; 8690 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7919 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8691 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7920 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8692 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7921 { 8693 }
7922 // This is for ground sitting avatars 8694 else
7923 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8695 {
7924 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8696 // This is for standing/flying avatars
7925 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8697 float height = presence.Appearance.AvatarHeight / 2.0f;
7926 } 8698 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7927 else 8699 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7928 { 8700 }
7929 // This is for standing/flying avatars 8701
7930 float height = presence.Appearance.AvatarHeight / 2.0f; 8702 // Adjust to the documented error offsets (see LSL Wiki)
7931 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8703 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7932 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8704 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7933 } 8705*/
7934 result.Add(lower); 8706 {
7935 result.Add(upper); 8707 // This is for ground sitting avatars TODO!
7936 return result; 8708 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8709 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7937 } 8710 }
7938 else 8711 else
7939 { 8712 {
7940 // sitting on an object so we need the bounding box of that 8713 // This is for standing/flying avatars
7941 // which should include the avatar so set the UUID to the 8714 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
7942 // UUID of the object the avatar is sat on and allow it to fall through 8715 upper = new LSL_Vector(box.X, box.Y, box.Z);
7943 // to processing an object
7944 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7945 objID = p.UUID;
7946 } 8716 }
8717
8718 if (lower.x > upper.x)
8719 lower.x = upper.x;
8720 if (lower.y > upper.y)
8721 lower.y = upper.y;
8722 if (lower.z > upper.z)
8723 lower.z = upper.z;
8724
8725 result.Add(lower);
8726 result.Add(upper);
8727 return result;
7947 } 8728 }
7948 SceneObjectPart part = World.GetSceneObjectPart(objID); 8729
8730 part = World.GetSceneObjectPart(objID);
7949 // Currently only works for single prims without a sitting avatar 8731 // Currently only works for single prims without a sitting avatar
7950 if (part != null) 8732 if (part != null)
7951 { 8733 {
7952 Vector3 halfSize = part.Scale / 2.0f; 8734 float minX;
7953 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8735 float maxX;
7954 LSL_Vector upper = new LSL_Vector(halfSize); 8736 float minY;
8737 float maxY;
8738 float minZ;
8739 float maxZ;
8740
8741 // This BBox is in sim coordinates, with the offset being
8742 // a contained point.
8743 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8744 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8745
8746 minX -= offsets[0].X;
8747 maxX -= offsets[0].X;
8748 minY -= offsets[0].Y;
8749 maxY -= offsets[0].Y;
8750 minZ -= offsets[0].Z;
8751 maxZ -= offsets[0].Z;
8752
8753 LSL_Vector lower;
8754 LSL_Vector upper;
8755
8756 // Adjust to the documented error offsets (see LSL Wiki)
8757 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8758 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8759
8760 if (lower.x > upper.x)
8761 lower.x = upper.x;
8762 if (lower.y > upper.y)
8763 lower.y = upper.y;
8764 if (lower.z > upper.z)
8765 lower.z = upper.z;
8766
7955 result.Add(lower); 8767 result.Add(lower);
7956 result.Add(upper); 8768 result.Add(upper);
7957 return result; 8769 return result;
@@ -7968,224 +8780,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7968 return new LSL_Vector(m_host.GetGeometricCenter()); 8780 return new LSL_Vector(m_host.GetGeometricCenter());
7969 } 8781 }
7970 8782
7971 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8783 public LSL_List llGetPrimitiveParams(LSL_List rules)
7972 { 8784 {
7973 LSL_List result = new LSL_List(); 8785 m_host.AddScriptLPS(1);
7974 LSL_List remaining = null;
7975 8786
7976 while (true) 8787 LSL_List result = new LSL_List();
7977 {
7978 if (entity is SceneObjectPart)
7979 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
7980 else
7981 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
7982 8788
7983 if (remaining == null || remaining.Length <= 2) 8789 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7984 return result;
7985 8790
8791 while ((object)remaining != null && remaining.Length > 2)
8792 {
7986 int linknumber = remaining.GetLSLIntegerItem(0); 8793 int linknumber = remaining.GetLSLIntegerItem(0);
7987 rules = remaining.GetSublist(1, -1); 8794 rules = remaining.GetSublist(1, -1);
7988 entity = GetLinkEntity(linknumber); 8795 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7989 }
7990 }
7991 8796
7992 public LSL_List llGetPrimitiveParams(LSL_List rules) 8797 foreach (SceneObjectPart part in parts)
7993 { 8798 remaining = GetPrimParams(part, rules, ref result);
7994 m_host.AddScriptLPS(1); 8799 }
7995 8800
7996 return GetEntityParams(m_host, rules); 8801 return result;
7997 } 8802 }
7998 8803
7999 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8804 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8000 { 8805 {
8001 m_host.AddScriptLPS(1); 8806 m_host.AddScriptLPS(1);
8002 8807
8003 return GetEntityParams(GetLinkEntity(linknumber), rules); 8808 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8004 } 8809 // keep other options as before
8005 8810
8006 public LSL_Vector GetAgentSize(ScenePresence sp) 8811 List<SceneObjectPart> parts;
8007 { 8812 List<ScenePresence> avatars;
8008 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8813
8009 } 8814 LSL_List res = new LSL_List();
8815 LSL_List remaining = null;
8010 8816
8011 /// <summary> 8817 while (rules.Length > 0)
8012 /// Gets params for a seated avatar in a linkset.
8013 /// </summary>
8014 /// <returns></returns>
8015 /// <param name='sp'></param>
8016 /// <param name='rules'></param>
8017 /// <param name='res'></param>
8018 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8019 {
8020 int idx = 0;
8021 while (idx < rules.Length)
8022 { 8818 {
8023 int code = (int)rules.GetLSLIntegerItem(idx++); 8819 parts = GetLinkParts(linknumber);
8024 int remain = rules.Length-idx; 8820 avatars = GetLinkAvatars(linknumber);
8025 8821
8026 switch (code) 8822 remaining = null;
8823 foreach (SceneObjectPart part in parts)
8027 { 8824 {
8028 case (int)ScriptBaseClass.PRIM_MATERIAL: 8825 remaining = GetPrimParams(part, rules, ref res);
8029 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8826 }
8030 break; 8827 foreach (ScenePresence avatar in avatars)
8031 8828 {
8032 case (int)ScriptBaseClass.PRIM_PHYSICS: 8829 remaining = GetPrimParams(avatar, rules, ref res);
8033 res.Add(ScriptBaseClass.FALSE); 8830 }
8034 break;
8035
8036 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8037 res.Add(ScriptBaseClass.FALSE);
8038 break;
8039
8040 case (int)ScriptBaseClass.PRIM_PHANTOM:
8041 res.Add(ScriptBaseClass.FALSE);
8042 break;
8043
8044 case (int)ScriptBaseClass.PRIM_POSITION:
8045 res.Add(new LSL_Vector(sp.AbsolutePosition));
8046 break;
8047
8048 case (int)ScriptBaseClass.PRIM_SIZE:
8049 res.Add(GetAgentSize(sp));
8050 break;
8051
8052 case (int)ScriptBaseClass.PRIM_ROTATION:
8053 res.Add(sp.GetWorldRotation());
8054 break;
8055
8056 case (int)ScriptBaseClass.PRIM_TYPE:
8057 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8058 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8059 res.Add(new LSL_Vector(0, 1, 0));
8060 res.Add(new LSL_Float(0));
8061 res.Add(new LSL_Vector(0, 0, 0));
8062 res.Add(new LSL_Vector(1, 1, 0));
8063 res.Add(new LSL_Vector(0, 0, 0));
8064 break;
8065
8066 case (int)ScriptBaseClass.PRIM_TEXTURE:
8067 if (remain < 1)
8068 return null;
8069
8070 int face = (int)rules.GetLSLIntegerItem(idx++);
8071 if (face > 21)
8072 break;
8073
8074 res.Add(new LSL_String(""));
8075 res.Add(ScriptBaseClass.ZERO_VECTOR);
8076 res.Add(ScriptBaseClass.ZERO_VECTOR);
8077 res.Add(new LSL_Float(0));
8078 break;
8079
8080 case (int)ScriptBaseClass.PRIM_COLOR:
8081 if (remain < 1)
8082 return null;
8083
8084 face = (int)rules.GetLSLIntegerItem(idx++);
8085 if (face > 21)
8086 break;
8087
8088 res.Add(ScriptBaseClass.ZERO_VECTOR);
8089 res.Add(new LSL_Float(0));
8090 break;
8091
8092 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8093 if (remain < 1)
8094 return null;
8095
8096 face = (int)rules.GetLSLIntegerItem(idx++);
8097 if (face > 21)
8098 break;
8099
8100 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8101 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8102 break;
8103
8104 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8105 if (remain < 1)
8106 return null;
8107
8108 face = (int)rules.GetLSLIntegerItem(idx++);
8109 if (face > 21)
8110 break;
8111
8112 res.Add(ScriptBaseClass.FALSE);
8113 break;
8114
8115 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8116 res.Add(ScriptBaseClass.FALSE);
8117 res.Add(new LSL_Integer(0));
8118 res.Add(new LSL_Float(0));
8119 res.Add(new LSL_Float(0));
8120 res.Add(new LSL_Float(0));
8121 res.Add(new LSL_Float(0));
8122 res.Add(ScriptBaseClass.ZERO_VECTOR);
8123 break;
8124
8125 case (int)ScriptBaseClass.PRIM_TEXGEN:
8126 if (remain < 1)
8127 return null;
8128
8129 face = (int)rules.GetLSLIntegerItem(idx++);
8130 if (face > 21)
8131 break;
8132
8133 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8134 break;
8135
8136 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8137 res.Add(ScriptBaseClass.FALSE);
8138 res.Add(ScriptBaseClass.ZERO_VECTOR);
8139 res.Add(ScriptBaseClass.ZERO_VECTOR);
8140 break;
8141
8142 case (int)ScriptBaseClass.PRIM_GLOW:
8143 if (remain < 1)
8144 return null;
8145
8146 face = (int)rules.GetLSLIntegerItem(idx++);
8147 if (face > 21)
8148 break;
8149
8150 res.Add(new LSL_Float(0));
8151 break;
8152
8153 case (int)ScriptBaseClass.PRIM_TEXT:
8154 res.Add(new LSL_String(""));
8155 res.Add(ScriptBaseClass.ZERO_VECTOR);
8156 res.Add(new LSL_Float(1));
8157 break;
8158
8159 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8160 res.Add(new LSL_Rotation(sp.Rotation));
8161 break;
8162
8163 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8164 res.Add(new LSL_Vector(sp.OffsetPosition));
8165 break;
8166
8167 case (int)ScriptBaseClass.PRIM_SLICE:
8168 res.Add(new LSL_Vector(0, 1, 0));
8169 break;
8170
8171 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8172 if(remain < 3)
8173 return null;
8174 8831
8175 return rules.GetSublist(idx, -1); 8832 if ((object)remaining != null && remaining.Length > 0)
8833 {
8834 linknumber = remaining.GetLSLIntegerItem(0);
8835 rules = remaining.GetSublist(1, -1);
8176 } 8836 }
8837 else
8838 break;
8177 } 8839 }
8178 8840
8179 return null; 8841 return res;
8180 } 8842 }
8181 8843
8182 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8844 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8183 { 8845 {
8184 int idx = 0; 8846 int idx=0;
8185 while (idx < rules.Length) 8847 while (idx < rules.Length)
8186 { 8848 {
8187 int code = (int)rules.GetLSLIntegerItem(idx++); 8849 int code=(int)rules.GetLSLIntegerItem(idx++);
8188 int remain = rules.Length-idx; 8850 int remain=rules.Length-idx;
8189 8851
8190 switch (code) 8852 switch (code)
8191 { 8853 {
@@ -8215,19 +8877,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8215 break; 8877 break;
8216 8878
8217 case (int)ScriptBaseClass.PRIM_POSITION: 8879 case (int)ScriptBaseClass.PRIM_POSITION:
8218 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8880 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8219 8881 part.AbsolutePosition.Y,
8220 // For some reason, the part.AbsolutePosition.* values do not change if the 8882 part.AbsolutePosition.Z);
8221 // linkset is rotated; they always reflect the child prim's world position
8222 // as though the linkset is unrotated. This is incompatible behavior with SL's
8223 // implementation, so will break scripts imported from there (not to mention it
8224 // makes it more difficult to determine a child prim's actual inworld position).
8225 if (!part.IsRoot)
8226 {
8227 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8228 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8229 }
8230
8231 res.Add(v); 8883 res.Add(v);
8232 break; 8884 break;
8233 8885
@@ -8397,30 +9049,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8397 if (remain < 1) 9049 if (remain < 1)
8398 return null; 9050 return null;
8399 9051
8400 face=(int)rules.GetLSLIntegerItem(idx++); 9052 face = (int)rules.GetLSLIntegerItem(idx++);
8401 9053
8402 tex = part.Shape.Textures; 9054 tex = part.Shape.Textures;
9055 int shiny;
8403 if (face == ScriptBaseClass.ALL_SIDES) 9056 if (face == ScriptBaseClass.ALL_SIDES)
8404 { 9057 {
8405 for (face = 0; face < GetNumberOfSides(part); face++) 9058 for (face = 0; face < GetNumberOfSides(part); face++)
8406 { 9059 {
8407 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9060 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8408 // Convert Shininess to PRIM_SHINY_* 9061 if (shinyness == Shininess.High)
8409 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9062 {
8410 // PRIM_BUMP_* 9063 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8411 res.Add(new LSL_Integer((int)texface.Bump)); 9064 }
9065 else if (shinyness == Shininess.Medium)
9066 {
9067 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9068 }
9069 else if (shinyness == Shininess.Low)
9070 {
9071 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9072 }
9073 else
9074 {
9075 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9076 }
9077 res.Add(new LSL_Integer(shiny));
9078 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8412 } 9079 }
8413 } 9080 }
8414 else 9081 else
8415 { 9082 {
8416 if (face >= 0 && face < GetNumberOfSides(part)) 9083 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9084 if (shinyness == Shininess.High)
8417 { 9085 {
8418 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9086 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8419 // Convert Shininess to PRIM_SHINY_* 9087 }
8420 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9088 else if (shinyness == Shininess.Medium)
8421 // PRIM_BUMP_* 9089 {
8422 res.Add(new LSL_Integer((int)texface.Bump)); 9090 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8423 } 9091 }
9092 else if (shinyness == Shininess.Low)
9093 {
9094 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9095 }
9096 else
9097 {
9098 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9099 }
9100 res.Add(new LSL_Integer(shiny));
9101 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8424 } 9102 }
8425 break; 9103 break;
8426 9104
@@ -8431,21 +9109,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8431 face = (int)rules.GetLSLIntegerItem(idx++); 9109 face = (int)rules.GetLSLIntegerItem(idx++);
8432 9110
8433 tex = part.Shape.Textures; 9111 tex = part.Shape.Textures;
9112 int fullbright;
8434 if (face == ScriptBaseClass.ALL_SIDES) 9113 if (face == ScriptBaseClass.ALL_SIDES)
8435 { 9114 {
8436 for (face = 0; face < GetNumberOfSides(part); face++) 9115 for (face = 0; face < GetNumberOfSides(part); face++)
8437 { 9116 {
8438 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9117 if (tex.GetFace((uint)face).Fullbright == true)
8439 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9118 {
9119 fullbright = ScriptBaseClass.TRUE;
9120 }
9121 else
9122 {
9123 fullbright = ScriptBaseClass.FALSE;
9124 }
9125 res.Add(new LSL_Integer(fullbright));
8440 } 9126 }
8441 } 9127 }
8442 else 9128 else
8443 { 9129 {
8444 if (face >= 0 && face < GetNumberOfSides(part)) 9130 if (tex.GetFace((uint)face).Fullbright == true)
8445 { 9131 {
8446 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9132 fullbright = ScriptBaseClass.TRUE;
8447 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9133 }
9134 else
9135 {
9136 fullbright = ScriptBaseClass.FALSE;
8448 } 9137 }
9138 res.Add(new LSL_Integer(fullbright));
8449 } 9139 }
8450 break; 9140 break;
8451 9141
@@ -8467,27 +9157,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8467 break; 9157 break;
8468 9158
8469 case (int)ScriptBaseClass.PRIM_TEXGEN: 9159 case (int)ScriptBaseClass.PRIM_TEXGEN:
9160 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8470 if (remain < 1) 9161 if (remain < 1)
8471 return null; 9162 return null;
8472 9163
8473 face=(int)rules.GetLSLIntegerItem(idx++); 9164 face = (int)rules.GetLSLIntegerItem(idx++);
8474 9165
8475 tex = part.Shape.Textures; 9166 tex = part.Shape.Textures;
8476 if (face == ScriptBaseClass.ALL_SIDES) 9167 if (face == ScriptBaseClass.ALL_SIDES)
8477 { 9168 {
8478 for (face = 0; face < GetNumberOfSides(part); face++) 9169 for (face = 0; face < GetNumberOfSides(part); face++)
8479 { 9170 {
8480 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9171 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8481 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9172 {
8482 res.Add(new LSL_Integer((uint)texgen >> 1)); 9173 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9174 }
9175 else
9176 {
9177 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9178 }
8483 } 9179 }
8484 } 9180 }
8485 else 9181 else
8486 { 9182 {
8487 if (face >= 0 && face < GetNumberOfSides(part)) 9183 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9184 {
9185 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9186 }
9187 else
8488 { 9188 {
8489 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9189 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8490 res.Add(new LSL_Integer((uint)texgen >> 1));
8491 } 9190 }
8492 } 9191 }
8493 break; 9192 break;
@@ -8511,24 +9210,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8511 if (remain < 1) 9210 if (remain < 1)
8512 return null; 9211 return null;
8513 9212
8514 face=(int)rules.GetLSLIntegerItem(idx++); 9213 face = (int)rules.GetLSLIntegerItem(idx++);
8515 9214
8516 tex = part.Shape.Textures; 9215 tex = part.Shape.Textures;
9216 float primglow;
8517 if (face == ScriptBaseClass.ALL_SIDES) 9217 if (face == ScriptBaseClass.ALL_SIDES)
8518 { 9218 {
8519 for (face = 0; face < GetNumberOfSides(part); face++) 9219 for (face = 0; face < GetNumberOfSides(part); face++)
8520 { 9220 {
8521 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9221 primglow = tex.GetFace((uint)face).Glow;
8522 res.Add(new LSL_Float(texface.Glow)); 9222 res.Add(new LSL_Float(primglow));
8523 } 9223 }
8524 } 9224 }
8525 else 9225 else
8526 { 9226 {
8527 if (face >= 0 && face < GetNumberOfSides(part)) 9227 primglow = tex.GetFace((uint)face).Glow;
8528 { 9228 res.Add(new LSL_Float(primglow));
8529 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8530 res.Add(new LSL_Float(texface.Glow));
8531 }
8532 } 9229 }
8533 break; 9230 break;
8534 9231
@@ -8540,15 +9237,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8540 textColor.B)); 9237 textColor.B));
8541 res.Add(new LSL_Float(textColor.A)); 9238 res.Add(new LSL_Float(textColor.A));
8542 break; 9239 break;
9240
8543 case (int)ScriptBaseClass.PRIM_NAME: 9241 case (int)ScriptBaseClass.PRIM_NAME:
8544 res.Add(new LSL_String(part.Name)); 9242 res.Add(new LSL_String(part.Name));
8545 break; 9243 break;
9244
8546 case (int)ScriptBaseClass.PRIM_DESC: 9245 case (int)ScriptBaseClass.PRIM_DESC:
8547 res.Add(new LSL_String(part.Description)); 9246 res.Add(new LSL_String(part.Description));
8548 break; 9247 break;
8549 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9248 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8550 res.Add(new LSL_Rotation(part.RotationOffset)); 9249 res.Add(new LSL_Rotation(part.RotationOffset));
8551 break; 9250 break;
9251
8552 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9252 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8553 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9253 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8554 break; 9254 break;
@@ -9159,8 +9859,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9159 // The function returns an ordered list 9859 // The function returns an ordered list
9160 // representing the tokens found in the supplied 9860 // representing the tokens found in the supplied
9161 // sources string. If two successive tokenizers 9861 // sources string. If two successive tokenizers
9162 // are encountered, then a NULL entry is added 9862 // are encountered, then a null-string entry is
9163 // to the list. 9863 // added to the list.
9164 // 9864 //
9165 // It is a precondition that the source and 9865 // It is a precondition that the source and
9166 // toekizer lisst are non-null. If they are null, 9866 // toekizer lisst are non-null. If they are null,
@@ -9168,7 +9868,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9168 // while their lengths are being determined. 9868 // while their lengths are being determined.
9169 // 9869 //
9170 // A small amount of working memoryis required 9870 // A small amount of working memoryis required
9171 // of approximately 8*#tokenizers. 9871 // of approximately 8*#tokenizers + 8*srcstrlen.
9172 // 9872 //
9173 // There are many ways in which this function 9873 // There are many ways in which this function
9174 // can be implemented, this implementation is 9874 // can be implemented, this implementation is
@@ -9184,155 +9884,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9184 // and eliminates redundant tokenizers as soon 9884 // and eliminates redundant tokenizers as soon
9185 // as is possible. 9885 // as is possible.
9186 // 9886 //
9187 // The implementation tries to avoid any copying 9887 // The implementation tries to minimize temporary
9188 // of arrays or other objects. 9888 // garbage generation.
9189 // </remarks> 9889 // </remarks>
9190 9890
9191 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9891 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9192 { 9892 {
9193 int beginning = 0; 9893 return ParseString2List(src, separators, spacers, true);
9194 int srclen = src.Length; 9894 }
9195 int seplen = separators.Length;
9196 object[] separray = separators.Data;
9197 int spclen = spacers.Length;
9198 object[] spcarray = spacers.Data;
9199 int mlen = seplen+spclen;
9200
9201 int[] offset = new int[mlen+1];
9202 bool[] active = new bool[mlen];
9203
9204 int best;
9205 int j;
9206
9207 // Initial capacity reduces resize cost
9208 9895
9209 LSL_List tokens = new LSL_List(); 9896 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9897 {
9898 int srclen = src.Length;
9899 int seplen = separators.Length;
9900 object[] separray = separators.Data;
9901 int spclen = spacers.Length;
9902 object[] spcarray = spacers.Data;
9903 int dellen = 0;
9904 string[] delarray = new string[seplen+spclen];
9210 9905
9211 // All entries are initially valid 9906 int outlen = 0;
9907 string[] outarray = new string[srclen*2+1];
9212 9908
9213 for (int i = 0; i < mlen; i++) 9909 int i, j;
9214 active[i] = true; 9910 string d;
9215 9911
9216 offset[mlen] = srclen; 9912 m_host.AddScriptLPS(1);
9217 9913
9218 while (beginning < srclen) 9914 /*
9915 * Convert separator and spacer lists to C# strings.
9916 * Also filter out null strings so we don't hang.
9917 */
9918 for (i = 0; i < seplen; i ++)
9219 { 9919 {
9920 d = separray[i].ToString();
9921 if (d.Length > 0)
9922 {
9923 delarray[dellen++] = d;
9924 }
9925 }
9926 seplen = dellen;
9220 9927
9221 best = mlen; // as bad as it gets 9928 for (i = 0; i < spclen; i ++)
9929 {
9930 d = spcarray[i].ToString();
9931 if (d.Length > 0)
9932 {
9933 delarray[dellen++] = d;
9934 }
9935 }
9222 9936
9223 // Scan for separators 9937 /*
9938 * Scan through source string from beginning to end.
9939 */
9940 for (i = 0;;)
9941 {
9224 9942
9225 for (j = 0; j < seplen; j++) 9943 /*
9944 * Find earliest delimeter in src starting at i (if any).
9945 */
9946 int earliestDel = -1;
9947 int earliestSrc = srclen;
9948 string earliestStr = null;
9949 for (j = 0; j < dellen; j ++)
9226 { 9950 {
9227 if (separray[j].ToString() == String.Empty) 9951 d = delarray[j];
9228 active[j] = false; 9952 if (d != null)
9229
9230 if (active[j])
9231 { 9953 {
9232 // scan all of the markers 9954 int index = src.IndexOf(d, i);
9233 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9955 if (index < 0)
9234 { 9956 {
9235 // not present at all 9957 delarray[j] = null; // delim nowhere in src, don't check it anymore
9236 active[j] = false;
9237 } 9958 }
9238 else 9959 else if (index < earliestSrc)
9239 { 9960 {
9240 // present and correct 9961 earliestSrc = index; // where delimeter starts in source string
9241 if (offset[j] < offset[best]) 9962 earliestDel = j; // where delimeter is in delarray[]
9242 { 9963 earliestStr = d; // the delimeter string from delarray[]
9243 // closest so far 9964 if (index == i) break; // can't do any better than found at beg of string
9244 best = j;
9245 if (offset[best] == beginning)
9246 break;
9247 }
9248 } 9965 }
9249 } 9966 }
9250 } 9967 }
9251 9968
9252 // Scan for spacers 9969 /*
9253 9970 * Output source string starting at i through start of earliest delimeter.
9254 if (offset[best] != beginning) 9971 */
9972 if (keepNulls || (earliestSrc > i))
9255 { 9973 {
9256 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9974 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9257 {
9258 if (spcarray[j-seplen].ToString() == String.Empty)
9259 active[j] = false;
9260
9261 if (active[j])
9262 {
9263 // scan all of the markers
9264 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9265 {
9266 // not present at all
9267 active[j] = false;
9268 }
9269 else
9270 {
9271 // present and correct
9272 if (offset[j] < offset[best])
9273 {
9274 // closest so far
9275 best = j;
9276 }
9277 }
9278 }
9279 }
9280 } 9975 }
9281 9976
9282 // This is the normal exit from the scanning loop 9977 /*
9978 * If no delimeter found at or after i, we're done scanning.
9979 */
9980 if (earliestDel < 0) break;
9283 9981
9284 if (best == mlen) 9982 /*
9983 * If delimeter was a spacer, output the spacer.
9984 */
9985 if (earliestDel >= seplen)
9285 { 9986 {
9286 // no markers were found on this pass 9987 outarray[outlen++] = earliestStr;
9287 // so we're pretty much done
9288 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9289 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9290 break;
9291 } 9988 }
9292 9989
9293 // Otherwise we just add the newly delimited token 9990 /*
9294 // and recalculate where the search should continue. 9991 * Look at rest of src string following delimeter.
9295 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9992 */
9296 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9993 i = earliestSrc + earliestStr.Length;
9297
9298 if (best < seplen)
9299 {
9300 beginning = offset[best] + (separray[best].ToString()).Length;
9301 }
9302 else
9303 {
9304 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9305 string str = spcarray[best - seplen].ToString();
9306 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9307 tokens.Add(new LSL_String(str));
9308 }
9309 } 9994 }
9310 9995
9311 // This an awkward an not very intuitive boundary case. If the 9996 /*
9312 // last substring is a tokenizer, then there is an implied trailing 9997 * Make up an exact-sized output array suitable for an LSL_List object.
9313 // null list entry. Hopefully the single comparison will not be too 9998 */
9314 // arduous. Alternatively the 'break' could be replced with a return 9999 object[] outlist = new object[outlen];
9315 // but that's shabby programming. 10000 for (i = 0; i < outlen; i ++)
9316
9317 if ((beginning == srclen) && (keepNulls))
9318 { 10001 {
9319 if (srclen != 0) 10002 outlist[i] = new LSL_String(outarray[i]);
9320 tokens.Add(new LSL_String(""));
9321 } 10003 }
9322 10004 return new LSL_List(outlist);
9323 return tokens;
9324 }
9325
9326 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9327 {
9328 m_host.AddScriptLPS(1);
9329 return this.ParseString(src, separators, spacers, false);
9330 }
9331
9332 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9333 {
9334 m_host.AddScriptLPS(1);
9335 return this.ParseString(src, separators, spacers, true);
9336 } 10005 }
9337 10006
9338 public LSL_Integer llGetObjectPermMask(int mask) 10007 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9427,6 +10096,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9427 case 4: 10096 case 4:
9428 return (int)item.NextPermissions; 10097 return (int)item.NextPermissions;
9429 } 10098 }
10099 m_host.TaskInventory.LockItemsForRead(false);
9430 10100
9431 return -1; 10101 return -1;
9432 } 10102 }
@@ -9630,31 +10300,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9630 UUID key = new UUID(); 10300 UUID key = new UUID();
9631 if (UUID.TryParse(id, out key)) 10301 if (UUID.TryParse(id, out key))
9632 { 10302 {
9633 try 10303 // return total object mass
9634 { 10304 SceneObjectPart part = World.GetSceneObjectPart(key);
9635 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10305 if (part != null)
9636 if (obj != null) 10306 return part.ParentGroup.GetMass();
9637 return (double)obj.GetMass(); 10307
9638 // the object is null so the key is for an avatar 10308 // the object is null so the key is for an avatar
9639 ScenePresence avatar = World.GetScenePresence(key); 10309 ScenePresence avatar = World.GetScenePresence(key);
9640 if (avatar != null) 10310 if (avatar != null)
9641 if (avatar.IsChildAgent)
9642 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9643 // child agents have a mass of 1.0
9644 return 1;
9645 else
9646 return (double)avatar.GetMass();
9647 }
9648 catch (KeyNotFoundException)
9649 { 10311 {
9650 return 0; // The Object/Agent not in the region so just return zero 10312 if (avatar.IsChildAgent)
10313 {
10314 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10315 // child agents have a mass of 1.0
10316 return 1;
10317 }
10318 else
10319 {
10320 return (double)avatar.GetMass();
10321 }
9651 } 10322 }
9652 } 10323 }
9653 return 0; 10324 return 0;
9654 } 10325 }
9655 10326
9656 /// <summary> 10327 /// <summary>
9657 /// illListReplaceList removes the sub-list defined by the inclusive indices 10328 /// llListReplaceList removes the sub-list defined by the inclusive indices
9658 /// start and end and inserts the src list in its place. The inclusive 10329 /// start and end and inserts the src list in its place. The inclusive
9659 /// nature of the indices means that at least one element must be deleted 10330 /// nature of the indices means that at least one element must be deleted
9660 /// if the indices are within the bounds of the existing list. I.e. 2,2 10331 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9711,16 +10382,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9711 // based upon end. Note that if end exceeds the upper 10382 // based upon end. Note that if end exceeds the upper
9712 // bound in this case, the entire destination list 10383 // bound in this case, the entire destination list
9713 // is removed. 10384 // is removed.
9714 else 10385 else if (start == 0)
9715 { 10386 {
9716 if (end + 1 < dest.Length) 10387 if (end + 1 < dest.Length)
9717 {
9718 return src + dest.GetSublist(end + 1, -1); 10388 return src + dest.GetSublist(end + 1, -1);
9719 }
9720 else 10389 else
9721 {
9722 return src; 10390 return src;
9723 } 10391 }
10392 else // Start < 0
10393 {
10394 if (end + 1 < dest.Length)
10395 return dest.GetSublist(end + 1, -1);
10396 else
10397 return new LSL_List();
9724 } 10398 }
9725 } 10399 }
9726 // Finally, if start > end, we strip away a prefix and 10400 // Finally, if start > end, we strip away a prefix and
@@ -9757,7 +10431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9757 // according to the docs, this command only works if script owner and land owner are the same 10431 // according to the docs, this command only works if script owner and land owner are the same
9758 // lets add estate owners and gods, too, and use the generic permission check. 10432 // lets add estate owners and gods, too, and use the generic permission check.
9759 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10433 ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
9760 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia)) return; 10434 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, landObject, GroupPowers.ChangeMedia, false)) return;
9761 10435
9762 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? 10436 bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)?
9763 byte loop = 0; 10437 byte loop = 0;
@@ -9771,17 +10445,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9771 int width = 0; 10445 int width = 0;
9772 int height = 0; 10446 int height = 0;
9773 10447
9774 ParcelMediaCommandEnum? commandToSend = null; 10448 uint commandToSend = 0;
9775 float time = 0.0f; // default is from start 10449 float time = 0.0f; // default is from start
9776 10450
9777 ScenePresence presence = null; 10451 ScenePresence presence = null;
9778 10452
9779 for (int i = 0; i < commandList.Data.Length; i++) 10453 for (int i = 0; i < commandList.Data.Length; i++)
9780 { 10454 {
9781 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10455 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9782 switch (command) 10456 switch (command)
9783 { 10457 {
9784 case ParcelMediaCommandEnum.Agent: 10458 case (uint)ParcelMediaCommandEnum.Agent:
9785 // we send only to one agent 10459 // we send only to one agent
9786 if ((i + 1) < commandList.Length) 10460 if ((i + 1) < commandList.Length)
9787 { 10461 {
@@ -9798,25 +10472,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9798 } 10472 }
9799 break; 10473 break;
9800 10474
9801 case ParcelMediaCommandEnum.Loop: 10475 case (uint)ParcelMediaCommandEnum.Loop:
9802 loop = 1; 10476 loop = 1;
9803 commandToSend = command; 10477 commandToSend = command;
9804 update = true; //need to send the media update packet to set looping 10478 update = true; //need to send the media update packet to set looping
9805 break; 10479 break;
9806 10480
9807 case ParcelMediaCommandEnum.Play: 10481 case (uint)ParcelMediaCommandEnum.Play:
9808 loop = 0; 10482 loop = 0;
9809 commandToSend = command; 10483 commandToSend = command;
9810 update = true; //need to send the media update packet to make sure it doesn't loop 10484 update = true; //need to send the media update packet to make sure it doesn't loop
9811 break; 10485 break;
9812 10486
9813 case ParcelMediaCommandEnum.Pause: 10487 case (uint)ParcelMediaCommandEnum.Pause:
9814 case ParcelMediaCommandEnum.Stop: 10488 case (uint)ParcelMediaCommandEnum.Stop:
9815 case ParcelMediaCommandEnum.Unload: 10489 case (uint)ParcelMediaCommandEnum.Unload:
9816 commandToSend = command; 10490 commandToSend = command;
9817 break; 10491 break;
9818 10492
9819 case ParcelMediaCommandEnum.Url: 10493 case (uint)ParcelMediaCommandEnum.Url:
9820 if ((i + 1) < commandList.Length) 10494 if ((i + 1) < commandList.Length)
9821 { 10495 {
9822 if (commandList.Data[i + 1] is LSL_String) 10496 if (commandList.Data[i + 1] is LSL_String)
@@ -9829,7 +10503,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9829 } 10503 }
9830 break; 10504 break;
9831 10505
9832 case ParcelMediaCommandEnum.Texture: 10506 case (uint)ParcelMediaCommandEnum.Texture:
9833 if ((i + 1) < commandList.Length) 10507 if ((i + 1) < commandList.Length)
9834 { 10508 {
9835 if (commandList.Data[i + 1] is LSL_String) 10509 if (commandList.Data[i + 1] is LSL_String)
@@ -9842,7 +10516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9842 } 10516 }
9843 break; 10517 break;
9844 10518
9845 case ParcelMediaCommandEnum.Time: 10519 case (uint)ParcelMediaCommandEnum.Time:
9846 if ((i + 1) < commandList.Length) 10520 if ((i + 1) < commandList.Length)
9847 { 10521 {
9848 if (commandList.Data[i + 1] is LSL_Float) 10522 if (commandList.Data[i + 1] is LSL_Float)
@@ -9854,7 +10528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9854 } 10528 }
9855 break; 10529 break;
9856 10530
9857 case ParcelMediaCommandEnum.AutoAlign: 10531 case (uint)ParcelMediaCommandEnum.AutoAlign:
9858 if ((i + 1) < commandList.Length) 10532 if ((i + 1) < commandList.Length)
9859 { 10533 {
9860 if (commandList.Data[i + 1] is LSL_Integer) 10534 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9868,7 +10542,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9868 } 10542 }
9869 break; 10543 break;
9870 10544
9871 case ParcelMediaCommandEnum.Type: 10545 case (uint)ParcelMediaCommandEnum.Type:
9872 if ((i + 1) < commandList.Length) 10546 if ((i + 1) < commandList.Length)
9873 { 10547 {
9874 if (commandList.Data[i + 1] is LSL_String) 10548 if (commandList.Data[i + 1] is LSL_String)
@@ -9881,7 +10555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9881 } 10555 }
9882 break; 10556 break;
9883 10557
9884 case ParcelMediaCommandEnum.Desc: 10558 case (uint)ParcelMediaCommandEnum.Desc:
9885 if ((i + 1) < commandList.Length) 10559 if ((i + 1) < commandList.Length)
9886 { 10560 {
9887 if (commandList.Data[i + 1] is LSL_String) 10561 if (commandList.Data[i + 1] is LSL_String)
@@ -9894,7 +10568,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9894 } 10568 }
9895 break; 10569 break;
9896 10570
9897 case ParcelMediaCommandEnum.Size: 10571 case (uint)ParcelMediaCommandEnum.Size:
9898 if ((i + 2) < commandList.Length) 10572 if ((i + 2) < commandList.Length)
9899 { 10573 {
9900 if (commandList.Data[i + 1] is LSL_Integer) 10574 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9964,7 +10638,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9964 } 10638 }
9965 } 10639 }
9966 10640
9967 if (commandToSend != null) 10641 if (commandToSend != 0)
9968 { 10642 {
9969 // the commandList contained a start/stop/... command, too 10643 // the commandList contained a start/stop/... command, too
9970 if (presence == null) 10644 if (presence == null)
@@ -10001,7 +10675,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10001 10675
10002 if (aList.Data[i] != null) 10676 if (aList.Data[i] != null)
10003 { 10677 {
10004 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10678 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10005 { 10679 {
10006 case ParcelMediaCommandEnum.Url: 10680 case ParcelMediaCommandEnum.Url:
10007 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10681 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10058,15 +10732,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10058 10732
10059 if (quick_pay_buttons.Data.Length < 4) 10733 if (quick_pay_buttons.Data.Length < 4)
10060 { 10734 {
10061 LSLError("List must have at least 4 elements"); 10735 int x;
10062 return; 10736 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10737 {
10738 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10739 }
10063 } 10740 }
10064 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10741 int[] nPrice = new int[5];
10065 10742 nPrice[0] = price;
10066 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10743 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10067 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10744 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10068 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10745 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10069 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10746 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10747 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10070 m_host.ParentGroup.HasGroupChanged = true; 10748 m_host.ParentGroup.HasGroupChanged = true;
10071 } 10749 }
10072 10750
@@ -10083,7 +10761,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10083 return Vector3.Zero; 10761 return Vector3.Zero;
10084 } 10762 }
10085 10763
10086 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10764// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10765 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10087 if (presence != null) 10766 if (presence != null)
10088 { 10767 {
10089 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10768 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10106,7 +10785,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10106 return Quaternion.Identity; 10785 return Quaternion.Identity;
10107 } 10786 }
10108 10787
10109 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10788// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10789 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10110 if (presence != null) 10790 if (presence != null)
10111 { 10791 {
10112 return new LSL_Rotation(presence.CameraRotation); 10792 return new LSL_Rotation(presence.CameraRotation);
@@ -10166,14 +10846,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10166 { 10846 {
10167 m_host.AddScriptLPS(1); 10847 m_host.AddScriptLPS(1);
10168 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10848 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10169 if (detectedParams == null) return; // only works on the first detected avatar 10849 if (detectedParams == null)
10170 10850 {
10851 if (m_host.ParentGroup.IsAttachment == true)
10852 {
10853 detectedParams = new DetectParams();
10854 detectedParams.Key = m_host.OwnerID;
10855 }
10856 else
10857 {
10858 return;
10859 }
10860 }
10861
10171 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10862 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10172 if (avatar != null) 10863 if (avatar != null)
10173 { 10864 {
10174 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10865 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10175 simname, pos, lookAt); 10866 simname, pos, lookAt);
10176 } 10867 }
10868
10177 ScriptSleep(1000); 10869 ScriptSleep(1000);
10178 } 10870 }
10179 10871
@@ -10182,7 +10874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10182 m_host.AddScriptLPS(1); 10874 m_host.AddScriptLPS(1);
10183 UUID key; 10875 UUID key;
10184 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10876 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10185 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10877 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
10186 { 10878 {
10187 int expires = 0; 10879 int expires = 0;
10188 if (hours != 0) 10880 if (hours != 0)
@@ -10223,7 +10915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10223 m_host.AddScriptLPS(1); 10915 m_host.AddScriptLPS(1);
10224 UUID key; 10916 UUID key;
10225 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10917 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10226 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed)) 10918 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageAllowed, false))
10227 { 10919 {
10228 if (UUID.TryParse(avatar, out key)) 10920 if (UUID.TryParse(avatar, out key))
10229 { 10921 {
@@ -10250,7 +10942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10250 m_host.AddScriptLPS(1); 10942 m_host.AddScriptLPS(1);
10251 UUID key; 10943 UUID key;
10252 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition); 10944 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
10253 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned)) 10945 if (World.Permissions.CanEditParcelProperties(m_host.OwnerID, land, GroupPowers.LandManageBanned, false))
10254 { 10946 {
10255 if (UUID.TryParse(avatar, out key)) 10947 if (UUID.TryParse(avatar, out key))
10256 { 10948 {
@@ -10297,12 +10989,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10297 10989
10298 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10990 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10299 object[] data = rules.Data; 10991 object[] data = rules.Data;
10300 for (int i = 0; i < data.Length; ++i) { 10992 for (int i = 0; i < data.Length; ++i)
10993 {
10301 int type = Convert.ToInt32(data[i++].ToString()); 10994 int type = Convert.ToInt32(data[i++].ToString());
10302 if (i >= data.Length) break; // odd number of entries => ignore the last 10995 if (i >= data.Length) break; // odd number of entries => ignore the last
10303 10996
10304 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10997 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10305 switch (type) { 10998 switch (type)
10999 {
10306 case ScriptBaseClass.CAMERA_FOCUS: 11000 case ScriptBaseClass.CAMERA_FOCUS:
10307 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11001 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10308 case ScriptBaseClass.CAMERA_POSITION: 11002 case ScriptBaseClass.CAMERA_POSITION:
@@ -10407,19 +11101,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10407 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11101 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10408 { 11102 {
10409 m_host.AddScriptLPS(1); 11103 m_host.AddScriptLPS(1);
10410 string ret = String.Empty; 11104
10411 string src1 = llBase64ToString(str1); 11105 if (str1 == String.Empty)
10412 string src2 = llBase64ToString(str2); 11106 return String.Empty;
10413 int c = 0; 11107 if (str2 == String.Empty)
10414 for (int i = 0; i < src1.Length; i++) 11108 return str1;
11109
11110 int len = str2.Length;
11111 if ((len % 4) != 0) // LL is EVIL!!!!
11112 {
11113 while (str2.EndsWith("="))
11114 str2 = str2.Substring(0, str2.Length - 1);
11115
11116 len = str2.Length;
11117 int mod = len % 4;
11118
11119 if (mod == 1)
11120 str2 = str2.Substring(0, str2.Length - 1);
11121 else if (mod == 2)
11122 str2 += "==";
11123 else if (mod == 3)
11124 str2 += "=";
11125 }
11126
11127 byte[] data1;
11128 byte[] data2;
11129 try
11130 {
11131 data1 = Convert.FromBase64String(str1);
11132 data2 = Convert.FromBase64String(str2);
11133 }
11134 catch (Exception)
11135 {
11136 return new LSL_String(String.Empty);
11137 }
11138
11139 byte[] d2 = new Byte[data1.Length];
11140 int pos = 0;
11141
11142 if (data1.Length <= data2.Length)
11143 {
11144 Array.Copy(data2, 0, d2, 0, data1.Length);
11145 }
11146 else
10415 { 11147 {
10416 ret += (char) (src1[i] ^ src2[c]); 11148 while (pos < data1.Length)
11149 {
11150 len = data1.Length - pos;
11151 if (len > data2.Length)
11152 len = data2.Length;
10417 11153
10418 c++; 11154 Array.Copy(data2, 0, d2, pos, len);
10419 if (c >= src2.Length) 11155 pos += len;
10420 c = 0; 11156 }
10421 } 11157 }
10422 return llStringToBase64(ret); 11158
11159 for (pos = 0 ; pos < data1.Length ; pos++ )
11160 data1[pos] ^= d2[pos];
11161
11162 return Convert.ToBase64String(data1);
10423 } 11163 }
10424 11164
10425 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11165 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10523,16 +11263,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10523 if (userAgent != null) 11263 if (userAgent != null)
10524 httpHeaders["User-Agent"] = userAgent; 11264 httpHeaders["User-Agent"] = userAgent;
10525 11265
11266 // See if the URL contains any header hacks
11267 string[] urlParts = url.Split(new char[] {'\n'});
11268 if (urlParts.Length > 1)
11269 {
11270 // Iterate the passed headers and parse them
11271 for (int i = 1 ; i < urlParts.Length ; i++ )
11272 {
11273 // The rest of those would be added to the body in SL.
11274 // Let's not do that.
11275 if (urlParts[i] == String.Empty)
11276 break;
11277
11278 // See if this could be a valid header
11279 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11280 if (headerParts.Length != 2)
11281 continue;
11282
11283 string headerName = headerParts[0].Trim();
11284 string headerValue = headerParts[1].Trim();
11285
11286 // Filter out headers that could be used to abuse
11287 // another system or cloak the request
11288 if (headerName.ToLower() == "x-secondlife-shard" ||
11289 headerName.ToLower() == "x-secondlife-object-name" ||
11290 headerName.ToLower() == "x-secondlife-object-key" ||
11291 headerName.ToLower() == "x-secondlife-region" ||
11292 headerName.ToLower() == "x-secondlife-local-position" ||
11293 headerName.ToLower() == "x-secondlife-local-velocity" ||
11294 headerName.ToLower() == "x-secondlife-local-rotation" ||
11295 headerName.ToLower() == "x-secondlife-owner-name" ||
11296 headerName.ToLower() == "x-secondlife-owner-key" ||
11297 headerName.ToLower() == "connection" ||
11298 headerName.ToLower() == "content-length" ||
11299 headerName.ToLower() == "from" ||
11300 headerName.ToLower() == "host" ||
11301 headerName.ToLower() == "proxy-authorization" ||
11302 headerName.ToLower() == "referer" ||
11303 headerName.ToLower() == "trailer" ||
11304 headerName.ToLower() == "transfer-encoding" ||
11305 headerName.ToLower() == "via" ||
11306 headerName.ToLower() == "authorization")
11307 continue;
11308
11309 httpHeaders[headerName] = headerValue;
11310 }
11311
11312 // Finally, strip any protocol specifier from the URL
11313 url = urlParts[0].Trim();
11314 int idx = url.IndexOf(" HTTP/");
11315 if (idx != -1)
11316 url = url.Substring(0, idx);
11317 }
11318
10526 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11319 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10527 Regex r = new Regex(authregex); 11320 Regex r = new Regex(authregex);
10528 int[] gnums = r.GetGroupNumbers(); 11321 int[] gnums = r.GetGroupNumbers();
10529 Match m = r.Match(url); 11322 Match m = r.Match(url);
10530 if (m.Success) { 11323 if (m.Success)
10531 for (int i = 1; i < gnums.Length; i++) { 11324 {
11325 for (int i = 1; i < gnums.Length; i++)
11326 {
10532 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11327 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10533 //CaptureCollection cc = g.Captures; 11328 //CaptureCollection cc = g.Captures;
10534 } 11329 }
10535 if (m.Groups.Count == 5) { 11330 if (m.Groups.Count == 5)
11331 {
10536 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11332 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10537 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11333 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10538 } 11334 }
@@ -10735,6 +11531,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10735 11531
10736 LSL_List ret = new LSL_List(); 11532 LSL_List ret = new LSL_List();
10737 UUID key = new UUID(); 11533 UUID key = new UUID();
11534
11535
10738 if (UUID.TryParse(id, out key)) 11536 if (UUID.TryParse(id, out key))
10739 { 11537 {
10740 ScenePresence av = World.GetScenePresence(key); 11538 ScenePresence av = World.GetScenePresence(key);
@@ -10752,13 +11550,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10752 ret.Add(new LSL_String("")); 11550 ret.Add(new LSL_String(""));
10753 break; 11551 break;
10754 case ScriptBaseClass.OBJECT_POS: 11552 case ScriptBaseClass.OBJECT_POS:
10755 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11553 Vector3 avpos;
11554
11555 if (av.ParentID != 0 && av.ParentPart != null)
11556 {
11557 avpos = av.OffsetPosition;
11558
11559 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11560 avpos -= sitOffset;
11561
11562 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11563 }
11564 else
11565 avpos = av.AbsolutePosition;
11566
11567 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10756 break; 11568 break;
10757 case ScriptBaseClass.OBJECT_ROT: 11569 case ScriptBaseClass.OBJECT_ROT:
10758 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11570 Quaternion avrot = av.Rotation;
11571 if (av.ParentID != 0 && av.ParentPart != null)
11572 {
11573 avrot = av.ParentPart.GetWorldRotation() * avrot;
11574 }
11575 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10759 break; 11576 break;
10760 case ScriptBaseClass.OBJECT_VELOCITY: 11577 case ScriptBaseClass.OBJECT_VELOCITY:
10761 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11578 Vector3 avvel = av.Velocity;
11579 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10762 break; 11580 break;
10763 case ScriptBaseClass.OBJECT_OWNER: 11581 case ScriptBaseClass.OBJECT_OWNER:
10764 ret.Add(new LSL_String(id)); 11582 ret.Add(new LSL_String(id));
@@ -10843,11 +11661,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10843 case ScriptBaseClass.OBJECT_NAME: 11661 case ScriptBaseClass.OBJECT_NAME:
10844 ret.Add(new LSL_String(obj.Name)); 11662 ret.Add(new LSL_String(obj.Name));
10845 break; 11663 break;
10846 case ScriptBaseClass.OBJECT_DESC: 11664 case ScriptBaseClass.OBJECT_DESC:
10847 ret.Add(new LSL_String(obj.Description)); 11665 ret.Add(new LSL_String(obj.Description));
10848 break; 11666 break;
10849 case ScriptBaseClass.OBJECT_POS: 11667 case ScriptBaseClass.OBJECT_POS:
10850 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11668 Vector3 opos = obj.AbsolutePosition;
11669 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10851 break; 11670 break;
10852 case ScriptBaseClass.OBJECT_ROT: 11671 case ScriptBaseClass.OBJECT_ROT:
10853 { 11672 {
@@ -10897,9 +11716,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10897 // The value returned in SL for normal prims is prim count 11716 // The value returned in SL for normal prims is prim count
10898 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11717 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10899 break; 11718 break;
10900 // The following 3 costs I have intentionaly coded to return zero. They are part of 11719
10901 // "Land Impact" calculations. These calculations are probably not applicable 11720 // costs below may need to be diferent for root parts, need to check
10902 // to OpenSim and are not yet complete in SL
10903 case ScriptBaseClass.OBJECT_SERVER_COST: 11721 case ScriptBaseClass.OBJECT_SERVER_COST:
10904 // The linden calculation is here 11722 // The linden calculation is here
10905 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11723 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10907,16 +11725,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10907 ret.Add(new LSL_Float(0)); 11725 ret.Add(new LSL_Float(0));
10908 break; 11726 break;
10909 case ScriptBaseClass.OBJECT_STREAMING_COST: 11727 case ScriptBaseClass.OBJECT_STREAMING_COST:
10910 // The linden calculation is here 11728 // The value returned in SL for normal prims is prim count * 0.06
10911 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11729 ret.Add(new LSL_Float(obj.StreamingCost));
10912 // The value returned in SL for normal prims looks like the prim count * 0.06
10913 ret.Add(new LSL_Float(0));
10914 break; 11730 break;
10915 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11731 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10916 // The linden calculation is here 11732 // The value returned in SL for normal prims is prim count
10917 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11733 ret.Add(new LSL_Float(obj.PhysicsCost));
10918 // The value returned in SL for normal prims looks like the prim count
10919 ret.Add(new LSL_Float(0));
10920 break; 11734 break;
10921 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11735 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10922 ret.Add(new LSL_Float(0)); 11736 ret.Add(new LSL_Float(0));
@@ -11175,15 +11989,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11175 return result; 11989 return result;
11176 } 11990 }
11177 11991
11178 public void print(string str) 11992 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11179 { 11993 {
11180 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11994 List<SceneObjectPart> parts = GetLinkParts(link);
11181 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11995 if (parts.Count < 1)
11182 if (ossl != null) 11996 return 0;
11183 { 11997
11184 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11998 return GetNumberOfSides(parts[0]);
11185 m_log.Info("LSL print():" + str);
11186 }
11187 } 11999 }
11188 12000
11189 private string Name2Username(string name) 12001 private string Name2Username(string name)
@@ -11228,7 +12040,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11228 12040
11229 return rq.ToString(); 12041 return rq.ToString();
11230 } 12042 }
11231 12043/*
12044 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12045 {
12046 m_SayShoutCount = 0;
12047 }
12048*/
11232 private struct Tri 12049 private struct Tri
11233 { 12050 {
11234 public Vector3 p1; 12051 public Vector3 p1;
@@ -11377,9 +12194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11377 12194
11378 ContactResult result = new ContactResult (); 12195 ContactResult result = new ContactResult ();
11379 result.ConsumerID = group.LocalId; 12196 result.ConsumerID = group.LocalId;
11380 result.Depth = intersection.distance; 12197// result.Depth = intersection.distance;
11381 result.Normal = intersection.normal; 12198 result.Normal = intersection.normal;
11382 result.Pos = intersection.ipoint; 12199 result.Pos = intersection.ipoint;
12200 result.Depth = Vector3.Mag(rayStart - result.Pos);
11383 12201
11384 contacts.Add(result); 12202 contacts.Add(result);
11385 }); 12203 });
@@ -11512,6 +12330,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11512 12330
11513 return contacts[0]; 12331 return contacts[0];
11514 } 12332 }
12333/*
12334 // not done:
12335 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12336 {
12337 ContactResult[] contacts = null;
12338 World.ForEachSOG(delegate(SceneObjectGroup group)
12339 {
12340 if (m_host.ParentGroup == group)
12341 return;
12342
12343 if (group.IsAttachment)
12344 return;
12345
12346 if(group.RootPart.PhysActor != null)
12347 return;
12348
12349 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12350 });
12351 return contacts;
12352 }
12353*/
11515 12354
11516 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12355 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11517 { 12356 {
@@ -11635,18 +12474,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11635 } 12474 }
11636 } 12475 }
11637 12476
12477 // Double check this
11638 if (checkTerrain) 12478 if (checkTerrain)
11639 { 12479 {
11640 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12480 bool skipGroundCheck = false;
11641 if (groundContact != null) 12481
11642 results.Add((ContactResult)groundContact); 12482 foreach (ContactResult c in results)
12483 {
12484 if (c.ConsumerID == 0) // Physics gave us a ground collision
12485 skipGroundCheck = true;
12486 }
12487
12488 if (!skipGroundCheck)
12489 {
12490 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12491 if (groundContact != null)
12492 results.Add((ContactResult)groundContact);
12493 }
11643 } 12494 }
11644 12495
11645 results.Sort(delegate(ContactResult a, ContactResult b) 12496 results.Sort(delegate(ContactResult a, ContactResult b)
11646 { 12497 {
11647 return a.Depth.CompareTo(b.Depth); 12498 return a.Depth.CompareTo(b.Depth);
11648 }); 12499 });
11649 12500
11650 int values = 0; 12501 int values = 0;
11651 SceneObjectGroup thisgrp = m_host.ParentGroup; 12502 SceneObjectGroup thisgrp = m_host.ParentGroup;
11652 12503
@@ -11739,7 +12590,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11739 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12590 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11740 if (!isAccount) return 0; 12591 if (!isAccount) return 0;
11741 if (estate.HasAccess(id)) return 1; 12592 if (estate.HasAccess(id)) return 1;
11742 if (estate.IsBanned(id)) 12593 if (estate.IsBanned(id, World.GetUserFlags(id)))
11743 estate.RemoveBan(id); 12594 estate.RemoveBan(id);
11744 estate.AddEstateUser(id); 12595 estate.AddEstateUser(id);
11745 break; 12596 break;
@@ -11758,14 +12609,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11758 break; 12609 break;
11759 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12610 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11760 if (!isAccount) return 0; 12611 if (!isAccount) return 0;
11761 if (estate.IsBanned(id)) return 1; 12612 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11762 EstateBan ban = new EstateBan(); 12613 EstateBan ban = new EstateBan();
11763 ban.EstateID = estate.EstateID; 12614 ban.EstateID = estate.EstateID;
11764 ban.BannedUserID = id; 12615 ban.BannedUserID = id;
11765 estate.AddBan(ban); 12616 estate.AddBan(ban);
11766 break; 12617 break;
11767 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12618 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11768 if (!isAccount || !estate.IsBanned(id)) return 0; 12619 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11769 estate.RemoveBan(id); 12620 estate.RemoveBan(id);
11770 break; 12621 break;
11771 default: return 0; 12622 default: return 0;
@@ -11822,19 +12673,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11822 public void llSetSoundQueueing(int queue) 12673 public void llSetSoundQueueing(int queue)
11823 { 12674 {
11824 m_host.AddScriptLPS(1); 12675 m_host.AddScriptLPS(1);
11825 NotImplemented("llSetSoundQueueing");
11826 } 12676 }
11827 12677
11828 public void llCollisionSprite(string impact_sprite) 12678 public void llCollisionSprite(string impact_sprite)
11829 { 12679 {
11830 m_host.AddScriptLPS(1); 12680 m_host.AddScriptLPS(1);
11831 NotImplemented("llCollisionSprite"); 12681 // Viewer 2.0 broke this and it's likely LL has no intention
12682 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11832 } 12683 }
11833 12684
11834 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12685 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11835 { 12686 {
11836 m_host.AddScriptLPS(1); 12687 m_host.AddScriptLPS(1);
11837 NotImplemented("llGodLikeRezObject"); 12688
12689 if (!World.Permissions.IsGod(m_host.OwnerID))
12690 NotImplemented("llGodLikeRezObject");
12691
12692 AssetBase rezAsset = World.AssetService.Get(inventory);
12693 if (rezAsset == null)
12694 {
12695 llSay(0, "Asset not found");
12696 return;
12697 }
12698
12699 SceneObjectGroup group = null;
12700
12701 try
12702 {
12703 string xmlData = Utils.BytesToString(rezAsset.Data);
12704 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12705 }
12706 catch
12707 {
12708 llSay(0, "Asset not found");
12709 return;
12710 }
12711
12712 if (group == null)
12713 {
12714 llSay(0, "Asset not found");
12715 return;
12716 }
12717
12718 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12719 group.RootPart.AttachOffset = group.AbsolutePosition;
12720
12721 group.ResetIDs();
12722
12723 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12724 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12725 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12726 group.ScheduleGroupForFullUpdate();
12727
12728 // objects rezzed with this method are die_at_edge by default.
12729 group.RootPart.SetDieAtEdge(true);
12730
12731 group.ResumeScripts();
12732
12733 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12734 "object_rez", new Object[] {
12735 new LSL_String(
12736 group.RootPart.UUID.ToString()) },
12737 new DetectParams[0]));
11838 } 12738 }
11839 12739
11840 public LSL_String llTransferLindenDollars(string destination, int amount) 12740 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11885,8 +12785,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11885 return; 12785 return;
11886 } 12786 }
11887 12787
12788 string reason;
11888 bool result = money.ObjectGiveMoney( 12789 bool result = money.ObjectGiveMoney(
11889 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12790 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
11890 12791
11891 if (result) 12792 if (result)
11892 { 12793 {
@@ -11894,7 +12795,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11894 return; 12795 return;
11895 } 12796 }
11896 12797
11897 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 12798 replydata = reason;
11898 } 12799 }
11899 finally 12800 finally
11900 { 12801 {
@@ -11911,6 +12812,610 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11911 } 12812 }
11912 12813
11913 #endregion 12814 #endregion
12815
12816 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12817 {
12818 SceneObjectGroup group = m_host.ParentGroup;
12819
12820 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12821 return;
12822 if (group.IsAttachment)
12823 return;
12824
12825 if (frames.Data.Length > 0) // We are getting a new motion
12826 {
12827 if (group.RootPart.KeyframeMotion != null)
12828 group.RootPart.KeyframeMotion.Delete();
12829 group.RootPart.KeyframeMotion = null;
12830
12831 int idx = 0;
12832
12833 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12834 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12835
12836 while (idx < options.Data.Length)
12837 {
12838 int option = (int)options.GetLSLIntegerItem(idx++);
12839 int remain = options.Data.Length - idx;
12840
12841 switch (option)
12842 {
12843 case ScriptBaseClass.KFM_MODE:
12844 if (remain < 1)
12845 break;
12846 int modeval = (int)options.GetLSLIntegerItem(idx++);
12847 switch(modeval)
12848 {
12849 case ScriptBaseClass.KFM_FORWARD:
12850 mode = KeyframeMotion.PlayMode.Forward;
12851 break;
12852 case ScriptBaseClass.KFM_REVERSE:
12853 mode = KeyframeMotion.PlayMode.Reverse;
12854 break;
12855 case ScriptBaseClass.KFM_LOOP:
12856 mode = KeyframeMotion.PlayMode.Loop;
12857 break;
12858 case ScriptBaseClass.KFM_PING_PONG:
12859 mode = KeyframeMotion.PlayMode.PingPong;
12860 break;
12861 }
12862 break;
12863 case ScriptBaseClass.KFM_DATA:
12864 if (remain < 1)
12865 break;
12866 int dataval = (int)options.GetLSLIntegerItem(idx++);
12867 data = (KeyframeMotion.DataFormat)dataval;
12868 break;
12869 }
12870 }
12871
12872 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12873
12874 idx = 0;
12875
12876 int elemLength = 2;
12877 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12878 elemLength = 3;
12879
12880 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12881 while (idx < frames.Data.Length)
12882 {
12883 int remain = frames.Data.Length - idx;
12884
12885 if (remain < elemLength)
12886 break;
12887
12888 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12889 frame.Position = null;
12890 frame.Rotation = null;
12891
12892 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12893 {
12894 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12895 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12896 }
12897 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12898 {
12899 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12900 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12901 q.Normalize();
12902 frame.Rotation = q;
12903 }
12904
12905 float tempf = (float)frames.GetLSLFloatItem(idx++);
12906 frame.TimeMS = (int)(tempf * 1000.0f);
12907
12908 keyframes.Add(frame);
12909 }
12910
12911 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12912 group.RootPart.KeyframeMotion.Start();
12913 }
12914 else
12915 {
12916 if (group.RootPart.KeyframeMotion == null)
12917 return;
12918
12919 if (options.Data.Length == 0)
12920 {
12921 group.RootPart.KeyframeMotion.Stop();
12922 return;
12923 }
12924
12925 int code = (int)options.GetLSLIntegerItem(0);
12926
12927 int idx = 0;
12928
12929 while (idx < options.Data.Length)
12930 {
12931 int option = (int)options.GetLSLIntegerItem(idx++);
12932 int remain = options.Data.Length - idx;
12933
12934 switch (option)
12935 {
12936 case ScriptBaseClass.KFM_COMMAND:
12937 int cmd = (int)options.GetLSLIntegerItem(idx++);
12938 switch (cmd)
12939 {
12940 case ScriptBaseClass.KFM_CMD_PLAY:
12941 group.RootPart.KeyframeMotion.Start();
12942 break;
12943 case ScriptBaseClass.KFM_CMD_STOP:
12944 group.RootPart.KeyframeMotion.Stop();
12945 break;
12946 case ScriptBaseClass.KFM_CMD_PAUSE:
12947 group.RootPart.KeyframeMotion.Pause();
12948 break;
12949 }
12950 break;
12951 }
12952 }
12953 }
12954 }
12955
12956 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12957 {
12958 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12959
12960 int idx = 0;
12961 int idxStart = 0;
12962
12963 bool positionChanged = false;
12964 Vector3 finalPos = Vector3.Zero;
12965
12966 try
12967 {
12968 while (idx < rules.Length)
12969 {
12970 ++rulesParsed;
12971 int code = rules.GetLSLIntegerItem(idx++);
12972
12973 int remain = rules.Length - idx;
12974 idxStart = idx;
12975
12976 switch (code)
12977 {
12978 case (int)ScriptBaseClass.PRIM_POSITION:
12979 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12980 {
12981 if (remain < 1)
12982 return null;
12983
12984 LSL_Vector v;
12985 v = rules.GetVector3Item(idx++);
12986
12987 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12988 if (part == null)
12989 break;
12990
12991 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12992 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12993 if (part.LinkNum > 1)
12994 {
12995 localRot = GetPartLocalRot(part);
12996 localPos = GetPartLocalPos(part);
12997 }
12998
12999 v -= localPos;
13000 v /= localRot;
13001
13002 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
13003
13004 v = v + 2 * sitOffset;
13005
13006 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
13007 av.SendAvatarDataToAllAgents();
13008
13009 }
13010 break;
13011
13012 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13013 case (int)ScriptBaseClass.PRIM_ROTATION:
13014 {
13015 if (remain < 1)
13016 return null;
13017
13018 LSL_Rotation r;
13019 r = rules.GetQuaternionItem(idx++);
13020
13021 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13022 if (part == null)
13023 break;
13024
13025 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13026 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13027
13028 if (part.LinkNum > 1)
13029 localRot = GetPartLocalRot(part);
13030
13031 r = r * llGetRootRotation() / localRot;
13032 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13033 av.SendAvatarDataToAllAgents();
13034 }
13035 break;
13036
13037 // parse rest doing nothing but number of parameters error check
13038 case (int)ScriptBaseClass.PRIM_SIZE:
13039 case (int)ScriptBaseClass.PRIM_MATERIAL:
13040 case (int)ScriptBaseClass.PRIM_PHANTOM:
13041 case (int)ScriptBaseClass.PRIM_PHYSICS:
13042 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13043 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13044 case (int)ScriptBaseClass.PRIM_NAME:
13045 case (int)ScriptBaseClass.PRIM_DESC:
13046 if (remain < 1)
13047 return null;
13048 idx++;
13049 break;
13050
13051 case (int)ScriptBaseClass.PRIM_GLOW:
13052 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13053 case (int)ScriptBaseClass.PRIM_TEXGEN:
13054 if (remain < 2)
13055 return null;
13056 idx += 2;
13057 break;
13058
13059 case (int)ScriptBaseClass.PRIM_TYPE:
13060 if (remain < 3)
13061 return null;
13062 code = (int)rules.GetLSLIntegerItem(idx++);
13063 remain = rules.Length - idx;
13064 switch (code)
13065 {
13066 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13067 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13068 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13069 if (remain < 6)
13070 return null;
13071 idx += 6;
13072 break;
13073
13074 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13075 if (remain < 5)
13076 return null;
13077 idx += 5;
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13081 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13082 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13083 if (remain < 11)
13084 return null;
13085 idx += 11;
13086 break;
13087
13088 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13089 if (remain < 2)
13090 return null;
13091 idx += 2;
13092 break;
13093 }
13094 break;
13095
13096 case (int)ScriptBaseClass.PRIM_COLOR:
13097 case (int)ScriptBaseClass.PRIM_TEXT:
13098 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13099 case (int)ScriptBaseClass.PRIM_OMEGA:
13100 if (remain < 3)
13101 return null;
13102 idx += 3;
13103 break;
13104
13105 case (int)ScriptBaseClass.PRIM_TEXTURE:
13106 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13107 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13108 if (remain < 5)
13109 return null;
13110 idx += 5;
13111 break;
13112
13113 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13114 if (remain < 7)
13115 return null;
13116
13117 idx += 7;
13118 break;
13119
13120 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13121 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13122 return null;
13123
13124 return rules.GetSublist(idx, -1);
13125 }
13126 }
13127 }
13128 catch (InvalidCastException e)
13129 {
13130 ShoutError(string.Format(
13131 "{0} error running rule #{1}: arg #{2} ",
13132 originFunc, rulesParsed, idx - idxStart) + e.Message);
13133 }
13134 finally
13135 {
13136 if (positionChanged)
13137 {
13138 av.OffsetPosition = finalPos;
13139// av.SendAvatarDataToAllAgents();
13140 av.SendTerseUpdateToAllClients();
13141 positionChanged = false;
13142 }
13143 }
13144 return null;
13145 }
13146
13147 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13148 {
13149 // avatars case
13150 // replies as SL wiki
13151
13152// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13153 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13154
13155 int idx = 0;
13156 while (idx < rules.Length)
13157 {
13158 int code = (int)rules.GetLSLIntegerItem(idx++);
13159 int remain = rules.Length - idx;
13160
13161 switch (code)
13162 {
13163 case (int)ScriptBaseClass.PRIM_MATERIAL:
13164 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13165 break;
13166
13167 case (int)ScriptBaseClass.PRIM_PHYSICS:
13168 res.Add(new LSL_Integer(0));
13169 break;
13170
13171 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13172 res.Add(new LSL_Integer(0));
13173 break;
13174
13175 case (int)ScriptBaseClass.PRIM_PHANTOM:
13176 res.Add(new LSL_Integer(0));
13177 break;
13178
13179 case (int)ScriptBaseClass.PRIM_POSITION:
13180
13181 Vector3 pos = avatar.OffsetPosition;
13182
13183 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13184 pos -= sitOffset;
13185
13186 if( sitPart != null)
13187 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13188
13189 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13190 break;
13191
13192 case (int)ScriptBaseClass.PRIM_SIZE:
13193 // as in llGetAgentSize above
13194// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13195 Vector3 s = avatar.Appearance.AvatarSize;
13196 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13197
13198 break;
13199
13200 case (int)ScriptBaseClass.PRIM_ROTATION:
13201 Quaternion rot = avatar.Rotation;
13202 if (sitPart != null)
13203 {
13204 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13205 }
13206
13207 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13208 break;
13209
13210 case (int)ScriptBaseClass.PRIM_TYPE:
13211 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13212 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13213 res.Add(new LSL_Vector(0f,1.0f,0f));
13214 res.Add(new LSL_Float(0.0f));
13215 res.Add(new LSL_Vector(0, 0, 0));
13216 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13217 res.Add(new LSL_Vector(0, 0, 0));
13218 break;
13219
13220 case (int)ScriptBaseClass.PRIM_TEXTURE:
13221 if (remain < 1)
13222 return null;
13223
13224 int face = (int)rules.GetLSLIntegerItem(idx++);
13225 if (face == ScriptBaseClass.ALL_SIDES)
13226 {
13227 for (face = 0; face < 21; face++)
13228 {
13229 res.Add(new LSL_String(""));
13230 res.Add(new LSL_Vector(0,0,0));
13231 res.Add(new LSL_Vector(0,0,0));
13232 res.Add(new LSL_Float(0.0));
13233 }
13234 }
13235 else
13236 {
13237 if (face >= 0 && face < 21)
13238 {
13239 res.Add(new LSL_String(""));
13240 res.Add(new LSL_Vector(0,0,0));
13241 res.Add(new LSL_Vector(0,0,0));
13242 res.Add(new LSL_Float(0.0));
13243 }
13244 }
13245 break;
13246
13247 case (int)ScriptBaseClass.PRIM_COLOR:
13248 if (remain < 1)
13249 return null;
13250
13251 face = (int)rules.GetLSLIntegerItem(idx++);
13252
13253 if (face == ScriptBaseClass.ALL_SIDES)
13254 {
13255 for (face = 0; face < 21; face++)
13256 {
13257 res.Add(new LSL_Vector(0,0,0));
13258 res.Add(new LSL_Float(0));
13259 }
13260 }
13261 else
13262 {
13263 res.Add(new LSL_Vector(0,0,0));
13264 res.Add(new LSL_Float(0));
13265 }
13266 break;
13267
13268 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13269 if (remain < 1)
13270 return null;
13271 face = (int)rules.GetLSLIntegerItem(idx++);
13272
13273 if (face == ScriptBaseClass.ALL_SIDES)
13274 {
13275 for (face = 0; face < 21; face++)
13276 {
13277 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13278 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13279 }
13280 }
13281 else
13282 {
13283 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13284 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13285 }
13286 break;
13287
13288 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13289 if (remain < 1)
13290 return null;
13291 face = (int)rules.GetLSLIntegerItem(idx++);
13292
13293 if (face == ScriptBaseClass.ALL_SIDES)
13294 {
13295 for (face = 0; face < 21; face++)
13296 {
13297 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13298 }
13299 }
13300 else
13301 {
13302 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13303 }
13304 break;
13305
13306 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13307 res.Add(new LSL_Integer(0));
13308 res.Add(new LSL_Integer(0));// softness
13309 res.Add(new LSL_Float(0.0f)); // gravity
13310 res.Add(new LSL_Float(0.0f)); // friction
13311 res.Add(new LSL_Float(0.0f)); // wind
13312 res.Add(new LSL_Float(0.0f)); // tension
13313 res.Add(new LSL_Vector(0f,0f,0f));
13314 break;
13315
13316 case (int)ScriptBaseClass.PRIM_TEXGEN:
13317 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13318 if (remain < 1)
13319 return null;
13320 face = (int)rules.GetLSLIntegerItem(idx++);
13321
13322 if (face == ScriptBaseClass.ALL_SIDES)
13323 {
13324 for (face = 0; face < 21; face++)
13325 {
13326 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13327 }
13328 }
13329 else
13330 {
13331 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13332 }
13333 break;
13334
13335 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13336 res.Add(new LSL_Integer(0));
13337 res.Add(new LSL_Vector(0f,0f,0f));
13338 res.Add(new LSL_Float(0f)); // intensity
13339 res.Add(new LSL_Float(0f)); // radius
13340 res.Add(new LSL_Float(0f)); // falloff
13341 break;
13342
13343 case (int)ScriptBaseClass.PRIM_GLOW:
13344 if (remain < 1)
13345 return null;
13346 face = (int)rules.GetLSLIntegerItem(idx++);
13347
13348 if (face == ScriptBaseClass.ALL_SIDES)
13349 {
13350 for (face = 0; face < 21; face++)
13351 {
13352 res.Add(new LSL_Float(0f));
13353 }
13354 }
13355 else
13356 {
13357 res.Add(new LSL_Float(0f));
13358 }
13359 break;
13360
13361 case (int)ScriptBaseClass.PRIM_TEXT:
13362 res.Add(new LSL_String(""));
13363 res.Add(new LSL_Vector(0f,0f,0f));
13364 res.Add(new LSL_Float(1.0f));
13365 break;
13366
13367 case (int)ScriptBaseClass.PRIM_NAME:
13368 res.Add(new LSL_String(avatar.Name));
13369 break;
13370
13371 case (int)ScriptBaseClass.PRIM_DESC:
13372 res.Add(new LSL_String(""));
13373 break;
13374
13375 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13376 Quaternion lrot = avatar.Rotation;
13377
13378 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13379 {
13380 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13381 }
13382 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13383 break;
13384
13385 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13386 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13387 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13388 lpos -= lsitOffset;
13389
13390 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13391 {
13392 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13393 }
13394 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13395 break;
13396
13397 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13398 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13399 return null;
13400
13401 return rules.GetSublist(idx, -1);
13402 }
13403 }
13404
13405 return null;
13406 }
13407
13408 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
13409 {
13410 if (m_UrlModule != null)
13411 {
13412 string type = "text.plain";
13413 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
13414 type = "text/html";
13415
13416 m_UrlModule.HttpContentType(new UUID(id),type);
13417 }
13418 }
11914 } 13419 }
11915 13420
11916 public class NotecardCache 13421 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -329,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 415166a..9c148d1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -139,6 +139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
140 internal float m_ScriptDelayFactor = 1.0f; 140 internal float m_ScriptDelayFactor = 1.0f;
141 internal float m_ScriptDistanceFactor = 1.0f; 141 internal float m_ScriptDistanceFactor = 1.0f;
142 internal bool m_debuggerSafe = false;
142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
143 144
144 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
149 m_ScriptEngine = scriptEngine; 150 m_ScriptEngine = scriptEngine;
150 m_host = host; 151 m_host = host;
151 m_item = item; 152 m_item = item;
153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
152 154
153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 155 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
154 156
@@ -212,7 +214,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 214
213 internal void OSSLError(string msg) 215 internal void OSSLError(string msg)
214 { 216 {
215 throw new ScriptException("OSSL Runtime Error: " + msg); 217 if (m_debuggerSafe)
218 {
219 OSSLShoutError(msg);
220 }
221 else
222 {
223 throw new ScriptException("OSSL Runtime Error: " + msg);
224 }
216 } 225 }
217 226
218 /// <summary> 227 /// <summary>
@@ -931,18 +940,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
931 if (target != null) 940 if (target != null)
932 { 941 {
933 UUID animID=UUID.Zero; 942 UUID animID=UUID.Zero;
934 lock (m_host.TaskInventory) 943 m_host.TaskInventory.LockItemsForRead(true);
944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
935 { 945 {
936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 946 if (inv.Value.Name == animation)
937 { 947 {
938 if (inv.Value.Name == animation) 948 if (inv.Value.Type == (int)AssetType.Animation)
939 { 949 animID = inv.Value.AssetID;
940 if (inv.Value.Type == (int)AssetType.Animation) 950 continue;
941 animID = inv.Value.AssetID;
942 continue;
943 }
944 } 951 }
945 } 952 }
953 m_host.TaskInventory.LockItemsForRead(false);
946 if (animID == UUID.Zero) 954 if (animID == UUID.Zero)
947 target.Animator.AddAnimation(animation, m_host.UUID); 955 target.Animator.AddAnimation(animation, m_host.UUID);
948 else 956 else
@@ -983,6 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
983 else 991 else
984 animID = UUID.Zero; 992 animID = UUID.Zero;
985 } 993 }
994 m_host.TaskInventory.LockItemsForRead(false);
986 995
987 if (animID == UUID.Zero) 996 if (animID == UUID.Zero)
988 target.Animator.RemoveAnimation(animation); 997 target.Animator.RemoveAnimation(animation);
@@ -1425,7 +1434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1425 return; 1434 return;
1426 } 1435 }
1427 1436
1428 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions)) 1437 if (!World.Permissions.CanEditParcelProperties(m_host.OwnerID, startLandObject, GroupPowers.LandOptions, false))
1429 { 1438 {
1430 OSSLShoutError("You do not have permission to modify the parcel"); 1439 OSSLShoutError("You do not have permission to modify the parcel");
1431 return; 1440 return;
@@ -1645,7 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 } 1654 }
1646 } 1655 }
1647 1656
1648 public Object osParseJSONNew(string JSON) 1657 private Object osParseJSONNew(string JSON)
1649 { 1658 {
1650 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1659 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1651 1660
@@ -1847,15 +1856,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 { 1856 {
1848 UUID assetID = UUID.Zero; 1857 UUID assetID = UUID.Zero;
1849 1858
1850 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1859 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1860
1861 if (!notecardNameIsUUID)
1851 { 1862 {
1852 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1863 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1853 {
1854 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1855 {
1856 assetID = item.AssetID;
1857 }
1858 }
1859 } 1864 }
1860 1865
1861 if (assetID == UUID.Zero) 1866 if (assetID == UUID.Zero)
@@ -1866,7 +1871,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1866 AssetBase a = World.AssetService.Get(assetID.ToString()); 1871 AssetBase a = World.AssetService.Get(assetID.ToString());
1867 1872
1868 if (a == null) 1873 if (a == null)
1869 return UUID.Zero; 1874 {
1875 // Whoops, it's still possible here that the notecard name was properly
1876 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1877 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1878 if (assetID == UUID.Zero)
1879 return UUID.Zero;
1880
1881 if (!NotecardCache.IsCached(assetID))
1882 {
1883 a = World.AssetService.Get(assetID.ToString());
1884
1885 if (a == null)
1886 {
1887 return UUID.Zero;
1888 }
1889 }
1890 }
1870 1891
1871 string data = Encoding.UTF8.GetString(a.Data); 1892 string data = Encoding.UTF8.GetString(a.Data);
1872 NotecardCache.Cache(assetID, data); 1893 NotecardCache.Cache(assetID, data);
@@ -1874,6 +1895,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 1895
1875 return assetID; 1896 return assetID;
1876 } 1897 }
1898 protected UUID SearchTaskInventoryForAssetId(string name)
1899 {
1900 UUID assetId = UUID.Zero;
1901 m_host.TaskInventory.LockItemsForRead(true);
1902 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1903 {
1904 if (item.Type == 7 && item.Name == name)
1905 {
1906 assetId = item.AssetID;
1907 }
1908 }
1909 m_host.TaskInventory.LockItemsForRead(false);
1910 return assetId;
1911 }
1877 1912
1878 /// <summary> 1913 /// <summary>
1879 /// Directly get an entire notecard at once. 1914 /// Directly get an entire notecard at once.
@@ -2351,7 +2386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2386 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2352 m_host.AddScriptLPS(1); 2387 m_host.AddScriptLPS(1);
2353 2388
2354 return NpcCreate(firstname, lastname, position, notecard, false, false); 2389 return NpcCreate(firstname, lastname, position, notecard, true, false);
2355 } 2390 }
2356 2391
2357 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2392 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2362,24 +2397,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2362 return NpcCreate( 2397 return NpcCreate(
2363 firstname, lastname, position, notecard, 2398 firstname, lastname, position, notecard,
2364 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2399 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2365 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2400 false);
2401// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2366 } 2402 }
2367 2403
2368 private LSL_Key NpcCreate( 2404 private LSL_Key NpcCreate(
2369 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2405 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2370 { 2406 {
2407 if (!owned)
2408 OSSLError("Unowned NPCs are unsupported");
2409
2410 string groupTitle = String.Empty;
2411
2412 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2413 return new LSL_Key(UUID.Zero.ToString());
2414
2415 if (firstname != String.Empty || lastname != String.Empty)
2416 {
2417 if (firstname != "Shown outfit:")
2418 groupTitle = "- NPC -";
2419 }
2420
2371 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2421 INPCModule module = World.RequestModuleInterface<INPCModule>();
2372 if (module != null) 2422 if (module != null)
2373 { 2423 {
2374 AvatarAppearance appearance = null; 2424 AvatarAppearance appearance = null;
2375 2425
2376 UUID id; 2426// UUID id;
2377 if (UUID.TryParse(notecard, out id)) 2427// if (UUID.TryParse(notecard, out id))
2378 { 2428// {
2379 ScenePresence clonePresence = World.GetScenePresence(id); 2429// ScenePresence clonePresence = World.GetScenePresence(id);
2380 if (clonePresence != null) 2430// if (clonePresence != null)
2381 appearance = clonePresence.Appearance; 2431// appearance = clonePresence.Appearance;
2382 } 2432// }
2383 2433
2384 if (appearance == null) 2434 if (appearance == null)
2385 { 2435 {
@@ -2387,9 +2437,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2387 2437
2388 if (appearanceSerialized != null) 2438 if (appearanceSerialized != null)
2389 { 2439 {
2390 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2440 try
2391 appearance = new AvatarAppearance(); 2441 {
2392 appearance.Unpack(appearanceOsd); 2442 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2443 appearance = new AvatarAppearance();
2444 appearance.Unpack(appearanceOsd);
2445 }
2446 catch
2447 {
2448 return UUID.Zero.ToString();
2449 }
2393 } 2450 }
2394 else 2451 else
2395 { 2452 {
@@ -2408,6 +2465,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2408 World, 2465 World,
2409 appearance); 2466 appearance);
2410 2467
2468 ScenePresence sp;
2469 if (World.TryGetScenePresence(x, out sp))
2470 {
2471 sp.Grouptitle = groupTitle;
2472 sp.SendAvatarDataToAllAgents();
2473 }
2411 return new LSL_Key(x.ToString()); 2474 return new LSL_Key(x.ToString());
2412 } 2475 }
2413 2476
@@ -2705,16 +2768,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2768 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2706 m_host.AddScriptLPS(1); 2769 m_host.AddScriptLPS(1);
2707 2770
2708 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2771 ManualResetEvent ev = new ManualResetEvent(false);
2709 if (module != null)
2710 {
2711 UUID npcId = new UUID(npc.m_string);
2712 2772
2713 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2773 Util.FireAndForget(delegate(object x) {
2714 return; 2774 try
2775 {
2776 INPCModule module = World.RequestModuleInterface<INPCModule>();
2777 if (module != null)
2778 {
2779 UUID npcId = new UUID(npc.m_string);
2715 2780
2716 module.DeleteNPC(npcId, World); 2781 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2717 } 2782 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2783 {
2784 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2785 return;
2786 }
2787
2788 module.DeleteNPC(npcId, World);
2789 }
2790 }
2791 finally
2792 {
2793 ev.Set();
2794 }
2795 });
2796 ev.WaitOne();
2718 } 2797 }
2719 2798
2720 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2799 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 88ab515..a47e452 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.GetWorldRotation() * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -397,7 +398,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
397 objtype = 0; 398 objtype = 0;
398 399
399 part = ((SceneObjectGroup)ent).RootPart; 400 part = ((SceneObjectGroup)ent).RootPart;
400 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore 401 if (part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.Tree &&
402 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
403 part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
401 continue; 404 continue;
402 405
403 if (part.Inventory.ContainsScripts()) 406 if (part.Inventory.ContainsScripts())
@@ -480,7 +483,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 483 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 484 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 485 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.GetWorldRotation() * q; 486 if (avatar == null)
487 return sensedEntities;
488 fromRegionPos = avatar.AbsolutePosition;
489 q = avatar.Rotation;
484 } 490 }
485 491
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 492 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 502// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 503// presence.Name, presence.PresenceType, ts.name, ts.type);
498 504
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 505 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 506 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 507 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 508 if (npcData == null || !npcData.SenseAsAgent)
@@ -696,4 +702,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
696 return retList; 702 return retList;
697 } 703 }
698 } 704 }
699} \ No newline at end of file 705}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 4ac179a..daf89e5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 void llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
211 LSL_String llTransferLindenDollars(string destination, int amount); 212 LSL_String llTransferLindenDollars(string destination, int amount);
212 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
213 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
@@ -331,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
331 void llSensorRemove(); 332 void llSensorRemove();
332 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
333 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
334 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
335 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
336 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -357,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
357 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
358 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
359 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
361 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
363 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
364 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
366 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
367 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -381,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
381 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
382 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
383 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
384 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
385 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
386 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -424,9 +427,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
424 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
425 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
426 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
427 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
428 432
429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
430 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
436 LSL_List llGetPhysicsMaterial();
437 void llSetContentType(LSL_Key id, LSL_Integer content_type);
431 } 438 }
432} 439}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 51d0581..a652cb8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
@@ -260,7 +260,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
260 string osGetScriptEngineName(); 260 string osGetScriptEngineName();
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 string osGetPhysicsEngineType(); 262 string osGetPhysicsEngineType();
263 Object osParseJSONNew(string JSON);
264 Hashtable osParseJSON(string JSON); 263 Hashtable osParseJSON(string JSON);
265 264
266 void osMessageObject(key objectUUID,string message); 265 void osMessageObject(key objectUUID,string message);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index dc5ef13..6efa73f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -81,6 +80,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
81 public const int PERMISSION_CHANGE_PERMISSIONS = 512; 80 public const int PERMISSION_CHANGE_PERMISSIONS = 512;
82 public const int PERMISSION_TRACK_CAMERA = 1024; 81 public const int PERMISSION_TRACK_CAMERA = 1024;
83 public const int PERMISSION_CONTROL_CAMERA = 2048; 82 public const int PERMISSION_CONTROL_CAMERA = 2048;
83 public const int PERMISSION_TELEPORT = 4096;
84 84
85 public const int AGENT_FLYING = 1; 85 public const int AGENT_FLYING = 1;
86 public const int AGENT_ATTACHMENTS = 2; 86 public const int AGENT_ATTACHMENTS = 2;
@@ -95,6 +95,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 95 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 96 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 97 public const int AGENT_ALWAYS_RUN = 4096;
98 public const int AGENT_MALE = 8192;
98 99
99 //Particle Systems 100 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 101 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -337,6 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 338 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 339 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 340 public const int CHANGED_ANIMATION = 16384;
341 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 342 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 343 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 344 public const int TYPE_FLOAT = 2;
@@ -674,7 +676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
674 public const int FRICTION = 2; 676 public const int FRICTION = 2;
675 public const int RESTITUTION = 4; 677 public const int RESTITUTION = 4;
676 public const int GRAVITY_MULTIPLIER = 8; 678 public const int GRAVITY_MULTIPLIER = 8;
677 679
678 // extra constants for llSetPrimMediaParams 680 // extra constants for llSetPrimMediaParams
679 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 681 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
680 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); 682 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
@@ -746,7 +748,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
746 748
747 public static readonly LSLInteger RCERR_UNKNOWN = -1; 749 public static readonly LSLInteger RCERR_UNKNOWN = -1;
748 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 750 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
749 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 751 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
752
753 public const int KFM_MODE = 1;
754 public const int KFM_LOOP = 1;
755 public const int KFM_REVERSE = 3;
756 public const int KFM_FORWARD = 0;
757 public const int KFM_PING_PONG = 2;
758 public const int KFM_DATA = 2;
759 public const int KFM_TRANSLATION = 2;
760 public const int KFM_ROTATION = 1;
761 public const int KFM_COMMAND = 0;
762 public const int KFM_CMD_PLAY = 0;
763 public const int KFM_CMD_STOP = 1;
764 public const int KFM_CMD_PAUSE = 2;
750 765
751 /// <summary> 766 /// <summary>
752 /// process name parameter as regex 767 /// process name parameter as regex
@@ -757,5 +772,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
757 /// process message parameter as regex 772 /// process message parameter as regex
758 /// </summary> 773 /// </summary>
759 public const int OS_LISTEN_REGEX_MESSAGE = 0x2; 774 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
775
776 public const int CONTENT_TYPE_TEXT = 0;
777 public const int CONTENT_TYPE_HTML = 1;
760 } 778 }
761} 779}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c7a7cf6..6f3677c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -869,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
869 m_LSL_Functions.llGiveInventoryList(destination, category, inventory); 876 m_LSL_Functions.llGiveInventoryList(destination, category, inventory);
870 } 877 }
871 878
872 public void llGiveMoney(string destination, int amount) 879 public LSL_Integer llGiveMoney(string destination, int amount)
873 { 880 {
874 m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
877 public LSL_String llTransferLindenDollars(string destination, int amount) 884 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -1488,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1488 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1489 } 1496 }
1490 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1491 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1492 { 1504 {
1493 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1613,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1613 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1614 } 1626 }
1615 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1616 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1617 { 1634 {
1618 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1628,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1628 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1629 } 1646 }
1630 1647
1631 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1632 {
1633 return m_LSL_Functions.llSetRegionPos(pos);
1634 }
1635
1636 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1637 { 1649 {
1638 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1728,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1728 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1729 } 1741 }
1730 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1731 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1732 { 1749 {
1733 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1978,9 +1995,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1978 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1979 } 1996 }
1980 1997
1981 public void print(string str) 1998 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1999 {
2000 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2001 }
2002
2003 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2004 {
2005 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2006 }
2007
2008 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
2009 {
2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
2011 }
2012
2013 public LSL_List llGetPhysicsMaterial()
2014 {
2015 return m_LSL_Functions.llGetPhysicsMaterial();
2016 }
2017
2018 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
1982 { 2019 {
1983 m_LSL_Functions.print(str); 2020 m_LSL_Functions.llSetContentType(id, content_type);
1984 } 2021 }
1985 } 2022 }
1986} 2023}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index c9902e4..b63773b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -435,11 +435,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
435 return m_OSSL_Functions.osParseJSON(JSON); 435 return m_OSSL_Functions.osParseJSON(JSON);
436 } 436 }
437 437
438 public Object osParseJSONNew(string JSON)
439 {
440 return m_OSSL_Functions.osParseJSONNew(JSON);
441 }
442
443 public void osMessageObject(key objectUUID,string message) 438 public void osMessageObject(key objectUUID,string message)
444 { 439 {
445 m_OSSL_Functions.osMessageObject(objectUUID,message); 440 m_OSSL_Functions.osMessageObject(objectUUID,message);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index e02d35e..e44a106 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -120,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
120 Type = 0; 121 Type = 0;
121 Velocity = new LSL_Types.Vector3(); 122 Velocity = new LSL_Types.Vector3();
122 initializeSurfaceTouch(); 123 initializeSurfaceTouch();
124 Country = String.Empty;
123 } 125 }
124 126
125 public UUID Key; 127 public UUID Key;
@@ -151,6 +153,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
151 private int touchFace; 153 private int touchFace;
152 public int TouchFace { get { return touchFace; } } 154 public int TouchFace { get { return touchFace; } }
153 155
156 public string Country;
157
154 // This can be done in two places including the constructor 158 // This can be done in two places including the constructor
155 // so be carefull what gets added here 159 // so be carefull what gets added here
156 private void initializeSurfaceTouch() 160 private void initializeSurfaceTouch()
@@ -198,6 +202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
198 return; 202 return;
199 203
200 Name = presence.Firstname + " " + presence.Lastname; 204 Name = presence.Firstname + " " + presence.Lastname;
205 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
206 if (account != null)
207 Country = account.UserCountry;
208
201 Owner = Key; 209 Owner = Key;
202 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 210 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
203 Rotation = new LSL_Types.Quaternion( 211 Rotation = new LSL_Types.Quaternion(
@@ -207,22 +215,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
207 presence.Rotation.W); 215 presence.Rotation.W);
208 Velocity = new LSL_Types.Vector3(presence.Velocity); 216 Velocity = new LSL_Types.Vector3(presence.Velocity);
209 217
210 if (presence.PresenceType != PresenceType.Npc) 218 Type = 0x01; // Avatar
211 { 219 if (presence.PresenceType == PresenceType.Npc)
212 Type = AGENT; 220 Type = 0x20;
213 } 221
214 else 222 // Cope Impl. We don't use OS_NPC.
215 { 223 //if (presence.PresenceType != PresenceType.Npc)
216 Type = OS_NPC; 224 //{
217 225 // Type = AGENT;
218 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 226 //}
219 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 227 //else
220 228 //{
221 if (npcData.SenseAsAgent) 229 // Type = OS_NPC;
222 { 230
223 Type |= AGENT; 231 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
224 } 232 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
225 } 233
234 // if (npcData.SenseAsAgent)
235 // {
236 // Type |= AGENT;
237 // }
238 //}
226 239
227 if (presence.Velocity != Vector3.Zero) 240 if (presence.Velocity != Vector3.Zero)
228 Type |= ACTIVE; 241 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index bf19a42..a2ac9c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -165,13 +166,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
165 166
166 public UUID ItemID { get; private set; } 167 public UUID ItemID { get; private set; }
167 168
168 public UUID ObjectID { get { return Part.UUID; } } 169 public UUID ObjectID { get; private set; }
169 170
170 public uint LocalID { get { return Part.LocalId; } } 171 public uint LocalID { get; private set; }
171 172
172 public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } 173 public UUID RootObjectID { get; private set; }
173 174
174 public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } 175 public uint RootLocalID { get; private set; }
175 176
176 public UUID AssetID { get; private set; } 177 public UUID AssetID { get; private set; }
177 178
@@ -230,13 +231,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
230 ItemID = ScriptTask.ItemID; 231 ItemID = ScriptTask.ItemID;
231 AssetID = ScriptTask.AssetID; 232 AssetID = ScriptTask.AssetID;
232 } 233 }
234 LocalID = part.LocalId;
233 235
234 PrimName = part.ParentGroup.Name; 236 PrimName = part.ParentGroup.Name;
235 StartParam = startParam; 237 StartParam = startParam;
236 m_MaxScriptQueue = maxScriptQueue; 238 m_MaxScriptQueue = maxScriptQueue;
237 m_postOnRez = postOnRez; 239 m_postOnRez = postOnRez;
238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 240 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 241 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
240 242
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") 243 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 { 244 {
@@ -481,27 +483,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
481 PostEvent(new EventParams("attach", 483 PostEvent(new EventParams("attach",
482 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 484 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
483 } 485 }
486
484 } 487 }
485 } 488 }
486 489
487 private void ReleaseControls() 490 private void ReleaseControls()
488 { 491 {
489 int permsMask; 492 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
490 UUID permsGranter; 493
491 lock (Part.TaskInventory) 494 if (part != null)
492 { 495 {
493 if (!Part.TaskInventory.ContainsKey(ItemID)) 496 int permsMask;
497 UUID permsGranter;
498 part.TaskInventory.LockItemsForRead(true);
499 if (!part.TaskInventory.ContainsKey(ItemID))
500 {
501 part.TaskInventory.LockItemsForRead(false);
494 return; 502 return;
503 }
504 permsGranter = part.TaskInventory[ItemID].PermsGranter;
505 permsMask = part.TaskInventory[ItemID].PermsMask;
506 part.TaskInventory.LockItemsForRead(false);
495 507
496 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 508 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
497 permsMask = Part.TaskInventory[ItemID].PermsMask; 509 {
498 } 510 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
499 511 if (presence != null)
500 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 512 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
501 { 513 }
502 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
503 if (presence != null)
504 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
505 } 514 }
506 } 515 }
507 516
@@ -650,6 +659,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
650 return true; 659 return true;
651 } 660 }
652 661
662 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
653 public void SetState(string state) 663 public void SetState(string state)
654 { 664 {
655 if (state == State) 665 if (state == State)
@@ -661,7 +671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
661 new DetectParams[0])); 671 new DetectParams[0]));
662 PostEvent(new EventParams("state_entry", new Object[0], 672 PostEvent(new EventParams("state_entry", new Object[0],
663 new DetectParams[0])); 673 new DetectParams[0]));
664 674
665 throw new EventAbortException(); 675 throw new EventAbortException();
666 } 676 }
667 677
@@ -751,57 +761,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
751 /// <returns></returns> 761 /// <returns></returns>
752 public object EventProcessor() 762 public object EventProcessor()
753 { 763 {
764 EventParams data = null;
754 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 765 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
755 if (!Running) 766 if (!Running)
756 return 0; 767 return 0;
757 768
758 lock (m_Script)
759 {
760// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 769// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
761 770
762 if (Suspended) 771 if (Suspended)
763 return 0; 772 return 0;
764
765 EventParams data = null;
766 773
767 lock (EventQueue) 774 lock (EventQueue)
775 {
776 data = (EventParams) EventQueue.Dequeue();
777 if (data == null) // Shouldn't happen
768 { 778 {
769 data = (EventParams)EventQueue.Dequeue(); 779 if (EventQueue.Count > 0 && Running && !ShuttingDown)
770 if (data == null) // Shouldn't happen
771 { 780 {
772 if (EventQueue.Count > 0 && Running && !ShuttingDown) 781 m_CurrentWorkItem = Engine.QueueEventHandler(this);
773 {
774 m_CurrentWorkItem = Engine.QueueEventHandler(this);
775 }
776 else
777 {
778 m_CurrentWorkItem = null;
779 }
780 return 0;
781 } 782 }
782 783 else
783 if (data.EventName == "timer")
784 m_TimerQueued = false;
785 if (data.EventName == "control")
786 { 784 {
787 if (m_ControlEventsInQueue > 0) 785 m_CurrentWorkItem = null;
788 m_ControlEventsInQueue--;
789 } 786 }
790 if (data.EventName == "collision") 787 return 0;
791 m_CollisionInQueue = false;
792 } 788 }
793 789
790 if (data.EventName == "timer")
791 m_TimerQueued = false;
792 if (data.EventName == "control")
793 {
794 if (m_ControlEventsInQueue > 0)
795 m_ControlEventsInQueue--;
796 }
797 if (data.EventName == "collision")
798 m_CollisionInQueue = false;
799 }
800
801 lock(m_Script)
802 {
803
804// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
805 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
806
794 if (DebugLevel >= 2) 807 if (DebugLevel >= 2)
795 m_log.DebugFormat( 808 m_log.DebugFormat(
796 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 809 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
797 data.EventName, 810 data.EventName,
798 ScriptName, 811 ScriptName,
799 Part.Name, 812 part.Name,
800 Part.LocalId, 813 part.LocalId,
801 Part.ParentGroup.Name, 814 part.ParentGroup.Name,
802 Part.ParentGroup.UUID, 815 part.ParentGroup.UUID,
803 Part.AbsolutePosition, 816 part.AbsolutePosition,
804 Part.ParentGroup.Scene.Name); 817 part.ParentGroup.Scene.Name);
805 818
806 m_DetectParams = data.DetectParams; 819 m_DetectParams = data.DetectParams;
807 820
@@ -814,17 +827,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
814 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 827 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
815 State, 828 State,
816 ScriptName, 829 ScriptName,
817 Part.Name, 830 part.Name,
818 Part.LocalId, 831 part.LocalId,
819 Part.ParentGroup.Name, 832 part.ParentGroup.Name,
820 Part.ParentGroup.UUID, 833 part.ParentGroup.UUID,
821 Part.AbsolutePosition, 834 part.AbsolutePosition,
822 Part.ParentGroup.Scene.Name); 835 part.ParentGroup.Scene.Name);
823 836
824 AsyncCommandManager.RemoveScript(Engine, 837 AsyncCommandManager.RemoveScript(Engine,
825 LocalID, ItemID); 838 LocalID, ItemID);
826 839
827 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 840 if (part != null)
841 {
842 part.SetScriptEvents(ItemID,
843 (int)m_Script.GetStateEventFlags(State));
844 }
828 } 845 }
829 else 846 else
830 { 847 {
@@ -887,17 +904,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
887 text = text.Substring(0, 1000); 904 text = text.Substring(0, 1000);
888 Engine.World.SimChat(Utils.StringToBytes(text), 905 Engine.World.SimChat(Utils.StringToBytes(text),
889 ChatTypeEnum.DebugChannel, 2147483647, 906 ChatTypeEnum.DebugChannel, 2147483647,
890 Part.AbsolutePosition, 907 part.AbsolutePosition,
891 Part.Name, Part.UUID, false); 908 part.Name, part.UUID, false);
892 909
893 910
894 m_log.DebugFormat( 911 m_log.DebugFormat(
895 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 912 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
896 ScriptName, 913 ScriptName,
897 PrimName, 914 PrimName,
898 Part.UUID, 915 part.UUID,
899 Part.AbsolutePosition, 916 part.AbsolutePosition,
900 Part.ParentGroup.Scene.Name, 917 part.ParentGroup.Scene.Name,
901 text.Replace("\n", "\\n"), 918 text.Replace("\n", "\\n"),
902 e.InnerException); 919 e.InnerException);
903 } 920 }
@@ -917,12 +934,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
917 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 934 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
918 { 935 {
919 m_InSelfDelete = true; 936 m_InSelfDelete = true;
920 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 937 if (part != null)
938 Engine.World.DeleteSceneObject(part.ParentGroup, false);
921 } 939 }
922 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 940 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
923 { 941 {
924 m_InSelfDelete = true; 942 m_InSelfDelete = true;
925 Part.Inventory.RemoveInventoryItem(ItemID); 943 if (part != null)
944 part.Inventory.RemoveInventoryItem(ItemID);
926 } 945 }
927 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 946 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
928 { 947 {
@@ -976,14 +995,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
976 ReleaseControls(); 995 ReleaseControls();
977 996
978 Stop(timeout); 997 Stop(timeout);
979 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 998 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
980 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 999 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1000 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1001 part.CollisionSound = UUID.Zero;
981 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1002 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
982 EventQueue.Clear(); 1003 EventQueue.Clear();
983 m_Script.ResetVars(); 1004 m_Script.ResetVars();
984 State = "default"; 1005 State = "default";
985 1006
986 Part.SetScriptEvents(ItemID, 1007 part.SetScriptEvents(ItemID,
987 (int)m_Script.GetStateEventFlags(State)); 1008 (int)m_Script.GetStateEventFlags(State));
988 if (running) 1009 if (running)
989 Start(); 1010 Start();
@@ -992,6 +1013,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
992 new Object[0], new DetectParams[0])); 1013 new Object[0], new DetectParams[0]));
993 } 1014 }
994 1015
1016 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
995 public void ApiResetScript() 1017 public void ApiResetScript()
996 { 1018 {
997 // bool running = Running; 1019 // bool running = Running;
@@ -1000,15 +1022,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1000 ReleaseControls(); 1022 ReleaseControls();
1001 1023
1002 m_Script.ResetVars(); 1024 m_Script.ResetVars();
1003 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1025 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1004 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1026 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1027 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1028 part.CollisionSound = UUID.Zero;
1005 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1029 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1006 1030
1007 EventQueue.Clear(); 1031 EventQueue.Clear();
1008 m_Script.ResetVars(); 1032 m_Script.ResetVars();
1009 State = "default"; 1033 State = "default";
1010 1034
1011 Part.SetScriptEvents(ItemID, 1035 part.SetScriptEvents(ItemID,
1012 (int)m_Script.GetStateEventFlags(State)); 1036 (int)m_Script.GetStateEventFlags(State));
1013 1037
1014 if (m_CurrentEvent != "state_entry") 1038 if (m_CurrentEvent != "state_entry")
@@ -1022,10 +1046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1022 1046
1023 public Dictionary<string, object> GetVars() 1047 public Dictionary<string, object> GetVars()
1024 { 1048 {
1025 if (m_Script != null) 1049 return m_Script.GetVars();
1026 return m_Script.GetVars();
1027 else
1028 return new Dictionary<string, object>();
1029 } 1050 }
1030 1051
1031 public void SetVars(Dictionary<string, object> vars) 1052 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 44fdd1a..b524a18 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -389,19 +389,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
389 389
390 public override string ToString() 390 public override string ToString()
391 { 391 {
392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
393 return st; 393 return st;
394 } 394 }
395 395
396 public static explicit operator string(Quaternion r) 396 public static explicit operator string(Quaternion r)
397 { 397 {
398 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 398 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
399 return s; 399 return s;
400 } 400 }
401 401
402 public static explicit operator LSLString(Quaternion r) 402 public static explicit operator LSLString(Quaternion r)
403 { 403 {
404 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 404 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
405 return new LSLString(s); 405 return new LSLString(s);
406 } 406 }
407 407
@@ -512,7 +512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
512 else if (o is LSL_Types.LSLFloat) 512 else if (o is LSL_Types.LSLFloat)
513 size += 8; 513 size += 8;
514 else if (o is LSL_Types.LSLString) 514 else if (o is LSL_Types.LSLString)
515 size += ((LSL_Types.LSLString)o).m_string.Length; 515 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
516 else if (o is LSL_Types.key) 516 else if (o is LSL_Types.key)
517 size += ((LSL_Types.key)o).value.Length; 517 size += ((LSL_Types.key)o).value.Length;
518 else if (o is LSL_Types.Vector3) 518 else if (o is LSL_Types.Vector3)
@@ -521,6 +521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
521 size += 64; 521 size += 64;
522 else if (o is int) 522 else if (o is int)
523 size += 4; 523 size += 4;
524 else if (o is uint)
525 size += 4;
524 else if (o is string) 526 else if (o is string)
525 size += ((string)o).Length; 527 size += ((string)o).Length;
526 else if (o is float) 528 else if (o is float)
@@ -711,24 +713,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
711 713
712 public static bool operator ==(list a, list b) 714 public static bool operator ==(list a, list b)
713 { 715 {
714 int la = -1; 716 int la = a.Length;
715 int lb = -1; 717 int lb = b.Length;
716 try { la = a.Length; }
717 catch (NullReferenceException) { }
718 try { lb = b.Length; }
719 catch (NullReferenceException) { }
720 718
721 return la == lb; 719 return la == lb;
722 } 720 }
723 721
724 public static bool operator !=(list a, list b) 722 public static bool operator !=(list a, list b)
725 { 723 {
726 int la = -1; 724 int la = a.Length;
727 int lb = -1; 725 int lb = b.Length;
728 try { la = a.Length; }
729 catch (NullReferenceException) { }
730 try {lb = b.Length;}
731 catch (NullReferenceException) { }
732 726
733 return la != lb; 727 return la != lb;
734 } 728 }
@@ -962,7 +956,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
962 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 956 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
963 } 957 }
964 958
965 if (ascending == 0) 959 if (ascending != 1)
966 { 960 {
967 ret = 0 - ret; 961 ret = 0 - ret;
968 } 962 }
@@ -995,6 +989,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
995 stride = 1; 989 stride = 1;
996 } 990 }
997 991
992 if ((Data.Length % stride) != 0)
993 return new list(ret);
994
998 // we can optimize here in the case where stride == 1 and the list 995 // we can optimize here in the case where stride == 1 and the list
999 // consists of homogeneous types 996 // consists of homogeneous types
1000 997
@@ -1014,7 +1011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1014 if (homogeneous) 1011 if (homogeneous)
1015 { 1012 {
1016 Array.Sort(ret, new HomogeneousComparer()); 1013 Array.Sort(ret, new HomogeneousComparer());
1017 if (ascending == 0) 1014 if (ascending != 1)
1018 { 1015 {
1019 Array.Reverse(ret); 1016 Array.Reverse(ret);
1020 } 1017 }