aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3176
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-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.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-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.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-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.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
18 files changed, 2986 insertions, 887 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..94fd940 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,26 @@ 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 xmlrpc.DeleteChannels(itemID);
321 xmlrpc.CancelSRDRequests(itemID);
322
323 // Remove Sensors
324 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
325
326 }
327
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 328 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 329 {
310 List<Object> data = new List<Object>(); 330 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..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
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.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 7e48659..d6aafaf 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.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -242,6 +285,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
242 } 285 }
243 } 286 }
244 287
288 public List<ScenePresence> GetLinkAvatars(int linkType)
289 {
290 List<ScenePresence> ret = new List<ScenePresence>();
291 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
292 return ret;
293
294 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
295
296 switch (linkType)
297 {
298 case ScriptBaseClass.LINK_SET:
299 return avs;
300
301 case ScriptBaseClass.LINK_ROOT:
302 return ret;
303
304 case ScriptBaseClass.LINK_ALL_OTHERS:
305 return avs;
306
307 case ScriptBaseClass.LINK_ALL_CHILDREN:
308 return avs;
309
310 case ScriptBaseClass.LINK_THIS:
311 return ret;
312
313 default:
314 if (linkType < 0)
315 return ret;
316
317 int partCount = m_host.ParentGroup.GetPartCount();
318
319 if (linkType <= partCount)
320 {
321 return ret;
322 }
323 else
324 {
325 linkType = linkType - partCount;
326 if (linkType > avs.Count)
327 {
328 return ret;
329 }
330 else
331 {
332 ret.Add(avs[linkType-1]);
333 return ret;
334 }
335 }
336 }
337 }
338
245 public List<SceneObjectPart> GetLinkParts(int linkType) 339 public List<SceneObjectPart> GetLinkParts(int linkType)
246 { 340 {
247 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
@@ -250,6 +344,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 private List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
251 { 345 {
252 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
348 return ret;
253 ret.Add(part); 349 ret.Add(part);
254 350
255 switch (linkType) 351 switch (linkType)
@@ -448,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
448 544
449 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
450 546
451 /// <summary> 547 // Utility function for llRot2Euler
452 /// Convert an LSL rotation to a Euler vector. 548
453 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
454 /// <remarks> 550 protected double NormalizeAngle(double angle)
455 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
456 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
457 /// </remarks>
458 /// <param name="r"></param>
459 /// <returns></returns>
460 public LSL_Vector llRot2Euler(LSL_Rotation r)
461 { 551 {
462 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
463 554
464 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 555 int numPis = (int)(Math.PI / angle);
465 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 556 double remainder = angle - Math.PI * numPis;
466 if (m == 0.0) return new LSL_Vector(); 557 if (numPis % 2 == 1)
467 double x = Math.Atan2(-v.y, v.z); 558 return Math.PI - angle;
468 double sin = v.x / m; 559 return remainder;
469 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 560 }
470 double y = Math.Asin(sin);
471 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
472 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)));
473 double z = Math.Atan2(v.y, v.x);
474 561
475 return new LSL_Vector(x, y, z); 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
563 {
564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
566
567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
476 } 589 }
477 590
478 /* From wiki: 591 /* From wiki:
@@ -525,18 +638,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
525 m_host.AddScriptLPS(1); 638 m_host.AddScriptLPS(1);
526 639
527 double x,y,z,s; 640 double x,y,z,s;
528 641 v.x *= 0.5;
529 double c1 = Math.Cos(v.x * 0.5); 642 v.y *= 0.5;
530 double c2 = Math.Cos(v.y * 0.5); 643 v.z *= 0.5;
531 double c3 = Math.Cos(v.z * 0.5); 644 double c1 = Math.Cos(v.x);
532 double s1 = Math.Sin(v.x * 0.5); 645 double c2 = Math.Cos(v.y);
533 double s2 = Math.Sin(v.y * 0.5); 646 double c1c2 = c1 * c2;
534 double s3 = Math.Sin(v.z * 0.5); 647 double s1 = Math.Sin(v.x);
535 648 double s2 = Math.Sin(v.y);
536 x = s1 * c2 * c3 + c1 * s2 * s3; 649 double s1s2 = s1 * s2;
537 y = c1 * s2 * c3 - s1 * c2 * s3; 650 double c1s2 = c1 * s2;
538 z = s1 * s2 * c3 + c1 * c2 * s3; 651 double s1c2 = s1 * c2;
539 s = c1 * c2 * c3 - s1 * s2 * s3; 652 double c3 = Math.Cos(v.z);
653 double s3 = Math.Sin(v.z);
654
655 x = s1c2 * c3 + c1s2 * s3;
656 y = c1s2 * c3 - s1c2 * s3;
657 z = s1s2 * c3 + c1c2 * s3;
658 s = c1c2 * c3 - s1s2 * s3;
540 659
541 return new LSL_Rotation(x, y, z, s); 660 return new LSL_Rotation(x, y, z, s);
542 } 661 }
@@ -674,77 +793,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
674 { 793 {
675 //A and B should both be normalized 794 //A and B should both be normalized
676 m_host.AddScriptLPS(1); 795 m_host.AddScriptLPS(1);
677 LSL_Rotation rotBetween; 796 /* This method is more accurate than the SL one, and thus causes problems
678 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 797 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
679 // continue calculation. 798
680 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 799 double dotProduct = LSL_Vector.Dot(a, b);
800 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
801 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
802 double angle = Math.Acos(dotProduct / magProduct);
803 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
804 double s = Math.Sin(angle / 2);
805
806 double x = axis.x * s;
807 double y = axis.y * s;
808 double z = axis.z * s;
809 double w = Math.Cos(angle / 2);
810
811 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
812 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813
814 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
815 */
816
817 // This method mimics the 180 errors found in SL
818 // See www.euclideanspace.com... angleBetween
819 LSL_Vector vec_a = a;
820 LSL_Vector vec_b = b;
821
822 // Eliminate zero length
823 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
824 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
825 if (vec_a_mag < 0.00001 ||
826 vec_b_mag < 0.00001)
681 { 827 {
682 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 828 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
683 } 829 }
684 else 830
831 // Normalize
832 vec_a = llVecNorm(vec_a);
833 vec_b = llVecNorm(vec_b);
834
835 // Calculate axis and rotation angle
836 LSL_Vector axis = vec_a % vec_b;
837 LSL_Float cos_theta = vec_a * vec_b;
838
839 // Check if parallel
840 if (cos_theta > 0.99999)
685 { 841 {
686 a = LSL_Vector.Norm(a); 842 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
687 b = LSL_Vector.Norm(b); 843 }
688 double dotProduct = LSL_Vector.Dot(a, b); 844
689 // There are two degenerate cases possible. These are for vectors 180 or 845 // Check if anti-parallel
690 // 0 degrees apart. These have to be detected and handled individually. 846 else if (cos_theta < -0.99999)
691 // 847 {
692 // Check for vectors 180 degrees apart. 848 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
693 // A dot product of -1 would mean the angle between vectors is 180 degrees. 849 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
694 if (dotProduct < -0.9999999f) 850 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
695 { 851 }
696 // First assume X axis is orthogonal to the vectors. 852 else // other rotation
697 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 853 {
698 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 854 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
699 // Check for near zero vector. A very small non-zero number here will create 855 axis = llVecNorm(axis);
700 // a rotation in an undesired direction. 856 double x, y, z, s, t;
701 if (LSL_Vector.Mag(orthoVector) > 0.0001) 857 s = Math.Cos(theta);
702 { 858 t = Math.Sin(theta);
703 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 859 x = axis.x * t;
704 } 860 y = axis.y * t;
705 // If the magnitude of the vector was near zero, then assume the X axis is not 861 z = axis.z * t;
706 // orthogonal and use the Z axis instead. 862 return new LSL_Rotation(x,y,z,s);
707 else
708 {
709 // Set 180 z rotation.
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
711 }
712 }
713 // Check for parallel vectors.
714 // A dot product of 1 would mean the angle between vectors is 0 degrees.
715 else if (dotProduct > 0.9999999f)
716 {
717 // Set zero rotation.
718 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
719 }
720 else
721 {
722 // All special checks have been performed so get the axis of rotation.
723 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
724 // Quarternion s value is the length of the unit vector + dot product.
725 double qs = 1.0 + dotProduct;
726 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
727 // Normalize the rotation.
728 double mag = LSL_Rotation.Mag(rotBetween);
729 // We shouldn't have to worry about a divide by zero here. The qs value will be
730 // non-zero because we already know if we're here, then the dotProduct is not -1 so
731 // qs will not be zero. Also, we've already handled the input vectors being zero so the
732 // crossProduct vector should also not be zero.
733 rotBetween.x = rotBetween.x / mag;
734 rotBetween.y = rotBetween.y / mag;
735 rotBetween.z = rotBetween.z / mag;
736 rotBetween.s = rotBetween.s / mag;
737 // Check for undefined values and set zero rotation if any found. This code might not actually be required
738 // any longer since zero vectors are checked for at the top.
739 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
740 {
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
742 }
743 }
744 } 863 }
745 return rotBetween;
746 } 864 }
747 865
748 public void llWhisper(int channelID, string text) 866 public void llWhisper(int channelID, string text)
749 { 867 {
750 m_host.AddScriptLPS(1); 868 m_host.AddScriptLPS(1);
@@ -760,10 +878,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
760 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 878 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
761 } 879 }
762 880
881 private void CheckSayShoutTime()
882 {
883 DateTime now = DateTime.UtcNow;
884 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
885 {
886 m_lastSayShoutCheck = now;
887 m_SayShoutCount = 0;
888 }
889 else
890 m_SayShoutCount++;
891 }
892
763 public void llSay(int channelID, string text) 893 public void llSay(int channelID, string text)
764 { 894 {
765 m_host.AddScriptLPS(1); 895 m_host.AddScriptLPS(1);
766 896
897 if (channelID == 0)
898// m_SayShoutCount++;
899 CheckSayShoutTime();
900
901 if (m_SayShoutCount >= 11)
902 ScriptSleep(2000);
903
767 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 904 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
768 { 905 {
769 Console.WriteLine(text); 906 Console.WriteLine(text);
@@ -786,6 +923,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
786 { 923 {
787 m_host.AddScriptLPS(1); 924 m_host.AddScriptLPS(1);
788 925
926 if (channelID == 0)
927// m_SayShoutCount++;
928 CheckSayShoutTime();
929
930 if (m_SayShoutCount >= 11)
931 ScriptSleep(2000);
932
789 if (text.Length > 1023) 933 if (text.Length > 1023)
790 text = text.Substring(0, 1023); 934 text = text.Substring(0, 1023);
791 935
@@ -817,22 +961,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
817 961
818 public void llRegionSayTo(string target, int channel, string msg) 962 public void llRegionSayTo(string target, int channel, string msg)
819 { 963 {
964 string error = String.Empty;
965
820 if (msg.Length > 1023) 966 if (msg.Length > 1023)
821 msg = msg.Substring(0, 1023); 967 msg = msg.Substring(0, 1023);
822 968
823 m_host.AddScriptLPS(1); 969 m_host.AddScriptLPS(1);
824 970
825 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
826 {
827 return;
828 }
829
830 UUID TargetID; 971 UUID TargetID;
831 UUID.TryParse(target, out TargetID); 972 UUID.TryParse(target, out TargetID);
832 973
833 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 974 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
834 if (wComm != null) 975 if (wComm != null)
835 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 976 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
977 LSLError(error);
836 } 978 }
837 979
838 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 980 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1088,10 +1230,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1088 return detectedParams.TouchUV; 1230 return detectedParams.TouchUV;
1089 } 1231 }
1090 1232
1233 [DebuggerNonUserCode]
1091 public virtual void llDie() 1234 public virtual void llDie()
1092 { 1235 {
1093 m_host.AddScriptLPS(1); 1236 m_host.AddScriptLPS(1);
1094 throw new SelfDeleteException(); 1237 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1095 } 1238 }
1096 1239
1097 public LSL_Float llGround(LSL_Vector offset) 1240 public LSL_Float llGround(LSL_Vector offset)
@@ -1164,6 +1307,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1164 1307
1165 public void llSetStatus(int status, int value) 1308 public void llSetStatus(int status, int value)
1166 { 1309 {
1310 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1311 return;
1167 m_host.AddScriptLPS(1); 1312 m_host.AddScriptLPS(1);
1168 1313
1169 int statusrotationaxis = 0; 1314 int statusrotationaxis = 0;
@@ -1187,6 +1332,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1187 if (!allow) 1332 if (!allow)
1188 return; 1333 return;
1189 1334
1335 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1336 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1337 return;
1338
1190 m_host.ScriptSetPhysicsStatus(true); 1339 m_host.ScriptSetPhysicsStatus(true);
1191 } 1340 }
1192 else 1341 else
@@ -1396,6 +1545,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1396 { 1545 {
1397 m_host.AddScriptLPS(1); 1546 m_host.AddScriptLPS(1);
1398 1547
1548 SetColor(m_host, color, face);
1549 }
1550
1551 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1552 {
1553 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1554 return;
1555
1556 Primitive.TextureEntry tex = part.Shape.Textures;
1557 Color4 texcolor;
1558 if (face >= 0 && face < GetNumberOfSides(part))
1559 {
1560 texcolor = tex.CreateFace((uint)face).RGBA;
1561 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1562 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1563 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1564 tex.FaceTextures[face].RGBA = texcolor;
1565 part.UpdateTextureEntry(tex.GetBytes());
1566 return;
1567 }
1568 else if (face == ScriptBaseClass.ALL_SIDES)
1569 {
1570 for (uint i = 0; i < GetNumberOfSides(part); i++)
1571 {
1572 if (tex.FaceTextures[i] != null)
1573 {
1574 texcolor = tex.FaceTextures[i].RGBA;
1575 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1576 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1577 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1578 tex.FaceTextures[i].RGBA = texcolor;
1579 }
1580 texcolor = tex.DefaultTexture.RGBA;
1581 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1582 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1583 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1584 tex.DefaultTexture.RGBA = texcolor;
1585 }
1586 part.UpdateTextureEntry(tex.GetBytes());
1587 return;
1588 }
1589
1399 if (face == ScriptBaseClass.ALL_SIDES) 1590 if (face == ScriptBaseClass.ALL_SIDES)
1400 face = SceneObjectPart.ALL_SIDES; 1591 face = SceneObjectPart.ALL_SIDES;
1401 1592
@@ -1404,6 +1595,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1404 1595
1405 public void SetTexGen(SceneObjectPart part, int face,int style) 1596 public void SetTexGen(SceneObjectPart part, int face,int style)
1406 { 1597 {
1598 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1599 return;
1600
1407 Primitive.TextureEntry tex = part.Shape.Textures; 1601 Primitive.TextureEntry tex = part.Shape.Textures;
1408 MappingType textype; 1602 MappingType textype;
1409 textype = MappingType.Default; 1603 textype = MappingType.Default;
@@ -1434,6 +1628,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1434 1628
1435 public void SetGlow(SceneObjectPart part, int face, float glow) 1629 public void SetGlow(SceneObjectPart part, int face, float glow)
1436 { 1630 {
1631 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1632 return;
1633
1437 Primitive.TextureEntry tex = part.Shape.Textures; 1634 Primitive.TextureEntry tex = part.Shape.Textures;
1438 if (face >= 0 && face < GetNumberOfSides(part)) 1635 if (face >= 0 && face < GetNumberOfSides(part))
1439 { 1636 {
@@ -1459,6 +1656,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1459 1656
1460 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1657 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1461 { 1658 {
1659 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1660 return;
1462 1661
1463 Shininess sval = new Shininess(); 1662 Shininess sval = new Shininess();
1464 1663
@@ -1509,6 +1708,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1509 1708
1510 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1709 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1511 { 1710 {
1711 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1712 return;
1713
1512 Primitive.TextureEntry tex = part.Shape.Textures; 1714 Primitive.TextureEntry tex = part.Shape.Textures;
1513 if (face >= 0 && face < GetNumberOfSides(part)) 1715 if (face >= 0 && face < GetNumberOfSides(part))
1514 { 1716 {
@@ -1569,13 +1771,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1569 m_host.AddScriptLPS(1); 1771 m_host.AddScriptLPS(1);
1570 1772
1571 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1773 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1572 1774 if (parts.Count > 0)
1573 foreach (SceneObjectPart part in parts) 1775 {
1574 SetAlpha(part, alpha, face); 1776 try
1777 {
1778 foreach (SceneObjectPart part in parts)
1779 SetAlpha(part, alpha, face);
1780 }
1781 finally
1782 {
1783 }
1784 }
1575 } 1785 }
1576 1786
1577 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1787 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1578 { 1788 {
1789 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1790 return;
1791
1579 Primitive.TextureEntry tex = part.Shape.Textures; 1792 Primitive.TextureEntry tex = part.Shape.Textures;
1580 Color4 texcolor; 1793 Color4 texcolor;
1581 if (face >= 0 && face < GetNumberOfSides(part)) 1794 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1628,7 +1841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1628 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1841 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1629 float wind, float tension, LSL_Vector Force) 1842 float wind, float tension, LSL_Vector Force)
1630 { 1843 {
1631 if (part == null) 1844 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1632 return; 1845 return;
1633 1846
1634 if (flexi) 1847 if (flexi)
@@ -1662,7 +1875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1875 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1876 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1877 {
1665 if (part == null) 1878 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1879 return;
1667 1880
1668 if (light) 1881 if (light)
@@ -1695,11 +1908,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1695 Primitive.TextureEntry tex = part.Shape.Textures; 1908 Primitive.TextureEntry tex = part.Shape.Textures;
1696 Color4 texcolor; 1909 Color4 texcolor;
1697 LSL_Vector rgb = new LSL_Vector(); 1910 LSL_Vector rgb = new LSL_Vector();
1911 int nsides = GetNumberOfSides(part);
1912
1698 if (face == ScriptBaseClass.ALL_SIDES) 1913 if (face == ScriptBaseClass.ALL_SIDES)
1699 { 1914 {
1700 int i; 1915 int i;
1701 1916 for (i = 0; i < nsides; i++)
1702 for (i = 0 ; i < GetNumberOfSides(part); i++)
1703 { 1917 {
1704 texcolor = tex.GetFace((uint)i).RGBA; 1918 texcolor = tex.GetFace((uint)i).RGBA;
1705 rgb.x += texcolor.R; 1919 rgb.x += texcolor.R;
@@ -1707,14 +1921,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1707 rgb.z += texcolor.B; 1921 rgb.z += texcolor.B;
1708 } 1922 }
1709 1923
1710 rgb.x /= (float)GetNumberOfSides(part); 1924 float invnsides = 1.0f / (float)nsides;
1711 rgb.y /= (float)GetNumberOfSides(part); 1925
1712 rgb.z /= (float)GetNumberOfSides(part); 1926 rgb.x *= invnsides;
1927 rgb.y *= invnsides;
1928 rgb.z *= invnsides;
1713 1929
1714 return rgb; 1930 return rgb;
1715 } 1931 }
1716 1932 if (face >= 0 && face < nsides)
1717 if (face >= 0 && face < GetNumberOfSides(part))
1718 { 1933 {
1719 texcolor = tex.GetFace((uint)face).RGBA; 1934 texcolor = tex.GetFace((uint)face).RGBA;
1720 rgb.x = texcolor.R; 1935 rgb.x = texcolor.R;
@@ -1741,15 +1956,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1741 m_host.AddScriptLPS(1); 1956 m_host.AddScriptLPS(1);
1742 1957
1743 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1958 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1744 1959 if (parts.Count > 0)
1745 foreach (SceneObjectPart part in parts) 1960 {
1746 SetTexture(part, texture, face); 1961 try
1747 1962 {
1963 foreach (SceneObjectPart part in parts)
1964 SetTexture(part, texture, face);
1965 }
1966 finally
1967 {
1968 }
1969 }
1748 ScriptSleep(200); 1970 ScriptSleep(200);
1749 } 1971 }
1750 1972
1751 protected void SetTexture(SceneObjectPart part, string texture, int face) 1973 protected void SetTexture(SceneObjectPart part, string texture, int face)
1752 { 1974 {
1975 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1976 return;
1977
1753 UUID textureID = new UUID(); 1978 UUID textureID = new UUID();
1754 1979
1755 textureID = InventoryKey(texture, (int)AssetType.Texture); 1980 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1794,6 +2019,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1794 2019
1795 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2020 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1796 { 2021 {
2022 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2023 return;
2024
1797 Primitive.TextureEntry tex = part.Shape.Textures; 2025 Primitive.TextureEntry tex = part.Shape.Textures;
1798 if (face >= 0 && face < GetNumberOfSides(part)) 2026 if (face >= 0 && face < GetNumberOfSides(part))
1799 { 2027 {
@@ -1830,6 +2058,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1830 2058
1831 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2059 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1832 { 2060 {
2061 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2062 return;
2063
1833 Primitive.TextureEntry tex = part.Shape.Textures; 2064 Primitive.TextureEntry tex = part.Shape.Textures;
1834 if (face >= 0 && face < GetNumberOfSides(part)) 2065 if (face >= 0 && face < GetNumberOfSides(part))
1835 { 2066 {
@@ -1866,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1866 2097
1867 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2098 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1868 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1869 Primitive.TextureEntry tex = part.Shape.Textures; 2103 Primitive.TextureEntry tex = part.Shape.Textures;
1870 if (face >= 0 && face < GetNumberOfSides(part)) 2104 if (face >= 0 && face < GetNumberOfSides(part))
1871 { 2105 {
@@ -1986,7 +2220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1986 2220
1987 bool sameParcel = here.GlobalID == there.GlobalID; 2221 bool sameParcel = here.GlobalID == there.GlobalID;
1988 2222
1989 if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2223 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
1990 { 2224 {
1991 return 0; 2225 return 0;
1992 } 2226 }
@@ -2035,24 +2269,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2035 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2269 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2036 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2270 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2037 { 2271 {
2038 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2272 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2273 return;
2274
2039 LSL_Vector currentPos = GetPartLocalPos(part); 2275 LSL_Vector currentPos = GetPartLocalPos(part);
2276 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2040 2277
2041 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2042 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2043 2278
2044 if (part.ParentGroup.RootPart == part) 2279 if (part.ParentGroup.RootPart == part)
2045 { 2280 {
2046 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2047 targetPos.z = ground;
2048 SceneObjectGroup parent = part.ParentGroup; 2281 SceneObjectGroup parent = part.ParentGroup;
2049 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2282 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2050 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2283 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2284 return;
2285 Util.FireAndForget(delegate(object x) {
2286 parent.UpdateGroupPosition(dest);
2287 });
2051 } 2288 }
2052 else 2289 else
2053 { 2290 {
2054 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2291 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2055 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2056 SceneObjectGroup parent = part.ParentGroup; 2292 SceneObjectGroup parent = part.ParentGroup;
2057 parent.HasGroupChanged = true; 2293 parent.HasGroupChanged = true;
2058 parent.ScheduleGroupForTerseUpdate(); 2294 parent.ScheduleGroupForTerseUpdate();
@@ -2085,17 +2321,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2085 else 2321 else
2086 { 2322 {
2087 if (part.ParentGroup.IsAttachment) 2323 if (part.ParentGroup.IsAttachment)
2088 {
2089 pos = part.AttachedPos; 2324 pos = part.AttachedPos;
2090 }
2091 else 2325 else
2092 {
2093 pos = part.AbsolutePosition; 2326 pos = part.AbsolutePosition;
2094 }
2095 } 2327 }
2096 2328
2097// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2098
2099 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2329 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2100 } 2330 }
2101 2331
@@ -2104,18 +2334,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2104 m_host.AddScriptLPS(1); 2334 m_host.AddScriptLPS(1);
2105 2335
2106 // try to let this work as in SL... 2336 // try to let this work as in SL...
2107 if (m_host.ParentID == 0) 2337 if (m_host.LinkNum < 2)
2108 { 2338 {
2109 // special case: If we are root, rotate complete SOG to new rotation 2339 // Special case: If we are root, rotate complete SOG to new
2340 // rotation.
2341 // We are root if the link number is 0 (single prim) or 1
2342 // (root prim). ParentID may be nonzero in attachments and
2343 // using it would cause attachments and HUDs to rotate
2344 // to the wrong positions.
2345
2110 SetRot(m_host, Rot2Quaternion(rot)); 2346 SetRot(m_host, Rot2Quaternion(rot));
2111 } 2347 }
2112 else 2348 else
2113 { 2349 {
2114 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2350 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2115 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2351 SceneObjectPart rootPart;
2116 if (rootPart != null) // better safe than sorry 2352 if (m_host.ParentGroup != null) // better safe than sorry
2117 { 2353 {
2118 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2354 rootPart = m_host.ParentGroup.RootPart;
2355 if (rootPart != null)
2356 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2119 } 2357 }
2120 } 2358 }
2121 2359
@@ -2125,31 +2363,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2125 public void llSetLocalRot(LSL_Rotation rot) 2363 public void llSetLocalRot(LSL_Rotation rot)
2126 { 2364 {
2127 m_host.AddScriptLPS(1); 2365 m_host.AddScriptLPS(1);
2366
2128 SetRot(m_host, Rot2Quaternion(rot)); 2367 SetRot(m_host, Rot2Quaternion(rot));
2129 ScriptSleep(200); 2368 ScriptSleep(200);
2130 } 2369 }
2131 2370
2132 protected void SetRot(SceneObjectPart part, Quaternion rot) 2371 protected void SetRot(SceneObjectPart part, Quaternion rot)
2133 { 2372 {
2134 part.UpdateRotation(rot); 2373 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2135 // Update rotation does not move the object in the physics scene if it's a linkset. 2374 return;
2136 2375
2137//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2376 bool isroot = (part == part.ParentGroup.RootPart);
2138// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2377 bool isphys;
2139 2378
2140 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2141 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2142 // It's perfectly okay when the object is not an active physical body though.
2143 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2144 // but only if the object is not physial and active. This is important for rotating doors.
2145 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2146 // scene
2147 PhysicsActor pa = part.PhysActor; 2379 PhysicsActor pa = part.PhysActor;
2148 2380
2149 if (pa != null && !pa.IsPhysical) 2381 // keep using physactor ideia of isphysical
2382 // it should be SOP ideia of that
2383 // not much of a issue with ubitODE
2384 if (pa != null && pa.IsPhysical)
2385 isphys = true;
2386 else
2387 isphys = false;
2388
2389 // SL doesn't let scripts rotate root of physical linksets
2390 if (isroot && isphys)
2391 return;
2392
2393 part.UpdateRotation(rot);
2394
2395 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2396 // so do a nasty update of parts positions if is a root part rotation
2397 if (isroot && pa != null) // with if above implies non physical root part
2150 { 2398 {
2151 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2399 part.ParentGroup.ResetChildPrimPhysicsPositions();
2152 } 2400 }
2401 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2402 {
2403 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2404 if (sittingavas.Count > 0)
2405 {
2406 foreach (ScenePresence av in sittingavas)
2407 {
2408 if (isroot || part.LocalId == av.ParentID)
2409 av.SendTerseUpdateToAllClients();
2410 }
2411 }
2412 }
2153 } 2413 }
2154 2414
2155 /// <summary> 2415 /// <summary>
@@ -2197,8 +2457,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2197 2457
2198 public LSL_Rotation llGetLocalRot() 2458 public LSL_Rotation llGetLocalRot()
2199 { 2459 {
2460 return GetPartLocalRot(m_host);
2461 }
2462
2463 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2464 {
2200 m_host.AddScriptLPS(1); 2465 m_host.AddScriptLPS(1);
2201 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2466 Quaternion rot = part.RotationOffset;
2467 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2202 } 2468 }
2203 2469
2204 public void llSetForce(LSL_Vector force, int local) 2470 public void llSetForce(LSL_Vector force, int local)
@@ -2282,16 +2548,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2282 m_host.ApplyImpulse(v, local != 0); 2548 m_host.ApplyImpulse(v, local != 0);
2283 } 2549 }
2284 2550
2551
2285 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2552 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2286 { 2553 {
2287 m_host.AddScriptLPS(1); 2554 m_host.AddScriptLPS(1);
2288 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2555 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2289 } 2556 }
2290 2557
2291 public void llSetTorque(LSL_Vector torque, int local) 2558 public void llSetTorque(LSL_Vector torque, int local)
2292 { 2559 {
2293 m_host.AddScriptLPS(1); 2560 m_host.AddScriptLPS(1);
2294 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2561 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2295 } 2562 }
2296 2563
2297 public LSL_Vector llGetTorque() 2564 public LSL_Vector llGetTorque()
@@ -2308,20 +2575,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2308 llSetTorque(torque, local); 2575 llSetTorque(torque, local);
2309 } 2576 }
2310 2577
2578 public void llSetVelocity(LSL_Vector vel, int local)
2579 {
2580 m_host.AddScriptLPS(1);
2581 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2582 }
2583
2311 public LSL_Vector llGetVel() 2584 public LSL_Vector llGetVel()
2312 { 2585 {
2313 m_host.AddScriptLPS(1); 2586 m_host.AddScriptLPS(1);
2314 2587
2315 Vector3 vel; 2588 Vector3 vel = Vector3.Zero;
2316 2589
2317 if (m_host.ParentGroup.IsAttachment) 2590 if (m_host.ParentGroup.IsAttachment)
2318 { 2591 {
2319 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2592 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2320 vel = avatar.Velocity; 2593 if (avatar != null)
2594 vel = avatar.Velocity;
2321 } 2595 }
2322 else 2596 else
2323 { 2597 {
2324 vel = m_host.Velocity; 2598 vel = m_host.ParentGroup.RootPart.Velocity;
2325 } 2599 }
2326 2600
2327 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2601 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2333,10 +2607,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2333 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2607 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2334 } 2608 }
2335 2609
2610 public void llSetAngularVelocity(LSL_Vector avel, int local)
2611 {
2612 m_host.AddScriptLPS(1);
2613 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2614 }
2615
2336 public LSL_Vector llGetOmega() 2616 public LSL_Vector llGetOmega()
2337 { 2617 {
2338 m_host.AddScriptLPS(1); 2618 m_host.AddScriptLPS(1);
2339 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2619 Vector3 avel = m_host.AngularVelocity;
2620 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2340 } 2621 }
2341 2622
2342 public LSL_Float llGetTimeOfDay() 2623 public LSL_Float llGetTimeOfDay()
@@ -2865,16 +3146,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2865 new_group.RootPart.UUID.ToString()) }, 3146 new_group.RootPart.UUID.ToString()) },
2866 new DetectParams[0])); 3147 new DetectParams[0]));
2867 3148
2868 float groupmass = new_group.GetMass(); 3149 // do recoil
3150 SceneObjectGroup hostgrp = m_host.ParentGroup;
3151 if (hostgrp == null)
3152 return;
3153
3154 if (hostgrp.IsAttachment) // don't recoil avatars
3155 return;
2869 3156
2870 PhysicsActor pa = new_group.RootPart.PhysActor; 3157 PhysicsActor pa = new_group.RootPart.PhysActor;
2871 3158
2872 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3159 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2873 { 3160 {
2874 //Recoil. 3161 float groupmass = new_group.GetMass();
2875 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3162 llvel *= -groupmass;
3163 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2876 } 3164 }
2877 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3165 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3166 return;
3167
2878 }); 3168 });
2879 3169
2880 //ScriptSleep((int)((groupmass * velmag) / 10)); 3170 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2889,35 +3179,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2889 public void llLookAt(LSL_Vector target, double strength, double damping) 3179 public void llLookAt(LSL_Vector target, double strength, double damping)
2890 { 3180 {
2891 m_host.AddScriptLPS(1); 3181 m_host.AddScriptLPS(1);
2892 // Determine where we are looking from
2893 LSL_Vector from = llGetPos();
2894 3182
2895 // Work out the normalised vector from the source to the target 3183 // Get the normalized vector to the target
2896 LSL_Vector delta = llVecNorm(target - from); 3184 LSL_Vector d1 = llVecNorm(target - llGetPos());
2897 LSL_Vector angle = new LSL_Vector(0,0,0);
2898 3185
2899 // Calculate the yaw 3186 // Get the bearing (yaw)
2900 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3187 LSL_Vector a1 = new LSL_Vector(0,0,0);
2901 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3188 a1.z = llAtan2(d1.y, d1.x);
2902 3189
2903 // Calculate pitch 3190 // Get the elevation (pitch)
2904 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3191 LSL_Vector a2 = new LSL_Vector(0,0,0);
3192 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2905 3193
2906 // we need to convert from a vector describing 3194 LSL_Rotation r1 = llEuler2Rot(a1);
2907 // the angles of rotation in radians into rotation value 3195 LSL_Rotation r2 = llEuler2Rot(a2);
2908 LSL_Rotation rot = llEuler2Rot(angle); 3196 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2909
2910 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2911 // set the rotation of the object, copy that behavior
2912 PhysicsActor pa = m_host.PhysActor;
2913 3197
2914 if (strength == 0 || pa == null || !pa.IsPhysical) 3198 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2915 { 3199 {
2916 llSetRot(rot); 3200 // Do nothing if either value is 0 (this has been checked in SL)
3201 if (strength <= 0.0 || damping <= 0.0)
3202 return;
3203
3204 llSetRot(r3 * r2 * r1);
2917 } 3205 }
2918 else 3206 else
2919 { 3207 {
2920 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3208 if (strength == 0)
3209 {
3210 llSetRot(r3 * r2 * r1);
3211 return;
3212 }
3213
3214 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2921 } 3215 }
2922 } 3216 }
2923 3217
@@ -2963,17 +3257,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2963 } 3257 }
2964 else 3258 else
2965 { 3259 {
2966 if (m_host.IsRoot) 3260 // new SL always returns object mass
2967 { 3261// if (m_host.IsRoot)
3262// {
2968 return m_host.ParentGroup.GetMass(); 3263 return m_host.ParentGroup.GetMass();
2969 } 3264// }
2970 else 3265// else
2971 { 3266// {
2972 return m_host.GetMass(); 3267// return m_host.GetMass();
2973 } 3268// }
2974 } 3269 }
2975 } 3270 }
2976 3271
3272
3273 public LSL_Float llGetMassMKS()
3274 {
3275 return 100f * llGetMass();
3276 }
3277
2977 public void llCollisionFilter(string name, string id, int accept) 3278 public void llCollisionFilter(string name, string id, int accept)
2978 { 3279 {
2979 m_host.AddScriptLPS(1); 3280 m_host.AddScriptLPS(1);
@@ -3021,8 +3322,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3021 { 3322 {
3022 // Unregister controls from Presence 3323 // Unregister controls from Presence
3023 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3324 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3024 // Remove Take Control permission.
3025 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3026 } 3325 }
3027 } 3326 }
3028 } 3327 }
@@ -3048,7 +3347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3048 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3347 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3049 3348
3050 if (attachmentsModule != null) 3349 if (attachmentsModule != null)
3051 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3350 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3052 else 3351 else
3053 return false; 3352 return false;
3054 } 3353 }
@@ -3078,9 +3377,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3078 { 3377 {
3079 m_host.AddScriptLPS(1); 3378 m_host.AddScriptLPS(1);
3080 3379
3081// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3082// return;
3083
3084 if (m_item.PermsGranter != m_host.OwnerID) 3380 if (m_item.PermsGranter != m_host.OwnerID)
3085 return; 3381 return;
3086 3382
@@ -3123,6 +3419,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 3419
3124 public void llInstantMessage(string user, string message) 3420 public void llInstantMessage(string user, string message)
3125 { 3421 {
3422 UUID result;
3423 if (!UUID.TryParse(user, out result))
3424 {
3425 ShoutError("An invalid key was passed to llInstantMessage");
3426 ScriptSleep(2000);
3427 return;
3428 }
3429
3430
3126 m_host.AddScriptLPS(1); 3431 m_host.AddScriptLPS(1);
3127 3432
3128 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3433 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3137,14 +3442,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3137 UUID friendTransactionID = UUID.Random(); 3442 UUID friendTransactionID = UUID.Random();
3138 3443
3139 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3444 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3140 3445
3141 GridInstantMessage msg = new GridInstantMessage(); 3446 GridInstantMessage msg = new GridInstantMessage();
3142 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3447 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3143 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3448 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3144 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3449 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3145// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3450// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3146// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3451// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3147 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3452// DateTime dt = DateTime.UtcNow;
3453//
3454// // Ticks from UtcNow, but make it look like local. Evil, huh?
3455// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3456//
3457// try
3458// {
3459// // Convert that to the PST timezone
3460// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3461// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3462// }
3463// catch
3464// {
3465// // No logging here, as it could be VERY spammy
3466// }
3467//
3468// // And make it look local again to fool the unix time util
3469// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3470
3471 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3472
3148 //if (client != null) 3473 //if (client != null)
3149 //{ 3474 //{
3150 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3475 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3158,12 +3483,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3158 msg.message = message.Substring(0, 1024); 3483 msg.message = message.Substring(0, 1024);
3159 else 3484 else
3160 msg.message = message; 3485 msg.message = message;
3161 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3486 msg.dialog = (byte)19; // MessageFromObject
3162 msg.fromGroup = false;// fromGroup; 3487 msg.fromGroup = false;// fromGroup;
3163 msg.offline = (byte)0; //offline; 3488 msg.offline = (byte)0; //offline;
3164 msg.ParentEstateID = 0; //ParentEstateID; 3489 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3165 msg.Position = new Vector3(m_host.AbsolutePosition); 3490 msg.Position = new Vector3(m_host.AbsolutePosition);
3166 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3491 msg.RegionID = World.RegionInfo.RegionID.Guid;
3167 msg.binaryBucket 3492 msg.binaryBucket
3168 = Util.StringToBytes256( 3493 = Util.StringToBytes256(
3169 "{0}/{1}/{2}/{3}", 3494 "{0}/{1}/{2}/{3}",
@@ -3191,7 +3516,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3191 } 3516 }
3192 3517
3193 emailModule.SendEmail(m_host.UUID, address, subject, message); 3518 emailModule.SendEmail(m_host.UUID, address, subject, message);
3194 llSleep(EMAIL_PAUSE_TIME); 3519 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3195 } 3520 }
3196 3521
3197 public void llGetNextEmail(string address, string subject) 3522 public void llGetNextEmail(string address, string subject)
@@ -3437,7 +3762,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3437 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3762 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3438 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3763 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3439 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3764 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3765 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3440 ScriptBaseClass.PERMISSION_ATTACH; 3766 ScriptBaseClass.PERMISSION_ATTACH;
3767
3441 } 3768 }
3442 else 3769 else
3443 { 3770 {
@@ -3472,11 +3799,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3472 3799
3473 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3800 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3474 { 3801 {
3475 lock (m_host.TaskInventory) 3802 m_host.TaskInventory.LockItemsForWrite(true);
3476 { 3803 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3477 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3804 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3478 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3805 m_host.TaskInventory.LockItemsForWrite(false);
3479 }
3480 3806
3481 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3807 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3482 "run_time_permissions", new Object[] { 3808 "run_time_permissions", new Object[] {
@@ -3519,11 +3845,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3519 3845
3520 if (!m_waitingForScriptAnswer) 3846 if (!m_waitingForScriptAnswer)
3521 { 3847 {
3522 lock (m_host.TaskInventory) 3848 m_host.TaskInventory.LockItemsForWrite(true);
3523 { 3849 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3524 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3850 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3525 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3851 m_host.TaskInventory.LockItemsForWrite(false);
3526 }
3527 3852
3528 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3853 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3529 m_waitingForScriptAnswer=true; 3854 m_waitingForScriptAnswer=true;
@@ -3552,14 +3877,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3552 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3877 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3553 llReleaseControls(); 3878 llReleaseControls();
3554 3879
3555 lock (m_host.TaskInventory) 3880 m_host.TaskInventory.LockItemsForWrite(true);
3556 { 3881 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3557 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3882 m_host.TaskInventory.LockItemsForWrite(false);
3558 } 3883
3559 3884 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3560 m_ScriptEngine.PostScriptEvent( 3885 "run_time_permissions", new Object[] {
3561 m_item.ItemID, 3886 new LSL_Integer(answer) },
3562 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3887 new DetectParams[0]));
3563 } 3888 }
3564 3889
3565 public LSL_String llGetPermissionsKey() 3890 public LSL_String llGetPermissionsKey()
@@ -3598,14 +3923,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3598 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3923 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3599 { 3924 {
3600 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3925 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3601 3926 if (parts.Count > 0)
3602 foreach (SceneObjectPart part in parts) 3927 {
3603 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3928 try
3929 {
3930 foreach (SceneObjectPart part in parts)
3931 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3932 }
3933 finally
3934 {
3935 }
3936 }
3604 } 3937 }
3605 3938
3606 public void llCreateLink(string target, int parent) 3939 public void llCreateLink(string target, int parent)
3607 { 3940 {
3608 m_host.AddScriptLPS(1); 3941 m_host.AddScriptLPS(1);
3942
3609 UUID targetID; 3943 UUID targetID;
3610 3944
3611 if (!UUID.TryParse(target, out targetID)) 3945 if (!UUID.TryParse(target, out targetID))
@@ -3711,10 +4045,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3711 // Restructuring Multiple Prims. 4045 // Restructuring Multiple Prims.
3712 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4046 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3713 parts.Remove(parentPrim.RootPart); 4047 parts.Remove(parentPrim.RootPart);
3714 foreach (SceneObjectPart part in parts) 4048 if (parts.Count > 0)
3715 { 4049 {
3716 parentPrim.DelinkFromGroup(part.LocalId, true); 4050 try
4051 {
4052 foreach (SceneObjectPart part in parts)
4053 {
4054 parentPrim.DelinkFromGroup(part.LocalId, true);
4055 }
4056 }
4057 finally
4058 {
4059 }
3717 } 4060 }
4061
3718 parentPrim.HasGroupChanged = true; 4062 parentPrim.HasGroupChanged = true;
3719 parentPrim.ScheduleGroupForFullUpdate(); 4063 parentPrim.ScheduleGroupForFullUpdate();
3720 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4064 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3723,12 +4067,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3723 { 4067 {
3724 SceneObjectPart newRoot = parts[0]; 4068 SceneObjectPart newRoot = parts[0];
3725 parts.Remove(newRoot); 4069 parts.Remove(newRoot);
3726 foreach (SceneObjectPart part in parts) 4070
4071 try
3727 { 4072 {
3728 // Required for linking 4073 foreach (SceneObjectPart part in parts)
3729 part.ClearUpdateSchedule(); 4074 {
3730 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4075 part.ClearUpdateSchedule();
4076 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4077 }
3731 } 4078 }
4079 finally
4080 {
4081 }
4082
4083
3732 newRoot.ParentGroup.HasGroupChanged = true; 4084 newRoot.ParentGroup.HasGroupChanged = true;
3733 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4085 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3734 } 4086 }
@@ -3748,6 +4100,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3748 public void llBreakAllLinks() 4100 public void llBreakAllLinks()
3749 { 4101 {
3750 m_host.AddScriptLPS(1); 4102 m_host.AddScriptLPS(1);
4103
4104 TaskInventoryItem item = m_item;
4105
4106 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4107 && !m_automaticLinkPermission)
4108 {
4109 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4110 return;
4111 }
4112
3751 SceneObjectGroup parentPrim = m_host.ParentGroup; 4113 SceneObjectGroup parentPrim = m_host.ParentGroup;
3752 if (parentPrim.AttachmentPoint != 0) 4114 if (parentPrim.AttachmentPoint != 0)
3753 return; // Fail silently if attached 4115 return; // Fail silently if attached
@@ -3767,25 +4129,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 public LSL_String llGetLinkKey(int linknum) 4129 public LSL_String llGetLinkKey(int linknum)
3768 { 4130 {
3769 m_host.AddScriptLPS(1); 4131 m_host.AddScriptLPS(1);
3770 List<UUID> keytable = new List<UUID>();
3771 // parse for sitting avatare-uuids
3772 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3773 {
3774 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3775 keytable.Add(presence.UUID);
3776 });
3777
3778 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3779 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3780 {
3781 return keytable[totalprims - linknum].ToString();
3782 }
3783
3784 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3785 {
3786 return m_host.UUID.ToString();
3787 }
3788
3789 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4132 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3790 if (part != null) 4133 if (part != null)
3791 { 4134 {
@@ -3793,6 +4136,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3793 } 4136 }
3794 else 4137 else
3795 { 4138 {
4139 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4140 {
4141 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4142
4143 if (linknum < 0)
4144 return UUID.Zero.ToString();
4145
4146 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4147 if (avatars.Count > linknum)
4148 {
4149 return avatars[linknum].UUID.ToString();
4150 }
4151 }
3796 return UUID.Zero.ToString(); 4152 return UUID.Zero.ToString();
3797 } 4153 }
3798 } 4154 }
@@ -3892,17 +4248,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3892 m_host.AddScriptLPS(1); 4248 m_host.AddScriptLPS(1);
3893 int count = 0; 4249 int count = 0;
3894 4250
3895 lock (m_host.TaskInventory) 4251 m_host.TaskInventory.LockItemsForRead(true);
4252 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3896 { 4253 {
3897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4254 if (inv.Value.Type == type || type == -1)
3898 { 4255 {
3899 if (inv.Value.Type == type || type == -1) 4256 count = count + 1;
3900 {
3901 count = count + 1;
3902 }
3903 } 4257 }
3904 } 4258 }
3905 4259
4260 m_host.TaskInventory.LockItemsForRead(false);
3906 return count; 4261 return count;
3907 } 4262 }
3908 4263
@@ -3911,16 +4266,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3911 m_host.AddScriptLPS(1); 4266 m_host.AddScriptLPS(1);
3912 ArrayList keys = new ArrayList(); 4267 ArrayList keys = new ArrayList();
3913 4268
3914 lock (m_host.TaskInventory) 4269 m_host.TaskInventory.LockItemsForRead(true);
4270 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3915 { 4271 {
3916 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4272 if (inv.Value.Type == type || type == -1)
3917 { 4273 {
3918 if (inv.Value.Type == type || type == -1) 4274 keys.Add(inv.Value.Name);
3919 {
3920 keys.Add(inv.Value.Name);
3921 }
3922 } 4275 }
3923 } 4276 }
4277 m_host.TaskInventory.LockItemsForRead(false);
3924 4278
3925 if (keys.Count == 0) 4279 if (keys.Count == 0)
3926 { 4280 {
@@ -3958,7 +4312,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3958 if (item == null) 4312 if (item == null)
3959 { 4313 {
3960 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4314 llSay(0, String.Format("Could not find object '{0}'", inventory));
3961 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4315 return;
4316// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3962 } 4317 }
3963 4318
3964 UUID objId = item.ItemID; 4319 UUID objId = item.ItemID;
@@ -3986,33 +4341,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3986 return; 4341 return;
3987 } 4342 }
3988 } 4343 }
4344
3989 // destination is an avatar 4345 // destination is an avatar
3990 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4346 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3991 4347
3992 if (agentItem == null) 4348 if (agentItem == null)
3993 return; 4349 return;
3994 4350
3995 if (m_TransferModule != null) 4351 byte[] bucket = new byte[1];
3996 { 4352 bucket[0] = (byte)item.Type;
3997 byte[] bucket = new byte[] { (byte)item.Type }; 4353 //byte[] objBytes = agentItem.ID.GetBytes();
4354 //Array.Copy(objBytes, 0, bucket, 1, 16);
3998 4355
3999 GridInstantMessage msg = new GridInstantMessage(World, 4356 GridInstantMessage msg = new GridInstantMessage(World,
4000 m_host.UUID, m_host.Name + ", an object owned by " + 4357 m_host.OwnerID, m_host.Name, destId,
4001 resolveName(m_host.OwnerID) + ",", destId, 4358 (byte)InstantMessageDialog.TaskInventoryOffered,
4002 (byte)InstantMessageDialog.TaskInventoryOffered, 4359 false, item.Name+". "+m_host.Name+" is located at "+
4003 false, item.Name + "\n" + m_host.Name + " is located at " + 4360 World.RegionInfo.RegionName+" "+
4004 World.RegionInfo.RegionName+" "+ 4361 m_host.AbsolutePosition.ToString(),
4005 m_host.AbsolutePosition.ToString(), 4362 agentItem.ID, true, m_host.AbsolutePosition,
4006 agentItem.ID, true, m_host.AbsolutePosition, 4363 bucket);
4007 bucket);
4008 4364
4009 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4365 ScenePresence sp;
4010 }
4011 4366
4367 if (World.TryGetScenePresence(destId, out sp))
4368 {
4369 sp.ControllingClient.SendInstantMessage(msg);
4370 }
4371 else
4372 {
4373 if (m_TransferModule != null)
4374 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4375 }
4376
4377 //This delay should only occur when giving inventory to avatars.
4012 ScriptSleep(3000); 4378 ScriptSleep(3000);
4013 } 4379 }
4014 } 4380 }
4015 4381
4382 [DebuggerNonUserCode]
4016 public void llRemoveInventory(string name) 4383 public void llRemoveInventory(string name)
4017 { 4384 {
4018 m_host.AddScriptLPS(1); 4385 m_host.AddScriptLPS(1);
@@ -4058,109 +4425,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4058 { 4425 {
4059 m_host.AddScriptLPS(1); 4426 m_host.AddScriptLPS(1);
4060 4427
4061 UUID uuid = (UUID)id; 4428 UUID uuid;
4062 PresenceInfo pinfo = null; 4429 if (UUID.TryParse(id, out uuid))
4063 UserAccount account;
4064
4065 UserInfoCacheEntry ce;
4066 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4067 { 4430 {
4068 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4431 PresenceInfo pinfo = null;
4069 if (account == null) 4432 UserAccount account;
4433
4434 UserInfoCacheEntry ce;
4435 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4070 { 4436 {
4071 m_userInfoCache[uuid] = null; // Cache negative 4437 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4072 return UUID.Zero.ToString(); 4438 if (account == null)
4073 } 4439 {
4440 m_userInfoCache[uuid] = null; // Cache negative
4441 return UUID.Zero.ToString();
4442 }
4074 4443
4075 4444
4076 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4445 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4077 if (pinfos != null && pinfos.Length > 0) 4446 if (pinfos != null && pinfos.Length > 0)
4078 {
4079 foreach (PresenceInfo p in pinfos)
4080 { 4447 {
4081 if (p.RegionID != UUID.Zero) 4448 foreach (PresenceInfo p in pinfos)
4082 { 4449 {
4083 pinfo = p; 4450 if (p.RegionID != UUID.Zero)
4451 {
4452 pinfo = p;
4453 }
4084 } 4454 }
4085 } 4455 }
4086 }
4087 4456
4088 ce = new UserInfoCacheEntry(); 4457 ce = new UserInfoCacheEntry();
4089 ce.time = Util.EnvironmentTickCount(); 4458 ce.time = Util.EnvironmentTickCount();
4090 ce.account = account; 4459 ce.account = account;
4091 ce.pinfo = pinfo; 4460 ce.pinfo = pinfo;
4092 } 4461 m_userInfoCache[uuid] = ce;
4093 else 4462 }
4094 { 4463 else
4095 if (ce == null) 4464 {
4096 return UUID.Zero.ToString(); 4465 if (ce == null)
4466 return UUID.Zero.ToString();
4097 4467
4098 account = ce.account; 4468 account = ce.account;
4099 pinfo = ce.pinfo; 4469 pinfo = ce.pinfo;
4100 } 4470 }
4101 4471
4102 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4472 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4103 {
4104 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4105 if (pinfos != null && pinfos.Length > 0)
4106 { 4473 {
4107 foreach (PresenceInfo p in pinfos) 4474 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4475 if (pinfos != null && pinfos.Length > 0)
4108 { 4476 {
4109 if (p.RegionID != UUID.Zero) 4477 foreach (PresenceInfo p in pinfos)
4110 { 4478 {
4111 pinfo = p; 4479 if (p.RegionID != UUID.Zero)
4480 {
4481 pinfo = p;
4482 }
4112 } 4483 }
4113 } 4484 }
4114 } 4485 else
4115 else 4486 pinfo = null;
4116 pinfo = null;
4117 4487
4118 ce.time = Util.EnvironmentTickCount(); 4488 ce.time = Util.EnvironmentTickCount();
4119 ce.pinfo = pinfo; 4489 ce.pinfo = pinfo;
4120 } 4490 }
4121 4491
4122 string reply = String.Empty; 4492 string reply = String.Empty;
4123 4493
4124 switch (data) 4494 switch (data)
4125 { 4495 {
4126 case 1: // DATA_ONLINE (0|1) 4496 case 1: // DATA_ONLINE (0|1)
4127 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4497 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4128 reply = "1"; 4498 reply = "1";
4129 else 4499 else
4130 reply = "0"; 4500 reply = "0";
4131 break; 4501 break;
4132 case 2: // DATA_NAME (First Last) 4502 case 2: // DATA_NAME (First Last)
4133 reply = account.FirstName + " " + account.LastName; 4503 reply = account.FirstName + " " + account.LastName;
4134 break; 4504 break;
4135 case 3: // DATA_BORN (YYYY-MM-DD) 4505 case 3: // DATA_BORN (YYYY-MM-DD)
4136 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4506 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4137 born = born.AddSeconds(account.Created); 4507 born = born.AddSeconds(account.Created);
4138 reply = born.ToString("yyyy-MM-dd"); 4508 reply = born.ToString("yyyy-MM-dd");
4139 break; 4509 break;
4140 case 4: // DATA_RATING (0,0,0,0,0,0) 4510 case 4: // DATA_RATING (0,0,0,0,0,0)
4141 reply = "0,0,0,0,0,0"; 4511 reply = "0,0,0,0,0,0";
4142 break; 4512 break;
4143 case 7: // DATA_USERLEVEL (integer) 4513 case 8: // DATA_PAYINFO (0|1|2|3)
4144 reply = account.UserLevel.ToString(); 4514 reply = "0";
4145 break; 4515 break;
4146 case 8: // DATA_PAYINFO (0|1|2|3) 4516 default:
4147 reply = "0"; 4517 return UUID.Zero.ToString(); // Raise no event
4148 break; 4518 }
4149 default:
4150 return UUID.Zero.ToString(); // Raise no event
4151 }
4152 4519
4153 UUID rq = UUID.Random(); 4520 UUID rq = UUID.Random();
4154 4521
4155 UUID tid = AsyncCommands. 4522 UUID tid = AsyncCommands.
4156 DataserverPlugin.RegisterRequest(m_host.LocalId, 4523 DataserverPlugin.RegisterRequest(m_host.LocalId,
4157 m_item.ItemID, rq.ToString()); 4524 m_item.ItemID, rq.ToString());
4158 4525
4159 AsyncCommands. 4526 AsyncCommands.
4160 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4527 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4161 4528
4162 ScriptSleep(100); 4529 ScriptSleep(100);
4163 return tid.ToString(); 4530 return tid.ToString();
4531 }
4532 else
4533 {
4534 ShoutError("Invalid UUID passed to llRequestAgentData.");
4535 }
4536 return "";
4164 } 4537 }
4165 4538
4166 public LSL_String llRequestInventoryData(string name) 4539 public LSL_String llRequestInventoryData(string name)
@@ -4217,13 +4590,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4217 if (UUID.TryParse(agent, out agentId)) 4590 if (UUID.TryParse(agent, out agentId))
4218 { 4591 {
4219 ScenePresence presence = World.GetScenePresence(agentId); 4592 ScenePresence presence = World.GetScenePresence(agentId);
4220 if (presence != null) 4593 if (presence != null && presence.PresenceType != PresenceType.Npc)
4221 { 4594 {
4595 // agent must not be a god
4596 if (presence.UserLevel >= 200) return;
4597
4222 // agent must be over the owners land 4598 // agent must be over the owners land
4223 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4599 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4224 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4600 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4225 { 4601 {
4226 World.TeleportClientHome(agentId, presence.ControllingClient); 4602 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4603 {
4604 // They can't be teleported home for some reason
4605 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4606 if (regionInfo != null)
4607 {
4608 World.RequestTeleportLocation(
4609 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4610 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4611 }
4612 }
4227 } 4613 }
4228 } 4614 }
4229 } 4615 }
@@ -4335,7 +4721,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4335 UUID av = new UUID(); 4721 UUID av = new UUID();
4336 if (!UUID.TryParse(agent,out av)) 4722 if (!UUID.TryParse(agent,out av))
4337 { 4723 {
4338 LSLError("First parameter to llDialog needs to be a key"); 4724 //LSLError("First parameter to llDialog needs to be a key");
4339 return; 4725 return;
4340 } 4726 }
4341 4727
@@ -4367,7 +4753,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4367 public void llCollisionSound(string impact_sound, double impact_volume) 4753 public void llCollisionSound(string impact_sound, double impact_volume)
4368 { 4754 {
4369 m_host.AddScriptLPS(1); 4755 m_host.AddScriptLPS(1);
4370 4756
4757 if(impact_sound == "")
4758 {
4759 m_host.CollisionSoundVolume = (float)impact_volume;
4760 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4761 m_host.CollisionSoundType = 0;
4762 return;
4763 }
4371 // TODO: Parameter check logic required. 4764 // TODO: Parameter check logic required.
4372 UUID soundId = UUID.Zero; 4765 UUID soundId = UUID.Zero;
4373 if (!UUID.TryParse(impact_sound, out soundId)) 4766 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4380,6 +4773,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4380 4773
4381 m_host.CollisionSound = soundId; 4774 m_host.CollisionSound = soundId;
4382 m_host.CollisionSoundVolume = (float)impact_volume; 4775 m_host.CollisionSoundVolume = (float)impact_volume;
4776 m_host.CollisionSoundType = 1;
4383 } 4777 }
4384 4778
4385 public LSL_String llGetAnimation(string id) 4779 public LSL_String llGetAnimation(string id)
@@ -4393,14 +4787,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4393 4787
4394 if (m_host.RegionHandle == presence.RegionHandle) 4788 if (m_host.RegionHandle == presence.RegionHandle)
4395 { 4789 {
4396 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4397
4398 if (presence != null) 4790 if (presence != null)
4399 { 4791 {
4400 AnimationSet currentAnims = presence.Animator.Animations; 4792 if (presence.SitGround)
4401 string currentAnimationState = String.Empty; 4793 return "Sitting on Ground";
4402 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4794 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4403 return currentAnimationState; 4795 return "Sitting";
4796
4797 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4798 string lslMovementAnimation;
4799
4800 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4801 return lslMovementAnimation;
4404 } 4802 }
4405 } 4803 }
4406 4804
@@ -4547,7 +4945,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4547 { 4945 {
4548 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4946 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4549 float distance_term = distance * distance * distance; // Script Energy 4947 float distance_term = distance * distance * distance; // Script Energy
4550 float pusher_mass = m_host.GetMass(); 4948 // use total object mass and not part
4949 float pusher_mass = m_host.ParentGroup.GetMass();
4551 4950
4552 float PUSH_ATTENUATION_DISTANCE = 17f; 4951 float PUSH_ATTENUATION_DISTANCE = 17f;
4553 float PUSH_ATTENUATION_SCALE = 5f; 4952 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4797,6 +5196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4797 { 5196 {
4798 return item.AssetID.ToString(); 5197 return item.AssetID.ToString();
4799 } 5198 }
5199 m_host.TaskInventory.LockItemsForRead(false);
4800 5200
4801 return UUID.Zero.ToString(); 5201 return UUID.Zero.ToString();
4802 } 5202 }
@@ -4930,7 +5330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 public LSL_Vector llGetCenterOfMass() 5330 public LSL_Vector llGetCenterOfMass()
4931 { 5331 {
4932 m_host.AddScriptLPS(1); 5332 m_host.AddScriptLPS(1);
4933 Vector3 center = m_host.GetGeometricCenter(); 5333 Vector3 center = m_host.GetCenterOfMass();
4934 return new LSL_Vector(center.X,center.Y,center.Z); 5334 return new LSL_Vector(center.X,center.Y,center.Z);
4935 } 5335 }
4936 5336
@@ -4949,14 +5349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4949 { 5349 {
4950 m_host.AddScriptLPS(1); 5350 m_host.AddScriptLPS(1);
4951 5351
4952 if (src == null) 5352 return src.Length;
4953 {
4954 return 0;
4955 }
4956 else
4957 {
4958 return src.Length;
4959 }
4960 } 5353 }
4961 5354
4962 public LSL_Integer llList2Integer(LSL_List src, int index) 5355 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5027,7 +5420,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5027 else if (src.Data[index] is LSL_Float) 5420 else if (src.Data[index] is LSL_Float)
5028 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5421 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5029 else if (src.Data[index] is LSL_String) 5422 else if (src.Data[index] is LSL_String)
5030 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5423 {
5424 string str = ((LSL_String) src.Data[index]).m_string;
5425 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5426 if (m != Match.Empty)
5427 {
5428 str = m.Value;
5429 double d = 0.0;
5430 if (!Double.TryParse(str, out d))
5431 return 0.0;
5432
5433 return d;
5434 }
5435 return 0.0;
5436 }
5031 return Convert.ToDouble(src.Data[index]); 5437 return Convert.ToDouble(src.Data[index]);
5032 } 5438 }
5033 catch (FormatException) 5439 catch (FormatException)
@@ -5337,7 +5743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5337 } 5743 }
5338 } 5744 }
5339 } 5745 }
5340 else { 5746 else
5747 {
5341 object[] array = new object[src.Length]; 5748 object[] array = new object[src.Length];
5342 Array.Copy(src.Data, 0, array, 0, src.Length); 5749 Array.Copy(src.Data, 0, array, 0, src.Length);
5343 result = new LSL_List(array); 5750 result = new LSL_List(array);
@@ -5444,7 +5851,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5444 public LSL_Integer llGetRegionAgentCount() 5851 public LSL_Integer llGetRegionAgentCount()
5445 { 5852 {
5446 m_host.AddScriptLPS(1); 5853 m_host.AddScriptLPS(1);
5447 return new LSL_Integer(World.GetRootAgentCount()); 5854
5855 int count = 0;
5856 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5857 count++;
5858 });
5859
5860 return new LSL_Integer(count);
5448 } 5861 }
5449 5862
5450 public LSL_Vector llGetRegionCorner() 5863 public LSL_Vector llGetRegionCorner()
@@ -5724,6 +6137,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5724 flags |= ScriptBaseClass.AGENT_SITTING; 6137 flags |= ScriptBaseClass.AGENT_SITTING;
5725 } 6138 }
5726 6139
6140 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6141 {
6142 flags |= ScriptBaseClass.AGENT_MALE;
6143 }
6144
5727 return flags; 6145 return flags;
5728 } 6146 }
5729 6147
@@ -5870,10 +6288,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5870 m_host.AddScriptLPS(1); 6288 m_host.AddScriptLPS(1);
5871 6289
5872 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6290 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5873 6291 if (parts.Count > 0)
5874 foreach (var part in parts)
5875 { 6292 {
5876 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6293 try
6294 {
6295 foreach (var part in parts)
6296 {
6297 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6298 }
6299 }
6300 finally
6301 {
6302 }
5877 } 6303 }
5878 } 6304 }
5879 6305
@@ -5925,13 +6351,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5925 6351
5926 if (m_host.OwnerID == land.LandData.OwnerID) 6352 if (m_host.OwnerID == land.LandData.OwnerID)
5927 { 6353 {
5928 World.TeleportClientHome(agentID, presence.ControllingClient); 6354 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6355 presence.TeleportWithMomentum(pos, null);
6356 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5929 } 6357 }
5930 } 6358 }
5931 } 6359 }
5932 ScriptSleep(5000); 6360 ScriptSleep(5000);
5933 } 6361 }
5934 6362
6363 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6364 {
6365 return ParseString2List(str, separators, in_spacers, false);
6366 }
6367
5935 public LSL_Integer llOverMyLand(string id) 6368 public LSL_Integer llOverMyLand(string id)
5936 { 6369 {
5937 m_host.AddScriptLPS(1); 6370 m_host.AddScriptLPS(1);
@@ -5990,20 +6423,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5990 return agentSize; 6423 return agentSize;
5991 } 6424 }
5992 6425
5993 public LSL_Integer llSameGroup(string agent) 6426 public LSL_Integer llSameGroup(string id)
5994 { 6427 {
5995 m_host.AddScriptLPS(1); 6428 m_host.AddScriptLPS(1);
5996 UUID agentId = new UUID(); 6429 UUID uuid = new UUID();
5997 if (!UUID.TryParse(agent, out agentId)) 6430 if (!UUID.TryParse(id, out uuid))
5998 return new LSL_Integer(0); 6431 return new LSL_Integer(0);
5999 ScenePresence presence = World.GetScenePresence(agentId); 6432
6000 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6433 // Check if it's a group key
6001 return new LSL_Integer(0); 6434 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6002 IClientAPI client = presence.ControllingClient;
6003 if (m_host.GroupID == client.ActiveGroupId)
6004 return new LSL_Integer(1); 6435 return new LSL_Integer(1);
6005 else 6436
6437 // We got passed a UUID.Zero
6438 if (uuid == UUID.Zero)
6006 return new LSL_Integer(0); 6439 return new LSL_Integer(0);
6440
6441 // Handle the case where id names an avatar
6442 ScenePresence presence = World.GetScenePresence(uuid);
6443 if (presence != null)
6444 {
6445 if (presence.IsChildAgent)
6446 return new LSL_Integer(0);
6447
6448 IClientAPI client = presence.ControllingClient;
6449 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6450 return new LSL_Integer(1);
6451
6452 return new LSL_Integer(0);
6453 }
6454
6455 // Handle object case
6456 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6457 if (part != null)
6458 {
6459 // This will handle both deed and non-deed and also the no
6460 // group case
6461 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6462 return new LSL_Integer(1);
6463
6464 return new LSL_Integer(0);
6465 }
6466
6467 return new LSL_Integer(0);
6007 } 6468 }
6008 6469
6009 public void llUnSit(string id) 6470 public void llUnSit(string id)
@@ -6132,7 +6593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6132 return m_host.ParentGroup.AttachmentPoint; 6593 return m_host.ParentGroup.AttachmentPoint;
6133 } 6594 }
6134 6595
6135 public LSL_Integer llGetFreeMemory() 6596 public virtual LSL_Integer llGetFreeMemory()
6136 { 6597 {
6137 m_host.AddScriptLPS(1); 6598 m_host.AddScriptLPS(1);
6138 // Make scripts designed for LSO happy 6599 // Make scripts designed for LSO happy
@@ -6249,7 +6710,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6249 SetParticleSystem(m_host, rules); 6710 SetParticleSystem(m_host, rules);
6250 } 6711 }
6251 6712
6252 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6713 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6714 {
6253 6715
6254 6716
6255 if (rules.Length == 0) 6717 if (rules.Length == 0)
@@ -6566,7 +7028,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6566 { 7028 {
6567 // LSL quaternions can normalize to 0, normal Quaternions can't. 7029 // LSL quaternions can normalize to 0, normal Quaternions can't.
6568 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 7030 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6569 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 7031 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6570 7032
6571 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 7033 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6572 part.SitTargetOrientation = Rot2Quaternion(rot); 7034 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6723,13 +7185,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6723 UUID av = new UUID(); 7185 UUID av = new UUID();
6724 if (!UUID.TryParse(avatar,out av)) 7186 if (!UUID.TryParse(avatar,out av))
6725 { 7187 {
6726 LSLError("First parameter to llDialog needs to be a key"); 7188 //LSLError("First parameter to llDialog needs to be a key");
6727 return; 7189 return;
6728 } 7190 }
6729 if (buttons.Length < 1) 7191 if (buttons.Length < 1)
6730 { 7192 {
6731 LSLError("No less than 1 button can be shown"); 7193 buttons.Add("OK");
6732 return;
6733 } 7194 }
6734 if (buttons.Length > 12) 7195 if (buttons.Length > 12)
6735 { 7196 {
@@ -6746,7 +7207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6746 } 7207 }
6747 if (buttons.Data[i].ToString().Length > 24) 7208 if (buttons.Data[i].ToString().Length > 24)
6748 { 7209 {
6749 LSLError("button label cannot be longer than 24 characters"); 7210 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6750 return; 7211 return;
6751 } 7212 }
6752 buts[i] = buttons.Data[i].ToString(); 7213 buts[i] = buttons.Data[i].ToString();
@@ -6813,9 +7274,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6813 return; 7274 return;
6814 } 7275 }
6815 7276
6816 // the rest of the permission checks are done in RezScript, so check the pin there as well 7277 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6817 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7278 if (dest != null)
7279 {
7280 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7281 {
7282 // the rest of the permission checks are done in RezScript, so check the pin there as well
7283 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6818 7284
7285 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7286 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7287 }
7288 }
6819 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7289 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6820 ScriptSleep(3000); 7290 ScriptSleep(3000);
6821 } 7291 }
@@ -6878,19 +7348,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6878 public LSL_String llMD5String(string src, int nonce) 7348 public LSL_String llMD5String(string src, int nonce)
6879 { 7349 {
6880 m_host.AddScriptLPS(1); 7350 m_host.AddScriptLPS(1);
6881 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7351 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6882 } 7352 }
6883 7353
6884 public LSL_String llSHA1String(string src) 7354 public LSL_String llSHA1String(string src)
6885 { 7355 {
6886 m_host.AddScriptLPS(1); 7356 m_host.AddScriptLPS(1);
6887 return Util.SHA1Hash(src).ToLower(); 7357 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6888 } 7358 }
6889 7359
6890 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7360 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6891 { 7361 {
6892 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7362 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6893 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7363 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7364 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7365 return shapeBlock;
6894 7366
6895 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7367 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6896 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7368 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6995,6 +7467,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6995 // Prim type box, cylinder and prism. 7467 // Prim type box, cylinder and prism.
6996 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) 7468 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)
6997 { 7469 {
7470 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7471 return;
7472
6998 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7473 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6999 ObjectShapePacket.ObjectDataBlock shapeBlock; 7474 ObjectShapePacket.ObjectDataBlock shapeBlock;
7000 7475
@@ -7048,6 +7523,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7048 // Prim type sphere. 7523 // Prim type sphere.
7049 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7524 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7050 { 7525 {
7526 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7527 return;
7528
7051 ObjectShapePacket.ObjectDataBlock shapeBlock; 7529 ObjectShapePacket.ObjectDataBlock shapeBlock;
7052 7530
7053 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7531 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7089,6 +7567,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7089 // Prim type torus, tube and ring. 7567 // Prim type torus, tube and ring.
7090 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) 7568 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)
7091 { 7569 {
7570 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7571 return;
7572
7092 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7573 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7093 ObjectShapePacket.ObjectDataBlock shapeBlock; 7574 ObjectShapePacket.ObjectDataBlock shapeBlock;
7094 7575
@@ -7224,6 +7705,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7224 // Prim type sculpt. 7705 // Prim type sculpt.
7225 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7706 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7226 { 7707 {
7708 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7709 return;
7710
7227 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7711 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7228 UUID sculptId; 7712 UUID sculptId;
7229 7713
@@ -7248,7 +7732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7248 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7732 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7249 { 7733 {
7250 // default 7734 // default
7251 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7735 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7252 } 7736 }
7253 7737
7254 part.Shape.SetSculptProperties((byte)type, sculptId); 7738 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7265,46 +7749,309 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7265 ScriptSleep(200); 7749 ScriptSleep(200);
7266 } 7750 }
7267 7751
7268 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7752 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7269 { 7753 {
7270 m_host.AddScriptLPS(1); 7754 m_host.AddScriptLPS(1);
7271 7755
7272 setLinkPrimParams(linknumber, rules); 7756 setLinkPrimParams(linknumber, rules);
7757 }
7758
7759 private void setLinkPrimParams(int linknumber, LSL_List rules)
7760 {
7761 List<object> parts = new List<object>();
7762 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7763 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7764 foreach (SceneObjectPart p in prims)
7765 parts.Add(p);
7766 foreach (ScenePresence p in avatars)
7767 parts.Add(p);
7273 7768
7769 LSL_List remaining = null;
7770
7771 if (parts.Count > 0)
7772 {
7773 foreach (object part in parts)
7774 {
7775 if (part is SceneObjectPart)
7776 remaining = SetPrimParams((SceneObjectPart)part, rules);
7777 else
7778 remaining = SetPrimParams((ScenePresence)part, rules);
7779 }
7780
7781 while((object)remaining != null && remaining.Length > 2)
7782 {
7783 linknumber = remaining.GetLSLIntegerItem(0);
7784 rules = remaining.GetSublist(1,-1);
7785 parts.Clear();
7786 prims = GetLinkParts(linknumber);
7787 avatars = GetLinkAvatars(linknumber);
7788 foreach (SceneObjectPart p in prims)
7789 parts.Add(p);
7790 foreach (ScenePresence p in avatars)
7791 parts.Add(p);
7792
7793 foreach (object part in parts)
7794 {
7795 if (part is SceneObjectPart)
7796 remaining = SetPrimParams((SceneObjectPart)part, rules);
7797 else
7798 remaining = SetPrimParams((ScenePresence)part, rules);
7799 }
7800 }
7801 }
7802 }
7803
7804 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7805 float material_density, float material_friction,
7806 float material_restitution, float material_gravity_modifier)
7807 {
7808 ExtraPhysicsData physdata = new ExtraPhysicsData();
7809 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7810 physdata.Density = part.Density;
7811 physdata.Friction = part.Friction;
7812 physdata.Bounce = part.Bounciness;
7813 physdata.GravitationModifier = part.GravityModifier;
7814
7815 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7816 physdata.Density = material_density;
7817 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7818 physdata.Friction = material_friction;
7819 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7820 physdata.Bounce = material_restitution;
7821 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7822 physdata.GravitationModifier = material_gravity_modifier;
7823
7824 part.UpdateExtraPhysics(physdata);
7825 }
7826
7827 public void llSetPhysicsMaterial(int material_bits,
7828 float material_gravity_modifier, float material_restitution,
7829 float material_friction, float material_density)
7830 {
7831 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7832 }
7833
7834 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7835 {
7836 llSetLinkPrimitiveParamsFast(linknumber, rules);
7274 ScriptSleep(200); 7837 ScriptSleep(200);
7275 } 7838 }
7276 7839
7277 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7840 // vector up using libomv (c&p from sop )
7841 // vector up rotated by r
7842 private Vector3 Zrot(Quaternion r)
7278 { 7843 {
7279 m_host.AddScriptLPS(1); 7844 double x, y, z, m;
7280 7845
7281 setLinkPrimParams(linknumber, rules); 7846 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7847 if (Math.Abs(1.0 - m) > 0.000001)
7848 {
7849 m = 1.0 / Math.Sqrt(m);
7850 r.X *= (float)m;
7851 r.Y *= (float)m;
7852 r.Z *= (float)m;
7853 r.W *= (float)m;
7854 }
7855
7856 x = 2 * (r.X * r.Z + r.Y * r.W);
7857 y = 2 * (-r.X * r.W + r.Y * r.Z);
7858 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7859
7860 return new Vector3((float)x, (float)y, (float)z);
7282 } 7861 }
7283 7862
7284 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7863 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules)
7285 { 7864 {
7286 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7865 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7287 7866
7288 LSL_List remaining = null; 7867 int idx = 0;
7289 7868
7290 foreach (SceneObjectPart part in parts) 7869 bool positionChanged = false;
7291 remaining = SetPrimParams(part, rules); 7870 Vector3 finalPos = Vector3.Zero;
7292 7871
7293 while(remaining != null && remaining.Length > 2) 7872 try
7294 { 7873 {
7295 linknumber = remaining.GetLSLIntegerItem(0); 7874 while (idx < rules.Length)
7296 rules = remaining.GetSublist(1,-1); 7875 {
7297 parts = GetLinkParts(linknumber); 7876 int code = rules.GetLSLIntegerItem(idx++);
7877
7878 int remain = rules.Length - idx;
7879
7880 switch (code)
7881 {
7882 case (int)ScriptBaseClass.PRIM_POSITION:
7883 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7884 {
7885 if (remain < 1)
7886 return null;
7887
7888 LSL_Vector v;
7889 v = rules.GetVector3Item(idx++);
7890
7891 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7892 if (part == null)
7893 break;
7894
7895 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7896 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7897 if (part.LinkNum > 1)
7898 {
7899 localRot = GetPartLocalRot(part);
7900 localPos = GetPartLocalPos(part);
7901 }
7902
7903 v -= localPos;
7904 v /= localRot;
7905
7906 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7907
7908 v = v + 2 * sitOffset;
7909
7910 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7911 av.SendAvatarDataToAllAgents();
7912
7913 }
7914 break;
7915
7916 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7917 case (int)ScriptBaseClass.PRIM_ROTATION:
7918 {
7919 if (remain < 1)
7920 return null;
7921
7922 LSL_Rotation r;
7923 r = rules.GetQuaternionItem(idx++);
7924
7925 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7926 if (part == null)
7927 break;
7928
7929 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7930 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7931
7932 if (part.LinkNum > 1)
7933 localRot = GetPartLocalRot(part);
7934
7935 r = r * llGetRootRotation() / localRot;
7936 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7937 av.SendAvatarDataToAllAgents();
7938 }
7939 break;
7940
7941 // parse rest doing nothing but number of parameters error check
7942 case (int)ScriptBaseClass.PRIM_SIZE:
7943 case (int)ScriptBaseClass.PRIM_MATERIAL:
7944 case (int)ScriptBaseClass.PRIM_PHANTOM:
7945 case (int)ScriptBaseClass.PRIM_PHYSICS:
7946 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7947 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7948 case (int)ScriptBaseClass.PRIM_NAME:
7949 case (int)ScriptBaseClass.PRIM_DESC:
7950 if (remain < 1)
7951 return null;
7952 idx++;
7953 break;
7954
7955 case (int)ScriptBaseClass.PRIM_GLOW:
7956 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7957 case (int)ScriptBaseClass.PRIM_TEXGEN:
7958 if (remain < 2)
7959 return null;
7960 idx += 2;
7961 break;
7962
7963 case (int)ScriptBaseClass.PRIM_TYPE:
7964 if (remain < 3)
7965 return null;
7966 code = (int)rules.GetLSLIntegerItem(idx++);
7967 remain = rules.Length - idx;
7968 switch (code)
7969 {
7970 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7971 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7972 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7973 if (remain < 6)
7974 return null;
7975 idx += 6;
7976 break;
7977
7978 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7979 if (remain < 5)
7980 return null;
7981 idx += 5;
7982 break;
7983
7984 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7985 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7986 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7987 if (remain < 11)
7988 return null;
7989 idx += 11;
7990 break;
7991
7992 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7993 if (remain < 2)
7994 return null;
7995 idx += 2;
7996 break;
7997 }
7998 break;
7999
8000 case (int)ScriptBaseClass.PRIM_COLOR:
8001 case (int)ScriptBaseClass.PRIM_TEXT:
8002 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8003 case (int)ScriptBaseClass.PRIM_OMEGA:
8004 if (remain < 3)
8005 return null;
8006 idx += 3;
8007 break;
8008
8009 case (int)ScriptBaseClass.PRIM_TEXTURE:
8010 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8011 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8012 if (remain < 5)
8013 return null;
8014 idx += 5;
8015 break;
8016
8017 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8018 if (remain < 7)
8019 return null;
8020
8021 idx += 7;
8022 break;
8023
8024 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8025 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8026 return null;
8027
8028 return rules.GetSublist(idx, -1);
8029 }
8030 }
8031 }
7298 8032
7299 foreach (SceneObjectPart part in parts) 8033 finally
7300 remaining = SetPrimParams(part, rules); 8034 {
8035 if (positionChanged)
8036 {
8037 av.OffsetPosition = finalPos;
8038// av.SendAvatarDataToAllAgents();
8039 av.SendTerseUpdateToAllClients();
8040 positionChanged = false;
8041 }
7301 } 8042 }
8043 return null;
7302 } 8044 }
7303 8045
7304 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules) 8046 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules)
7305 { 8047 {
8048 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8049 return null;
8050
7306 int idx = 0; 8051 int idx = 0;
7307 8052
8053 SceneObjectGroup parentgrp = part.ParentGroup;
8054
7308 bool positionChanged = false; 8055 bool positionChanged = false;
7309 LSL_Vector currentPosition = GetPartLocalPos(part); 8056 LSL_Vector currentPosition = GetPartLocalPos(part);
7310 8057
@@ -7327,8 +8074,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7327 return null; 8074 return null;
7328 8075
7329 v=rules.GetVector3Item(idx++); 8076 v=rules.GetVector3Item(idx++);
7330 positionChanged = true;
7331 currentPosition = GetSetPosTarget(part, v, currentPosition); 8077 currentPosition = GetSetPosTarget(part, v, currentPosition);
8078 positionChanged = true;
7332 8079
7333 break; 8080 break;
7334 case (int)ScriptBaseClass.PRIM_SIZE: 8081 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7344,8 +8091,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7344 return null; 8091 return null;
7345 8092
7346 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8093 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8094 SceneObjectPart rootPart = parentgrp.RootPart;
7347 // try to let this work as in SL... 8095 // try to let this work as in SL...
7348 if (part.ParentID == 0) 8096 if (rootPart == part)
7349 { 8097 {
7350 // special case: If we are root, rotate complete SOG to new rotation 8098 // special case: If we are root, rotate complete SOG to new rotation
7351 SetRot(part, Rot2Quaternion(q)); 8099 SetRot(part, Rot2Quaternion(q));
@@ -7353,7 +8101,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7353 else 8101 else
7354 { 8102 {
7355 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8103 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7356 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8104 // sounds like sl bug that we need to replicate
7357 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8105 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7358 } 8106 }
7359 8107
@@ -7606,7 +8354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7606 return null; 8354 return null;
7607 8355
7608 string ph = rules.Data[idx++].ToString(); 8356 string ph = rules.Data[idx++].ToString();
7609 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8357 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7610 8358
7611 break; 8359 break;
7612 8360
@@ -7624,12 +8372,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7624 part.ScriptSetPhysicsStatus(physics); 8372 part.ScriptSetPhysicsStatus(physics);
7625 break; 8373 break;
7626 8374
8375 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8376 if (remain < 1)
8377 return null;
8378
8379 int shape_type = rules.GetLSLIntegerItem(idx++);
8380
8381 ExtraPhysicsData physdata = new ExtraPhysicsData();
8382 physdata.Density = part.Density;
8383 physdata.Bounce = part.Bounciness;
8384 physdata.GravitationModifier = part.GravityModifier;
8385 physdata.PhysShapeType = (PhysShapeType)shape_type;
8386
8387 part.UpdateExtraPhysics(physdata);
8388
8389 break;
8390
8391 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8392 if (remain < 5)
8393 return null;
8394
8395 int material_bits = rules.GetLSLIntegerItem(idx++);
8396 float material_density = (float)rules.GetLSLFloatItem(idx++);
8397 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8398 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8399 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8400
8401 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8402
8403 break;
8404
7627 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8405 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7628 if (remain < 1) 8406 if (remain < 1)
7629 return null; 8407 return null;
7630 string temp = rules.Data[idx++].ToString(); 8408 string temp = rules.Data[idx++].ToString();
7631 8409
7632 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8410 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7633 8411
7634 break; 8412 break;
7635 8413
@@ -7679,6 +8457,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7679 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8457 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7680 TargetOmega(part, axis, (double)spinrate, (double)gain); 8458 TargetOmega(part, axis, (double)spinrate, (double)gain);
7681 break; 8459 break;
8460
7682 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8461 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7683 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8462 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7684 return null; 8463 return null;
@@ -7694,7 +8473,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7694 if (part.ParentGroup.RootPart == part) 8473 if (part.ParentGroup.RootPart == part)
7695 { 8474 {
7696 SceneObjectGroup parent = part.ParentGroup; 8475 SceneObjectGroup parent = part.ParentGroup;
7697 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8476 Util.FireAndForget(delegate(object x) {
8477 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8478 });
7698 } 8479 }
7699 else 8480 else
7700 { 8481 {
@@ -7739,10 +8520,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7739 8520
7740 public LSL_String llXorBase64Strings(string str1, string str2) 8521 public LSL_String llXorBase64Strings(string str1, string str2)
7741 { 8522 {
7742 m_host.AddScriptLPS(1); 8523 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7743 Deprecated("llXorBase64Strings"); 8524
7744 ScriptSleep(300); 8525 ScriptSleep(300);
7745 return String.Empty; 8526 m_host.AddScriptLPS(1);
8527
8528 if (str1 == String.Empty)
8529 return String.Empty;
8530 if (str2 == String.Empty)
8531 return str1;
8532
8533 int len = str2.Length;
8534 if ((len % 4) != 0) // LL is EVIL!!!!
8535 {
8536 while (str2.EndsWith("="))
8537 str2 = str2.Substring(0, str2.Length - 1);
8538
8539 len = str2.Length;
8540 int mod = len % 4;
8541
8542 if (mod == 1)
8543 str2 = str2.Substring(0, str2.Length - 1);
8544 else if (mod == 2)
8545 str2 += "==";
8546 else if (mod == 3)
8547 str2 += "=";
8548 }
8549
8550 byte[] data1;
8551 byte[] data2;
8552 try
8553 {
8554 data1 = Convert.FromBase64String(str1);
8555 data2 = Convert.FromBase64String(str2);
8556 }
8557 catch (Exception)
8558 {
8559 return new LSL_String(String.Empty);
8560 }
8561
8562 // For cases where the decoded length of s2 is greater
8563 // than the decoded length of s1, simply perform a normal
8564 // decode and XOR
8565 //
8566 if (data2.Length >= data1.Length)
8567 {
8568 for (int pos = 0 ; pos < data1.Length ; pos++ )
8569 data1[pos] ^= data2[pos];
8570
8571 return Convert.ToBase64String(data1);
8572 }
8573
8574 // Remove padding
8575 while (str1.EndsWith("="))
8576 str1 = str1.Substring(0, str1.Length - 1);
8577 while (str2.EndsWith("="))
8578 str2 = str2.Substring(0, str2.Length - 1);
8579
8580 byte[] d1 = new byte[str1.Length];
8581 byte[] d2 = new byte[str2.Length];
8582
8583 for (int i = 0 ; i < str1.Length ; i++)
8584 {
8585 int idx = b64.IndexOf(str1.Substring(i, 1));
8586 if (idx == -1)
8587 idx = 0;
8588 d1[i] = (byte)idx;
8589 }
8590
8591 for (int i = 0 ; i < str2.Length ; i++)
8592 {
8593 int idx = b64.IndexOf(str2.Substring(i, 1));
8594 if (idx == -1)
8595 idx = 0;
8596 d2[i] = (byte)idx;
8597 }
8598
8599 string output = String.Empty;
8600
8601 for (int pos = 0 ; pos < d1.Length ; pos++)
8602 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8603
8604 while (output.Length % 3 > 0)
8605 output += "=";
8606
8607 return output;
7746 } 8608 }
7747 8609
7748 public void llRemoteDataSetRegion() 8610 public void llRemoteDataSetRegion()
@@ -7866,13 +8728,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7866 public LSL_Integer llGetNumberOfPrims() 8728 public LSL_Integer llGetNumberOfPrims()
7867 { 8729 {
7868 m_host.AddScriptLPS(1); 8730 m_host.AddScriptLPS(1);
7869 int avatarCount = 0; 8731 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7870 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8732
7871 {
7872 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7873 avatarCount++;
7874 });
7875
7876 return m_host.ParentGroup.PrimCount + avatarCount; 8733 return m_host.ParentGroup.PrimCount + avatarCount;
7877 } 8734 }
7878 8735
@@ -7888,55 +8745,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7888 m_host.AddScriptLPS(1); 8745 m_host.AddScriptLPS(1);
7889 UUID objID = UUID.Zero; 8746 UUID objID = UUID.Zero;
7890 LSL_List result = new LSL_List(); 8747 LSL_List result = new LSL_List();
8748
8749 // If the ID is not valid, return null result
7891 if (!UUID.TryParse(obj, out objID)) 8750 if (!UUID.TryParse(obj, out objID))
7892 { 8751 {
7893 result.Add(new LSL_Vector()); 8752 result.Add(new LSL_Vector());
7894 result.Add(new LSL_Vector()); 8753 result.Add(new LSL_Vector());
7895 return result; 8754 return result;
7896 } 8755 }
8756
8757 // Check if this is an attached prim. If so, replace
8758 // the UUID with the avatar UUID and report it's bounding box
8759 SceneObjectPart part = World.GetSceneObjectPart(objID);
8760 if (part != null && part.ParentGroup.IsAttachment)
8761 objID = part.ParentGroup.AttachedAvatar;
8762
8763 // Find out if this is an avatar ID. If so, return it's box
7897 ScenePresence presence = World.GetScenePresence(objID); 8764 ScenePresence presence = World.GetScenePresence(objID);
7898 if (presence != null) 8765 if (presence != null)
7899 { 8766 {
7900 if (presence.ParentID == 0) // not sat on an object 8767 // As per LSL Wiki, there is no difference between sitting
8768 // and standing avatar since server 1.36
8769 LSL_Vector lower;
8770 LSL_Vector upper;
8771 if (presence.Animator.Animations.DefaultAnimation.AnimID
8772 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7901 { 8773 {
7902 LSL_Vector lower; 8774 // This is for ground sitting avatars
7903 LSL_Vector upper; 8775 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7904 if (presence.Animator.Animations.DefaultAnimation.AnimID 8776 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7905 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8777 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7906 {
7907 // This is for ground sitting avatars
7908 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7909 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7910 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7911 }
7912 else
7913 {
7914 // This is for standing/flying avatars
7915 float height = presence.Appearance.AvatarHeight / 2.0f;
7916 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7917 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7918 }
7919 result.Add(lower);
7920 result.Add(upper);
7921 return result;
7922 } 8778 }
7923 else 8779 else
7924 { 8780 {
7925 // sitting on an object so we need the bounding box of that 8781 // This is for standing/flying avatars
7926 // which should include the avatar so set the UUID to the 8782 float height = presence.Appearance.AvatarHeight / 2.0f;
7927 // UUID of the object the avatar is sat on and allow it to fall through 8783 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7928 // to processing an object 8784 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7929 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7930 objID = p.UUID;
7931 } 8785 }
8786
8787 // Adjust to the documented error offsets (see LSL Wiki)
8788 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8789 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8790
8791 if (lower.x > upper.x)
8792 lower.x = upper.x;
8793 if (lower.y > upper.y)
8794 lower.y = upper.y;
8795 if (lower.z > upper.z)
8796 lower.z = upper.z;
8797
8798 result.Add(lower);
8799 result.Add(upper);
8800 return result;
7932 } 8801 }
7933 SceneObjectPart part = World.GetSceneObjectPart(objID); 8802
8803 part = World.GetSceneObjectPart(objID);
7934 // Currently only works for single prims without a sitting avatar 8804 // Currently only works for single prims without a sitting avatar
7935 if (part != null) 8805 if (part != null)
7936 { 8806 {
7937 Vector3 halfSize = part.Scale / 2.0f; 8807 float minX;
7938 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8808 float maxX;
7939 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8809 float minY;
8810 float maxY;
8811 float minZ;
8812 float maxZ;
8813
8814 // This BBox is in sim coordinates, with the offset being
8815 // a contained point.
8816 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8817 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8818
8819 minX -= offsets[0].X;
8820 maxX -= offsets[0].X;
8821 minY -= offsets[0].Y;
8822 maxY -= offsets[0].Y;
8823 minZ -= offsets[0].Z;
8824 maxZ -= offsets[0].Z;
8825
8826 LSL_Vector lower;
8827 LSL_Vector upper;
8828
8829 // Adjust to the documented error offsets (see LSL Wiki)
8830 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8831 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8832
8833 if (lower.x > upper.x)
8834 lower.x = upper.x;
8835 if (lower.y > upper.y)
8836 lower.y = upper.y;
8837 if (lower.z > upper.z)
8838 lower.z = upper.z;
8839
7940 result.Add(lower); 8840 result.Add(lower);
7941 result.Add(upper); 8841 result.Add(upper);
7942 return result; 8842 return result;
@@ -7950,7 +8850,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7950 8850
7951 public LSL_Vector llGetGeometricCenter() 8851 public LSL_Vector llGetGeometricCenter()
7952 { 8852 {
7953 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8853 Vector3 tmp = m_host.GetGeometricCenter();
8854 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7954 } 8855 }
7955 8856
7956 public LSL_List llGetPrimitiveParams(LSL_List rules) 8857 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7963,16 +8864,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7963 { 8864 {
7964 m_host.AddScriptLPS(1); 8865 m_host.AddScriptLPS(1);
7965 8866
8867 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8868 // keep other options as before
8869
7966 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8870 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8871 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7967 8872
7968 LSL_List res = new LSL_List(); 8873 LSL_List res = new LSL_List();
7969 8874
7970 foreach (var part in parts) 8875 if (parts.Count > 0)
8876 {
8877 foreach (var part in parts)
8878 {
8879 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8880 res += partRes;
8881 }
8882 }
8883 if (avatars.Count > 0)
7971 { 8884 {
7972 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8885 foreach (ScenePresence avatar in avatars)
7973 res += partRes; 8886 {
8887 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8888 res += avaRes;
8889 }
7974 } 8890 }
8891 return res;
8892 }
8893
8894 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8895 {
8896 // avatars case
8897 // replies as SL wiki
8898
8899 LSL_List res = new LSL_List();
8900// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8901 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8902
8903 int idx = 0;
8904 while (idx < rules.Length)
8905 {
8906 int code = (int)rules.GetLSLIntegerItem(idx++);
8907 int remain = rules.Length - idx;
8908
8909 switch (code)
8910 {
8911 case (int)ScriptBaseClass.PRIM_MATERIAL:
8912 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8913 break;
8914
8915 case (int)ScriptBaseClass.PRIM_PHYSICS:
8916 res.Add(new LSL_Integer(0));
8917 break;
8918
8919 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8920 res.Add(new LSL_Integer(0));
8921 break;
7975 8922
8923 case (int)ScriptBaseClass.PRIM_PHANTOM:
8924 res.Add(new LSL_Integer(0));
8925 break;
8926
8927 case (int)ScriptBaseClass.PRIM_POSITION:
8928
8929 Vector3 pos = avatar.OffsetPosition;
8930
8931 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8932 pos -= sitOffset;
8933
8934 if( sitPart != null)
8935 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8936
8937 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8938 break;
8939
8940 case (int)ScriptBaseClass.PRIM_SIZE:
8941 // as in llGetAgentSize above
8942 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8943 break;
8944
8945 case (int)ScriptBaseClass.PRIM_ROTATION:
8946 Quaternion rot = avatar.Rotation;
8947 if (sitPart != null)
8948 {
8949 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8950 }
8951
8952 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8953 break;
8954
8955 case (int)ScriptBaseClass.PRIM_TYPE:
8956 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8957 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8958 res.Add(new LSL_Vector(0f,1.0f,0f));
8959 res.Add(new LSL_Float(0.0f));
8960 res.Add(new LSL_Vector(0, 0, 0));
8961 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8962 res.Add(new LSL_Vector(0, 0, 0));
8963 break;
8964
8965 case (int)ScriptBaseClass.PRIM_TEXTURE:
8966 if (remain < 1)
8967 return res;
8968
8969 int face = (int)rules.GetLSLIntegerItem(idx++);
8970 if (face == ScriptBaseClass.ALL_SIDES)
8971 {
8972 for (face = 0; face < 21; face++)
8973 {
8974 res.Add(new LSL_String(""));
8975 res.Add(new LSL_Vector(0,0,0));
8976 res.Add(new LSL_Vector(0,0,0));
8977 res.Add(new LSL_Float(0.0));
8978 }
8979 }
8980 else
8981 {
8982 if (face >= 0 && face < 21)
8983 {
8984 res.Add(new LSL_String(""));
8985 res.Add(new LSL_Vector(0,0,0));
8986 res.Add(new LSL_Vector(0,0,0));
8987 res.Add(new LSL_Float(0.0));
8988 }
8989 }
8990 break;
8991
8992 case (int)ScriptBaseClass.PRIM_COLOR:
8993 if (remain < 1)
8994 return res;
8995
8996 face = (int)rules.GetLSLIntegerItem(idx++);
8997
8998 if (face == ScriptBaseClass.ALL_SIDES)
8999 {
9000 for (face = 0; face < 21; face++)
9001 {
9002 res.Add(new LSL_Vector(0,0,0));
9003 res.Add(new LSL_Float(0));
9004 }
9005 }
9006 else
9007 {
9008 res.Add(new LSL_Vector(0,0,0));
9009 res.Add(new LSL_Float(0));
9010 }
9011 break;
9012
9013 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9014 if (remain < 1)
9015 return res;
9016 face = (int)rules.GetLSLIntegerItem(idx++);
9017
9018 if (face == ScriptBaseClass.ALL_SIDES)
9019 {
9020 for (face = 0; face < 21; face++)
9021 {
9022 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9023 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9024 }
9025 }
9026 else
9027 {
9028 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9029 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9030 }
9031 break;
9032
9033 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9034 if (remain < 1)
9035 return res;
9036 face = (int)rules.GetLSLIntegerItem(idx++);
9037
9038 if (face == ScriptBaseClass.ALL_SIDES)
9039 {
9040 for (face = 0; face < 21; face++)
9041 {
9042 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9043 }
9044 }
9045 else
9046 {
9047 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9048 }
9049 break;
9050
9051 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9052 res.Add(new LSL_Integer(0));
9053 res.Add(new LSL_Integer(0));// softness
9054 res.Add(new LSL_Float(0.0f)); // gravity
9055 res.Add(new LSL_Float(0.0f)); // friction
9056 res.Add(new LSL_Float(0.0f)); // wind
9057 res.Add(new LSL_Float(0.0f)); // tension
9058 res.Add(new LSL_Vector(0f,0f,0f));
9059 break;
9060
9061 case (int)ScriptBaseClass.PRIM_TEXGEN:
9062 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9063 if (remain < 1)
9064 return res;
9065 face = (int)rules.GetLSLIntegerItem(idx++);
9066
9067 if (face == ScriptBaseClass.ALL_SIDES)
9068 {
9069 for (face = 0; face < 21; face++)
9070 {
9071 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9072 }
9073 }
9074 else
9075 {
9076 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9077 }
9078 break;
9079
9080 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9081 res.Add(new LSL_Integer(0));
9082 res.Add(new LSL_Vector(0f,0f,0f));
9083 res.Add(new LSL_Float(0f)); // intensity
9084 res.Add(new LSL_Float(0f)); // radius
9085 res.Add(new LSL_Float(0f)); // falloff
9086 break;
9087
9088 case (int)ScriptBaseClass.PRIM_GLOW:
9089 if (remain < 1)
9090 return res;
9091 face = (int)rules.GetLSLIntegerItem(idx++);
9092
9093 if (face == ScriptBaseClass.ALL_SIDES)
9094 {
9095 for (face = 0; face < 21; face++)
9096 {
9097 res.Add(new LSL_Float(0f));
9098 }
9099 }
9100 else
9101 {
9102 res.Add(new LSL_Float(0f));
9103 }
9104 break;
9105
9106 case (int)ScriptBaseClass.PRIM_TEXT:
9107 res.Add(new LSL_String(""));
9108 res.Add(new LSL_Vector(0f,0f,0f));
9109 res.Add(new LSL_Float(1.0f));
9110 break;
9111
9112 case (int)ScriptBaseClass.PRIM_NAME:
9113 res.Add(new LSL_String(avatar.Name));
9114 break;
9115
9116 case (int)ScriptBaseClass.PRIM_DESC:
9117 res.Add(new LSL_String(""));
9118 break;
9119
9120 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9121 Quaternion lrot = avatar.Rotation;
9122
9123 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9124 {
9125 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9126 }
9127 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9128 break;
9129
9130 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9131 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9132 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9133 lpos -= lsitOffset;
9134
9135 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9136 {
9137 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9138 }
9139 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9140 break;
9141
9142 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9143 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9144 return res;
9145 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9146 LSL_List new_rules = rules.GetSublist(idx, -1);
9147
9148 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9149 return res;
9150 }
9151 }
7976 return res; 9152 return res;
7977 } 9153 }
7978 9154
@@ -8016,13 +9192,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8016 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9192 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8017 part.AbsolutePosition.Y, 9193 part.AbsolutePosition.Y,
8018 part.AbsolutePosition.Z); 9194 part.AbsolutePosition.Z);
8019 // For some reason, the part.AbsolutePosition.* values do not change if the
8020 // linkset is rotated; they always reflect the child prim's world position
8021 // as though the linkset is unrotated. This is incompatible behavior with SL's
8022 // implementation, so will break scripts imported from there (not to mention it
8023 // makes it more difficult to determine a child prim's actual inworld position).
8024 if (part.ParentID != 0)
8025 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8026 res.Add(v); 9195 res.Add(v);
8027 break; 9196 break;
8028 9197
@@ -8193,56 +9362,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8193 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9362 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8194 if (remain < 1) 9363 if (remain < 1)
8195 return res; 9364 return res;
8196 9365 face = (int)rules.GetLSLIntegerItem(idx++);
8197 face=(int)rules.GetLSLIntegerItem(idx++);
8198 9366
8199 tex = part.Shape.Textures; 9367 tex = part.Shape.Textures;
9368 int shiny;
8200 if (face == ScriptBaseClass.ALL_SIDES) 9369 if (face == ScriptBaseClass.ALL_SIDES)
8201 { 9370 {
8202 for (face = 0; face < GetNumberOfSides(part); face++) 9371 for (face = 0; face < GetNumberOfSides(part); face++)
8203 { 9372 {
8204 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9373 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8205 // Convert Shininess to PRIM_SHINY_* 9374 if (shinyness == Shininess.High)
8206 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9375 {
8207 // PRIM_BUMP_* 9376 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8208 res.Add(new LSL_Integer((int)texface.Bump)); 9377 }
9378 else if (shinyness == Shininess.Medium)
9379 {
9380 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9381 }
9382 else if (shinyness == Shininess.Low)
9383 {
9384 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9385 }
9386 else
9387 {
9388 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9389 }
9390 res.Add(new LSL_Integer(shiny));
9391 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8209 } 9392 }
8210 } 9393 }
8211 else 9394 else
8212 { 9395 {
8213 if (face >= 0 && face < GetNumberOfSides(part)) 9396 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9397 if (shinyness == Shininess.High)
8214 { 9398 {
8215 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9399 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8216 // Convert Shininess to PRIM_SHINY_* 9400 }
8217 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9401 else if (shinyness == Shininess.Medium)
8218 // PRIM_BUMP_* 9402 {
8219 res.Add(new LSL_Integer((int)texface.Bump)); 9403 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9404 }
9405 else if (shinyness == Shininess.Low)
9406 {
9407 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9408 }
9409 else
9410 {
9411 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8220 } 9412 }
9413 res.Add(new LSL_Integer(shiny));
9414 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8221 } 9415 }
8222 break; 9416 break;
8223 9417
8224 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9418 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8225 if (remain < 1) 9419 if (remain < 1)
8226 return res; 9420 return res;
8227 9421 face = (int)rules.GetLSLIntegerItem(idx++);
8228 face=(int)rules.GetLSLIntegerItem(idx++);
8229 9422
8230 tex = part.Shape.Textures; 9423 tex = part.Shape.Textures;
9424 int fullbright;
8231 if (face == ScriptBaseClass.ALL_SIDES) 9425 if (face == ScriptBaseClass.ALL_SIDES)
8232 { 9426 {
8233 for (face = 0; face < GetNumberOfSides(part); face++) 9427 for (face = 0; face < GetNumberOfSides(part); face++)
8234 { 9428 {
8235 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9429 if (tex.GetFace((uint)face).Fullbright == true)
8236 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9430 {
9431 fullbright = ScriptBaseClass.TRUE;
9432 }
9433 else
9434 {
9435 fullbright = ScriptBaseClass.FALSE;
9436 }
9437 res.Add(new LSL_Integer(fullbright));
8237 } 9438 }
8238 } 9439 }
8239 else 9440 else
8240 { 9441 {
8241 if (face >= 0 && face < GetNumberOfSides(part)) 9442 if (tex.GetFace((uint)face).Fullbright == true)
8242 { 9443 {
8243 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9444 fullbright = ScriptBaseClass.TRUE;
8244 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9445 }
9446 else
9447 {
9448 fullbright = ScriptBaseClass.FALSE;
8245 } 9449 }
9450 res.Add(new LSL_Integer(fullbright));
8246 } 9451 }
8247 break; 9452 break;
8248 9453
@@ -8264,27 +9469,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8264 break; 9469 break;
8265 9470
8266 case (int)ScriptBaseClass.PRIM_TEXGEN: 9471 case (int)ScriptBaseClass.PRIM_TEXGEN:
9472 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8267 if (remain < 1) 9473 if (remain < 1)
8268 return res; 9474 return res;
8269 9475 face = (int)rules.GetLSLIntegerItem(idx++);
8270 face=(int)rules.GetLSLIntegerItem(idx++);
8271 9476
8272 tex = part.Shape.Textures; 9477 tex = part.Shape.Textures;
8273 if (face == ScriptBaseClass.ALL_SIDES) 9478 if (face == ScriptBaseClass.ALL_SIDES)
8274 { 9479 {
8275 for (face = 0; face < GetNumberOfSides(part); face++) 9480 for (face = 0; face < GetNumberOfSides(part); face++)
8276 { 9481 {
8277 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9482 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8278 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9483 {
8279 res.Add(new LSL_Integer((uint)texgen >> 1)); 9484 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9485 }
9486 else
9487 {
9488 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9489 }
8280 } 9490 }
8281 } 9491 }
8282 else 9492 else
8283 { 9493 {
8284 if (face >= 0 && face < GetNumberOfSides(part)) 9494 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9495 {
9496 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9497 }
9498 else
8285 { 9499 {
8286 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9500 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8287 res.Add(new LSL_Integer((uint)texgen >> 1));
8288 } 9501 }
8289 } 9502 }
8290 break; 9503 break;
@@ -8307,25 +9520,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8307 case (int)ScriptBaseClass.PRIM_GLOW: 9520 case (int)ScriptBaseClass.PRIM_GLOW:
8308 if (remain < 1) 9521 if (remain < 1)
8309 return res; 9522 return res;
8310 9523 face = (int)rules.GetLSLIntegerItem(idx++);
8311 face=(int)rules.GetLSLIntegerItem(idx++);
8312 9524
8313 tex = part.Shape.Textures; 9525 tex = part.Shape.Textures;
9526 float primglow;
8314 if (face == ScriptBaseClass.ALL_SIDES) 9527 if (face == ScriptBaseClass.ALL_SIDES)
8315 { 9528 {
8316 for (face = 0; face < GetNumberOfSides(part); face++) 9529 for (face = 0; face < GetNumberOfSides(part); face++)
8317 { 9530 {
8318 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9531 primglow = tex.GetFace((uint)face).Glow;
8319 res.Add(new LSL_Float(texface.Glow)); 9532 res.Add(new LSL_Float(primglow));
8320 } 9533 }
8321 } 9534 }
8322 else 9535 else
8323 { 9536 {
8324 if (face >= 0 && face < GetNumberOfSides(part)) 9537 primglow = tex.GetFace((uint)face).Glow;
8325 { 9538 res.Add(new LSL_Float(primglow));
8326 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8327 res.Add(new LSL_Float(texface.Glow));
8328 }
8329 } 9539 }
8330 break; 9540 break;
8331 9541
@@ -8337,18 +9547,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8337 textColor.B)); 9547 textColor.B));
8338 res.Add(new LSL_Float(textColor.A)); 9548 res.Add(new LSL_Float(textColor.A));
8339 break; 9549 break;
9550
8340 case (int)ScriptBaseClass.PRIM_NAME: 9551 case (int)ScriptBaseClass.PRIM_NAME:
8341 res.Add(new LSL_String(part.Name)); 9552 res.Add(new LSL_String(part.Name));
8342 break; 9553 break;
9554
8343 case (int)ScriptBaseClass.PRIM_DESC: 9555 case (int)ScriptBaseClass.PRIM_DESC:
8344 res.Add(new LSL_String(part.Description)); 9556 res.Add(new LSL_String(part.Description));
8345 break; 9557 break;
9558
8346 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9559 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8347 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9560 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8348 break; 9561 break;
9562
8349 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9563 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8350 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9564 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8351 break; 9565 break;
9566
9567 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9568 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9569 return res;
9570 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9571 LSL_List new_rules = rules.GetSublist(idx, -1);
9572 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9573 res += tres;
9574 return res;
8352 } 9575 }
8353 } 9576 }
8354 return res; 9577 return res;
@@ -8941,8 +10164,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8941 // The function returns an ordered list 10164 // The function returns an ordered list
8942 // representing the tokens found in the supplied 10165 // representing the tokens found in the supplied
8943 // sources string. If two successive tokenizers 10166 // sources string. If two successive tokenizers
8944 // are encountered, then a NULL entry is added 10167 // are encountered, then a null-string entry is
8945 // to the list. 10168 // added to the list.
8946 // 10169 //
8947 // It is a precondition that the source and 10170 // It is a precondition that the source and
8948 // toekizer lisst are non-null. If they are null, 10171 // toekizer lisst are non-null. If they are null,
@@ -8950,7 +10173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8950 // while their lengths are being determined. 10173 // while their lengths are being determined.
8951 // 10174 //
8952 // A small amount of working memoryis required 10175 // A small amount of working memoryis required
8953 // of approximately 8*#tokenizers. 10176 // of approximately 8*#tokenizers + 8*srcstrlen.
8954 // 10177 //
8955 // There are many ways in which this function 10178 // There are many ways in which this function
8956 // can be implemented, this implementation is 10179 // can be implemented, this implementation is
@@ -8966,155 +10189,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8966 // and eliminates redundant tokenizers as soon 10189 // and eliminates redundant tokenizers as soon
8967 // as is possible. 10190 // as is possible.
8968 // 10191 //
8969 // The implementation tries to avoid any copying 10192 // The implementation tries to minimize temporary
8970 // of arrays or other objects. 10193 // garbage generation.
8971 // </remarks> 10194 // </remarks>
8972 10195
8973 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10196 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8974 { 10197 {
8975 int beginning = 0; 10198 return ParseString2List(src, separators, spacers, true);
8976 int srclen = src.Length; 10199 }
8977 int seplen = separators.Length;
8978 object[] separray = separators.Data;
8979 int spclen = spacers.Length;
8980 object[] spcarray = spacers.Data;
8981 int mlen = seplen+spclen;
8982
8983 int[] offset = new int[mlen+1];
8984 bool[] active = new bool[mlen];
8985
8986 int best;
8987 int j;
8988
8989 // Initial capacity reduces resize cost
8990 10200
8991 LSL_List tokens = new LSL_List(); 10201 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10202 {
10203 int srclen = src.Length;
10204 int seplen = separators.Length;
10205 object[] separray = separators.Data;
10206 int spclen = spacers.Length;
10207 object[] spcarray = spacers.Data;
10208 int dellen = 0;
10209 string[] delarray = new string[seplen+spclen];
8992 10210
8993 // All entries are initially valid 10211 int outlen = 0;
10212 string[] outarray = new string[srclen*2+1];
8994 10213
8995 for (int i = 0; i < mlen; i++) 10214 int i, j;
8996 active[i] = true; 10215 string d;
8997 10216
8998 offset[mlen] = srclen; 10217 m_host.AddScriptLPS(1);
8999 10218
9000 while (beginning < srclen) 10219 /*
10220 * Convert separator and spacer lists to C# strings.
10221 * Also filter out null strings so we don't hang.
10222 */
10223 for (i = 0; i < seplen; i ++)
9001 { 10224 {
10225 d = separray[i].ToString();
10226 if (d.Length > 0)
10227 {
10228 delarray[dellen++] = d;
10229 }
10230 }
10231 seplen = dellen;
9002 10232
9003 best = mlen; // as bad as it gets 10233 for (i = 0; i < spclen; i ++)
10234 {
10235 d = spcarray[i].ToString();
10236 if (d.Length > 0)
10237 {
10238 delarray[dellen++] = d;
10239 }
10240 }
9004 10241
9005 // Scan for separators 10242 /*
10243 * Scan through source string from beginning to end.
10244 */
10245 for (i = 0;;)
10246 {
9006 10247
9007 for (j = 0; j < seplen; j++) 10248 /*
10249 * Find earliest delimeter in src starting at i (if any).
10250 */
10251 int earliestDel = -1;
10252 int earliestSrc = srclen;
10253 string earliestStr = null;
10254 for (j = 0; j < dellen; j ++)
9008 { 10255 {
9009 if (separray[j].ToString() == String.Empty) 10256 d = delarray[j];
9010 active[j] = false; 10257 if (d != null)
9011
9012 if (active[j])
9013 { 10258 {
9014 // scan all of the markers 10259 int index = src.IndexOf(d, i);
9015 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10260 if (index < 0)
9016 { 10261 {
9017 // not present at all 10262 delarray[j] = null; // delim nowhere in src, don't check it anymore
9018 active[j] = false;
9019 } 10263 }
9020 else 10264 else if (index < earliestSrc)
9021 { 10265 {
9022 // present and correct 10266 earliestSrc = index; // where delimeter starts in source string
9023 if (offset[j] < offset[best]) 10267 earliestDel = j; // where delimeter is in delarray[]
9024 { 10268 earliestStr = d; // the delimeter string from delarray[]
9025 // closest so far 10269 if (index == i) break; // can't do any better than found at beg of string
9026 best = j;
9027 if (offset[best] == beginning)
9028 break;
9029 }
9030 } 10270 }
9031 } 10271 }
9032 } 10272 }
9033 10273
9034 // Scan for spacers 10274 /*
9035 10275 * Output source string starting at i through start of earliest delimeter.
9036 if (offset[best] != beginning) 10276 */
10277 if (keepNulls || (earliestSrc > i))
9037 { 10278 {
9038 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10279 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9039 {
9040 if (spcarray[j-seplen].ToString() == String.Empty)
9041 active[j] = false;
9042
9043 if (active[j])
9044 {
9045 // scan all of the markers
9046 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9047 {
9048 // not present at all
9049 active[j] = false;
9050 }
9051 else
9052 {
9053 // present and correct
9054 if (offset[j] < offset[best])
9055 {
9056 // closest so far
9057 best = j;
9058 }
9059 }
9060 }
9061 }
9062 } 10280 }
9063 10281
9064 // This is the normal exit from the scanning loop 10282 /*
10283 * If no delimeter found at or after i, we're done scanning.
10284 */
10285 if (earliestDel < 0) break;
9065 10286
9066 if (best == mlen) 10287 /*
10288 * If delimeter was a spacer, output the spacer.
10289 */
10290 if (earliestDel >= seplen)
9067 { 10291 {
9068 // no markers were found on this pass 10292 outarray[outlen++] = earliestStr;
9069 // so we're pretty much done
9070 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9071 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9072 break;
9073 } 10293 }
9074 10294
9075 // Otherwise we just add the newly delimited token 10295 /*
9076 // and recalculate where the search should continue. 10296 * Look at rest of src string following delimeter.
9077 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10297 */
9078 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10298 i = earliestSrc + earliestStr.Length;
9079
9080 if (best < seplen)
9081 {
9082 beginning = offset[best] + (separray[best].ToString()).Length;
9083 }
9084 else
9085 {
9086 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9087 string str = spcarray[best - seplen].ToString();
9088 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9089 tokens.Add(new LSL_String(str));
9090 }
9091 } 10299 }
9092 10300
9093 // This an awkward an not very intuitive boundary case. If the 10301 /*
9094 // last substring is a tokenizer, then there is an implied trailing 10302 * Make up an exact-sized output array suitable for an LSL_List object.
9095 // null list entry. Hopefully the single comparison will not be too 10303 */
9096 // arduous. Alternatively the 'break' could be replced with a return 10304 object[] outlist = new object[outlen];
9097 // but that's shabby programming. 10305 for (i = 0; i < outlen; i ++)
9098
9099 if ((beginning == srclen) && (keepNulls))
9100 { 10306 {
9101 if (srclen != 0) 10307 outlist[i] = new LSL_String(outarray[i]);
9102 tokens.Add(new LSL_String(""));
9103 } 10308 }
9104 10309 return new LSL_List(outlist);
9105 return tokens;
9106 }
9107
9108 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9109 {
9110 m_host.AddScriptLPS(1);
9111 return this.ParseString(src, separators, spacers, false);
9112 }
9113
9114 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9115 {
9116 m_host.AddScriptLPS(1);
9117 return this.ParseString(src, separators, spacers, true);
9118 } 10310 }
9119 10311
9120 public LSL_Integer llGetObjectPermMask(int mask) 10312 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9209,6 +10401,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9209 case 4: 10401 case 4:
9210 return (int)item.NextPermissions; 10402 return (int)item.NextPermissions;
9211 } 10403 }
10404 m_host.TaskInventory.LockItemsForRead(false);
9212 10405
9213 return -1; 10406 return -1;
9214 } 10407 }
@@ -9399,9 +10592,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9399 { 10592 {
9400 try 10593 try
9401 { 10594 {
10595 /*
9402 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10596 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9403 if (obj != null) 10597 if (obj != null)
9404 return (double)obj.GetMass(); 10598 return (double)obj.GetMass();
10599 */
10600 // return total object mass
10601 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10602 if (obj != null)
10603 return obj.GetMass();
10604
9405 // the object is null so the key is for an avatar 10605 // the object is null so the key is for an avatar
9406 ScenePresence avatar = World.GetScenePresence(key); 10606 ScenePresence avatar = World.GetScenePresence(key);
9407 if (avatar != null) 10607 if (avatar != null)
@@ -9421,7 +10621,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9421 } 10621 }
9422 10622
9423 /// <summary> 10623 /// <summary>
9424 /// illListReplaceList removes the sub-list defined by the inclusive indices 10624 /// llListReplaceList removes the sub-list defined by the inclusive indices
9425 /// start and end and inserts the src list in its place. The inclusive 10625 /// start and end and inserts the src list in its place. The inclusive
9426 /// nature of the indices means that at least one element must be deleted 10626 /// nature of the indices means that at least one element must be deleted
9427 /// if the indices are within the bounds of the existing list. I.e. 2,2 10627 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9478,16 +10678,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9478 // based upon end. Note that if end exceeds the upper 10678 // based upon end. Note that if end exceeds the upper
9479 // bound in this case, the entire destination list 10679 // bound in this case, the entire destination list
9480 // is removed. 10680 // is removed.
9481 else 10681 else if (start == 0)
9482 { 10682 {
9483 if (end + 1 < dest.Length) 10683 if (end + 1 < dest.Length)
9484 {
9485 return src + dest.GetSublist(end + 1, -1); 10684 return src + dest.GetSublist(end + 1, -1);
9486 }
9487 else 10685 else
9488 {
9489 return src; 10686 return src;
9490 } 10687 }
10688 else // Start < 0
10689 {
10690 if (end + 1 < dest.Length)
10691 return dest.GetSublist(end + 1, -1);
10692 else
10693 return new LSL_List();
9491 } 10694 }
9492 } 10695 }
9493 // Finally, if start > end, we strip away a prefix and 10696 // Finally, if start > end, we strip away a prefix and
@@ -9538,17 +10741,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9538 int width = 0; 10741 int width = 0;
9539 int height = 0; 10742 int height = 0;
9540 10743
9541 ParcelMediaCommandEnum? commandToSend = null; 10744 uint commandToSend = 0;
9542 float time = 0.0f; // default is from start 10745 float time = 0.0f; // default is from start
9543 10746
9544 ScenePresence presence = null; 10747 ScenePresence presence = null;
9545 10748
9546 for (int i = 0; i < commandList.Data.Length; i++) 10749 for (int i = 0; i < commandList.Data.Length; i++)
9547 { 10750 {
9548 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10751 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9549 switch (command) 10752 switch (command)
9550 { 10753 {
9551 case ParcelMediaCommandEnum.Agent: 10754 case (uint)ParcelMediaCommandEnum.Agent:
9552 // we send only to one agent 10755 // we send only to one agent
9553 if ((i + 1) < commandList.Length) 10756 if ((i + 1) < commandList.Length)
9554 { 10757 {
@@ -9565,25 +10768,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9565 } 10768 }
9566 break; 10769 break;
9567 10770
9568 case ParcelMediaCommandEnum.Loop: 10771 case (uint)ParcelMediaCommandEnum.Loop:
9569 loop = 1; 10772 loop = 1;
9570 commandToSend = command; 10773 commandToSend = command;
9571 update = true; //need to send the media update packet to set looping 10774 update = true; //need to send the media update packet to set looping
9572 break; 10775 break;
9573 10776
9574 case ParcelMediaCommandEnum.Play: 10777 case (uint)ParcelMediaCommandEnum.Play:
9575 loop = 0; 10778 loop = 0;
9576 commandToSend = command; 10779 commandToSend = command;
9577 update = true; //need to send the media update packet to make sure it doesn't loop 10780 update = true; //need to send the media update packet to make sure it doesn't loop
9578 break; 10781 break;
9579 10782
9580 case ParcelMediaCommandEnum.Pause: 10783 case (uint)ParcelMediaCommandEnum.Pause:
9581 case ParcelMediaCommandEnum.Stop: 10784 case (uint)ParcelMediaCommandEnum.Stop:
9582 case ParcelMediaCommandEnum.Unload: 10785 case (uint)ParcelMediaCommandEnum.Unload:
9583 commandToSend = command; 10786 commandToSend = command;
9584 break; 10787 break;
9585 10788
9586 case ParcelMediaCommandEnum.Url: 10789 case (uint)ParcelMediaCommandEnum.Url:
9587 if ((i + 1) < commandList.Length) 10790 if ((i + 1) < commandList.Length)
9588 { 10791 {
9589 if (commandList.Data[i + 1] is LSL_String) 10792 if (commandList.Data[i + 1] is LSL_String)
@@ -9596,7 +10799,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9596 } 10799 }
9597 break; 10800 break;
9598 10801
9599 case ParcelMediaCommandEnum.Texture: 10802 case (uint)ParcelMediaCommandEnum.Texture:
9600 if ((i + 1) < commandList.Length) 10803 if ((i + 1) < commandList.Length)
9601 { 10804 {
9602 if (commandList.Data[i + 1] is LSL_String) 10805 if (commandList.Data[i + 1] is LSL_String)
@@ -9609,7 +10812,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9609 } 10812 }
9610 break; 10813 break;
9611 10814
9612 case ParcelMediaCommandEnum.Time: 10815 case (uint)ParcelMediaCommandEnum.Time:
9613 if ((i + 1) < commandList.Length) 10816 if ((i + 1) < commandList.Length)
9614 { 10817 {
9615 if (commandList.Data[i + 1] is LSL_Float) 10818 if (commandList.Data[i + 1] is LSL_Float)
@@ -9621,7 +10824,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9621 } 10824 }
9622 break; 10825 break;
9623 10826
9624 case ParcelMediaCommandEnum.AutoAlign: 10827 case (uint)ParcelMediaCommandEnum.AutoAlign:
9625 if ((i + 1) < commandList.Length) 10828 if ((i + 1) < commandList.Length)
9626 { 10829 {
9627 if (commandList.Data[i + 1] is LSL_Integer) 10830 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9635,7 +10838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9635 } 10838 }
9636 break; 10839 break;
9637 10840
9638 case ParcelMediaCommandEnum.Type: 10841 case (uint)ParcelMediaCommandEnum.Type:
9639 if ((i + 1) < commandList.Length) 10842 if ((i + 1) < commandList.Length)
9640 { 10843 {
9641 if (commandList.Data[i + 1] is LSL_String) 10844 if (commandList.Data[i + 1] is LSL_String)
@@ -9648,7 +10851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9648 } 10851 }
9649 break; 10852 break;
9650 10853
9651 case ParcelMediaCommandEnum.Desc: 10854 case (uint)ParcelMediaCommandEnum.Desc:
9652 if ((i + 1) < commandList.Length) 10855 if ((i + 1) < commandList.Length)
9653 { 10856 {
9654 if (commandList.Data[i + 1] is LSL_String) 10857 if (commandList.Data[i + 1] is LSL_String)
@@ -9661,7 +10864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9661 } 10864 }
9662 break; 10865 break;
9663 10866
9664 case ParcelMediaCommandEnum.Size: 10867 case (uint)ParcelMediaCommandEnum.Size:
9665 if ((i + 2) < commandList.Length) 10868 if ((i + 2) < commandList.Length)
9666 { 10869 {
9667 if (commandList.Data[i + 1] is LSL_Integer) 10870 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9731,7 +10934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9731 } 10934 }
9732 } 10935 }
9733 10936
9734 if (commandToSend != null) 10937 if (commandToSend != 0)
9735 { 10938 {
9736 // the commandList contained a start/stop/... command, too 10939 // the commandList contained a start/stop/... command, too
9737 if (presence == null) 10940 if (presence == null)
@@ -9768,7 +10971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9768 10971
9769 if (aList.Data[i] != null) 10972 if (aList.Data[i] != null)
9770 { 10973 {
9771 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10974 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9772 { 10975 {
9773 case ParcelMediaCommandEnum.Url: 10976 case ParcelMediaCommandEnum.Url:
9774 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10977 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9825,15 +11028,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9825 11028
9826 if (quick_pay_buttons.Data.Length < 4) 11029 if (quick_pay_buttons.Data.Length < 4)
9827 { 11030 {
9828 LSLError("List must have at least 4 elements"); 11031 int x;
9829 return; 11032 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
11033 {
11034 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
11035 }
9830 } 11036 }
9831 m_host.ParentGroup.RootPart.PayPrice[0]=price; 11037 int[] nPrice = new int[5];
9832 11038 nPrice[0] = price;
9833 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 11039 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9834 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11040 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9835 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11041 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9836 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11042 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11043 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9837 m_host.ParentGroup.HasGroupChanged = true; 11044 m_host.ParentGroup.HasGroupChanged = true;
9838 } 11045 }
9839 11046
@@ -9850,7 +11057,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9850 return new LSL_Vector(); 11057 return new LSL_Vector();
9851 } 11058 }
9852 11059
9853 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11060// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11061 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9854 if (presence != null) 11062 if (presence != null)
9855 { 11063 {
9856 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11064 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9872,7 +11080,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9872 return new LSL_Rotation(); 11080 return new LSL_Rotation();
9873 } 11081 }
9874 11082
9875 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11083// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11084 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9876 if (presence != null) 11085 if (presence != null)
9877 { 11086 {
9878 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11087 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9932,8 +11141,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9932 { 11141 {
9933 m_host.AddScriptLPS(1); 11142 m_host.AddScriptLPS(1);
9934 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11143 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9935 if (detectedParams == null) return; // only works on the first detected avatar 11144 if (detectedParams == null)
9936 11145 {
11146 if (m_host.ParentGroup.IsAttachment == true)
11147 {
11148 detectedParams = new DetectParams();
11149 detectedParams.Key = m_host.OwnerID;
11150 }
11151 else
11152 {
11153 return;
11154 }
11155 }
11156
9937 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11157 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9938 if (avatar != null) 11158 if (avatar != null)
9939 { 11159 {
@@ -9941,6 +11161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9941 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11161 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9942 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11162 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9943 } 11163 }
11164
9944 ScriptSleep(1000); 11165 ScriptSleep(1000);
9945 } 11166 }
9946 11167
@@ -10064,12 +11285,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10064 11285
10065 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11286 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10066 object[] data = rules.Data; 11287 object[] data = rules.Data;
10067 for (int i = 0; i < data.Length; ++i) { 11288 for (int i = 0; i < data.Length; ++i)
11289 {
10068 int type = Convert.ToInt32(data[i++].ToString()); 11290 int type = Convert.ToInt32(data[i++].ToString());
10069 if (i >= data.Length) break; // odd number of entries => ignore the last 11291 if (i >= data.Length) break; // odd number of entries => ignore the last
10070 11292
10071 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11293 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10072 switch (type) { 11294 switch (type)
11295 {
10073 case ScriptBaseClass.CAMERA_FOCUS: 11296 case ScriptBaseClass.CAMERA_FOCUS:
10074 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11297 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10075 case ScriptBaseClass.CAMERA_POSITION: 11298 case ScriptBaseClass.CAMERA_POSITION:
@@ -10175,19 +11398,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10175 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11398 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10176 { 11399 {
10177 m_host.AddScriptLPS(1); 11400 m_host.AddScriptLPS(1);
10178 string ret = String.Empty; 11401
10179 string src1 = llBase64ToString(str1); 11402 if (str1 == String.Empty)
10180 string src2 = llBase64ToString(str2); 11403 return String.Empty;
10181 int c = 0; 11404 if (str2 == String.Empty)
10182 for (int i = 0; i < src1.Length; i++) 11405 return str1;
11406
11407 int len = str2.Length;
11408 if ((len % 4) != 0) // LL is EVIL!!!!
10183 { 11409 {
10184 ret += (char) (src1[i] ^ src2[c]); 11410 while (str2.EndsWith("="))
11411 str2 = str2.Substring(0, str2.Length - 1);
10185 11412
10186 c++; 11413 len = str2.Length;
10187 if (c >= src2.Length) 11414 int mod = len % 4;
10188 c = 0; 11415
11416 if (mod == 1)
11417 str2 = str2.Substring(0, str2.Length - 1);
11418 else if (mod == 2)
11419 str2 += "==";
11420 else if (mod == 3)
11421 str2 += "=";
10189 } 11422 }
10190 return llStringToBase64(ret); 11423
11424 byte[] data1;
11425 byte[] data2;
11426 try
11427 {
11428 data1 = Convert.FromBase64String(str1);
11429 data2 = Convert.FromBase64String(str2);
11430 }
11431 catch (Exception)
11432 {
11433 return new LSL_String(String.Empty);
11434 }
11435
11436 byte[] d2 = new Byte[data1.Length];
11437 int pos = 0;
11438
11439 if (data1.Length <= data2.Length)
11440 {
11441 Array.Copy(data2, 0, d2, 0, data1.Length);
11442 }
11443 else
11444 {
11445 while (pos < data1.Length)
11446 {
11447 len = data1.Length - pos;
11448 if (len > data2.Length)
11449 len = data2.Length;
11450
11451 Array.Copy(data2, 0, d2, pos, len);
11452 pos += len;
11453 }
11454 }
11455
11456 for (pos = 0 ; pos < data1.Length ; pos++ )
11457 data1[pos] ^= d2[pos];
11458
11459 return Convert.ToBase64String(data1);
10191 } 11460 }
10192 11461
10193 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11462 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10240,16 +11509,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10240 if (userAgent != null) 11509 if (userAgent != null)
10241 httpHeaders["User-Agent"] = userAgent; 11510 httpHeaders["User-Agent"] = userAgent;
10242 11511
11512 // See if the URL contains any header hacks
11513 string[] urlParts = url.Split(new char[] {'\n'});
11514 if (urlParts.Length > 1)
11515 {
11516 // Iterate the passed headers and parse them
11517 for (int i = 1 ; i < urlParts.Length ; i++ )
11518 {
11519 // The rest of those would be added to the body in SL.
11520 // Let's not do that.
11521 if (urlParts[i] == String.Empty)
11522 break;
11523
11524 // See if this could be a valid header
11525 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11526 if (headerParts.Length != 2)
11527 continue;
11528
11529 string headerName = headerParts[0].Trim();
11530 string headerValue = headerParts[1].Trim();
11531
11532 // Filter out headers that could be used to abuse
11533 // another system or cloak the request
11534 if (headerName.ToLower() == "x-secondlife-shard" ||
11535 headerName.ToLower() == "x-secondlife-object-name" ||
11536 headerName.ToLower() == "x-secondlife-object-key" ||
11537 headerName.ToLower() == "x-secondlife-region" ||
11538 headerName.ToLower() == "x-secondlife-local-position" ||
11539 headerName.ToLower() == "x-secondlife-local-velocity" ||
11540 headerName.ToLower() == "x-secondlife-local-rotation" ||
11541 headerName.ToLower() == "x-secondlife-owner-name" ||
11542 headerName.ToLower() == "x-secondlife-owner-key" ||
11543 headerName.ToLower() == "connection" ||
11544 headerName.ToLower() == "content-length" ||
11545 headerName.ToLower() == "from" ||
11546 headerName.ToLower() == "host" ||
11547 headerName.ToLower() == "proxy-authorization" ||
11548 headerName.ToLower() == "referer" ||
11549 headerName.ToLower() == "trailer" ||
11550 headerName.ToLower() == "transfer-encoding" ||
11551 headerName.ToLower() == "via" ||
11552 headerName.ToLower() == "authorization")
11553 continue;
11554
11555 httpHeaders[headerName] = headerValue;
11556 }
11557
11558 // Finally, strip any protocol specifier from the URL
11559 url = urlParts[0].Trim();
11560 int idx = url.IndexOf(" HTTP/");
11561 if (idx != -1)
11562 url = url.Substring(0, idx);
11563 }
11564
10243 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11565 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10244 Regex r = new Regex(authregex); 11566 Regex r = new Regex(authregex);
10245 int[] gnums = r.GetGroupNumbers(); 11567 int[] gnums = r.GetGroupNumbers();
10246 Match m = r.Match(url); 11568 Match m = r.Match(url);
10247 if (m.Success) { 11569 if (m.Success)
10248 for (int i = 1; i < gnums.Length; i++) { 11570 {
11571 for (int i = 1; i < gnums.Length; i++)
11572 {
10249 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11573 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10250 //CaptureCollection cc = g.Captures; 11574 //CaptureCollection cc = g.Captures;
10251 } 11575 }
10252 if (m.Groups.Count == 5) { 11576 if (m.Groups.Count == 5)
11577 {
10253 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11578 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10254 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11579 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10255 } 11580 }
@@ -10452,6 +11777,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10452 11777
10453 LSL_List ret = new LSL_List(); 11778 LSL_List ret = new LSL_List();
10454 UUID key = new UUID(); 11779 UUID key = new UUID();
11780
11781
10455 if (UUID.TryParse(id, out key)) 11782 if (UUID.TryParse(id, out key))
10456 { 11783 {
10457 ScenePresence av = World.GetScenePresence(key); 11784 ScenePresence av = World.GetScenePresence(key);
@@ -10469,13 +11796,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10469 ret.Add(new LSL_String("")); 11796 ret.Add(new LSL_String(""));
10470 break; 11797 break;
10471 case ScriptBaseClass.OBJECT_POS: 11798 case ScriptBaseClass.OBJECT_POS:
10472 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11799 Vector3 avpos;
11800
11801 if (av.ParentID != 0 && av.ParentPart != null)
11802 {
11803 avpos = av.OffsetPosition;
11804
11805 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11806 avpos -= sitOffset;
11807
11808 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11809 }
11810 else
11811 avpos = av.AbsolutePosition;
11812
11813 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10473 break; 11814 break;
10474 case ScriptBaseClass.OBJECT_ROT: 11815 case ScriptBaseClass.OBJECT_ROT:
10475 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11816 Quaternion avrot = av.Rotation;
11817 if (av.ParentID != 0 && av.ParentPart != null)
11818 {
11819 avrot = av.ParentPart.GetWorldRotation() * avrot;
11820 }
11821 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10476 break; 11822 break;
10477 case ScriptBaseClass.OBJECT_VELOCITY: 11823 case ScriptBaseClass.OBJECT_VELOCITY:
10478 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11824 Vector3 avvel = av.Velocity;
11825 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10479 break; 11826 break;
10480 case ScriptBaseClass.OBJECT_OWNER: 11827 case ScriptBaseClass.OBJECT_OWNER:
10481 ret.Add(new LSL_String(id)); 11828 ret.Add(new LSL_String(id));
@@ -10531,11 +11878,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10531 case ScriptBaseClass.OBJECT_NAME: 11878 case ScriptBaseClass.OBJECT_NAME:
10532 ret.Add(new LSL_String(obj.Name)); 11879 ret.Add(new LSL_String(obj.Name));
10533 break; 11880 break;
10534 case ScriptBaseClass.OBJECT_DESC: 11881 case ScriptBaseClass.OBJECT_DESC:
10535 ret.Add(new LSL_String(obj.Description)); 11882 ret.Add(new LSL_String(obj.Description));
10536 break; 11883 break;
10537 case ScriptBaseClass.OBJECT_POS: 11884 case ScriptBaseClass.OBJECT_POS:
10538 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11885 Vector3 opos = obj.AbsolutePosition;
11886 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10539 break; 11887 break;
10540 case ScriptBaseClass.OBJECT_ROT: 11888 case ScriptBaseClass.OBJECT_ROT:
10541 { 11889 {
@@ -10551,7 +11899,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10551 } 11899 }
10552 break; 11900 break;
10553 case ScriptBaseClass.OBJECT_VELOCITY: 11901 case ScriptBaseClass.OBJECT_VELOCITY:
10554 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11902 Vector3 ovel = obj.Velocity;
11903 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10555 break; 11904 break;
10556 case ScriptBaseClass.OBJECT_OWNER: 11905 case ScriptBaseClass.OBJECT_OWNER:
10557 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11906 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10585,9 +11934,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10585 // The value returned in SL for normal prims is prim count 11934 // The value returned in SL for normal prims is prim count
10586 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11935 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10587 break; 11936 break;
10588 // The following 3 costs I have intentionaly coded to return zero. They are part of 11937
10589 // "Land Impact" calculations. These calculations are probably not applicable 11938 // costs below may need to be diferent for root parts, need to check
10590 // to OpenSim and are not yet complete in SL
10591 case ScriptBaseClass.OBJECT_SERVER_COST: 11939 case ScriptBaseClass.OBJECT_SERVER_COST:
10592 // The linden calculation is here 11940 // The linden calculation is here
10593 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11941 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10595,16 +11943,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10595 ret.Add(new LSL_Float(0)); 11943 ret.Add(new LSL_Float(0));
10596 break; 11944 break;
10597 case ScriptBaseClass.OBJECT_STREAMING_COST: 11945 case ScriptBaseClass.OBJECT_STREAMING_COST:
10598 // The linden calculation is here 11946 // The value returned in SL for normal prims is prim count * 0.06
10599 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11947 ret.Add(new LSL_Float(obj.StreamingCost));
10600 // The value returned in SL for normal prims looks like the prim count * 0.06
10601 ret.Add(new LSL_Float(0));
10602 break; 11948 break;
10603 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11949 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10604 // The linden calculation is here 11950 // The value returned in SL for normal prims is prim count
10605 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11951 ret.Add(new LSL_Float(obj.PhysicsCost));
10606 // The value returned in SL for normal prims looks like the prim count
10607 ret.Add(new LSL_Float(0));
10608 break; 11952 break;
10609 default: 11953 default:
10610 // Invalid or unhandled constant. 11954 // Invalid or unhandled constant.
@@ -10802,15 +12146,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10802 return GetLinkPrimitiveParams(obj, rules); 12146 return GetLinkPrimitiveParams(obj, rules);
10803 } 12147 }
10804 12148
10805 public void print(string str) 12149 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10806 { 12150 {
10807 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12151 List<SceneObjectPart> parts = GetLinkParts(link);
10808 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12152 if (parts.Count < 1)
10809 if (ossl != null) 12153 return 0;
10810 { 12154
10811 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12155 return GetNumberOfSides(parts[0]);
10812 m_log.Info("LSL print():" + str);
10813 }
10814 } 12156 }
10815 12157
10816 private string Name2Username(string name) 12158 private string Name2Username(string name)
@@ -10855,7 +12197,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10855 12197
10856 return rq.ToString(); 12198 return rq.ToString();
10857 } 12199 }
10858 12200/*
12201 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12202 {
12203 m_SayShoutCount = 0;
12204 }
12205*/
10859 private struct Tri 12206 private struct Tri
10860 { 12207 {
10861 public Vector3 p1; 12208 public Vector3 p1;
@@ -10995,9 +12342,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10995 12342
10996 ContactResult result = new ContactResult (); 12343 ContactResult result = new ContactResult ();
10997 result.ConsumerID = group.LocalId; 12344 result.ConsumerID = group.LocalId;
10998 result.Depth = intersection.distance; 12345// result.Depth = intersection.distance;
10999 result.Normal = intersection.normal; 12346 result.Normal = intersection.normal;
11000 result.Pos = intersection.ipoint; 12347 result.Pos = intersection.ipoint;
12348 result.Depth = Vector3.Mag(rayStart - result.Pos);
11001 12349
11002 contacts.Add(result); 12350 contacts.Add(result);
11003 }); 12351 });
@@ -11130,6 +12478,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11130 12478
11131 return contacts[0]; 12479 return contacts[0];
11132 } 12480 }
12481/*
12482 // not done:
12483 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12484 {
12485 ContactResult[] contacts = null;
12486 World.ForEachSOG(delegate(SceneObjectGroup group)
12487 {
12488 if (m_host.ParentGroup == group)
12489 return;
12490
12491 if (group.IsAttachment)
12492 return;
12493
12494 if(group.RootPart.PhysActor != null)
12495 return;
12496
12497 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12498 });
12499 return contacts;
12500 }
12501*/
11133 12502
11134 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12503 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11135 { 12504 {
@@ -11171,32 +12540,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11171 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12540 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11172 12541
11173 12542
11174 if (checkTerrain) 12543 if (World.SuportsRayCastFiltered())
11175 { 12544 {
11176 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12545 if (dist == 0)
11177 if (groundContact != null) 12546 return list;
11178 results.Add((ContactResult)groundContact);
11179 }
11180 12547
11181 if (checkAgents) 12548 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11182 { 12549 if (checkTerrain)
11183 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12550 rayfilter |= RayFilterFlags.land;
11184 foreach (ContactResult r in agentHits) 12551// if (checkAgents)
11185 results.Add(r); 12552// rayfilter |= RayFilterFlags.agent;
11186 } 12553 if (checkPhysical)
12554 rayfilter |= RayFilterFlags.physical;
12555 if (checkNonPhysical)
12556 rayfilter |= RayFilterFlags.nonphysical;
12557 if (detectPhantom)
12558 rayfilter |= RayFilterFlags.LSLPhanton;
12559
12560 Vector3 direction = dir * ( 1/dist);
11187 12561
11188 if (checkPhysical || checkNonPhysical || detectPhantom) 12562 if(rayfilter == 0)
12563 {
12564 list.Add(new LSL_Integer(0));
12565 return list;
12566 }
12567
12568 // get some more contacts to sort ???
12569 int physcount = 4 * count;
12570 if (physcount > 20)
12571 physcount = 20;
12572
12573 object physresults;
12574 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12575
12576 if (physresults == null)
12577 {
12578 list.Add(new LSL_Integer(-3)); // timeout error
12579 return list;
12580 }
12581
12582 results = (List<ContactResult>)physresults;
12583
12584 // for now physics doesn't detect sitted avatars so do it outside physics
12585 if (checkAgents)
12586 {
12587 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12588 foreach (ContactResult r in agentHits)
12589 results.Add(r);
12590 }
12591
12592 // TODO: Replace this with a better solution. ObjectIntersection can only
12593 // detect nonphysical phantoms. They are detected by virtue of being
12594 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12595 // physicsl phantoms as done by the physics scene
12596 // We don't want anything else but phantoms here.
12597 if (detectPhantom)
12598 {
12599 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12600 foreach (ContactResult r in objectHits)
12601 results.Add(r);
12602 }
12603 }
12604 else
11189 { 12605 {
11190 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12606 if (checkTerrain)
11191 foreach (ContactResult r in objectHits) 12607 {
11192 results.Add(r); 12608 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12609 if (groundContact != null)
12610 results.Add((ContactResult)groundContact);
12611 }
12612
12613 if (checkAgents)
12614 {
12615 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12616 foreach (ContactResult r in agentHits)
12617 results.Add(r);
12618 }
12619
12620 if (checkPhysical || checkNonPhysical || detectPhantom)
12621 {
12622 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12623 foreach (ContactResult r in objectHits)
12624 results.Add(r);
12625 }
11193 } 12626 }
11194 12627
11195 results.Sort(delegate(ContactResult a, ContactResult b) 12628 results.Sort(delegate(ContactResult a, ContactResult b)
11196 { 12629 {
11197 return a.Depth.CompareTo(b.Depth); 12630 return a.Depth.CompareTo(b.Depth);
11198 }); 12631 });
11199 12632
11200 int values = 0; 12633 int values = 0;
11201 SceneObjectGroup thisgrp = m_host.ParentGroup; 12634 SceneObjectGroup thisgrp = m_host.ParentGroup;
11202 12635
@@ -11289,7 +12722,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11289 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12722 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11290 if (!isAccount) return 0; 12723 if (!isAccount) return 0;
11291 if (estate.HasAccess(id)) return 1; 12724 if (estate.HasAccess(id)) return 1;
11292 if (estate.IsBanned(id)) 12725 if (estate.IsBanned(id, World.GetUserFlags(id)))
11293 estate.RemoveBan(id); 12726 estate.RemoveBan(id);
11294 estate.AddEstateUser(id); 12727 estate.AddEstateUser(id);
11295 break; 12728 break;
@@ -11308,14 +12741,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11308 break; 12741 break;
11309 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12742 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11310 if (!isAccount) return 0; 12743 if (!isAccount) return 0;
11311 if (estate.IsBanned(id)) return 1; 12744 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11312 EstateBan ban = new EstateBan(); 12745 EstateBan ban = new EstateBan();
11313 ban.EstateID = estate.EstateID; 12746 ban.EstateID = estate.EstateID;
11314 ban.BannedUserID = id; 12747 ban.BannedUserID = id;
11315 estate.AddBan(ban); 12748 estate.AddBan(ban);
11316 break; 12749 break;
11317 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12750 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11318 if (!isAccount || !estate.IsBanned(id)) return 0; 12751 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11319 estate.RemoveBan(id); 12752 estate.RemoveBan(id);
11320 break; 12753 break;
11321 default: return 0; 12754 default: return 0;
@@ -11344,7 +12777,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11344 return 16384; 12777 return 16384;
11345 } 12778 }
11346 12779
11347 public LSL_Integer llGetUsedMemory() 12780 public virtual LSL_Integer llGetUsedMemory()
11348 { 12781 {
11349 m_host.AddScriptLPS(1); 12782 m_host.AddScriptLPS(1);
11350 // The value returned for LSO scripts in SL 12783 // The value returned for LSO scripts in SL
@@ -11372,7 +12805,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11372 public void llSetSoundQueueing(int queue) 12805 public void llSetSoundQueueing(int queue)
11373 { 12806 {
11374 m_host.AddScriptLPS(1); 12807 m_host.AddScriptLPS(1);
11375 NotImplemented("llSetSoundQueueing");
11376 } 12808 }
11377 12809
11378 public void llCollisionSprite(string impact_sprite) 12810 public void llCollisionSprite(string impact_sprite)
@@ -11384,10 +12816,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11384 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12816 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11385 { 12817 {
11386 m_host.AddScriptLPS(1); 12818 m_host.AddScriptLPS(1);
11387 NotImplemented("llGodLikeRezObject"); 12819
12820 if (!World.Permissions.IsGod(m_host.OwnerID))
12821 NotImplemented("llGodLikeRezObject");
12822
12823 AssetBase rezAsset = World.AssetService.Get(inventory);
12824 if (rezAsset == null)
12825 {
12826 llSay(0, "Asset not found");
12827 return;
12828 }
12829
12830 SceneObjectGroup group = null;
12831
12832 try
12833 {
12834 string xmlData = Utils.BytesToString(rezAsset.Data);
12835 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12836 }
12837 catch
12838 {
12839 llSay(0, "Asset not found");
12840 return;
12841 }
12842
12843 if (group == null)
12844 {
12845 llSay(0, "Asset not found");
12846 return;
12847 }
12848
12849 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12850 group.RootPart.AttachOffset = group.AbsolutePosition;
12851
12852 group.ResetIDs();
12853
12854 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12855 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12856 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12857 group.ScheduleGroupForFullUpdate();
12858
12859 // objects rezzed with this method are die_at_edge by default.
12860 group.RootPart.SetDieAtEdge(true);
12861
12862 group.ResumeScripts();
12863
12864 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12865 "object_rez", new Object[] {
12866 new LSL_String(
12867 group.RootPart.UUID.ToString()) },
12868 new DetectParams[0]));
12869 }
12870
12871 public LSL_String llTransferLindenDollars(string destination, int amount)
12872 {
12873 UUID txn = UUID.Random();
12874
12875 Util.FireAndForget(delegate(object x)
12876 {
12877 int replycode = 0;
12878 string replydata = destination + "," + amount.ToString();
12879
12880 try
12881 {
12882 TaskInventoryItem item = m_item;
12883 if (item == null)
12884 {
12885 replydata = "SERVICE_ERROR";
12886 return;
12887 }
12888
12889 m_host.AddScriptLPS(1);
12890
12891 if (item.PermsGranter == UUID.Zero)
12892 {
12893 replydata = "MISSING_PERMISSION_DEBIT";
12894 return;
12895 }
12896
12897 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12898 {
12899 replydata = "MISSING_PERMISSION_DEBIT";
12900 return;
12901 }
12902
12903 UUID toID = new UUID();
12904
12905 if (!UUID.TryParse(destination, out toID))
12906 {
12907 replydata = "INVALID_AGENT";
12908 return;
12909 }
12910
12911 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12912
12913 if (money == null)
12914 {
12915 replydata = "TRANSFERS_DISABLED";
12916 return;
12917 }
12918
12919 bool result = money.ObjectGiveMoney(
12920 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12921
12922 if (result)
12923 {
12924 replycode = 1;
12925 return;
12926 }
12927
12928 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12929 }
12930 finally
12931 {
12932 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12933 "transaction_result", new Object[] {
12934 new LSL_String(txn.ToString()),
12935 new LSL_Integer(replycode),
12936 new LSL_String(replydata) },
12937 new DetectParams[0]));
12938 }
12939 });
12940
12941 return txn.ToString();
11388 } 12942 }
11389 12943
11390 #endregion 12944 #endregion
12945
12946 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12947 {
12948 SceneObjectGroup group = m_host.ParentGroup;
12949
12950 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12951 return;
12952 if (group.IsAttachment)
12953 return;
12954
12955 if (frames.Data.Length > 0) // We are getting a new motion
12956 {
12957 if (group.RootPart.KeyframeMotion != null)
12958 group.RootPart.KeyframeMotion.Stop();
12959 group.RootPart.KeyframeMotion = null;
12960
12961 int idx = 0;
12962
12963 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12964 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12965
12966 while (idx < options.Data.Length)
12967 {
12968 int option = (int)options.GetLSLIntegerItem(idx++);
12969 int remain = options.Data.Length - idx;
12970
12971 switch (option)
12972 {
12973 case ScriptBaseClass.KFM_MODE:
12974 if (remain < 1)
12975 break;
12976 int modeval = (int)options.GetLSLIntegerItem(idx++);
12977 switch(modeval)
12978 {
12979 case ScriptBaseClass.KFM_FORWARD:
12980 mode = KeyframeMotion.PlayMode.Forward;
12981 break;
12982 case ScriptBaseClass.KFM_REVERSE:
12983 mode = KeyframeMotion.PlayMode.Reverse;
12984 break;
12985 case ScriptBaseClass.KFM_LOOP:
12986 mode = KeyframeMotion.PlayMode.Loop;
12987 break;
12988 case ScriptBaseClass.KFM_PING_PONG:
12989 mode = KeyframeMotion.PlayMode.PingPong;
12990 break;
12991 }
12992 break;
12993 case ScriptBaseClass.KFM_DATA:
12994 if (remain < 1)
12995 break;
12996 int dataval = (int)options.GetLSLIntegerItem(idx++);
12997 data = (KeyframeMotion.DataFormat)dataval;
12998 break;
12999 }
13000 }
13001
13002 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
13003
13004 idx = 0;
13005
13006 int elemLength = 2;
13007 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
13008 elemLength = 3;
13009
13010 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
13011 while (idx < frames.Data.Length)
13012 {
13013 int remain = frames.Data.Length - idx;
13014
13015 if (remain < elemLength)
13016 break;
13017
13018 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
13019 frame.Position = null;
13020 frame.Rotation = null;
13021
13022 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
13023 {
13024 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
13025 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
13026 }
13027 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
13028 {
13029 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
13030 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
13031 }
13032
13033 float tempf = (float)frames.GetLSLFloatItem(idx++);
13034 frame.TimeMS = (int)(tempf * 1000.0f);
13035
13036 keyframes.Add(frame);
13037 }
13038
13039 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
13040 group.RootPart.KeyframeMotion.Start();
13041 }
13042 else
13043 {
13044 if (group.RootPart.KeyframeMotion == null)
13045 return;
13046
13047 if (options.Data.Length == 0)
13048 {
13049 group.RootPart.KeyframeMotion.Stop();
13050 return;
13051 }
13052
13053 int code = (int)options.GetLSLIntegerItem(0);
13054
13055 int idx = 0;
13056
13057 while (idx < options.Data.Length)
13058 {
13059 int option = (int)options.GetLSLIntegerItem(idx++);
13060 int remain = options.Data.Length - idx;
13061
13062 switch (option)
13063 {
13064 case ScriptBaseClass.KFM_COMMAND:
13065 int cmd = (int)options.GetLSLIntegerItem(idx++);
13066 switch (cmd)
13067 {
13068 case ScriptBaseClass.KFM_CMD_PLAY:
13069 group.RootPart.KeyframeMotion.Start();
13070 break;
13071 case ScriptBaseClass.KFM_CMD_STOP:
13072 group.RootPart.KeyframeMotion.Stop();
13073 break;
13074 case ScriptBaseClass.KFM_CMD_PAUSE:
13075 group.RootPart.KeyframeMotion.Pause();
13076 break;
13077 }
13078 break;
13079 }
13080 }
13081 }
13082 }
11391 } 13083 }
11392 13084
11393 public class NotecardCache 13085 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 859ee93..2f02f1f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -916,18 +925,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
916 if (target != null) 925 if (target != null)
917 { 926 {
918 UUID animID=UUID.Zero; 927 UUID animID=UUID.Zero;
919 lock (m_host.TaskInventory) 928 m_host.TaskInventory.LockItemsForRead(true);
929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
920 { 930 {
921 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 931 if (inv.Value.Name == animation)
922 { 932 {
923 if (inv.Value.Name == animation) 933 if (inv.Value.Type == (int)AssetType.Animation)
924 { 934 animID = inv.Value.AssetID;
925 if (inv.Value.Type == (int)AssetType.Animation) 935 continue;
926 animID = inv.Value.AssetID;
927 continue;
928 }
929 } 936 }
930 } 937 }
938 m_host.TaskInventory.LockItemsForRead(false);
931 if (animID == UUID.Zero) 939 if (animID == UUID.Zero)
932 target.Animator.AddAnimation(animation, m_host.UUID); 940 target.Animator.AddAnimation(animation, m_host.UUID);
933 else 941 else
@@ -968,6 +976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
968 else 976 else
969 animID = UUID.Zero; 977 animID = UUID.Zero;
970 } 978 }
979 m_host.TaskInventory.LockItemsForRead(false);
971 980
972 if (animID == UUID.Zero) 981 if (animID == UUID.Zero)
973 target.Animator.RemoveAnimation(animation); 982 target.Animator.RemoveAnimation(animation);
@@ -1801,6 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1801 1810
1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1811 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1803 { 1812 {
1813 m_host.TaskInventory.LockItemsForRead(true);
1804 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1814 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1805 { 1815 {
1806 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1816 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1808,6 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 assetID = item.AssetID; 1818 assetID = item.AssetID;
1809 } 1819 }
1810 } 1820 }
1821 m_host.TaskInventory.LockItemsForRead(false);
1811 } 1822 }
1812 1823
1813 if (assetID == UUID.Zero) 1824 if (assetID == UUID.Zero)
@@ -2279,7 +2290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2290 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2280 m_host.AddScriptLPS(1); 2291 m_host.AddScriptLPS(1);
2281 2292
2282 return NpcCreate(firstname, lastname, position, notecard, false, false); 2293 return NpcCreate(firstname, lastname, position, notecard, true, false);
2283 } 2294 }
2284 2295
2285 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2296 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2290,24 +2301,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2290 return NpcCreate( 2301 return NpcCreate(
2291 firstname, lastname, position, notecard, 2302 firstname, lastname, position, notecard,
2292 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2303 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2293 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2304 false);
2305// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2294 } 2306 }
2295 2307
2296 private LSL_Key NpcCreate( 2308 private LSL_Key NpcCreate(
2297 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2309 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2298 { 2310 {
2311 if (!owned)
2312 OSSLError("Unowned NPCs are unsupported");
2313
2314 string groupTitle = String.Empty;
2315
2316 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2317 return new LSL_Key(UUID.Zero.ToString());
2318
2319 if (firstname != String.Empty || lastname != String.Empty)
2320 {
2321 if (firstname != "Shown outfit:")
2322 groupTitle = "- NPC -";
2323 }
2324
2299 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2325 INPCModule module = World.RequestModuleInterface<INPCModule>();
2300 if (module != null) 2326 if (module != null)
2301 { 2327 {
2302 AvatarAppearance appearance = null; 2328 AvatarAppearance appearance = null;
2303 2329
2304 UUID id; 2330// UUID id;
2305 if (UUID.TryParse(notecard, out id)) 2331// if (UUID.TryParse(notecard, out id))
2306 { 2332// {
2307 ScenePresence clonePresence = World.GetScenePresence(id); 2333// ScenePresence clonePresence = World.GetScenePresence(id);
2308 if (clonePresence != null) 2334// if (clonePresence != null)
2309 appearance = clonePresence.Appearance; 2335// appearance = clonePresence.Appearance;
2310 } 2336// }
2311 2337
2312 if (appearance == null) 2338 if (appearance == null)
2313 { 2339 {
@@ -2335,6 +2361,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2335 World, 2361 World,
2336 appearance); 2362 appearance);
2337 2363
2364 ScenePresence sp;
2365 if (World.TryGetScenePresence(x, out sp))
2366 {
2367 sp.Grouptitle = groupTitle;
2368 sp.SendAvatarDataToAllAgents();
2369 }
2338 return new LSL_Key(x.ToString()); 2370 return new LSL_Key(x.ToString());
2339 } 2371 }
2340 2372
@@ -2636,16 +2668,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2636 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2668 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2637 m_host.AddScriptLPS(1); 2669 m_host.AddScriptLPS(1);
2638 2670
2639 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2671 ManualResetEvent ev = new ManualResetEvent(false);
2640 if (module != null)
2641 {
2642 UUID npcId = new UUID(npc.m_string);
2643 2672
2644 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2673 Util.FireAndForget(delegate(object x) {
2645 return; 2674 try
2675 {
2676 INPCModule module = World.RequestModuleInterface<INPCModule>();
2677 if (module != null)
2678 {
2679 UUID npcId = new UUID(npc.m_string);
2646 2680
2647 module.DeleteNPC(npcId, World); 2681 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2648 } 2682 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2683 {
2684 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2685 return;
2686 }
2687
2688 module.DeleteNPC(npcId, World);
2689 }
2690 }
2691 finally
2692 {
2693 ev.Set();
2694 }
2695 });
2696 ev.WaitOne();
2649 } 2697 }
2650 2698
2651 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2699 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3338,4 +3386,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3338 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3386 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3339 } 3387 }
3340 } 3388 }
3341} \ No newline at end of file 3389}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index a626be8..678f9d5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -476,7 +477,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
476 // Position of a sensor in a child prim attached to an avatar 477 // Position of a sensor in a child prim attached to an avatar
477 // will be still wrong. 478 // will be still wrong.
478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 479 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
479 q = avatar.Rotation * q; 480 if (avatar == null)
481 return sensedEntities;
482 fromRegionPos = avatar.AbsolutePosition;
483 q = avatar.Rotation;
480 } 484 }
481 485
482 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -492,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
492// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
493// presence.Name, presence.PresenceType, ts.name, ts.type); 497// presence.Name, presence.PresenceType, ts.name, ts.type);
494 498
495 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 499 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
496 { 500 {
497 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
498 if (npcData == null || !npcData.SenseAsAgent) 502 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
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 3fb463b..af35258 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,12 @@ 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 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 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);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
428 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 1f000a3..8c34ed3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
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 e1c054d..f989cc6 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;
@@ -95,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
98 98
99 //Particle Systems 99 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -285,6 +285,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
285 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 285 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
286 public const int CHANGED_MEDIA = 2048; 286 public const int CHANGED_MEDIA = 2048;
287 public const int CHANGED_ANIMATION = 16384; 287 public const int CHANGED_ANIMATION = 16384;
288 public const int CHANGED_POSITION = 32768;
288 public const int TYPE_INVALID = 0; 289 public const int TYPE_INVALID = 0;
289 public const int TYPE_INTEGER = 1; 290 public const int TYPE_INTEGER = 1;
290 public const int TYPE_FLOAT = 2; 291 public const int TYPE_FLOAT = 2;
@@ -589,6 +590,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
589 public const int PRIM_MEDIA_PERM_OWNER = 1; 590 public const int PRIM_MEDIA_PERM_OWNER = 1;
590 public const int PRIM_MEDIA_PERM_GROUP = 2; 591 public const int PRIM_MEDIA_PERM_GROUP = 2;
591 public const int PRIM_MEDIA_PERM_ANYONE = 4; 592 public const int PRIM_MEDIA_PERM_ANYONE = 4;
593
594 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
595 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
596 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
597 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
598
599 public const int PRIM_PHYSICS_MATERIAL = 31;
600 public const int DENSITY = 1;
601 public const int FRICTION = 2;
602 public const int RESTITUTION = 4;
603 public const int GRAVITY_MULTIPLIER = 8;
592 604
593 // extra constants for llSetPrimMediaParams 605 // extra constants for llSetPrimMediaParams
594 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 606 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -661,6 +673,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
661 673
662 public static readonly LSLInteger RCERR_UNKNOWN = -1; 674 public static readonly LSLInteger RCERR_UNKNOWN = -1;
663 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 675 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
664 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 676 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
677
678 public const int KFM_MODE = 1;
679 public const int KFM_LOOP = 1;
680 public const int KFM_REVERSE = 3;
681 public const int KFM_FORWARD = 0;
682 public const int KFM_PING_PONG = 2;
683 public const int KFM_DATA = 2;
684 public const int KFM_TRANSLATION = 2;
685 public const int KFM_ROTATION = 1;
686 public const int KFM_COMMAND = 0;
687 public const int KFM_CMD_PLAY = 0;
688 public const int KFM_CMD_STOP = 1;
689 public const int KFM_CMD_PAUSE = 2;
665 } 690 }
666} 691}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 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();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
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/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 0108f44..9e5fb24 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
@@ -102,6 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 Type = 0; 103 Type = 0;
103 Velocity = new LSL_Types.Vector3(); 104 Velocity = new LSL_Types.Vector3();
104 initializeSurfaceTouch(); 105 initializeSurfaceTouch();
106 Country = String.Empty;
105 } 107 }
106 108
107 public UUID Key; 109 public UUID Key;
@@ -133,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
133 private int touchFace; 135 private int touchFace;
134 public int TouchFace { get { return touchFace; } } 136 public int TouchFace { get { return touchFace; } }
135 137
138 public string Country;
139
136 // This can be done in two places including the constructor 140 // This can be done in two places including the constructor
137 // so be carefull what gets added here 141 // so be carefull what gets added here
138 private void initializeSurfaceTouch() 142 private void initializeSurfaceTouch()
@@ -180,6 +184,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
180 return; 184 return;
181 185
182 Name = presence.Firstname + " " + presence.Lastname; 186 Name = presence.Firstname + " " + presence.Lastname;
187 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
188 if (account != null)
189 Country = account.UserCountry;
190
183 Owner = Key; 191 Owner = Key;
184 Position = new LSL_Types.Vector3( 192 Position = new LSL_Types.Vector3(
185 presence.AbsolutePosition.X, 193 presence.AbsolutePosition.X,
@@ -195,22 +203,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
195 presence.Velocity.Y, 203 presence.Velocity.Y,
196 presence.Velocity.Z); 204 presence.Velocity.Z);
197 205
198 if (presence.PresenceType != PresenceType.Npc) 206 Type = 0x01; // Avatar
199 { 207 if (presence.PresenceType == PresenceType.Npc)
200 Type = AGENT; 208 Type = 0x20;
201 } 209
202 else 210 // Cope Impl. We don't use OS_NPC.
203 { 211 //if (presence.PresenceType != PresenceType.Npc)
204 Type = OS_NPC; 212 //{
205 213 // Type = AGENT;
206 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 214 //}
207 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 215 //else
208 216 //{
209 if (npcData.SenseAsAgent) 217 // Type = OS_NPC;
210 { 218
211 Type |= AGENT; 219 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
212 } 220 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
213 } 221
222 // if (npcData.SenseAsAgent)
223 // {
224 // Type |= AGENT;
225 // }
226 //}
214 227
215 if (presence.Velocity != Vector3.Zero) 228 if (presence.Velocity != Vector3.Zero)
216 Type |= ACTIVE; 229 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5793cc9..771db0c 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;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -417,14 +417,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
417 { 417 {
418 int permsMask; 418 int permsMask;
419 UUID permsGranter; 419 UUID permsGranter;
420 lock (part.TaskInventory) 420 part.TaskInventory.LockItemsForRead(true);
421 if (!part.TaskInventory.ContainsKey(ItemID))
421 { 422 {
422 if (!part.TaskInventory.ContainsKey(ItemID)) 423 part.TaskInventory.LockItemsForRead(false);
423 return; 424 return;
424
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 } 425 }
426 permsGranter = part.TaskInventory[ItemID].PermsGranter;
427 permsMask = part.TaskInventory[ItemID].PermsMask;
428 part.TaskInventory.LockItemsForRead(false);
428 429
429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 430 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
430 { 431 {
@@ -552,6 +553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 return true; 553 return true;
553 } 554 }
554 555
556 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
555 public void SetState(string state) 557 public void SetState(string state)
556 { 558 {
557 if (state == State) 559 if (state == State)
@@ -563,7 +565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 new DetectParams[0])); 565 new DetectParams[0]));
564 PostEvent(new EventParams("state_entry", new Object[0], 566 PostEvent(new EventParams("state_entry", new Object[0],
565 new DetectParams[0])); 567 new DetectParams[0]));
566 568
567 throw new EventAbortException(); 569 throw new EventAbortException();
568 } 570 }
569 571
@@ -653,45 +655,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
653 /// <returns></returns> 655 /// <returns></returns>
654 public object EventProcessor() 656 public object EventProcessor()
655 { 657 {
658 EventParams data = null;
656 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 659 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
657 if (!Running) 660 if (!Running)
658 return 0; 661 return 0;
659 662
660 lock (m_Script)
661 {
662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 663// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
663 664
664 if (Suspended) 665 if (Suspended)
665 return 0; 666 return 0;
666
667 EventParams data = null;
668 667
669 lock (EventQueue) 668 lock (EventQueue)
669 {
670 data = (EventParams) EventQueue.Dequeue();
671 if (data == null) // Shouldn't happen
670 { 672 {
671 data = (EventParams)EventQueue.Dequeue(); 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
672 if (data == null) // Shouldn't happen
673 { 674 {
674 if (EventQueue.Count > 0 && Running && !ShuttingDown) 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 {
676 m_CurrentWorkItem = Engine.QueueEventHandler(this);
677 }
678 else
679 {
680 m_CurrentWorkItem = null;
681 }
682 return 0;
683 } 676 }
684 677 else
685 if (data.EventName == "timer")
686 m_TimerQueued = false;
687 if (data.EventName == "control")
688 { 678 {
689 if (m_ControlEventsInQueue > 0) 679 m_CurrentWorkItem = null;
690 m_ControlEventsInQueue--;
691 } 680 }
692 if (data.EventName == "collision") 681 return 0;
693 m_CollisionInQueue = false;
694 } 682 }
683
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 {
688 if (m_ControlEventsInQueue > 0)
689 m_ControlEventsInQueue--;
690 }
691 if (data.EventName == "collision")
692 m_CollisionInQueue = false;
693 }
694
695 lock(m_Script)
696 {
695 697
696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 698// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
697 699
@@ -846,6 +848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
851 part.CollisionSound = UUID.Zero;
849 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 852 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
850 EventQueue.Clear(); 853 EventQueue.Clear();
851 m_Script.ResetVars(); 854 m_Script.ResetVars();
@@ -860,6 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 863 new Object[0], new DetectParams[0]));
861 } 864 }
862 865
866 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 867 public void ApiResetScript()
864 { 868 {
865 // bool running = Running; 869 // bool running = Running;
@@ -871,6 +875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
871 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 875 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
872 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 876 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
873 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 877 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
878 part.CollisionSound = UUID.Zero;
874 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 879 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
875 880
876 EventQueue.Clear(); 881 EventQueue.Clear();
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 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 d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {