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.cs23
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3218
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs155
-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.cs11
-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.cs51
-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.cs172
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs37
18 files changed, 3084 insertions, 966 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..6879ebb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 if (xmlrpc != null)
321 {
322 xmlrpc.DeleteChannels(itemID);
323 xmlrpc.CancelSRDRequests(itemID);
324 }
325
326 // Remove Sensors
327 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
328
329 }
330
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 331 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 332 {
310 List<Object> data = new List<Object>(); 333 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..d03955b
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 632b73f..9df04df 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;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -112,17 +116,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
112 protected int m_notecardLineReadCharsMax = 255; 116 protected int m_notecardLineReadCharsMax = 255;
113 protected int m_scriptConsoleChannel = 0; 117 protected int m_scriptConsoleChannel = 0;
114 protected bool m_scriptConsoleChannelEnabled = false; 118 protected bool m_scriptConsoleChannelEnabled = false;
119 protected bool m_debuggerSafe = false;
115 protected IUrlModule m_UrlModule = null; 120 protected IUrlModule m_UrlModule = null;
116 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 121 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
117 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 122 new Dictionary<UUID, UserInfoCacheEntry>();
123 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
118 protected ISoundModule m_SoundModule = null; 124 protected ISoundModule m_SoundModule = null;
119 125
126// protected Timer m_ShoutSayTimer;
127 protected int m_SayShoutCount = 0;
128 DateTime m_lastSayShoutCheck;
129
130 private Dictionary<string, string> MovementAnimationsForLSL =
131 new Dictionary<string, string> {
132 {"FLY", "Flying"},
133 {"FLYSLOW", "FlyingSlow"},
134 {"HOVER_UP", "Hovering Up"},
135 {"HOVER_DOWN", "Hovering Down"},
136 {"HOVER", "Hovering"},
137 {"LAND", "Landing"},
138 {"FALLDOWN", "Falling Down"},
139 {"PREJUMP", "PreJumping"},
140 {"JUMP", "Jumping"},
141 {"STANDUP", "Standing Up"},
142 {"SOFT_LAND", "Soft Landing"},
143 {"STAND", "Standing"},
144 {"CROUCHWALK", "CrouchWalking"},
145 {"RUN", "Running"},
146 {"WALK", "Walking"},
147 {"CROUCH", "Crouching"},
148 {"TURNLEFT", "Turning Left"},
149 {"TURNRIGHT", "Turning Right"}
150 };
151
120 public void Initialize( 152 public void Initialize(
121 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle) 153 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, EventWaitHandle coopSleepHandle)
122 { 154 {
155 m_lastSayShoutCheck = DateTime.UtcNow;
156
123 m_ScriptEngine = scriptEngine; 157 m_ScriptEngine = scriptEngine;
124 m_host = host; 158 m_host = host;
125 m_item = item; 159 m_item = item;
160 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
126 m_coopSleepHandle = coopSleepHandle; 161 m_coopSleepHandle = coopSleepHandle;
127 162
128 LoadConfig(); 163 LoadConfig();
@@ -201,6 +236,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
201 get { return m_ScriptEngine.World; } 236 get { return m_ScriptEngine.World; }
202 } 237 }
203 238
239 [DebuggerNonUserCode]
204 public void state(string newState) 240 public void state(string newState)
205 { 241 {
206 m_ScriptEngine.SetState(m_item.ItemID, newState); 242 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -210,6 +246,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 /// Reset the named script. The script must be present 246 /// Reset the named script. The script must be present
211 /// in the same prim. 247 /// in the same prim.
212 /// </summary> 248 /// </summary>
249 [DebuggerNonUserCode]
213 public void llResetScript() 250 public void llResetScript()
214 { 251 {
215 m_host.AddScriptLPS(1); 252 m_host.AddScriptLPS(1);
@@ -272,6 +309,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
272 } 309 }
273 } 310 }
274 311
312 public List<ScenePresence> GetLinkAvatars(int linkType)
313 {
314 List<ScenePresence> ret = new List<ScenePresence>();
315 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
316 return ret;
317
318 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
319
320 switch (linkType)
321 {
322 case ScriptBaseClass.LINK_SET:
323 return avs;
324
325 case ScriptBaseClass.LINK_ROOT:
326 return ret;
327
328 case ScriptBaseClass.LINK_ALL_OTHERS:
329 return avs;
330
331 case ScriptBaseClass.LINK_ALL_CHILDREN:
332 return avs;
333
334 case ScriptBaseClass.LINK_THIS:
335 return ret;
336
337 default:
338 if (linkType < 0)
339 return ret;
340
341 int partCount = m_host.ParentGroup.GetPartCount();
342
343 if (linkType <= partCount)
344 {
345 return ret;
346 }
347 else
348 {
349 linkType = linkType - partCount;
350 if (linkType > avs.Count)
351 {
352 return ret;
353 }
354 else
355 {
356 ret.Add(avs[linkType-1]);
357 return ret;
358 }
359 }
360 }
361 }
362
275 public List<SceneObjectPart> GetLinkParts(int linkType) 363 public List<SceneObjectPart> GetLinkParts(int linkType)
276 { 364 {
277 return GetLinkParts(m_host, linkType); 365 return GetLinkParts(m_host, linkType);
@@ -280,6 +368,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
280 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 368 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
281 { 369 {
282 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 370 List<SceneObjectPart> ret = new List<SceneObjectPart>();
371 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
372 return ret;
283 ret.Add(part); 373 ret.Add(part);
284 374
285 switch (linkType) 375 switch (linkType)
@@ -506,31 +596,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
506 596
507 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 597 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
508 598
509 /// <summary> 599 // Utility function for llRot2Euler
510 /// Convert an LSL rotation to a Euler vector. 600
511 /// </summary> 601 // normalize an angle between -PI and PI (-180 to +180 degrees)
512 /// <remarks> 602 protected double NormalizeAngle(double angle)
513 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
514 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
515 /// </remarks>
516 /// <param name="r"></param>
517 /// <returns></returns>
518 public LSL_Vector llRot2Euler(LSL_Rotation r)
519 { 603 {
520 m_host.AddScriptLPS(1); 604 if (angle > -Math.PI && angle < Math.PI)
605 return angle;
521 606
522 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 607 int numPis = (int)(Math.PI / angle);
523 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 608 double remainder = angle - Math.PI * numPis;
524 if (m == 0.0) return new LSL_Vector(); 609 if (numPis % 2 == 1)
525 double x = Math.Atan2(-v.y, v.z); 610 return Math.PI - angle;
526 double sin = v.x / m; 611 return remainder;
527 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 612 }
528 double y = Math.Asin(sin);
529 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
530 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)));
531 double z = Math.Atan2(v.y, v.x);
532 613
533 return new LSL_Vector(x, y, z); 614 public LSL_Vector llRot2Euler(LSL_Rotation q1)
615 {
616 m_host.AddScriptLPS(1);
617 LSL_Vector eul = new LSL_Vector();
618
619 double sqw = q1.s*q1.s;
620 double sqx = q1.x*q1.x;
621 double sqy = q1.z*q1.z;
622 double sqz = q1.y*q1.y;
623 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
624 double test = q1.x*q1.z + q1.y*q1.s;
625 if (test > 0.4999*unit) { // singularity at north pole
626 eul.z = 2 * Math.Atan2(q1.x,q1.s);
627 eul.y = Math.PI/2;
628 eul.x = 0;
629 return eul;
630 }
631 if (test < -0.4999*unit) { // singularity at south pole
632 eul.z = -2 * Math.Atan2(q1.x,q1.s);
633 eul.y = -Math.PI/2;
634 eul.x = 0;
635 return eul;
636 }
637 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
638 eul.y = Math.Asin(2*test/unit);
639 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
640 return eul;
534 } 641 }
535 642
536 /* From wiki: 643 /* From wiki:
@@ -583,18 +690,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
583 m_host.AddScriptLPS(1); 690 m_host.AddScriptLPS(1);
584 691
585 double x,y,z,s; 692 double x,y,z,s;
586 693 v.x *= 0.5;
587 double c1 = Math.Cos(v.x * 0.5); 694 v.y *= 0.5;
588 double c2 = Math.Cos(v.y * 0.5); 695 v.z *= 0.5;
589 double c3 = Math.Cos(v.z * 0.5); 696 double c1 = Math.Cos(v.x);
590 double s1 = Math.Sin(v.x * 0.5); 697 double c2 = Math.Cos(v.y);
591 double s2 = Math.Sin(v.y * 0.5); 698 double c1c2 = c1 * c2;
592 double s3 = Math.Sin(v.z * 0.5); 699 double s1 = Math.Sin(v.x);
593 700 double s2 = Math.Sin(v.y);
594 x = s1 * c2 * c3 + c1 * s2 * s3; 701 double s1s2 = s1 * s2;
595 y = c1 * s2 * c3 - s1 * c2 * s3; 702 double c1s2 = c1 * s2;
596 z = s1 * s2 * c3 + c1 * c2 * s3; 703 double s1c2 = s1 * c2;
597 s = c1 * c2 * c3 - s1 * s2 * s3; 704 double c3 = Math.Cos(v.z);
705 double s3 = Math.Sin(v.z);
706
707 x = s1c2 * c3 + c1s2 * s3;
708 y = c1s2 * c3 - s1c2 * s3;
709 z = s1s2 * c3 + c1c2 * s3;
710 s = c1c2 * c3 - s1s2 * s3;
598 711
599 return new LSL_Rotation(x, y, z, s); 712 return new LSL_Rotation(x, y, z, s);
600 } 713 }
@@ -732,77 +845,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
732 { 845 {
733 //A and B should both be normalized 846 //A and B should both be normalized
734 m_host.AddScriptLPS(1); 847 m_host.AddScriptLPS(1);
735 LSL_Rotation rotBetween; 848 /* This method is more accurate than the SL one, and thus causes problems
736 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 849 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
737 // continue calculation. 850
738 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 851 double dotProduct = LSL_Vector.Dot(a, b);
852 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
853 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
854 double angle = Math.Acos(dotProduct / magProduct);
855 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
856 double s = Math.Sin(angle / 2);
857
858 double x = axis.x * s;
859 double y = axis.y * s;
860 double z = axis.z * s;
861 double w = Math.Cos(angle / 2);
862
863 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
864 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
865
866 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
867 */
868
869 // This method mimics the 180 errors found in SL
870 // See www.euclideanspace.com... angleBetween
871 LSL_Vector vec_a = a;
872 LSL_Vector vec_b = b;
873
874 // Eliminate zero length
875 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
876 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
877 if (vec_a_mag < 0.00001 ||
878 vec_b_mag < 0.00001)
739 { 879 {
740 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 880 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
741 } 881 }
742 else 882
883 // Normalize
884 vec_a = llVecNorm(vec_a);
885 vec_b = llVecNorm(vec_b);
886
887 // Calculate axis and rotation angle
888 LSL_Vector axis = vec_a % vec_b;
889 LSL_Float cos_theta = vec_a * vec_b;
890
891 // Check if parallel
892 if (cos_theta > 0.99999)
743 { 893 {
744 a = LSL_Vector.Norm(a); 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
745 b = LSL_Vector.Norm(b); 895 }
746 double dotProduct = LSL_Vector.Dot(a, b); 896
747 // There are two degenerate cases possible. These are for vectors 180 or 897 // Check if anti-parallel
748 // 0 degrees apart. These have to be detected and handled individually. 898 else if (cos_theta < -0.99999)
749 // 899 {
750 // Check for vectors 180 degrees apart. 900 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
751 // A dot product of -1 would mean the angle between vectors is 180 degrees. 901 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
752 if (dotProduct < -0.9999999f) 902 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
753 { 903 }
754 // First assume X axis is orthogonal to the vectors. 904 else // other rotation
755 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 905 {
756 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 906 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
757 // Check for near zero vector. A very small non-zero number here will create 907 axis = llVecNorm(axis);
758 // a rotation in an undesired direction. 908 double x, y, z, s, t;
759 if (LSL_Vector.Mag(orthoVector) > 0.0001) 909 s = Math.Cos(theta);
760 { 910 t = Math.Sin(theta);
761 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 911 x = axis.x * t;
762 } 912 y = axis.y * t;
763 // If the magnitude of the vector was near zero, then assume the X axis is not 913 z = axis.z * t;
764 // orthogonal and use the Z axis instead. 914 return new LSL_Rotation(x,y,z,s);
765 else
766 {
767 // Set 180 z rotation.
768 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
769 }
770 }
771 // Check for parallel vectors.
772 // A dot product of 1 would mean the angle between vectors is 0 degrees.
773 else if (dotProduct > 0.9999999f)
774 {
775 // Set zero rotation.
776 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
777 }
778 else
779 {
780 // All special checks have been performed so get the axis of rotation.
781 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
782 // Quarternion s value is the length of the unit vector + dot product.
783 double qs = 1.0 + dotProduct;
784 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
785 // Normalize the rotation.
786 double mag = LSL_Rotation.Mag(rotBetween);
787 // We shouldn't have to worry about a divide by zero here. The qs value will be
788 // non-zero because we already know if we're here, then the dotProduct is not -1 so
789 // qs will not be zero. Also, we've already handled the input vectors being zero so the
790 // crossProduct vector should also not be zero.
791 rotBetween.x = rotBetween.x / mag;
792 rotBetween.y = rotBetween.y / mag;
793 rotBetween.z = rotBetween.z / mag;
794 rotBetween.s = rotBetween.s / mag;
795 // Check for undefined values and set zero rotation if any found. This code might not actually be required
796 // any longer since zero vectors are checked for at the top.
797 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
798 {
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
800 }
801 }
802 } 915 }
803 return rotBetween;
804 } 916 }
805 917
806 public void llWhisper(int channelID, string text) 918 public void llWhisper(int channelID, string text)
807 { 919 {
808 m_host.AddScriptLPS(1); 920 m_host.AddScriptLPS(1);
@@ -818,10 +930,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
818 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 930 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
819 } 931 }
820 932
933 private void CheckSayShoutTime()
934 {
935 DateTime now = DateTime.UtcNow;
936 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
937 {
938 m_lastSayShoutCheck = now;
939 m_SayShoutCount = 0;
940 }
941 else
942 m_SayShoutCount++;
943 }
944
821 public void llSay(int channelID, string text) 945 public void llSay(int channelID, string text)
822 { 946 {
823 m_host.AddScriptLPS(1); 947 m_host.AddScriptLPS(1);
824 948
949 if (channelID == 0)
950// m_SayShoutCount++;
951 CheckSayShoutTime();
952
953 if (m_SayShoutCount >= 11)
954 ScriptSleep(2000);
955
825 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 956 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
826 { 957 {
827 Console.WriteLine(text); 958 Console.WriteLine(text);
@@ -844,6 +975,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
844 { 975 {
845 m_host.AddScriptLPS(1); 976 m_host.AddScriptLPS(1);
846 977
978 if (channelID == 0)
979// m_SayShoutCount++;
980 CheckSayShoutTime();
981
982 if (m_SayShoutCount >= 11)
983 ScriptSleep(2000);
984
847 if (text.Length > 1023) 985 if (text.Length > 1023)
848 text = text.Substring(0, 1023); 986 text = text.Substring(0, 1023);
849 987
@@ -875,22 +1013,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 1013
876 public void llRegionSayTo(string target, int channel, string msg) 1014 public void llRegionSayTo(string target, int channel, string msg)
877 { 1015 {
1016 string error = String.Empty;
1017
878 if (msg.Length > 1023) 1018 if (msg.Length > 1023)
879 msg = msg.Substring(0, 1023); 1019 msg = msg.Substring(0, 1023);
880 1020
881 m_host.AddScriptLPS(1); 1021 m_host.AddScriptLPS(1);
882 1022
883 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
884 {
885 return;
886 }
887
888 UUID TargetID; 1023 UUID TargetID;
889 UUID.TryParse(target, out TargetID); 1024 UUID.TryParse(target, out TargetID);
890 1025
891 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1026 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
892 if (wComm != null) 1027 if (wComm != null)
893 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1028 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1029 LSLError(error);
894 } 1030 }
895 1031
896 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1032 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1146,10 +1282,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1146 return detectedParams.TouchUV; 1282 return detectedParams.TouchUV;
1147 } 1283 }
1148 1284
1285 [DebuggerNonUserCode]
1149 public virtual void llDie() 1286 public virtual void llDie()
1150 { 1287 {
1151 m_host.AddScriptLPS(1); 1288 m_host.AddScriptLPS(1);
1152 throw new SelfDeleteException(); 1289 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1153 } 1290 }
1154 1291
1155 public LSL_Float llGround(LSL_Vector offset) 1292 public LSL_Float llGround(LSL_Vector offset)
@@ -1220,6 +1357,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1220 1357
1221 public void llSetStatus(int status, int value) 1358 public void llSetStatus(int status, int value)
1222 { 1359 {
1360 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1361 return;
1223 m_host.AddScriptLPS(1); 1362 m_host.AddScriptLPS(1);
1224 1363
1225 int statusrotationaxis = 0; 1364 int statusrotationaxis = 0;
@@ -1243,6 +1382,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1243 if (!allow) 1382 if (!allow)
1244 return; 1383 return;
1245 1384
1385 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1386 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1387 return;
1388
1246 m_host.ScriptSetPhysicsStatus(true); 1389 m_host.ScriptSetPhysicsStatus(true);
1247 } 1390 }
1248 else 1391 else
@@ -1443,6 +1586,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1443 { 1586 {
1444 m_host.AddScriptLPS(1); 1587 m_host.AddScriptLPS(1);
1445 1588
1589 SetColor(m_host, color, face);
1590 }
1591
1592 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1593 {
1594 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1595 return;
1596
1597 Primitive.TextureEntry tex = part.Shape.Textures;
1598 Color4 texcolor;
1599 if (face >= 0 && face < GetNumberOfSides(part))
1600 {
1601 texcolor = tex.CreateFace((uint)face).RGBA;
1602 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1603 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1604 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1605 tex.FaceTextures[face].RGBA = texcolor;
1606 part.UpdateTextureEntry(tex.GetBytes());
1607 return;
1608 }
1609 else if (face == ScriptBaseClass.ALL_SIDES)
1610 {
1611 for (uint i = 0; i < GetNumberOfSides(part); i++)
1612 {
1613 if (tex.FaceTextures[i] != null)
1614 {
1615 texcolor = tex.FaceTextures[i].RGBA;
1616 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1617 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1618 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1619 tex.FaceTextures[i].RGBA = texcolor;
1620 }
1621 texcolor = tex.DefaultTexture.RGBA;
1622 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1623 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1624 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1625 tex.DefaultTexture.RGBA = texcolor;
1626 }
1627 part.UpdateTextureEntry(tex.GetBytes());
1628 return;
1629 }
1630
1446 if (face == ScriptBaseClass.ALL_SIDES) 1631 if (face == ScriptBaseClass.ALL_SIDES)
1447 face = SceneObjectPart.ALL_SIDES; 1632 face = SceneObjectPart.ALL_SIDES;
1448 1633
@@ -1451,6 +1636,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1451 1636
1452 public void SetTexGen(SceneObjectPart part, int face,int style) 1637 public void SetTexGen(SceneObjectPart part, int face,int style)
1453 { 1638 {
1639 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1640 return;
1641
1454 Primitive.TextureEntry tex = part.Shape.Textures; 1642 Primitive.TextureEntry tex = part.Shape.Textures;
1455 MappingType textype; 1643 MappingType textype;
1456 textype = MappingType.Default; 1644 textype = MappingType.Default;
@@ -1481,6 +1669,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1481 1669
1482 public void SetGlow(SceneObjectPart part, int face, float glow) 1670 public void SetGlow(SceneObjectPart part, int face, float glow)
1483 { 1671 {
1672 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1673 return;
1674
1484 Primitive.TextureEntry tex = part.Shape.Textures; 1675 Primitive.TextureEntry tex = part.Shape.Textures;
1485 if (face >= 0 && face < GetNumberOfSides(part)) 1676 if (face >= 0 && face < GetNumberOfSides(part))
1486 { 1677 {
@@ -1506,6 +1697,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1506 1697
1507 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1698 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1508 { 1699 {
1700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1701 return;
1509 1702
1510 Shininess sval = new Shininess(); 1703 Shininess sval = new Shininess();
1511 1704
@@ -1556,6 +1749,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1556 1749
1557 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1750 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1558 { 1751 {
1752 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1753 return;
1754
1559 Primitive.TextureEntry tex = part.Shape.Textures; 1755 Primitive.TextureEntry tex = part.Shape.Textures;
1560 if (face >= 0 && face < GetNumberOfSides(part)) 1756 if (face >= 0 && face < GetNumberOfSides(part))
1561 { 1757 {
@@ -1616,13 +1812,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1616 m_host.AddScriptLPS(1); 1812 m_host.AddScriptLPS(1);
1617 1813
1618 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1814 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1619 1815 if (parts.Count > 0)
1620 foreach (SceneObjectPart part in parts) 1816 {
1621 SetAlpha(part, alpha, face); 1817 try
1818 {
1819 foreach (SceneObjectPart part in parts)
1820 SetAlpha(part, alpha, face);
1821 }
1822 finally
1823 {
1824 }
1825 }
1622 } 1826 }
1623 1827
1624 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1828 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1625 { 1829 {
1830 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1831 return;
1832
1626 Primitive.TextureEntry tex = part.Shape.Textures; 1833 Primitive.TextureEntry tex = part.Shape.Textures;
1627 Color4 texcolor; 1834 Color4 texcolor;
1628 if (face >= 0 && face < GetNumberOfSides(part)) 1835 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1675,7 +1882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1882 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1676 float wind, float tension, LSL_Vector Force) 1883 float wind, float tension, LSL_Vector Force)
1677 { 1884 {
1678 if (part == null) 1885 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1679 return; 1886 return;
1680 1887
1681 if (flexi) 1888 if (flexi)
@@ -1709,7 +1916,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1709 /// <param name="falloff"></param> 1916 /// <param name="falloff"></param>
1710 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1917 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1711 { 1918 {
1712 if (part == null) 1919 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1713 return; 1920 return;
1714 1921
1715 if (light) 1922 if (light)
@@ -1742,11 +1949,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1742 Primitive.TextureEntry tex = part.Shape.Textures; 1949 Primitive.TextureEntry tex = part.Shape.Textures;
1743 Color4 texcolor; 1950 Color4 texcolor;
1744 LSL_Vector rgb = new LSL_Vector(); 1951 LSL_Vector rgb = new LSL_Vector();
1952 int nsides = GetNumberOfSides(part);
1953
1745 if (face == ScriptBaseClass.ALL_SIDES) 1954 if (face == ScriptBaseClass.ALL_SIDES)
1746 { 1955 {
1747 int i; 1956 int i;
1748 1957 for (i = 0; i < nsides; i++)
1749 for (i = 0 ; i < GetNumberOfSides(part); i++)
1750 { 1958 {
1751 texcolor = tex.GetFace((uint)i).RGBA; 1959 texcolor = tex.GetFace((uint)i).RGBA;
1752 rgb.x += texcolor.R; 1960 rgb.x += texcolor.R;
@@ -1754,14 +1962,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1754 rgb.z += texcolor.B; 1962 rgb.z += texcolor.B;
1755 } 1963 }
1756 1964
1757 rgb.x /= (float)GetNumberOfSides(part); 1965 float invnsides = 1.0f / (float)nsides;
1758 rgb.y /= (float)GetNumberOfSides(part); 1966
1759 rgb.z /= (float)GetNumberOfSides(part); 1967 rgb.x *= invnsides;
1968 rgb.y *= invnsides;
1969 rgb.z *= invnsides;
1760 1970
1761 return rgb; 1971 return rgb;
1762 } 1972 }
1763 1973 if (face >= 0 && face < nsides)
1764 if (face >= 0 && face < GetNumberOfSides(part))
1765 { 1974 {
1766 texcolor = tex.GetFace((uint)face).RGBA; 1975 texcolor = tex.GetFace((uint)face).RGBA;
1767 rgb.x = texcolor.R; 1976 rgb.x = texcolor.R;
@@ -1788,15 +1997,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1788 m_host.AddScriptLPS(1); 1997 m_host.AddScriptLPS(1);
1789 1998
1790 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1999 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1791 2000 if (parts.Count > 0)
1792 foreach (SceneObjectPart part in parts) 2001 {
1793 SetTexture(part, texture, face); 2002 try
1794 2003 {
2004 foreach (SceneObjectPart part in parts)
2005 SetTexture(part, texture, face);
2006 }
2007 finally
2008 {
2009 }
2010 }
1795 ScriptSleep(200); 2011 ScriptSleep(200);
1796 } 2012 }
1797 2013
1798 protected void SetTexture(SceneObjectPart part, string texture, int face) 2014 protected void SetTexture(SceneObjectPart part, string texture, int face)
1799 { 2015 {
2016 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2017 return;
2018
1800 UUID textureID = new UUID(); 2019 UUID textureID = new UUID();
1801 2020
1802 textureID = InventoryKey(texture, (int)AssetType.Texture); 2021 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1841,6 +2060,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1841 2060
1842 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2061 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1843 { 2062 {
2063 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2064 return;
2065
1844 Primitive.TextureEntry tex = part.Shape.Textures; 2066 Primitive.TextureEntry tex = part.Shape.Textures;
1845 if (face >= 0 && face < GetNumberOfSides(part)) 2067 if (face >= 0 && face < GetNumberOfSides(part))
1846 { 2068 {
@@ -1877,6 +2099,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1877 2099
1878 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2100 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1879 { 2101 {
2102 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2103 return;
2104
1880 Primitive.TextureEntry tex = part.Shape.Textures; 2105 Primitive.TextureEntry tex = part.Shape.Textures;
1881 if (face >= 0 && face < GetNumberOfSides(part)) 2106 if (face >= 0 && face < GetNumberOfSides(part))
1882 { 2107 {
@@ -1913,6 +2138,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1913 2138
1914 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2139 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1915 { 2140 {
2141 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2142 return;
2143
1916 Primitive.TextureEntry tex = part.Shape.Textures; 2144 Primitive.TextureEntry tex = part.Shape.Textures;
1917 if (face >= 0 && face < GetNumberOfSides(part)) 2145 if (face >= 0 && face < GetNumberOfSides(part))
1918 { 2146 {
@@ -2054,7 +2282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2054 return end; 2282 return end;
2055 } 2283 }
2056 2284
2057 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2285 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2058 { 2286 {
2059 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2287 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2060 return fromPos; 2288 return fromPos;
@@ -2070,9 +2298,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2070 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2298 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2071 targetPos.z = ground; 2299 targetPos.z = ground;
2072 } 2300 }
2073 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2301 if (adjust)
2302 return SetPosAdjust(fromPos, targetPos);
2074 2303
2075 return real_vec; 2304 return targetPos;
2076 } 2305 }
2077 2306
2078 /// <summary> 2307 /// <summary>
@@ -2083,27 +2312,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2083 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2312 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2084 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2313 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2085 { 2314 {
2086 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2315 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2316 return;
2317
2087 LSL_Vector currentPos = GetPartLocalPos(part); 2318 LSL_Vector currentPos = GetPartLocalPos(part);
2319 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2088 2320
2089 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2090 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2091 2321
2092 if (part.ParentGroup.RootPart == part) 2322 if (part.ParentGroup.RootPart == part)
2093 { 2323 {
2094 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2095 targetPos.z = ground;
2096 SceneObjectGroup parent = part.ParentGroup; 2324 SceneObjectGroup parent = part.ParentGroup;
2097 parent.UpdateGroupPosition(!adjust ? targetPos : 2325 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2098 SetPosAdjust(currentPos, targetPos)); 2326 return;
2327 Util.FireAndForget(delegate(object x) {
2328 parent.UpdateGroupPosition((Vector3)toPos);
2329 });
2099 } 2330 }
2100 else 2331 else
2101 { 2332 {
2102 part.OffsetPosition = !adjust ? targetPos : 2333 part.OffsetPosition = (Vector3)toPos;
2103 SetPosAdjust(currentPos, targetPos); 2334// SceneObjectGroup parent = part.ParentGroup;
2104 SceneObjectGroup parent = part.ParentGroup; 2335// parent.HasGroupChanged = true;
2105 parent.HasGroupChanged = true; 2336// parent.ScheduleGroupForTerseUpdate();
2106 parent.ScheduleGroupForTerseUpdate(); 2337 part.ScheduleTerseUpdate();
2107 } 2338 }
2108 } 2339 }
2109 2340
@@ -2132,13 +2363,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2132 else 2363 else
2133 { 2364 {
2134 if (part.ParentGroup.IsAttachment) 2365 if (part.ParentGroup.IsAttachment)
2135 {
2136 pos = part.AttachedPos; 2366 pos = part.AttachedPos;
2137 }
2138 else 2367 else
2139 {
2140 pos = part.AbsolutePosition; 2368 pos = part.AbsolutePosition;
2141 }
2142 } 2369 }
2143 2370
2144// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2371// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2150,8 +2377,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2150 { 2377 {
2151 m_host.AddScriptLPS(1); 2378 m_host.AddScriptLPS(1);
2152 2379
2380
2381 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2382 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2383 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2384 // RootPart != null should shortcircuit
2385
2153 // try to let this work as in SL... 2386 // try to let this work as in SL...
2154 if (m_host.ParentID == 0) 2387 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2155 { 2388 {
2156 // special case: If we are root, rotate complete SOG to new rotation 2389 // special case: If we are root, rotate complete SOG to new rotation
2157 SetRot(m_host, rot); 2390 SetRot(m_host, rot);
@@ -2178,25 +2411,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2411
2179 protected void SetRot(SceneObjectPart part, Quaternion rot) 2412 protected void SetRot(SceneObjectPart part, Quaternion rot)
2180 { 2413 {
2181 part.UpdateRotation(rot); 2414 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2182 // Update rotation does not move the object in the physics scene if it's a linkset. 2415 return;
2183 2416
2184//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2417 bool isroot = (part == part.ParentGroup.RootPart);
2185// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2418 bool isphys;
2186 2419
2187 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2188 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2189 // It's perfectly okay when the object is not an active physical body though.
2190 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2191 // but only if the object is not physial and active. This is important for rotating doors.
2192 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2193 // scene
2194 PhysicsActor pa = part.PhysActor; 2420 PhysicsActor pa = part.PhysActor;
2195 2421
2196 if (pa != null && !pa.IsPhysical) 2422 // keep using physactor ideia of isphysical
2423 // it should be SOP ideia of that
2424 // not much of a issue with ubitODE
2425 if (pa != null && pa.IsPhysical)
2426 isphys = true;
2427 else
2428 isphys = false;
2429
2430 // SL doesn't let scripts rotate root of physical linksets
2431 if (isroot && isphys)
2432 return;
2433
2434 part.UpdateRotation(rot);
2435
2436 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2437 // so do a nasty update of parts positions if is a root part rotation
2438 if (isroot && pa != null) // with if above implies non physical root part
2197 { 2439 {
2198 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2440 part.ParentGroup.ResetChildPrimPhysicsPositions();
2199 } 2441 }
2442 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2443 {
2444 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2445 if (sittingavas.Count > 0)
2446 {
2447 foreach (ScenePresence av in sittingavas)
2448 {
2449 if (isroot || part.LocalId == av.ParentID)
2450 av.SendTerseUpdateToAllClients();
2451 }
2452 }
2453 }
2200 } 2454 }
2201 2455
2202 /// <summary> 2456 /// <summary>
@@ -2213,6 +2467,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2213 2467
2214 m_host.AddScriptLPS(1); 2468 m_host.AddScriptLPS(1);
2215 Quaternion q = m_host.GetWorldRotation(); 2469 Quaternion q = m_host.GetWorldRotation();
2470
2471 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2472 {
2473 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2474 if (avatar != null)
2475 {
2476 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2477 q = avatar.CameraRotation * q; // Mouselook
2478 else
2479 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2480 }
2481 }
2482
2216 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2483 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2217 } 2484 }
2218 2485
@@ -2238,14 +2505,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2238 q = part.ParentGroup.GroupRotation; // just the group rotation 2505 q = part.ParentGroup.GroupRotation; // just the group rotation
2239 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2506 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2240 } 2507 }
2508
2241 q = part.GetWorldRotation(); 2509 q = part.GetWorldRotation();
2510 if (part.ParentGroup.AttachmentPoint != 0)
2511 {
2512 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2513 if (avatar != null)
2514 {
2515 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2516 q = avatar.CameraRotation * q; // Mouselook
2517 else
2518 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2519 }
2520 }
2521
2242 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2522 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2243 } 2523 }
2244 2524
2245 public LSL_Rotation llGetLocalRot() 2525 public LSL_Rotation llGetLocalRot()
2246 { 2526 {
2527 return GetPartLocalRot(m_host);
2528 }
2529
2530 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2531 {
2247 m_host.AddScriptLPS(1); 2532 m_host.AddScriptLPS(1);
2248 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2533 Quaternion rot = part.RotationOffset;
2534 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2249 } 2535 }
2250 2536
2251 public void llSetForce(LSL_Vector force, int local) 2537 public void llSetForce(LSL_Vector force, int local)
@@ -2325,16 +2611,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2325 m_host.ApplyImpulse(v, local != 0); 2611 m_host.ApplyImpulse(v, local != 0);
2326 } 2612 }
2327 2613
2614
2328 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2615 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2329 { 2616 {
2330 m_host.AddScriptLPS(1); 2617 m_host.AddScriptLPS(1);
2331 m_host.ApplyAngularImpulse(force, local != 0); 2618 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2332 } 2619 }
2333 2620
2334 public void llSetTorque(LSL_Vector torque, int local) 2621 public void llSetTorque(LSL_Vector torque, int local)
2335 { 2622 {
2336 m_host.AddScriptLPS(1); 2623 m_host.AddScriptLPS(1);
2337 m_host.SetAngularImpulse(torque, local != 0); 2624 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2338 } 2625 }
2339 2626
2340 public LSL_Vector llGetTorque() 2627 public LSL_Vector llGetTorque()
@@ -2351,20 +2638,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 llSetTorque(torque, local); 2638 llSetTorque(torque, local);
2352 } 2639 }
2353 2640
2641 public void llSetVelocity(LSL_Vector vel, int local)
2642 {
2643 m_host.AddScriptLPS(1);
2644 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2645 }
2646
2354 public LSL_Vector llGetVel() 2647 public LSL_Vector llGetVel()
2355 { 2648 {
2356 m_host.AddScriptLPS(1); 2649 m_host.AddScriptLPS(1);
2357 2650
2358 Vector3 vel; 2651 Vector3 vel = Vector3.Zero;
2359 2652
2360 if (m_host.ParentGroup.IsAttachment) 2653 if (m_host.ParentGroup.IsAttachment)
2361 { 2654 {
2362 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2655 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2363 vel = avatar.Velocity; 2656 if (avatar != null)
2657 vel = avatar.Velocity;
2364 } 2658 }
2365 else 2659 else
2366 { 2660 {
2367 vel = m_host.Velocity; 2661 vel = m_host.ParentGroup.RootPart.Velocity;
2368 } 2662 }
2369 2663
2370 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2664 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2376,10 +2670,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2376 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2670 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2377 } 2671 }
2378 2672
2673 public void llSetAngularVelocity(LSL_Vector avel, int local)
2674 {
2675 m_host.AddScriptLPS(1);
2676 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2677 }
2678
2379 public LSL_Vector llGetOmega() 2679 public LSL_Vector llGetOmega()
2380 { 2680 {
2381 m_host.AddScriptLPS(1); 2681 m_host.AddScriptLPS(1);
2382 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2682 Vector3 avel = m_host.AngularVelocity;
2683 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2383 } 2684 }
2384 2685
2385 public LSL_Float llGetTimeOfDay() 2686 public LSL_Float llGetTimeOfDay()
@@ -2770,7 +3071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2770 } 3071 }
2771 3072
2772 money.ObjectGiveMoney( 3073 money.ObjectGiveMoney(
2773 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3074 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2774 }); 3075 });
2775 } 3076 }
2776 3077
@@ -2850,13 +3151,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2850 new_group.RootPart.UUID.ToString()) }, 3151 new_group.RootPart.UUID.ToString()) },
2851 new DetectParams[0])); 3152 new DetectParams[0]));
2852 3153
2853 float groupmass = new_group.GetMass(); 3154 // do recoil
3155 SceneObjectGroup hostgrp = m_host.ParentGroup;
3156 if (hostgrp == null)
3157 return;
3158
3159 if (hostgrp.IsAttachment) // don't recoil avatars
3160 return;
2854 3161
2855 PhysicsActor pa = new_group.RootPart.PhysActor; 3162 PhysicsActor pa = new_group.RootPart.PhysActor;
2856 3163
2857 //Recoil. 3164 //Recoil.
2858 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3165 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2859 { 3166 {
3167 float groupmass = new_group.GetMass();
2860 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3168 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2861 if (recoil != Vector3.Zero) 3169 if (recoil != Vector3.Zero)
2862 { 3170 {
@@ -2864,6 +3172,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2864 } 3172 }
2865 } 3173 }
2866 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3174 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3175 return;
3176
2867 }); 3177 });
2868 3178
2869 //ScriptSleep((int)((groupmass * velmag) / 10)); 3179 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2878,35 +3188,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 public void llLookAt(LSL_Vector target, double strength, double damping) 3188 public void llLookAt(LSL_Vector target, double strength, double damping)
2879 { 3189 {
2880 m_host.AddScriptLPS(1); 3190 m_host.AddScriptLPS(1);
2881 // Determine where we are looking from
2882 LSL_Vector from = llGetPos();
2883 3191
2884 // Work out the normalised vector from the source to the target 3192 // Get the normalized vector to the target
2885 LSL_Vector delta = llVecNorm(target - from); 3193 LSL_Vector d1 = llVecNorm(target - llGetPos());
2886 LSL_Vector angle = new LSL_Vector(0,0,0);
2887 3194
2888 // Calculate the yaw 3195 // Get the bearing (yaw)
2889 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3196 LSL_Vector a1 = new LSL_Vector(0,0,0);
2890 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3197 a1.z = llAtan2(d1.y, d1.x);
2891 3198
2892 // Calculate pitch 3199 // Get the elevation (pitch)
2893 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3200 LSL_Vector a2 = new LSL_Vector(0,0,0);
3201 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2894 3202
2895 // we need to convert from a vector describing 3203 LSL_Rotation r1 = llEuler2Rot(a1);
2896 // the angles of rotation in radians into rotation value 3204 LSL_Rotation r2 = llEuler2Rot(a2);
2897 LSL_Rotation rot = llEuler2Rot(angle); 3205 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2898
2899 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2900 // set the rotation of the object, copy that behavior
2901 PhysicsActor pa = m_host.PhysActor;
2902 3206
2903 if (strength == 0 || pa == null || !pa.IsPhysical) 3207 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2904 { 3208 {
2905 llSetRot(rot); 3209 // Do nothing if either value is 0 (this has been checked in SL)
3210 if (strength <= 0.0 || damping <= 0.0)
3211 return;
3212
3213 llSetRot(r3 * r2 * r1);
2906 } 3214 }
2907 else 3215 else
2908 { 3216 {
2909 m_host.StartLookAt(rot, (float)strength, (float)damping); 3217 if (strength == 0)
3218 {
3219 llSetRot(r3 * r2 * r1);
3220 return;
3221 }
3222
3223 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2910 } 3224 }
2911 } 3225 }
2912 3226
@@ -2953,17 +3267,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 } 3267 }
2954 else 3268 else
2955 { 3269 {
2956 if (m_host.IsRoot) 3270 // new SL always returns object mass
2957 { 3271// if (m_host.IsRoot)
3272// {
2958 return m_host.ParentGroup.GetMass(); 3273 return m_host.ParentGroup.GetMass();
2959 } 3274// }
2960 else 3275// else
2961 { 3276// {
2962 return m_host.GetMass(); 3277// return m_host.GetMass();
2963 } 3278// }
2964 } 3279 }
2965 } 3280 }
2966 3281
3282
3283 public LSL_Float llGetMassMKS()
3284 {
3285 return 100f * llGetMass();
3286 }
3287
2967 public void llCollisionFilter(string name, string id, int accept) 3288 public void llCollisionFilter(string name, string id, int accept)
2968 { 3289 {
2969 m_host.AddScriptLPS(1); 3290 m_host.AddScriptLPS(1);
@@ -3011,8 +3332,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3011 { 3332 {
3012 // Unregister controls from Presence 3333 // Unregister controls from Presence
3013 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3334 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3014 // Remove Take Control permission.
3015 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3016 } 3335 }
3017 } 3336 }
3018 } 3337 }
@@ -3040,7 +3359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3040 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3359 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3041 3360
3042 if (attachmentsModule != null) 3361 if (attachmentsModule != null)
3043 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3362 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3044 else 3363 else
3045 return false; 3364 return false;
3046 } 3365 }
@@ -3070,9 +3389,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3070 { 3389 {
3071 m_host.AddScriptLPS(1); 3390 m_host.AddScriptLPS(1);
3072 3391
3073// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3074// return;
3075
3076 if (m_item.PermsGranter != m_host.OwnerID) 3392 if (m_item.PermsGranter != m_host.OwnerID)
3077 return; 3393 return;
3078 3394
@@ -3115,6 +3431,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3115 3431
3116 public void llInstantMessage(string user, string message) 3432 public void llInstantMessage(string user, string message)
3117 { 3433 {
3434 UUID result;
3435 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3436 {
3437 ShoutError("An invalid key was passed to llInstantMessage");
3438 ScriptSleep(2000);
3439 return;
3440 }
3441
3442
3118 m_host.AddScriptLPS(1); 3443 m_host.AddScriptLPS(1);
3119 3444
3120 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3445 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3129,14 +3454,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3129 UUID friendTransactionID = UUID.Random(); 3454 UUID friendTransactionID = UUID.Random();
3130 3455
3131 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3456 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3132 3457
3133 GridInstantMessage msg = new GridInstantMessage(); 3458 GridInstantMessage msg = new GridInstantMessage();
3134 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3459 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3135 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3460 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3136 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3461 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3137// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3462// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3138// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3463// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3139 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3464// DateTime dt = DateTime.UtcNow;
3465//
3466// // Ticks from UtcNow, but make it look like local. Evil, huh?
3467// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3468//
3469// try
3470// {
3471// // Convert that to the PST timezone
3472// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3473// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3474// }
3475// catch
3476// {
3477// // No logging here, as it could be VERY spammy
3478// }
3479//
3480// // And make it look local again to fool the unix time util
3481// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3482
3483 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3484
3140 //if (client != null) 3485 //if (client != null)
3141 //{ 3486 //{
3142 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3487 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3150,12 +3495,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3150 msg.message = message.Substring(0, 1024); 3495 msg.message = message.Substring(0, 1024);
3151 else 3496 else
3152 msg.message = message; 3497 msg.message = message;
3153 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3498 msg.dialog = (byte)19; // MessageFromObject
3154 msg.fromGroup = false;// fromGroup; 3499 msg.fromGroup = false;// fromGroup;
3155 msg.offline = (byte)0; //offline; 3500 msg.offline = (byte)0; //offline;
3156 msg.ParentEstateID = 0; //ParentEstateID; 3501 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3157 msg.Position = new Vector3(m_host.AbsolutePosition); 3502 msg.Position = new Vector3(m_host.AbsolutePosition);
3158 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3503 msg.RegionID = World.RegionInfo.RegionID.Guid;
3159 msg.binaryBucket 3504 msg.binaryBucket
3160 = Util.StringToBytes256( 3505 = Util.StringToBytes256(
3161 "{0}/{1}/{2}/{3}", 3506 "{0}/{1}/{2}/{3}",
@@ -3183,7 +3528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3183 } 3528 }
3184 3529
3185 emailModule.SendEmail(m_host.UUID, address, subject, message); 3530 emailModule.SendEmail(m_host.UUID, address, subject, message);
3186 llSleep(EMAIL_PAUSE_TIME); 3531 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3187 } 3532 }
3188 3533
3189 public void llGetNextEmail(string address, string subject) 3534 public void llGetNextEmail(string address, string subject)
@@ -3429,7 +3774,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3774 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3430 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3775 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3431 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3776 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3777 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3432 ScriptBaseClass.PERMISSION_ATTACH; 3778 ScriptBaseClass.PERMISSION_ATTACH;
3779
3433 } 3780 }
3434 else 3781 else
3435 { 3782 {
@@ -3446,15 +3793,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3793 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3447 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3794 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3448 } 3795 }
3796 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3797 {
3798 implicitPerms = perm;
3799 }
3449 } 3800 }
3450 3801
3451 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3802 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3452 { 3803 {
3453 lock (m_host.TaskInventory) 3804 m_host.TaskInventory.LockItemsForWrite(true);
3454 { 3805 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3455 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3806 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3456 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3807 m_host.TaskInventory.LockItemsForWrite(false);
3457 }
3458 3808
3459 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3809 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3460 "run_time_permissions", new Object[] { 3810 "run_time_permissions", new Object[] {
@@ -3497,11 +3847,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3497 3847
3498 if (!m_waitingForScriptAnswer) 3848 if (!m_waitingForScriptAnswer)
3499 { 3849 {
3500 lock (m_host.TaskInventory) 3850 m_host.TaskInventory.LockItemsForWrite(true);
3501 { 3851 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3502 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3852 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3503 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3853 m_host.TaskInventory.LockItemsForWrite(false);
3504 }
3505 3854
3506 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3855 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3507 m_waitingForScriptAnswer=true; 3856 m_waitingForScriptAnswer=true;
@@ -3530,14 +3879,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3530 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3879 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3531 llReleaseControls(); 3880 llReleaseControls();
3532 3881
3533 lock (m_host.TaskInventory) 3882 m_host.TaskInventory.LockItemsForWrite(true);
3534 { 3883 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3535 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3884 m_host.TaskInventory.LockItemsForWrite(false);
3536 } 3885
3537 3886 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3538 m_ScriptEngine.PostScriptEvent( 3887 "run_time_permissions", new Object[] {
3539 m_item.ItemID, 3888 new LSL_Integer(answer) },
3540 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3889 new DetectParams[0]));
3541 } 3890 }
3542 3891
3543 public LSL_String llGetPermissionsKey() 3892 public LSL_String llGetPermissionsKey()
@@ -3576,14 +3925,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3576 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3925 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3577 { 3926 {
3578 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3927 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3579 3928 if (parts.Count > 0)
3580 foreach (SceneObjectPart part in parts) 3929 {
3581 part.SetFaceColorAlpha(face, color, null); 3930 try
3931 {
3932 foreach (SceneObjectPart part in parts)
3933 part.SetFaceColorAlpha(face, color, null);
3934 }
3935 finally
3936 {
3937 }
3938 }
3582 } 3939 }
3583 3940
3584 public void llCreateLink(string target, int parent) 3941 public void llCreateLink(string target, int parent)
3585 { 3942 {
3586 m_host.AddScriptLPS(1); 3943 m_host.AddScriptLPS(1);
3944
3587 UUID targetID; 3945 UUID targetID;
3588 3946
3589 if (!UUID.TryParse(target, out targetID)) 3947 if (!UUID.TryParse(target, out targetID))
@@ -3689,10 +4047,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3689 // Restructuring Multiple Prims. 4047 // Restructuring Multiple Prims.
3690 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4048 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3691 parts.Remove(parentPrim.RootPart); 4049 parts.Remove(parentPrim.RootPart);
3692 foreach (SceneObjectPart part in parts) 4050 if (parts.Count > 0)
3693 { 4051 {
3694 parentPrim.DelinkFromGroup(part.LocalId, true); 4052 try
4053 {
4054 foreach (SceneObjectPart part in parts)
4055 {
4056 parentPrim.DelinkFromGroup(part.LocalId, true);
4057 }
4058 }
4059 finally
4060 {
4061 }
3695 } 4062 }
4063
3696 parentPrim.HasGroupChanged = true; 4064 parentPrim.HasGroupChanged = true;
3697 parentPrim.ScheduleGroupForFullUpdate(); 4065 parentPrim.ScheduleGroupForFullUpdate();
3698 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4066 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3701,12 +4069,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3701 { 4069 {
3702 SceneObjectPart newRoot = parts[0]; 4070 SceneObjectPart newRoot = parts[0];
3703 parts.Remove(newRoot); 4071 parts.Remove(newRoot);
3704 foreach (SceneObjectPart part in parts) 4072
4073 try
3705 { 4074 {
3706 // Required for linking 4075 foreach (SceneObjectPart part in parts)
3707 part.ClearUpdateSchedule(); 4076 {
3708 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4077 part.ClearUpdateSchedule();
4078 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4079 }
3709 } 4080 }
4081 finally
4082 {
4083 }
4084
4085
3710 newRoot.ParentGroup.HasGroupChanged = true; 4086 newRoot.ParentGroup.HasGroupChanged = true;
3711 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4087 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3712 } 4088 }
@@ -3726,6 +4102,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 public void llBreakAllLinks() 4102 public void llBreakAllLinks()
3727 { 4103 {
3728 m_host.AddScriptLPS(1); 4104 m_host.AddScriptLPS(1);
4105
4106 TaskInventoryItem item = m_item;
4107
4108 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4109 && !m_automaticLinkPermission)
4110 {
4111 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4112 return;
4113 }
4114
3729 SceneObjectGroup parentPrim = m_host.ParentGroup; 4115 SceneObjectGroup parentPrim = m_host.ParentGroup;
3730 if (parentPrim.AttachmentPoint != 0) 4116 if (parentPrim.AttachmentPoint != 0)
3731 return; // Fail silently if attached 4117 return; // Fail silently if attached
@@ -3745,47 +4131,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3745 public LSL_String llGetLinkKey(int linknum) 4131 public LSL_String llGetLinkKey(int linknum)
3746 { 4132 {
3747 m_host.AddScriptLPS(1); 4133 m_host.AddScriptLPS(1);
3748 4134 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3749 if (linknum < 0) 4135 if (part != null)
3750 {
3751 if (linknum == ScriptBaseClass.LINK_THIS)
3752 return m_host.UUID.ToString();
3753 else
3754 return ScriptBaseClass.NULL_KEY;
3755 }
3756
3757 int actualPrimCount = m_host.ParentGroup.PrimCount;
3758 List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
3759 int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
3760
3761 // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
3762 // prim that has any avatars sat upon it (in which case the root prim is link 1).
3763 if (linknum == 0)
3764 {
3765 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
3766 return m_host.UUID.ToString();
3767
3768 return ScriptBaseClass.NULL_KEY;
3769 }
3770 // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
3771 // here we must match 1 (ScriptBaseClass.LINK_ROOT).
3772 else if (linknum == 1 && actualPrimCount == 1)
3773 {
3774 if (sittingAvatarIds.Count > 0)
3775 return m_host.ParentGroup.RootPart.UUID.ToString();
3776 else
3777 return ScriptBaseClass.NULL_KEY;
3778 }
3779 else if (linknum <= adjustedPrimCount)
3780 { 4136 {
3781 if (linknum <= actualPrimCount) 4137 return part.UUID.ToString();
3782 return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
3783 else
3784 return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
3785 } 4138 }
3786 else 4139 else
3787 { 4140 {
3788 return ScriptBaseClass.NULL_KEY; 4141 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4142 {
4143 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4144
4145 if (linknum < 0)
4146 return UUID.Zero.ToString();
4147
4148 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4149 if (avatars.Count > linknum)
4150 {
4151 return avatars[linknum].UUID.ToString();
4152 }
4153 }
4154 return UUID.Zero.ToString();
3789 } 4155 }
3790 } 4156 }
3791 4157
@@ -3888,17 +4254,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3888 m_host.AddScriptLPS(1); 4254 m_host.AddScriptLPS(1);
3889 int count = 0; 4255 int count = 0;
3890 4256
3891 lock (m_host.TaskInventory) 4257 m_host.TaskInventory.LockItemsForRead(true);
4258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3892 { 4259 {
3893 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4260 if (inv.Value.Type == type || type == -1)
3894 { 4261 {
3895 if (inv.Value.Type == type || type == -1) 4262 count = count + 1;
3896 {
3897 count = count + 1;
3898 }
3899 } 4263 }
3900 } 4264 }
3901 4265
4266 m_host.TaskInventory.LockItemsForRead(false);
3902 return count; 4267 return count;
3903 } 4268 }
3904 4269
@@ -3907,16 +4272,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3907 m_host.AddScriptLPS(1); 4272 m_host.AddScriptLPS(1);
3908 ArrayList keys = new ArrayList(); 4273 ArrayList keys = new ArrayList();
3909 4274
3910 lock (m_host.TaskInventory) 4275 m_host.TaskInventory.LockItemsForRead(true);
4276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3911 { 4277 {
3912 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4278 if (inv.Value.Type == type || type == -1)
3913 { 4279 {
3914 if (inv.Value.Type == type || type == -1) 4280 keys.Add(inv.Value.Name);
3915 {
3916 keys.Add(inv.Value.Name);
3917 }
3918 } 4281 }
3919 } 4282 }
4283 m_host.TaskInventory.LockItemsForRead(false);
3920 4284
3921 if (keys.Count == 0) 4285 if (keys.Count == 0)
3922 { 4286 {
@@ -3954,7 +4318,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3954 if (item == null) 4318 if (item == null)
3955 { 4319 {
3956 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4320 llSay(0, String.Format("Could not find object '{0}'", inventory));
3957 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4321 return;
4322// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3958 } 4323 }
3959 4324
3960 UUID objId = item.ItemID; 4325 UUID objId = item.ItemID;
@@ -3982,33 +4347,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3982 return; 4347 return;
3983 } 4348 }
3984 } 4349 }
4350
3985 // destination is an avatar 4351 // destination is an avatar
3986 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4352 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3987 4353
3988 if (agentItem == null) 4354 if (agentItem == null)
3989 return; 4355 return;
3990 4356
3991 if (m_TransferModule != null) 4357 byte[] bucket = new byte[1];
3992 { 4358 bucket[0] = (byte)item.Type;
3993 byte[] bucket = new byte[1]; 4359 //byte[] objBytes = agentItem.ID.GetBytes();
3994 bucket[0] = (byte)item.Type; 4360 //Array.Copy(objBytes, 0, bucket, 1, 16);
3995 4361
3996 GridInstantMessage msg = new GridInstantMessage(World, 4362 GridInstantMessage msg = new GridInstantMessage(World,
3997 m_host.OwnerID, m_host.Name, destId, 4363 m_host.OwnerID, m_host.Name, destId,
3998 (byte)InstantMessageDialog.TaskInventoryOffered, 4364 (byte)InstantMessageDialog.TaskInventoryOffered,
3999 false, item.Name+". "+m_host.Name+" is located at "+ 4365 false, item.Name+". "+m_host.Name+" is located at "+
4000 World.RegionInfo.RegionName+" "+ 4366 World.RegionInfo.RegionName+" "+
4001 m_host.AbsolutePosition.ToString(), 4367 m_host.AbsolutePosition.ToString(),
4002 agentItem.ID, true, m_host.AbsolutePosition, 4368 agentItem.ID, true, m_host.AbsolutePosition,
4003 bucket, true); 4369 bucket, true);
4004 4370
4005 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4371 ScenePresence sp;
4006 }
4007 4372
4373 if (World.TryGetScenePresence(destId, out sp))
4374 {
4375 sp.ControllingClient.SendInstantMessage(msg);
4376 }
4377 else
4378 {
4379 if (m_TransferModule != null)
4380 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4381 }
4382
4383 //This delay should only occur when giving inventory to avatars.
4008 ScriptSleep(3000); 4384 ScriptSleep(3000);
4009 } 4385 }
4010 } 4386 }
4011 4387
4388 [DebuggerNonUserCode]
4012 public void llRemoveInventory(string name) 4389 public void llRemoveInventory(string name)
4013 { 4390 {
4014 m_host.AddScriptLPS(1); 4391 m_host.AddScriptLPS(1);
@@ -4063,109 +4440,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4063 { 4440 {
4064 m_host.AddScriptLPS(1); 4441 m_host.AddScriptLPS(1);
4065 4442
4066 UUID uuid = (UUID)id; 4443 UUID uuid;
4067 PresenceInfo pinfo = null; 4444 if (UUID.TryParse(id, out uuid))
4068 UserAccount account;
4069
4070 UserInfoCacheEntry ce;
4071 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4072 { 4445 {
4073 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4446 PresenceInfo pinfo = null;
4074 if (account == null) 4447 UserAccount account;
4448
4449 UserInfoCacheEntry ce;
4450 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4075 { 4451 {
4076 m_userInfoCache[uuid] = null; // Cache negative 4452 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4077 return UUID.Zero.ToString(); 4453 if (account == null)
4078 } 4454 {
4455 m_userInfoCache[uuid] = null; // Cache negative
4456 return UUID.Zero.ToString();
4457 }
4079 4458
4080 4459
4081 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4460 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4082 if (pinfos != null && pinfos.Length > 0) 4461 if (pinfos != null && pinfos.Length > 0)
4083 {
4084 foreach (PresenceInfo p in pinfos)
4085 { 4462 {
4086 if (p.RegionID != UUID.Zero) 4463 foreach (PresenceInfo p in pinfos)
4087 { 4464 {
4088 pinfo = p; 4465 if (p.RegionID != UUID.Zero)
4466 {
4467 pinfo = p;
4468 }
4089 } 4469 }
4090 } 4470 }
4091 }
4092 4471
4093 ce = new UserInfoCacheEntry(); 4472 ce = new UserInfoCacheEntry();
4094 ce.time = Util.EnvironmentTickCount(); 4473 ce.time = Util.EnvironmentTickCount();
4095 ce.account = account; 4474 ce.account = account;
4096 ce.pinfo = pinfo; 4475 ce.pinfo = pinfo;
4097 } 4476 m_userInfoCache[uuid] = ce;
4098 else 4477 }
4099 { 4478 else
4100 if (ce == null) 4479 {
4101 return UUID.Zero.ToString(); 4480 if (ce == null)
4481 return UUID.Zero.ToString();
4102 4482
4103 account = ce.account; 4483 account = ce.account;
4104 pinfo = ce.pinfo; 4484 pinfo = ce.pinfo;
4105 } 4485 }
4106 4486
4107 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4487 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4108 {
4109 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4110 if (pinfos != null && pinfos.Length > 0)
4111 { 4488 {
4112 foreach (PresenceInfo p in pinfos) 4489 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4490 if (pinfos != null && pinfos.Length > 0)
4113 { 4491 {
4114 if (p.RegionID != UUID.Zero) 4492 foreach (PresenceInfo p in pinfos)
4115 { 4493 {
4116 pinfo = p; 4494 if (p.RegionID != UUID.Zero)
4495 {
4496 pinfo = p;
4497 }
4117 } 4498 }
4118 } 4499 }
4119 } 4500 else
4120 else 4501 pinfo = null;
4121 pinfo = null;
4122 4502
4123 ce.time = Util.EnvironmentTickCount(); 4503 ce.time = Util.EnvironmentTickCount();
4124 ce.pinfo = pinfo; 4504 ce.pinfo = pinfo;
4125 } 4505 }
4126 4506
4127 string reply = String.Empty; 4507 string reply = String.Empty;
4128 4508
4129 switch (data) 4509 switch (data)
4130 { 4510 {
4131 case 1: // DATA_ONLINE (0|1) 4511 case 1: // DATA_ONLINE (0|1)
4132 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4512 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4133 reply = "1"; 4513 reply = "1";
4134 else 4514 else
4135 reply = "0"; 4515 reply = "0";
4136 break; 4516 break;
4137 case 2: // DATA_NAME (First Last) 4517 case 2: // DATA_NAME (First Last)
4138 reply = account.FirstName + " " + account.LastName; 4518 reply = account.FirstName + " " + account.LastName;
4139 break; 4519 break;
4140 case 3: // DATA_BORN (YYYY-MM-DD) 4520 case 3: // DATA_BORN (YYYY-MM-DD)
4141 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4521 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4142 born = born.AddSeconds(account.Created); 4522 born = born.AddSeconds(account.Created);
4143 reply = born.ToString("yyyy-MM-dd"); 4523 reply = born.ToString("yyyy-MM-dd");
4144 break; 4524 break;
4145 case 4: // DATA_RATING (0,0,0,0,0,0) 4525 case 4: // DATA_RATING (0,0,0,0,0,0)
4146 reply = "0,0,0,0,0,0"; 4526 reply = "0,0,0,0,0,0";
4147 break; 4527 break;
4148 case 7: // DATA_USERLEVEL (integer) 4528 case 8: // DATA_PAYINFO (0|1|2|3)
4149 reply = account.UserLevel.ToString(); 4529 reply = "0";
4150 break; 4530 break;
4151 case 8: // DATA_PAYINFO (0|1|2|3) 4531 default:
4152 reply = "0"; 4532 return UUID.Zero.ToString(); // Raise no event
4153 break; 4533 }
4154 default:
4155 return UUID.Zero.ToString(); // Raise no event
4156 }
4157 4534
4158 UUID rq = UUID.Random(); 4535 UUID rq = UUID.Random();
4159 4536
4160 UUID tid = AsyncCommands. 4537 UUID tid = AsyncCommands.
4161 DataserverPlugin.RegisterRequest(m_host.LocalId, 4538 DataserverPlugin.RegisterRequest(m_host.LocalId,
4162 m_item.ItemID, rq.ToString()); 4539 m_item.ItemID, rq.ToString());
4163 4540
4164 AsyncCommands. 4541 AsyncCommands.
4165 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4542 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4166 4543
4167 ScriptSleep(100); 4544 ScriptSleep(100);
4168 return tid.ToString(); 4545 return tid.ToString();
4546 }
4547 else
4548 {
4549 ShoutError("Invalid UUID passed to llRequestAgentData.");
4550 }
4551 return "";
4169 } 4552 }
4170 4553
4171 public LSL_String llRequestInventoryData(string name) 4554 public LSL_String llRequestInventoryData(string name)
@@ -4222,13 +4605,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 if (UUID.TryParse(agent, out agentId)) 4605 if (UUID.TryParse(agent, out agentId))
4223 { 4606 {
4224 ScenePresence presence = World.GetScenePresence(agentId); 4607 ScenePresence presence = World.GetScenePresence(agentId);
4225 if (presence != null) 4608 if (presence != null && presence.PresenceType != PresenceType.Npc)
4226 { 4609 {
4610 // agent must not be a god
4611 if (presence.UserLevel >= 200) return;
4612
4227 // agent must be over the owners land 4613 // agent must be over the owners land
4228 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4614 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4229 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4615 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4230 { 4616 {
4231 World.TeleportClientHome(agentId, presence.ControllingClient); 4617 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4618 {
4619 // They can't be teleported home for some reason
4620 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4621 if (regionInfo != null)
4622 {
4623 World.RequestTeleportLocation(
4624 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4625 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4626 }
4627 }
4232 } 4628 }
4233 } 4629 }
4234 } 4630 }
@@ -4335,7 +4731,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4335 UUID av = new UUID(); 4731 UUID av = new UUID();
4336 if (!UUID.TryParse(agent,out av)) 4732 if (!UUID.TryParse(agent,out av))
4337 { 4733 {
4338 LSLError("First parameter to llDialog needs to be a key"); 4734 //LSLError("First parameter to llDialog needs to be a key");
4339 return; 4735 return;
4340 } 4736 }
4341 4737
@@ -4367,10 +4763,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4367 public void llCollisionSound(string impact_sound, double impact_volume) 4763 public void llCollisionSound(string impact_sound, double impact_volume)
4368 { 4764 {
4369 m_host.AddScriptLPS(1); 4765 m_host.AddScriptLPS(1);
4370 4766
4767 if(impact_sound == "")
4768 {
4769 m_host.CollisionSoundVolume = (float)impact_volume;
4770 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4771 m_host.CollisionSoundType = 0;
4772 return;
4773 }
4371 // TODO: Parameter check logic required. 4774 // TODO: Parameter check logic required.
4372 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4775 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4373 m_host.CollisionSoundVolume = (float)impact_volume; 4776 m_host.CollisionSoundVolume = (float)impact_volume;
4777 m_host.CollisionSoundType = 1;
4374 } 4778 }
4375 4779
4376 public LSL_String llGetAnimation(string id) 4780 public LSL_String llGetAnimation(string id)
@@ -4384,14 +4788,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4384 4788
4385 if (m_host.RegionHandle == presence.RegionHandle) 4789 if (m_host.RegionHandle == presence.RegionHandle)
4386 { 4790 {
4387 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4388
4389 if (presence != null) 4791 if (presence != null)
4390 { 4792 {
4391 AnimationSet currentAnims = presence.Animator.Animations; 4793 if (presence.SitGround)
4392 string currentAnimationState = String.Empty; 4794 return "Sitting on Ground";
4393 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4795 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4394 return currentAnimationState; 4796 return "Sitting";
4797
4798 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4799 string lslMovementAnimation;
4800
4801 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4802 return lslMovementAnimation;
4395 } 4803 }
4396 } 4804 }
4397 4805
@@ -4538,7 +4946,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4538 { 4946 {
4539 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4947 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4540 float distance_term = distance * distance * distance; // Script Energy 4948 float distance_term = distance * distance * distance; // Script Energy
4541 float pusher_mass = m_host.GetMass(); 4949 // use total object mass and not part
4950 float pusher_mass = m_host.ParentGroup.GetMass();
4542 4951
4543 float PUSH_ATTENUATION_DISTANCE = 17f; 4952 float PUSH_ATTENUATION_DISTANCE = 17f;
4544 float PUSH_ATTENUATION_SCALE = 5f; 4953 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4788,6 +5197,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4788 { 5197 {
4789 return item.AssetID.ToString(); 5198 return item.AssetID.ToString();
4790 } 5199 }
5200 m_host.TaskInventory.LockItemsForRead(false);
4791 5201
4792 return UUID.Zero.ToString(); 5202 return UUID.Zero.ToString();
4793 } 5203 }
@@ -4940,14 +5350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4940 { 5350 {
4941 m_host.AddScriptLPS(1); 5351 m_host.AddScriptLPS(1);
4942 5352
4943 if (src == null) 5353 return src.Length;
4944 {
4945 return 0;
4946 }
4947 else
4948 {
4949 return src.Length;
4950 }
4951 } 5354 }
4952 5355
4953 public LSL_Integer llList2Integer(LSL_List src, int index) 5356 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5018,7 +5421,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5018 else if (src.Data[index] is LSL_Float) 5421 else if (src.Data[index] is LSL_Float)
5019 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5422 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5020 else if (src.Data[index] is LSL_String) 5423 else if (src.Data[index] is LSL_String)
5021 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5424 {
5425 string str = ((LSL_String) src.Data[index]).m_string;
5426 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5427 if (m != Match.Empty)
5428 {
5429 str = m.Value;
5430 double d = 0.0;
5431 if (!Double.TryParse(str, out d))
5432 return 0.0;
5433
5434 return d;
5435 }
5436 return 0.0;
5437 }
5022 return Convert.ToDouble(src.Data[index]); 5438 return Convert.ToDouble(src.Data[index]);
5023 } 5439 }
5024 catch (FormatException) 5440 catch (FormatException)
@@ -5060,7 +5476,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5060 // for completion and should LSL_Key ever be implemented 5476 // for completion and should LSL_Key ever be implemented
5061 // as it's own struct 5477 // as it's own struct
5062 else if (!(src.Data[index] is LSL_String || 5478 else if (!(src.Data[index] is LSL_String ||
5063 src.Data[index] is LSL_Key)) 5479 src.Data[index] is LSL_Key ||
5480 src.Data[index] is String))
5064 { 5481 {
5065 return ""; 5482 return "";
5066 } 5483 }
@@ -5318,7 +5735,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5318 } 5735 }
5319 } 5736 }
5320 } 5737 }
5321 else { 5738 else
5739 {
5322 object[] array = new object[src.Length]; 5740 object[] array = new object[src.Length];
5323 Array.Copy(src.Data, 0, array, 0, src.Length); 5741 Array.Copy(src.Data, 0, array, 0, src.Length);
5324 result = new LSL_List(array); 5742 result = new LSL_List(array);
@@ -5425,7 +5843,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5425 public LSL_Integer llGetRegionAgentCount() 5843 public LSL_Integer llGetRegionAgentCount()
5426 { 5844 {
5427 m_host.AddScriptLPS(1); 5845 m_host.AddScriptLPS(1);
5428 return new LSL_Integer(World.GetRootAgentCount()); 5846
5847 int count = 0;
5848 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5849 count++;
5850 });
5851
5852 return new LSL_Integer(count);
5429 } 5853 }
5430 5854
5431 public LSL_Vector llGetRegionCorner() 5855 public LSL_Vector llGetRegionCorner()
@@ -5666,6 +6090,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5666 flags |= ScriptBaseClass.AGENT_AWAY; 6090 flags |= ScriptBaseClass.AGENT_AWAY;
5667 } 6091 }
5668 6092
6093 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6094 UUID[] anims = agent.Animator.GetAnimationArray();
6095 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6096 {
6097 flags |= ScriptBaseClass.AGENT_BUSY;
6098 }
6099
5669 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6100 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5670 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6101 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5671 { 6102 {
@@ -5713,6 +6144,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5713 flags |= ScriptBaseClass.AGENT_SITTING; 6144 flags |= ScriptBaseClass.AGENT_SITTING;
5714 } 6145 }
5715 6146
6147 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6148 {
6149 flags |= ScriptBaseClass.AGENT_MALE;
6150 }
6151
5716 return flags; 6152 return flags;
5717 } 6153 }
5718 6154
@@ -5860,9 +6296,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5860 6296
5861 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6297 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5862 6298
5863 foreach (SceneObjectPart part in parts) 6299 try
6300 {
6301 foreach (SceneObjectPart part in parts)
6302 {
6303 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6304 }
6305 }
6306 finally
5864 { 6307 {
5865 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5866 } 6308 }
5867 } 6309 }
5868 6310
@@ -5916,13 +6358,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5916 6358
5917 if (m_host.OwnerID == land.LandData.OwnerID) 6359 if (m_host.OwnerID == land.LandData.OwnerID)
5918 { 6360 {
5919 World.TeleportClientHome(agentID, presence.ControllingClient); 6361 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6362 presence.TeleportWithMomentum(pos, null);
6363 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5920 } 6364 }
5921 } 6365 }
5922 } 6366 }
5923 ScriptSleep(5000); 6367 ScriptSleep(5000);
5924 } 6368 }
5925 6369
6370 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6371 {
6372 return ParseString2List(str, separators, in_spacers, false);
6373 }
6374
5926 public LSL_Integer llOverMyLand(string id) 6375 public LSL_Integer llOverMyLand(string id)
5927 { 6376 {
5928 m_host.AddScriptLPS(1); 6377 m_host.AddScriptLPS(1);
@@ -5976,25 +6425,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5976 } 6425 }
5977 else 6426 else
5978 { 6427 {
5979 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6428// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6429 Vector3 s = avatar.Appearance.AvatarSize;
6430 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5980 } 6431 }
5981 return agentSize; 6432 return agentSize;
5982 } 6433 }
5983 6434
5984 public LSL_Integer llSameGroup(string agent) 6435 public LSL_Integer llSameGroup(string id)
5985 { 6436 {
5986 m_host.AddScriptLPS(1); 6437 m_host.AddScriptLPS(1);
5987 UUID agentId = new UUID(); 6438 UUID uuid = new UUID();
5988 if (!UUID.TryParse(agent, out agentId)) 6439 if (!UUID.TryParse(id, out uuid))
5989 return new LSL_Integer(0); 6440 return new LSL_Integer(0);
5990 ScenePresence presence = World.GetScenePresence(agentId); 6441
5991 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6442 // Check if it's a group key
5992 return new LSL_Integer(0); 6443 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5993 IClientAPI client = presence.ControllingClient;
5994 if (m_host.GroupID == client.ActiveGroupId)
5995 return new LSL_Integer(1); 6444 return new LSL_Integer(1);
5996 else 6445
6446 // We got passed a UUID.Zero
6447 if (uuid == UUID.Zero)
6448 return new LSL_Integer(0);
6449
6450 // Handle the case where id names an avatar
6451 ScenePresence presence = World.GetScenePresence(uuid);
6452 if (presence != null)
6453 {
6454 if (presence.IsChildAgent)
6455 return new LSL_Integer(0);
6456
6457 IClientAPI client = presence.ControllingClient;
6458 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6459 return new LSL_Integer(1);
6460
6461 return new LSL_Integer(0);
6462 }
6463
6464 // Handle object case
6465 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6466 if (part != null)
6467 {
6468 // This will handle both deed and non-deed and also the no
6469 // group case
6470 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6471 return new LSL_Integer(1);
6472
5997 return new LSL_Integer(0); 6473 return new LSL_Integer(0);
6474 }
6475
6476 return new LSL_Integer(0);
5998 } 6477 }
5999 6478
6000 public void llUnSit(string id) 6479 public void llUnSit(string id)
@@ -6119,7 +6598,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6119 return m_host.ParentGroup.AttachmentPoint; 6598 return m_host.ParentGroup.AttachmentPoint;
6120 } 6599 }
6121 6600
6122 public LSL_Integer llGetFreeMemory() 6601 public virtual LSL_Integer llGetFreeMemory()
6123 { 6602 {
6124 m_host.AddScriptLPS(1); 6603 m_host.AddScriptLPS(1);
6125 // Make scripts designed for LSO happy 6604 // Make scripts designed for LSO happy
@@ -6551,6 +7030,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6551 7030
6552 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7031 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6553 { 7032 {
7033 // LSL quaternions can normalize to 0, normal Quaternions can't.
7034 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7035 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7036
6554 part.SitTargetPosition = offset; 7037 part.SitTargetPosition = offset;
6555 part.SitTargetOrientation = rot; 7038 part.SitTargetOrientation = rot;
6556 part.ParentGroup.HasGroupChanged = true; 7039 part.ParentGroup.HasGroupChanged = true;
@@ -6736,13 +7219,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6736 UUID av = new UUID(); 7219 UUID av = new UUID();
6737 if (!UUID.TryParse(avatar,out av)) 7220 if (!UUID.TryParse(avatar,out av))
6738 { 7221 {
6739 LSLError("First parameter to llDialog needs to be a key"); 7222 //LSLError("First parameter to llDialog needs to be a key");
6740 return; 7223 return;
6741 } 7224 }
6742 if (buttons.Length < 1) 7225 if (buttons.Length < 1)
6743 { 7226 {
6744 LSLError("No less than 1 button can be shown"); 7227 buttons.Add("OK");
6745 return;
6746 } 7228 }
6747 if (buttons.Length > 12) 7229 if (buttons.Length > 12)
6748 { 7230 {
@@ -6759,7 +7241,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6759 } 7241 }
6760 if (buttons.Data[i].ToString().Length > 24) 7242 if (buttons.Data[i].ToString().Length > 24)
6761 { 7243 {
6762 LSLError("button label cannot be longer than 24 characters"); 7244 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6763 return; 7245 return;
6764 } 7246 }
6765 buts[i] = buttons.Data[i].ToString(); 7247 buts[i] = buttons.Data[i].ToString();
@@ -6826,9 +7308,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6826 return; 7308 return;
6827 } 7309 }
6828 7310
6829 // the rest of the permission checks are done in RezScript, so check the pin there as well 7311 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6830 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7312 if (dest != null)
7313 {
7314 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7315 {
7316 // the rest of the permission checks are done in RezScript, so check the pin there as well
7317 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6831 7318
7319 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7320 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7321 }
7322 }
6832 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7323 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6833 ScriptSleep(3000); 7324 ScriptSleep(3000);
6834 } 7325 }
@@ -6902,19 +7393,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6902 public LSL_String llMD5String(string src, int nonce) 7393 public LSL_String llMD5String(string src, int nonce)
6903 { 7394 {
6904 m_host.AddScriptLPS(1); 7395 m_host.AddScriptLPS(1);
6905 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7396 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6906 } 7397 }
6907 7398
6908 public LSL_String llSHA1String(string src) 7399 public LSL_String llSHA1String(string src)
6909 { 7400 {
6910 m_host.AddScriptLPS(1); 7401 m_host.AddScriptLPS(1);
6911 return Util.SHA1Hash(src).ToLower(); 7402 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6912 } 7403 }
6913 7404
6914 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7405 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6915 { 7406 {
6916 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7407 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6917 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7408 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7409 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7410 return shapeBlock;
6918 7411
6919 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7412 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6920 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7413 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7019,6 +7512,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7019 // Prim type box, cylinder and prism. 7512 // Prim type box, cylinder and prism.
7020 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) 7513 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)
7021 { 7514 {
7515 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7516 return;
7517
7022 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7518 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7023 ObjectShapePacket.ObjectDataBlock shapeBlock; 7519 ObjectShapePacket.ObjectDataBlock shapeBlock;
7024 7520
@@ -7072,6 +7568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7072 // Prim type sphere. 7568 // Prim type sphere.
7073 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7569 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7074 { 7570 {
7571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7572 return;
7573
7075 ObjectShapePacket.ObjectDataBlock shapeBlock; 7574 ObjectShapePacket.ObjectDataBlock shapeBlock;
7076 7575
7077 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7576 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7113,6 +7612,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7113 // Prim type torus, tube and ring. 7612 // Prim type torus, tube and ring.
7114 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) 7613 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)
7115 { 7614 {
7615 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7616 return;
7617
7116 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7618 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7117 ObjectShapePacket.ObjectDataBlock shapeBlock; 7619 ObjectShapePacket.ObjectDataBlock shapeBlock;
7118 7620
@@ -7248,6 +7750,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7248 // Prim type sculpt. 7750 // Prim type sculpt.
7249 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7751 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7250 { 7752 {
7753 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7754 return;
7755
7251 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7756 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7252 UUID sculptId; 7757 UUID sculptId;
7253 7758
@@ -7272,7 +7777,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7272 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7777 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7273 { 7778 {
7274 // default 7779 // default
7275 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7780 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7276 } 7781 }
7277 7782
7278 part.Shape.SetSculptProperties((byte)type, sculptId); 7783 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7289,48 +7794,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7289 ScriptSleep(200); 7794 ScriptSleep(200);
7290 } 7795 }
7291 7796
7292 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7797 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7293 { 7798 {
7294 m_host.AddScriptLPS(1); 7799 m_host.AddScriptLPS(1);
7295 7800
7296 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7801 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7802 }
7297 7803
7298 ScriptSleep(200); 7804 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7805 {
7806 List<object> parts = new List<object>();
7807 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7808 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7809 foreach (SceneObjectPart p in prims)
7810 parts.Add(p);
7811 foreach (ScenePresence p in avatars)
7812 parts.Add(p);
7813
7814 LSL_List remaining = null;
7815 uint rulesParsed = 0;
7816
7817 if (parts.Count > 0)
7818 {
7819 foreach (object part in parts)
7820 {
7821 if (part is SceneObjectPart)
7822 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7823 else
7824 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7825 }
7826
7827 while ((object)remaining != null && remaining.Length > 2)
7828 {
7829 linknumber = remaining.GetLSLIntegerItem(0);
7830 rules = remaining.GetSublist(1, -1);
7831 parts.Clear();
7832 prims = GetLinkParts(linknumber);
7833 avatars = GetLinkAvatars(linknumber);
7834 foreach (SceneObjectPart p in prims)
7835 parts.Add(p);
7836 foreach (ScenePresence p in avatars)
7837 parts.Add(p);
7838
7839 remaining = null;
7840 foreach (object part in parts)
7841 {
7842 if (part is SceneObjectPart)
7843 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7844 else
7845 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7846 }
7847 }
7848 }
7299 } 7849 }
7300 7850
7301 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7851 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7852 float material_density, float material_friction,
7853 float material_restitution, float material_gravity_modifier)
7302 { 7854 {
7303 m_host.AddScriptLPS(1); 7855 ExtraPhysicsData physdata = new ExtraPhysicsData();
7856 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7857 physdata.Density = part.Density;
7858 physdata.Friction = part.Friction;
7859 physdata.Bounce = part.Bounciness;
7860 physdata.GravitationModifier = part.GravityModifier;
7304 7861
7305 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7862 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7863 physdata.Density = material_density;
7864 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7865 physdata.Friction = material_friction;
7866 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7867 physdata.Bounce = material_restitution;
7868 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7869 physdata.GravitationModifier = material_gravity_modifier;
7870
7871 part.UpdateExtraPhysics(physdata);
7306 } 7872 }
7307 7873
7308 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7874 public void llSetPhysicsMaterial(int material_bits,
7875 float material_gravity_modifier, float material_restitution,
7876 float material_friction, float material_density)
7309 { 7877 {
7310 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7878 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7879 }
7311 7880
7312 LSL_List remaining = null; 7881 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7313 uint rulesParsed = 0; 7882 {
7883 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7884 llSetLinkPrimitiveParamsFast(linknumber, rules);
7885 ScriptSleep(200);
7886 }
7314 7887
7315 foreach (SceneObjectPart part in parts) 7888 // vector up using libomv (c&p from sop )
7316 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7889 // vector up rotated by r
7890 private Vector3 Zrot(Quaternion r)
7891 {
7892 double x, y, z, m;
7317 7893
7318 while (remaining != null && remaining.Length > 2) 7894 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7895 if (Math.Abs(1.0 - m) > 0.000001)
7319 { 7896 {
7320 linknumber = remaining.GetLSLIntegerItem(0); 7897 m = 1.0 / Math.Sqrt(m);
7321 rules = remaining.GetSublist(1, -1); 7898 r.X *= (float)m;
7322 parts = GetLinkParts(linknumber); 7899 r.Y *= (float)m;
7323 7900 r.Z *= (float)m;
7324 foreach (SceneObjectPart part in parts) 7901 r.W *= (float)m;
7325 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7326 } 7902 }
7903
7904 x = 2 * (r.X * r.Z + r.Y * r.W);
7905 y = 2 * (-r.X * r.W + r.Y * r.Z);
7906 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7907
7908 return new Vector3((float)x, (float)y, (float)z);
7327 } 7909 }
7328 7910
7329 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7911 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7330 { 7912 {
7913 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7914 return null;
7915
7331 int idx = 0; 7916 int idx = 0;
7332 int idxStart = 0; 7917 int idxStart = 0;
7333 7918
7919 SceneObjectGroup parentgrp = part.ParentGroup;
7920
7334 bool positionChanged = false; 7921 bool positionChanged = false;
7335 LSL_Vector currentPosition = GetPartLocalPos(part); 7922 LSL_Vector currentPosition = GetPartLocalPos(part);
7336 7923
@@ -7355,8 +7942,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7355 return null; 7942 return null;
7356 7943
7357 v=rules.GetVector3Item(idx++); 7944 v=rules.GetVector3Item(idx++);
7945 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7946 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7947 else
7948 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7358 positionChanged = true; 7949 positionChanged = true;
7359 currentPosition = GetSetPosTarget(part, v, currentPosition);
7360 7950
7361 break; 7951 break;
7362 case (int)ScriptBaseClass.PRIM_SIZE: 7952 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7373,7 +7963,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7373 7963
7374 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7964 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7375 // try to let this work as in SL... 7965 // try to let this work as in SL...
7376 if (part.ParentID == 0) 7966 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7377 { 7967 {
7378 // special case: If we are root, rotate complete SOG to new rotation 7968 // special case: If we are root, rotate complete SOG to new rotation
7379 SetRot(part, q); 7969 SetRot(part, q);
@@ -7633,7 +8223,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7633 return null; 8223 return null;
7634 8224
7635 string ph = rules.Data[idx++].ToString(); 8225 string ph = rules.Data[idx++].ToString();
7636 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8226 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7637 8227
7638 break; 8228 break;
7639 8229
@@ -7651,12 +8241,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7651 part.ScriptSetPhysicsStatus(physics); 8241 part.ScriptSetPhysicsStatus(physics);
7652 break; 8242 break;
7653 8243
8244 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8245 if (remain < 1)
8246 return null;
8247
8248 int shape_type = rules.GetLSLIntegerItem(idx++);
8249
8250 ExtraPhysicsData physdata = new ExtraPhysicsData();
8251 physdata.Density = part.Density;
8252 physdata.Bounce = part.Bounciness;
8253 physdata.GravitationModifier = part.GravityModifier;
8254 physdata.PhysShapeType = (PhysShapeType)shape_type;
8255
8256 part.UpdateExtraPhysics(physdata);
8257
8258 break;
8259
8260 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8261 if (remain < 5)
8262 return null;
8263
8264 int material_bits = rules.GetLSLIntegerItem(idx++);
8265 float material_density = (float)rules.GetLSLFloatItem(idx++);
8266 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8267 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8268 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8269
8270 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8271
8272 break;
8273
7654 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8274 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7655 if (remain < 1) 8275 if (remain < 1)
7656 return null; 8276 return null;
7657 string temp = rules.Data[idx++].ToString(); 8277 string temp = rules.Data[idx++].ToString();
7658 8278
7659 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8279 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7660 8280
7661 break; 8281 break;
7662 8282
@@ -7730,14 +8350,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7730 if (part.ParentGroup.RootPart == part) 8350 if (part.ParentGroup.RootPart == part)
7731 { 8351 {
7732 SceneObjectGroup parent = part.ParentGroup; 8352 SceneObjectGroup parent = part.ParentGroup;
7733 parent.UpdateGroupPosition(currentPosition); 8353 Util.FireAndForget(delegate(object x) {
8354 parent.UpdateGroupPosition(currentPosition);
8355 });
7734 } 8356 }
7735 else 8357 else
7736 { 8358 {
7737 part.OffsetPosition = currentPosition; 8359 part.OffsetPosition = currentPosition;
7738 SceneObjectGroup parent = part.ParentGroup; 8360// SceneObjectGroup parent = part.ParentGroup;
7739 parent.HasGroupChanged = true; 8361// parent.HasGroupChanged = true;
7740 parent.ScheduleGroupForTerseUpdate(); 8362// parent.ScheduleGroupForTerseUpdate();
8363 part.ScheduleTerseUpdate();
7741 } 8364 }
7742 } 8365 }
7743 } 8366 }
@@ -7775,10 +8398,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7775 8398
7776 public LSL_String llXorBase64Strings(string str1, string str2) 8399 public LSL_String llXorBase64Strings(string str1, string str2)
7777 { 8400 {
7778 m_host.AddScriptLPS(1); 8401 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7779 Deprecated("llXorBase64Strings"); 8402
7780 ScriptSleep(300); 8403 ScriptSleep(300);
7781 return String.Empty; 8404 m_host.AddScriptLPS(1);
8405
8406 if (str1 == String.Empty)
8407 return String.Empty;
8408 if (str2 == String.Empty)
8409 return str1;
8410
8411 int len = str2.Length;
8412 if ((len % 4) != 0) // LL is EVIL!!!!
8413 {
8414 while (str2.EndsWith("="))
8415 str2 = str2.Substring(0, str2.Length - 1);
8416
8417 len = str2.Length;
8418 int mod = len % 4;
8419
8420 if (mod == 1)
8421 str2 = str2.Substring(0, str2.Length - 1);
8422 else if (mod == 2)
8423 str2 += "==";
8424 else if (mod == 3)
8425 str2 += "=";
8426 }
8427
8428 byte[] data1;
8429 byte[] data2;
8430 try
8431 {
8432 data1 = Convert.FromBase64String(str1);
8433 data2 = Convert.FromBase64String(str2);
8434 }
8435 catch (Exception)
8436 {
8437 return new LSL_String(String.Empty);
8438 }
8439
8440 // For cases where the decoded length of s2 is greater
8441 // than the decoded length of s1, simply perform a normal
8442 // decode and XOR
8443 //
8444 if (data2.Length >= data1.Length)
8445 {
8446 for (int pos = 0 ; pos < data1.Length ; pos++ )
8447 data1[pos] ^= data2[pos];
8448
8449 return Convert.ToBase64String(data1);
8450 }
8451
8452 // Remove padding
8453 while (str1.EndsWith("="))
8454 str1 = str1.Substring(0, str1.Length - 1);
8455 while (str2.EndsWith("="))
8456 str2 = str2.Substring(0, str2.Length - 1);
8457
8458 byte[] d1 = new byte[str1.Length];
8459 byte[] d2 = new byte[str2.Length];
8460
8461 for (int i = 0 ; i < str1.Length ; i++)
8462 {
8463 int idx = b64.IndexOf(str1.Substring(i, 1));
8464 if (idx == -1)
8465 idx = 0;
8466 d1[i] = (byte)idx;
8467 }
8468
8469 for (int i = 0 ; i < str2.Length ; i++)
8470 {
8471 int idx = b64.IndexOf(str2.Substring(i, 1));
8472 if (idx == -1)
8473 idx = 0;
8474 d2[i] = (byte)idx;
8475 }
8476
8477 string output = String.Empty;
8478
8479 for (int pos = 0 ; pos < d1.Length ; pos++)
8480 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8481
8482 while (output.Length % 3 > 0)
8483 output += "=";
8484
8485 return output;
7782 } 8486 }
7783 8487
7784 public void llRemoteDataSetRegion() 8488 public void llRemoteDataSetRegion()
@@ -7902,8 +8606,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7902 public LSL_Integer llGetNumberOfPrims() 8606 public LSL_Integer llGetNumberOfPrims()
7903 { 8607 {
7904 m_host.AddScriptLPS(1); 8608 m_host.AddScriptLPS(1);
7905 8609 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7906 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8610
8611 return m_host.ParentGroup.PrimCount + avatarCount;
7907 } 8612 }
7908 8613
7909 /// <summary> 8614 /// <summary>
@@ -7918,55 +8623,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7918 m_host.AddScriptLPS(1); 8623 m_host.AddScriptLPS(1);
7919 UUID objID = UUID.Zero; 8624 UUID objID = UUID.Zero;
7920 LSL_List result = new LSL_List(); 8625 LSL_List result = new LSL_List();
8626
8627 // If the ID is not valid, return null result
7921 if (!UUID.TryParse(obj, out objID)) 8628 if (!UUID.TryParse(obj, out objID))
7922 { 8629 {
7923 result.Add(new LSL_Vector()); 8630 result.Add(new LSL_Vector());
7924 result.Add(new LSL_Vector()); 8631 result.Add(new LSL_Vector());
7925 return result; 8632 return result;
7926 } 8633 }
8634
8635 // Check if this is an attached prim. If so, replace
8636 // the UUID with the avatar UUID and report it's bounding box
8637 SceneObjectPart part = World.GetSceneObjectPart(objID);
8638 if (part != null && part.ParentGroup.IsAttachment)
8639 objID = part.ParentGroup.AttachedAvatar;
8640
8641 // Find out if this is an avatar ID. If so, return it's box
7927 ScenePresence presence = World.GetScenePresence(objID); 8642 ScenePresence presence = World.GetScenePresence(objID);
7928 if (presence != null) 8643 if (presence != null)
7929 { 8644 {
7930 if (presence.ParentID == 0) // not sat on an object 8645 // As per LSL Wiki, there is no difference between sitting
8646 // and standing avatar since server 1.36
8647 LSL_Vector lower;
8648 LSL_Vector upper;
8649
8650 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8651
8652 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8653 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8654/*
7931 { 8655 {
7932 LSL_Vector lower; 8656 // This is for ground sitting avatars
7933 LSL_Vector upper; 8657 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7934 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8658 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7935 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8659 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7936 {
7937 // This is for ground sitting avatars
7938 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7939 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7940 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7941 }
7942 else
7943 {
7944 // This is for standing/flying avatars
7945 float height = presence.Appearance.AvatarHeight / 2.0f;
7946 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7947 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7948 }
7949 result.Add(lower);
7950 result.Add(upper);
7951 return result;
7952 } 8660 }
7953 else 8661 else
7954 { 8662 {
7955 // sitting on an object so we need the bounding box of that 8663 // This is for standing/flying avatars
7956 // which should include the avatar so set the UUID to the 8664 float height = presence.Appearance.AvatarHeight / 2.0f;
7957 // UUID of the object the avatar is sat on and allow it to fall through 8665 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7958 // to processing an object 8666 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7959 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); 8667 }
7960 objID = p.UUID; 8668
8669 // Adjust to the documented error offsets (see LSL Wiki)
8670 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8671 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8672*/
8673 {
8674 // This is for ground sitting avatars TODO!
8675 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8676 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7961 } 8677 }
8678 else
8679 {
8680 // This is for standing/flying avatars
8681 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8682 upper = new LSL_Vector(box.X, box.Y, box.Z);
8683 }
8684
8685 if (lower.x > upper.x)
8686 lower.x = upper.x;
8687 if (lower.y > upper.y)
8688 lower.y = upper.y;
8689 if (lower.z > upper.z)
8690 lower.z = upper.z;
8691
8692 result.Add(lower);
8693 result.Add(upper);
8694 return result;
7962 } 8695 }
7963 SceneObjectPart part = World.GetSceneObjectPart(objID); 8696
8697 part = World.GetSceneObjectPart(objID);
7964 // Currently only works for single prims without a sitting avatar 8698 // Currently only works for single prims without a sitting avatar
7965 if (part != null) 8699 if (part != null)
7966 { 8700 {
7967 Vector3 halfSize = part.Scale / 2.0f; 8701 float minX;
7968 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8702 float maxX;
7969 LSL_Vector upper = new LSL_Vector(halfSize); 8703 float minY;
8704 float maxY;
8705 float minZ;
8706 float maxZ;
8707
8708 // This BBox is in sim coordinates, with the offset being
8709 // a contained point.
8710 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8711 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8712
8713 minX -= offsets[0].X;
8714 maxX -= offsets[0].X;
8715 minY -= offsets[0].Y;
8716 maxY -= offsets[0].Y;
8717 minZ -= offsets[0].Z;
8718 maxZ -= offsets[0].Z;
8719
8720 LSL_Vector lower;
8721 LSL_Vector upper;
8722
8723 // Adjust to the documented error offsets (see LSL Wiki)
8724 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8725 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8726
8727 if (lower.x > upper.x)
8728 lower.x = upper.x;
8729 if (lower.y > upper.y)
8730 lower.y = upper.y;
8731 if (lower.z > upper.z)
8732 lower.z = upper.z;
8733
7970 result.Add(lower); 8734 result.Add(lower);
7971 result.Add(upper); 8735 result.Add(upper);
7972 return result; 8736 return result;
@@ -7980,7 +8744,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7980 8744
7981 public LSL_Vector llGetGeometricCenter() 8745 public LSL_Vector llGetGeometricCenter()
7982 { 8746 {
7983 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8747 Vector3 tmp = m_host.GetGeometricCenter();
8748 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7984 } 8749 }
7985 8750
7986 public LSL_List llGetPrimitiveParams(LSL_List rules) 8751 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7991,7 +8756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7991 8756
7992 LSL_List remaining = GetPrimParams(m_host, rules, ref result); 8757 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7993 8758
7994 while (remaining != null && remaining.Length > 2) 8759 while ((object)remaining != null && remaining.Length > 2)
7995 { 8760 {
7996 int linknumber = remaining.GetLSLIntegerItem(0); 8761 int linknumber = remaining.GetLSLIntegerItem(0);
7997 rules = remaining.GetSublist(1, -1); 8762 rules = remaining.GetSublist(1, -1);
@@ -8008,24 +8773,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 { 8773 {
8009 m_host.AddScriptLPS(1); 8774 m_host.AddScriptLPS(1);
8010 8775
8011 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8776 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8777 // keep other options as before
8012 8778
8779 List<SceneObjectPart> parts;
8780 List<ScenePresence> avatars;
8781
8013 LSL_List res = new LSL_List(); 8782 LSL_List res = new LSL_List();
8014 LSL_List remaining = null; 8783 LSL_List remaining = null;
8015 8784
8016 foreach (SceneObjectPart part in parts) 8785 while (rules.Length > 0)
8017 {
8018 remaining = GetPrimParams(part, rules, ref res);
8019 }
8020
8021 while (remaining != null && remaining.Length > 2)
8022 { 8786 {
8023 linknumber = remaining.GetLSLIntegerItem(0);
8024 rules = remaining.GetSublist(1, -1);
8025 parts = GetLinkParts(linknumber); 8787 parts = GetLinkParts(linknumber);
8788 avatars = GetLinkAvatars(linknumber);
8026 8789
8790 remaining = null;
8027 foreach (SceneObjectPart part in parts) 8791 foreach (SceneObjectPart part in parts)
8792 {
8028 remaining = GetPrimParams(part, rules, ref res); 8793 remaining = GetPrimParams(part, rules, ref res);
8794 }
8795 foreach (ScenePresence avatar in avatars)
8796 {
8797 remaining = GetPrimParams(avatar, rules, ref res);
8798 }
8799
8800 if ((object)remaining != null && remaining.Length > 0)
8801 {
8802 linknumber = remaining.GetLSLIntegerItem(0);
8803 rules = remaining.GetSublist(1, -1);
8804 }
8805 else
8806 break;
8029 } 8807 }
8030 8808
8031 return res; 8809 return res;
@@ -8070,13 +8848,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8070 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8848 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8071 part.AbsolutePosition.Y, 8849 part.AbsolutePosition.Y,
8072 part.AbsolutePosition.Z); 8850 part.AbsolutePosition.Z);
8073 // For some reason, the part.AbsolutePosition.* values do not change if the
8074 // linkset is rotated; they always reflect the child prim's world position
8075 // as though the linkset is unrotated. This is incompatible behavior with SL's
8076 // implementation, so will break scripts imported from there (not to mention it
8077 // makes it more difficult to determine a child prim's actual inworld position).
8078 if (part.ParentID != 0)
8079 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8080 res.Add(v); 8851 res.Add(v);
8081 break; 8852 break;
8082 8853
@@ -8248,30 +9019,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8248 if (remain < 1) 9019 if (remain < 1)
8249 return null; 9020 return null;
8250 9021
8251 face=(int)rules.GetLSLIntegerItem(idx++); 9022 face = (int)rules.GetLSLIntegerItem(idx++);
8252 9023
8253 tex = part.Shape.Textures; 9024 tex = part.Shape.Textures;
9025 int shiny;
8254 if (face == ScriptBaseClass.ALL_SIDES) 9026 if (face == ScriptBaseClass.ALL_SIDES)
8255 { 9027 {
8256 for (face = 0; face < GetNumberOfSides(part); face++) 9028 for (face = 0; face < GetNumberOfSides(part); face++)
8257 { 9029 {
8258 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9030 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8259 // Convert Shininess to PRIM_SHINY_* 9031 if (shinyness == Shininess.High)
8260 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9032 {
8261 // PRIM_BUMP_* 9033 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8262 res.Add(new LSL_Integer((int)texface.Bump)); 9034 }
9035 else if (shinyness == Shininess.Medium)
9036 {
9037 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9038 }
9039 else if (shinyness == Shininess.Low)
9040 {
9041 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9042 }
9043 else
9044 {
9045 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9046 }
9047 res.Add(new LSL_Integer(shiny));
9048 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8263 } 9049 }
8264 } 9050 }
8265 else 9051 else
8266 { 9052 {
8267 if (face >= 0 && face < GetNumberOfSides(part)) 9053 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9054 if (shinyness == Shininess.High)
8268 { 9055 {
8269 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9056 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8270 // Convert Shininess to PRIM_SHINY_* 9057 }
8271 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9058 else if (shinyness == Shininess.Medium)
8272 // PRIM_BUMP_* 9059 {
8273 res.Add(new LSL_Integer((int)texface.Bump)); 9060 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9061 }
9062 else if (shinyness == Shininess.Low)
9063 {
9064 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9065 }
9066 else
9067 {
9068 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8274 } 9069 }
9070 res.Add(new LSL_Integer(shiny));
9071 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8275 } 9072 }
8276 break; 9073 break;
8277 9074
@@ -8279,24 +9076,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8279 if (remain < 1) 9076 if (remain < 1)
8280 return null; 9077 return null;
8281 9078
8282 face=(int)rules.GetLSLIntegerItem(idx++); 9079 face = (int)rules.GetLSLIntegerItem(idx++);
8283 9080
8284 tex = part.Shape.Textures; 9081 tex = part.Shape.Textures;
9082 int fullbright;
8285 if (face == ScriptBaseClass.ALL_SIDES) 9083 if (face == ScriptBaseClass.ALL_SIDES)
8286 { 9084 {
8287 for (face = 0; face < GetNumberOfSides(part); face++) 9085 for (face = 0; face < GetNumberOfSides(part); face++)
8288 { 9086 {
8289 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9087 if (tex.GetFace((uint)face).Fullbright == true)
8290 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9088 {
9089 fullbright = ScriptBaseClass.TRUE;
9090 }
9091 else
9092 {
9093 fullbright = ScriptBaseClass.FALSE;
9094 }
9095 res.Add(new LSL_Integer(fullbright));
8291 } 9096 }
8292 } 9097 }
8293 else 9098 else
8294 { 9099 {
8295 if (face >= 0 && face < GetNumberOfSides(part)) 9100 if (tex.GetFace((uint)face).Fullbright == true)
8296 { 9101 {
8297 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9102 fullbright = ScriptBaseClass.TRUE;
8298 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8299 } 9103 }
9104 else
9105 {
9106 fullbright = ScriptBaseClass.FALSE;
9107 }
9108 res.Add(new LSL_Integer(fullbright));
8300 } 9109 }
8301 break; 9110 break;
8302 9111
@@ -8318,27 +9127,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8318 break; 9127 break;
8319 9128
8320 case (int)ScriptBaseClass.PRIM_TEXGEN: 9129 case (int)ScriptBaseClass.PRIM_TEXGEN:
9130 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8321 if (remain < 1) 9131 if (remain < 1)
8322 return null; 9132 return null;
8323 9133
8324 face=(int)rules.GetLSLIntegerItem(idx++); 9134 face = (int)rules.GetLSLIntegerItem(idx++);
8325 9135
8326 tex = part.Shape.Textures; 9136 tex = part.Shape.Textures;
8327 if (face == ScriptBaseClass.ALL_SIDES) 9137 if (face == ScriptBaseClass.ALL_SIDES)
8328 { 9138 {
8329 for (face = 0; face < GetNumberOfSides(part); face++) 9139 for (face = 0; face < GetNumberOfSides(part); face++)
8330 { 9140 {
8331 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9141 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8332 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9142 {
8333 res.Add(new LSL_Integer((uint)texgen >> 1)); 9143 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9144 }
9145 else
9146 {
9147 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9148 }
8334 } 9149 }
8335 } 9150 }
8336 else 9151 else
8337 { 9152 {
8338 if (face >= 0 && face < GetNumberOfSides(part)) 9153 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8339 { 9154 {
8340 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9155 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8341 res.Add(new LSL_Integer((uint)texgen >> 1)); 9156 }
9157 else
9158 {
9159 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8342 } 9160 }
8343 } 9161 }
8344 break; 9162 break;
@@ -8362,24 +9180,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8362 if (remain < 1) 9180 if (remain < 1)
8363 return null; 9181 return null;
8364 9182
8365 face=(int)rules.GetLSLIntegerItem(idx++); 9183 face = (int)rules.GetLSLIntegerItem(idx++);
8366 9184
8367 tex = part.Shape.Textures; 9185 tex = part.Shape.Textures;
9186 float primglow;
8368 if (face == ScriptBaseClass.ALL_SIDES) 9187 if (face == ScriptBaseClass.ALL_SIDES)
8369 { 9188 {
8370 for (face = 0; face < GetNumberOfSides(part); face++) 9189 for (face = 0; face < GetNumberOfSides(part); face++)
8371 { 9190 {
8372 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9191 primglow = tex.GetFace((uint)face).Glow;
8373 res.Add(new LSL_Float(texface.Glow)); 9192 res.Add(new LSL_Float(primglow));
8374 } 9193 }
8375 } 9194 }
8376 else 9195 else
8377 { 9196 {
8378 if (face >= 0 && face < GetNumberOfSides(part)) 9197 primglow = tex.GetFace((uint)face).Glow;
8379 { 9198 res.Add(new LSL_Float(primglow));
8380 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8381 res.Add(new LSL_Float(texface.Glow));
8382 }
8383 } 9199 }
8384 break; 9200 break;
8385 9201
@@ -8391,15 +9207,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8391 textColor.B)); 9207 textColor.B));
8392 res.Add(new LSL_Float(textColor.A)); 9208 res.Add(new LSL_Float(textColor.A));
8393 break; 9209 break;
9210
8394 case (int)ScriptBaseClass.PRIM_NAME: 9211 case (int)ScriptBaseClass.PRIM_NAME:
8395 res.Add(new LSL_String(part.Name)); 9212 res.Add(new LSL_String(part.Name));
8396 break; 9213 break;
9214
8397 case (int)ScriptBaseClass.PRIM_DESC: 9215 case (int)ScriptBaseClass.PRIM_DESC:
8398 res.Add(new LSL_String(part.Description)); 9216 res.Add(new LSL_String(part.Description));
8399 break; 9217 break;
9218
8400 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9219 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8401 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9220 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8402 break; 9221 break;
9222
8403 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9223 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8404 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9224 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8405 break; 9225 break;
@@ -9010,8 +9830,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9010 // The function returns an ordered list 9830 // The function returns an ordered list
9011 // representing the tokens found in the supplied 9831 // representing the tokens found in the supplied
9012 // sources string. If two successive tokenizers 9832 // sources string. If two successive tokenizers
9013 // are encountered, then a NULL entry is added 9833 // are encountered, then a null-string entry is
9014 // to the list. 9834 // added to the list.
9015 // 9835 //
9016 // It is a precondition that the source and 9836 // It is a precondition that the source and
9017 // toekizer lisst are non-null. If they are null, 9837 // toekizer lisst are non-null. If they are null,
@@ -9019,7 +9839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9019 // while their lengths are being determined. 9839 // while their lengths are being determined.
9020 // 9840 //
9021 // A small amount of working memoryis required 9841 // A small amount of working memoryis required
9022 // of approximately 8*#tokenizers. 9842 // of approximately 8*#tokenizers + 8*srcstrlen.
9023 // 9843 //
9024 // There are many ways in which this function 9844 // There are many ways in which this function
9025 // can be implemented, this implementation is 9845 // can be implemented, this implementation is
@@ -9035,155 +9855,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9035 // and eliminates redundant tokenizers as soon 9855 // and eliminates redundant tokenizers as soon
9036 // as is possible. 9856 // as is possible.
9037 // 9857 //
9038 // The implementation tries to avoid any copying 9858 // The implementation tries to minimize temporary
9039 // of arrays or other objects. 9859 // garbage generation.
9040 // </remarks> 9860 // </remarks>
9041 9861
9042 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9862 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9043 { 9863 {
9044 int beginning = 0; 9864 return ParseString2List(src, separators, spacers, true);
9045 int srclen = src.Length; 9865 }
9046 int seplen = separators.Length;
9047 object[] separray = separators.Data;
9048 int spclen = spacers.Length;
9049 object[] spcarray = spacers.Data;
9050 int mlen = seplen+spclen;
9051
9052 int[] offset = new int[mlen+1];
9053 bool[] active = new bool[mlen];
9054
9055 int best;
9056 int j;
9057
9058 // Initial capacity reduces resize cost
9059 9866
9060 LSL_List tokens = new LSL_List(); 9867 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9868 {
9869 int srclen = src.Length;
9870 int seplen = separators.Length;
9871 object[] separray = separators.Data;
9872 int spclen = spacers.Length;
9873 object[] spcarray = spacers.Data;
9874 int dellen = 0;
9875 string[] delarray = new string[seplen+spclen];
9061 9876
9062 // All entries are initially valid 9877 int outlen = 0;
9878 string[] outarray = new string[srclen*2+1];
9063 9879
9064 for (int i = 0; i < mlen; i++) 9880 int i, j;
9065 active[i] = true; 9881 string d;
9066 9882
9067 offset[mlen] = srclen; 9883 m_host.AddScriptLPS(1);
9068 9884
9069 while (beginning < srclen) 9885 /*
9886 * Convert separator and spacer lists to C# strings.
9887 * Also filter out null strings so we don't hang.
9888 */
9889 for (i = 0; i < seplen; i ++)
9070 { 9890 {
9891 d = separray[i].ToString();
9892 if (d.Length > 0)
9893 {
9894 delarray[dellen++] = d;
9895 }
9896 }
9897 seplen = dellen;
9071 9898
9072 best = mlen; // as bad as it gets 9899 for (i = 0; i < spclen; i ++)
9900 {
9901 d = spcarray[i].ToString();
9902 if (d.Length > 0)
9903 {
9904 delarray[dellen++] = d;
9905 }
9906 }
9073 9907
9074 // Scan for separators 9908 /*
9909 * Scan through source string from beginning to end.
9910 */
9911 for (i = 0;;)
9912 {
9075 9913
9076 for (j = 0; j < seplen; j++) 9914 /*
9915 * Find earliest delimeter in src starting at i (if any).
9916 */
9917 int earliestDel = -1;
9918 int earliestSrc = srclen;
9919 string earliestStr = null;
9920 for (j = 0; j < dellen; j ++)
9077 { 9921 {
9078 if (separray[j].ToString() == String.Empty) 9922 d = delarray[j];
9079 active[j] = false; 9923 if (d != null)
9080
9081 if (active[j])
9082 { 9924 {
9083 // scan all of the markers 9925 int index = src.IndexOf(d, i);
9084 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9926 if (index < 0)
9085 { 9927 {
9086 // not present at all 9928 delarray[j] = null; // delim nowhere in src, don't check it anymore
9087 active[j] = false;
9088 } 9929 }
9089 else 9930 else if (index < earliestSrc)
9090 { 9931 {
9091 // present and correct 9932 earliestSrc = index; // where delimeter starts in source string
9092 if (offset[j] < offset[best]) 9933 earliestDel = j; // where delimeter is in delarray[]
9093 { 9934 earliestStr = d; // the delimeter string from delarray[]
9094 // closest so far 9935 if (index == i) break; // can't do any better than found at beg of string
9095 best = j;
9096 if (offset[best] == beginning)
9097 break;
9098 }
9099 } 9936 }
9100 } 9937 }
9101 } 9938 }
9102 9939
9103 // Scan for spacers 9940 /*
9104 9941 * Output source string starting at i through start of earliest delimeter.
9105 if (offset[best] != beginning) 9942 */
9943 if (keepNulls || (earliestSrc > i))
9106 { 9944 {
9107 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9945 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9108 {
9109 if (spcarray[j-seplen].ToString() == String.Empty)
9110 active[j] = false;
9111
9112 if (active[j])
9113 {
9114 // scan all of the markers
9115 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9116 {
9117 // not present at all
9118 active[j] = false;
9119 }
9120 else
9121 {
9122 // present and correct
9123 if (offset[j] < offset[best])
9124 {
9125 // closest so far
9126 best = j;
9127 }
9128 }
9129 }
9130 }
9131 } 9946 }
9132 9947
9133 // This is the normal exit from the scanning loop 9948 /*
9949 * If no delimeter found at or after i, we're done scanning.
9950 */
9951 if (earliestDel < 0) break;
9134 9952
9135 if (best == mlen) 9953 /*
9954 * If delimeter was a spacer, output the spacer.
9955 */
9956 if (earliestDel >= seplen)
9136 { 9957 {
9137 // no markers were found on this pass 9958 outarray[outlen++] = earliestStr;
9138 // so we're pretty much done
9139 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9140 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9141 break;
9142 } 9959 }
9143 9960
9144 // Otherwise we just add the newly delimited token 9961 /*
9145 // and recalculate where the search should continue. 9962 * Look at rest of src string following delimeter.
9146 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9963 */
9147 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9964 i = earliestSrc + earliestStr.Length;
9148
9149 if (best < seplen)
9150 {
9151 beginning = offset[best] + (separray[best].ToString()).Length;
9152 }
9153 else
9154 {
9155 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9156 string str = spcarray[best - seplen].ToString();
9157 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9158 tokens.Add(new LSL_String(str));
9159 }
9160 } 9965 }
9161 9966
9162 // This an awkward an not very intuitive boundary case. If the 9967 /*
9163 // last substring is a tokenizer, then there is an implied trailing 9968 * Make up an exact-sized output array suitable for an LSL_List object.
9164 // null list entry. Hopefully the single comparison will not be too 9969 */
9165 // arduous. Alternatively the 'break' could be replced with a return 9970 object[] outlist = new object[outlen];
9166 // but that's shabby programming. 9971 for (i = 0; i < outlen; i ++)
9167
9168 if ((beginning == srclen) && (keepNulls))
9169 { 9972 {
9170 if (srclen != 0) 9973 outlist[i] = new LSL_String(outarray[i]);
9171 tokens.Add(new LSL_String(""));
9172 } 9974 }
9173 9975 return new LSL_List(outlist);
9174 return tokens;
9175 }
9176
9177 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9178 {
9179 m_host.AddScriptLPS(1);
9180 return this.ParseString(src, separators, spacers, false);
9181 }
9182
9183 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9184 {
9185 m_host.AddScriptLPS(1);
9186 return this.ParseString(src, separators, spacers, true);
9187 } 9976 }
9188 9977
9189 public LSL_Integer llGetObjectPermMask(int mask) 9978 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9278,6 +10067,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9278 case 4: 10067 case 4:
9279 return (int)item.NextPermissions; 10068 return (int)item.NextPermissions;
9280 } 10069 }
10070 m_host.TaskInventory.LockItemsForRead(false);
9281 10071
9282 return -1; 10072 return -1;
9283 } 10073 }
@@ -9480,31 +10270,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 UUID key = new UUID(); 10270 UUID key = new UUID();
9481 if (UUID.TryParse(id, out key)) 10271 if (UUID.TryParse(id, out key))
9482 { 10272 {
9483 try 10273 // return total object mass
9484 { 10274 SceneObjectPart part = World.GetSceneObjectPart(key);
9485 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10275 if (part != null)
9486 if (obj != null) 10276 return part.ParentGroup.GetMass();
9487 return (double)obj.GetMass(); 10277
9488 // the object is null so the key is for an avatar 10278 // the object is null so the key is for an avatar
9489 ScenePresence avatar = World.GetScenePresence(key); 10279 ScenePresence avatar = World.GetScenePresence(key);
9490 if (avatar != null) 10280 if (avatar != null)
9491 if (avatar.IsChildAgent)
9492 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9493 // child agents have a mass of 1.0
9494 return 1;
9495 else
9496 return (double)avatar.GetMass();
9497 }
9498 catch (KeyNotFoundException)
9499 { 10281 {
9500 return 0; // The Object/Agent not in the region so just return zero 10282 if (avatar.IsChildAgent)
10283 {
10284 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10285 // child agents have a mass of 1.0
10286 return 1;
10287 }
10288 else
10289 {
10290 return (double)avatar.GetMass();
10291 }
9501 } 10292 }
9502 } 10293 }
9503 return 0; 10294 return 0;
9504 } 10295 }
9505 10296
9506 /// <summary> 10297 /// <summary>
9507 /// illListReplaceList removes the sub-list defined by the inclusive indices 10298 /// llListReplaceList removes the sub-list defined by the inclusive indices
9508 /// start and end and inserts the src list in its place. The inclusive 10299 /// start and end and inserts the src list in its place. The inclusive
9509 /// nature of the indices means that at least one element must be deleted 10300 /// nature of the indices means that at least one element must be deleted
9510 /// if the indices are within the bounds of the existing list. I.e. 2,2 10301 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9561,16 +10352,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9561 // based upon end. Note that if end exceeds the upper 10352 // based upon end. Note that if end exceeds the upper
9562 // bound in this case, the entire destination list 10353 // bound in this case, the entire destination list
9563 // is removed. 10354 // is removed.
9564 else 10355 else if (start == 0)
9565 { 10356 {
9566 if (end + 1 < dest.Length) 10357 if (end + 1 < dest.Length)
9567 {
9568 return src + dest.GetSublist(end + 1, -1); 10358 return src + dest.GetSublist(end + 1, -1);
9569 }
9570 else 10359 else
9571 {
9572 return src; 10360 return src;
9573 } 10361 }
10362 else // Start < 0
10363 {
10364 if (end + 1 < dest.Length)
10365 return dest.GetSublist(end + 1, -1);
10366 else
10367 return new LSL_List();
9574 } 10368 }
9575 } 10369 }
9576 // Finally, if start > end, we strip away a prefix and 10370 // Finally, if start > end, we strip away a prefix and
@@ -9621,17 +10415,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9621 int width = 0; 10415 int width = 0;
9622 int height = 0; 10416 int height = 0;
9623 10417
9624 ParcelMediaCommandEnum? commandToSend = null; 10418 uint commandToSend = 0;
9625 float time = 0.0f; // default is from start 10419 float time = 0.0f; // default is from start
9626 10420
9627 ScenePresence presence = null; 10421 ScenePresence presence = null;
9628 10422
9629 for (int i = 0; i < commandList.Data.Length; i++) 10423 for (int i = 0; i < commandList.Data.Length; i++)
9630 { 10424 {
9631 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10425 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9632 switch (command) 10426 switch (command)
9633 { 10427 {
9634 case ParcelMediaCommandEnum.Agent: 10428 case (uint)ParcelMediaCommandEnum.Agent:
9635 // we send only to one agent 10429 // we send only to one agent
9636 if ((i + 1) < commandList.Length) 10430 if ((i + 1) < commandList.Length)
9637 { 10431 {
@@ -9648,25 +10442,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9648 } 10442 }
9649 break; 10443 break;
9650 10444
9651 case ParcelMediaCommandEnum.Loop: 10445 case (uint)ParcelMediaCommandEnum.Loop:
9652 loop = 1; 10446 loop = 1;
9653 commandToSend = command; 10447 commandToSend = command;
9654 update = true; //need to send the media update packet to set looping 10448 update = true; //need to send the media update packet to set looping
9655 break; 10449 break;
9656 10450
9657 case ParcelMediaCommandEnum.Play: 10451 case (uint)ParcelMediaCommandEnum.Play:
9658 loop = 0; 10452 loop = 0;
9659 commandToSend = command; 10453 commandToSend = command;
9660 update = true; //need to send the media update packet to make sure it doesn't loop 10454 update = true; //need to send the media update packet to make sure it doesn't loop
9661 break; 10455 break;
9662 10456
9663 case ParcelMediaCommandEnum.Pause: 10457 case (uint)ParcelMediaCommandEnum.Pause:
9664 case ParcelMediaCommandEnum.Stop: 10458 case (uint)ParcelMediaCommandEnum.Stop:
9665 case ParcelMediaCommandEnum.Unload: 10459 case (uint)ParcelMediaCommandEnum.Unload:
9666 commandToSend = command; 10460 commandToSend = command;
9667 break; 10461 break;
9668 10462
9669 case ParcelMediaCommandEnum.Url: 10463 case (uint)ParcelMediaCommandEnum.Url:
9670 if ((i + 1) < commandList.Length) 10464 if ((i + 1) < commandList.Length)
9671 { 10465 {
9672 if (commandList.Data[i + 1] is LSL_String) 10466 if (commandList.Data[i + 1] is LSL_String)
@@ -9679,7 +10473,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9679 } 10473 }
9680 break; 10474 break;
9681 10475
9682 case ParcelMediaCommandEnum.Texture: 10476 case (uint)ParcelMediaCommandEnum.Texture:
9683 if ((i + 1) < commandList.Length) 10477 if ((i + 1) < commandList.Length)
9684 { 10478 {
9685 if (commandList.Data[i + 1] is LSL_String) 10479 if (commandList.Data[i + 1] is LSL_String)
@@ -9692,7 +10486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9692 } 10486 }
9693 break; 10487 break;
9694 10488
9695 case ParcelMediaCommandEnum.Time: 10489 case (uint)ParcelMediaCommandEnum.Time:
9696 if ((i + 1) < commandList.Length) 10490 if ((i + 1) < commandList.Length)
9697 { 10491 {
9698 if (commandList.Data[i + 1] is LSL_Float) 10492 if (commandList.Data[i + 1] is LSL_Float)
@@ -9704,7 +10498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9704 } 10498 }
9705 break; 10499 break;
9706 10500
9707 case ParcelMediaCommandEnum.AutoAlign: 10501 case (uint)ParcelMediaCommandEnum.AutoAlign:
9708 if ((i + 1) < commandList.Length) 10502 if ((i + 1) < commandList.Length)
9709 { 10503 {
9710 if (commandList.Data[i + 1] is LSL_Integer) 10504 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9718,7 +10512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9718 } 10512 }
9719 break; 10513 break;
9720 10514
9721 case ParcelMediaCommandEnum.Type: 10515 case (uint)ParcelMediaCommandEnum.Type:
9722 if ((i + 1) < commandList.Length) 10516 if ((i + 1) < commandList.Length)
9723 { 10517 {
9724 if (commandList.Data[i + 1] is LSL_String) 10518 if (commandList.Data[i + 1] is LSL_String)
@@ -9731,7 +10525,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9731 } 10525 }
9732 break; 10526 break;
9733 10527
9734 case ParcelMediaCommandEnum.Desc: 10528 case (uint)ParcelMediaCommandEnum.Desc:
9735 if ((i + 1) < commandList.Length) 10529 if ((i + 1) < commandList.Length)
9736 { 10530 {
9737 if (commandList.Data[i + 1] is LSL_String) 10531 if (commandList.Data[i + 1] is LSL_String)
@@ -9744,7 +10538,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9744 } 10538 }
9745 break; 10539 break;
9746 10540
9747 case ParcelMediaCommandEnum.Size: 10541 case (uint)ParcelMediaCommandEnum.Size:
9748 if ((i + 2) < commandList.Length) 10542 if ((i + 2) < commandList.Length)
9749 { 10543 {
9750 if (commandList.Data[i + 1] is LSL_Integer) 10544 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9814,7 +10608,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9814 } 10608 }
9815 } 10609 }
9816 10610
9817 if (commandToSend != null) 10611 if (commandToSend != 0)
9818 { 10612 {
9819 // the commandList contained a start/stop/... command, too 10613 // the commandList contained a start/stop/... command, too
9820 if (presence == null) 10614 if (presence == null)
@@ -9851,7 +10645,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9851 10645
9852 if (aList.Data[i] != null) 10646 if (aList.Data[i] != null)
9853 { 10647 {
9854 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10648 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9855 { 10649 {
9856 case ParcelMediaCommandEnum.Url: 10650 case ParcelMediaCommandEnum.Url:
9857 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10651 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9908,15 +10702,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9908 10702
9909 if (quick_pay_buttons.Data.Length < 4) 10703 if (quick_pay_buttons.Data.Length < 4)
9910 { 10704 {
9911 LSLError("List must have at least 4 elements"); 10705 int x;
9912 return; 10706 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10707 {
10708 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10709 }
9913 } 10710 }
9914 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10711 int[] nPrice = new int[5];
9915 10712 nPrice[0] = price;
9916 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10713 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9917 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10714 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9918 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10715 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9919 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10716 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10717 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9920 m_host.ParentGroup.HasGroupChanged = true; 10718 m_host.ParentGroup.HasGroupChanged = true;
9921 } 10719 }
9922 10720
@@ -9933,7 +10731,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9933 return new LSL_Vector(); 10731 return new LSL_Vector();
9934 } 10732 }
9935 10733
9936 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10734// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10735 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9937 if (presence != null) 10736 if (presence != null)
9938 { 10737 {
9939 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10738 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9955,7 +10754,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9955 return new LSL_Rotation(); 10754 return new LSL_Rotation();
9956 } 10755 }
9957 10756
9958 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10757// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10758 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9959 if (presence != null) 10759 if (presence != null)
9960 { 10760 {
9961 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10761 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10015,14 +10815,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10015 { 10815 {
10016 m_host.AddScriptLPS(1); 10816 m_host.AddScriptLPS(1);
10017 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10817 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10018 if (detectedParams == null) return; // only works on the first detected avatar 10818 if (detectedParams == null)
10019 10819 {
10820 if (m_host.ParentGroup.IsAttachment == true)
10821 {
10822 detectedParams = new DetectParams();
10823 detectedParams.Key = m_host.OwnerID;
10824 }
10825 else
10826 {
10827 return;
10828 }
10829 }
10830
10020 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10831 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10021 if (avatar != null) 10832 if (avatar != null)
10022 { 10833 {
10023 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10834 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10024 simname, pos, lookAt); 10835 simname, pos, lookAt);
10025 } 10836 }
10837
10026 ScriptSleep(1000); 10838 ScriptSleep(1000);
10027 } 10839 }
10028 10840
@@ -10146,12 +10958,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10146 10958
10147 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10959 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10148 object[] data = rules.Data; 10960 object[] data = rules.Data;
10149 for (int i = 0; i < data.Length; ++i) { 10961 for (int i = 0; i < data.Length; ++i)
10962 {
10150 int type = Convert.ToInt32(data[i++].ToString()); 10963 int type = Convert.ToInt32(data[i++].ToString());
10151 if (i >= data.Length) break; // odd number of entries => ignore the last 10964 if (i >= data.Length) break; // odd number of entries => ignore the last
10152 10965
10153 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10966 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10154 switch (type) { 10967 switch (type)
10968 {
10155 case ScriptBaseClass.CAMERA_FOCUS: 10969 case ScriptBaseClass.CAMERA_FOCUS:
10156 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10970 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10157 case ScriptBaseClass.CAMERA_POSITION: 10971 case ScriptBaseClass.CAMERA_POSITION:
@@ -10256,19 +11070,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10256 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11070 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10257 { 11071 {
10258 m_host.AddScriptLPS(1); 11072 m_host.AddScriptLPS(1);
10259 string ret = String.Empty; 11073
10260 string src1 = llBase64ToString(str1); 11074 if (str1 == String.Empty)
10261 string src2 = llBase64ToString(str2); 11075 return String.Empty;
10262 int c = 0; 11076 if (str2 == String.Empty)
10263 for (int i = 0; i < src1.Length; i++) 11077 return str1;
11078
11079 int len = str2.Length;
11080 if ((len % 4) != 0) // LL is EVIL!!!!
11081 {
11082 while (str2.EndsWith("="))
11083 str2 = str2.Substring(0, str2.Length - 1);
11084
11085 len = str2.Length;
11086 int mod = len % 4;
11087
11088 if (mod == 1)
11089 str2 = str2.Substring(0, str2.Length - 1);
11090 else if (mod == 2)
11091 str2 += "==";
11092 else if (mod == 3)
11093 str2 += "=";
11094 }
11095
11096 byte[] data1;
11097 byte[] data2;
11098 try
11099 {
11100 data1 = Convert.FromBase64String(str1);
11101 data2 = Convert.FromBase64String(str2);
11102 }
11103 catch (Exception)
10264 { 11104 {
10265 ret += (char) (src1[i] ^ src2[c]); 11105 return new LSL_String(String.Empty);
11106 }
10266 11107
10267 c++; 11108 byte[] d2 = new Byte[data1.Length];
10268 if (c >= src2.Length) 11109 int pos = 0;
10269 c = 0; 11110
11111 if (data1.Length <= data2.Length)
11112 {
11113 Array.Copy(data2, 0, d2, 0, data1.Length);
10270 } 11114 }
10271 return llStringToBase64(ret); 11115 else
11116 {
11117 while (pos < data1.Length)
11118 {
11119 len = data1.Length - pos;
11120 if (len > data2.Length)
11121 len = data2.Length;
11122
11123 Array.Copy(data2, 0, d2, pos, len);
11124 pos += len;
11125 }
11126 }
11127
11128 for (pos = 0 ; pos < data1.Length ; pos++ )
11129 data1[pos] ^= d2[pos];
11130
11131 return Convert.ToBase64String(data1);
10272 } 11132 }
10273 11133
10274 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11134 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10321,16 +11181,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10321 if (userAgent != null) 11181 if (userAgent != null)
10322 httpHeaders["User-Agent"] = userAgent; 11182 httpHeaders["User-Agent"] = userAgent;
10323 11183
11184 // See if the URL contains any header hacks
11185 string[] urlParts = url.Split(new char[] {'\n'});
11186 if (urlParts.Length > 1)
11187 {
11188 // Iterate the passed headers and parse them
11189 for (int i = 1 ; i < urlParts.Length ; i++ )
11190 {
11191 // The rest of those would be added to the body in SL.
11192 // Let's not do that.
11193 if (urlParts[i] == String.Empty)
11194 break;
11195
11196 // See if this could be a valid header
11197 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11198 if (headerParts.Length != 2)
11199 continue;
11200
11201 string headerName = headerParts[0].Trim();
11202 string headerValue = headerParts[1].Trim();
11203
11204 // Filter out headers that could be used to abuse
11205 // another system or cloak the request
11206 if (headerName.ToLower() == "x-secondlife-shard" ||
11207 headerName.ToLower() == "x-secondlife-object-name" ||
11208 headerName.ToLower() == "x-secondlife-object-key" ||
11209 headerName.ToLower() == "x-secondlife-region" ||
11210 headerName.ToLower() == "x-secondlife-local-position" ||
11211 headerName.ToLower() == "x-secondlife-local-velocity" ||
11212 headerName.ToLower() == "x-secondlife-local-rotation" ||
11213 headerName.ToLower() == "x-secondlife-owner-name" ||
11214 headerName.ToLower() == "x-secondlife-owner-key" ||
11215 headerName.ToLower() == "connection" ||
11216 headerName.ToLower() == "content-length" ||
11217 headerName.ToLower() == "from" ||
11218 headerName.ToLower() == "host" ||
11219 headerName.ToLower() == "proxy-authorization" ||
11220 headerName.ToLower() == "referer" ||
11221 headerName.ToLower() == "trailer" ||
11222 headerName.ToLower() == "transfer-encoding" ||
11223 headerName.ToLower() == "via" ||
11224 headerName.ToLower() == "authorization")
11225 continue;
11226
11227 httpHeaders[headerName] = headerValue;
11228 }
11229
11230 // Finally, strip any protocol specifier from the URL
11231 url = urlParts[0].Trim();
11232 int idx = url.IndexOf(" HTTP/");
11233 if (idx != -1)
11234 url = url.Substring(0, idx);
11235 }
11236
10324 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11237 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10325 Regex r = new Regex(authregex); 11238 Regex r = new Regex(authregex);
10326 int[] gnums = r.GetGroupNumbers(); 11239 int[] gnums = r.GetGroupNumbers();
10327 Match m = r.Match(url); 11240 Match m = r.Match(url);
10328 if (m.Success) { 11241 if (m.Success)
10329 for (int i = 1; i < gnums.Length; i++) { 11242 {
11243 for (int i = 1; i < gnums.Length; i++)
11244 {
10330 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11245 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10331 //CaptureCollection cc = g.Captures; 11246 //CaptureCollection cc = g.Captures;
10332 } 11247 }
10333 if (m.Groups.Count == 5) { 11248 if (m.Groups.Count == 5)
11249 {
10334 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11250 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10335 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11251 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10336 } 11252 }
@@ -10533,6 +11449,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10533 11449
10534 LSL_List ret = new LSL_List(); 11450 LSL_List ret = new LSL_List();
10535 UUID key = new UUID(); 11451 UUID key = new UUID();
11452
11453
10536 if (UUID.TryParse(id, out key)) 11454 if (UUID.TryParse(id, out key))
10537 { 11455 {
10538 ScenePresence av = World.GetScenePresence(key); 11456 ScenePresence av = World.GetScenePresence(key);
@@ -10550,13 +11468,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10550 ret.Add(new LSL_String("")); 11468 ret.Add(new LSL_String(""));
10551 break; 11469 break;
10552 case ScriptBaseClass.OBJECT_POS: 11470 case ScriptBaseClass.OBJECT_POS:
10553 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11471 Vector3 avpos;
11472
11473 if (av.ParentID != 0 && av.ParentPart != null)
11474 {
11475 avpos = av.OffsetPosition;
11476
11477 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11478 avpos -= sitOffset;
11479
11480 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11481 }
11482 else
11483 avpos = av.AbsolutePosition;
11484
11485 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10554 break; 11486 break;
10555 case ScriptBaseClass.OBJECT_ROT: 11487 case ScriptBaseClass.OBJECT_ROT:
10556 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11488 Quaternion avrot = av.Rotation;
11489 if (av.ParentID != 0 && av.ParentPart != null)
11490 {
11491 avrot = av.ParentPart.GetWorldRotation() * avrot;
11492 }
11493 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10557 break; 11494 break;
10558 case ScriptBaseClass.OBJECT_VELOCITY: 11495 case ScriptBaseClass.OBJECT_VELOCITY:
10559 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11496 Vector3 avvel = av.Velocity;
11497 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10560 break; 11498 break;
10561 case ScriptBaseClass.OBJECT_OWNER: 11499 case ScriptBaseClass.OBJECT_OWNER:
10562 ret.Add(new LSL_String(id)); 11500 ret.Add(new LSL_String(id));
@@ -10641,11 +11579,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10641 case ScriptBaseClass.OBJECT_NAME: 11579 case ScriptBaseClass.OBJECT_NAME:
10642 ret.Add(new LSL_String(obj.Name)); 11580 ret.Add(new LSL_String(obj.Name));
10643 break; 11581 break;
10644 case ScriptBaseClass.OBJECT_DESC: 11582 case ScriptBaseClass.OBJECT_DESC:
10645 ret.Add(new LSL_String(obj.Description)); 11583 ret.Add(new LSL_String(obj.Description));
10646 break; 11584 break;
10647 case ScriptBaseClass.OBJECT_POS: 11585 case ScriptBaseClass.OBJECT_POS:
10648 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11586 Vector3 opos = obj.AbsolutePosition;
11587 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10649 break; 11588 break;
10650 case ScriptBaseClass.OBJECT_ROT: 11589 case ScriptBaseClass.OBJECT_ROT:
10651 { 11590 {
@@ -10695,9 +11634,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10695 // The value returned in SL for normal prims is prim count 11634 // The value returned in SL for normal prims is prim count
10696 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11635 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10697 break; 11636 break;
10698 // The following 3 costs I have intentionaly coded to return zero. They are part of 11637
10699 // "Land Impact" calculations. These calculations are probably not applicable 11638 // costs below may need to be diferent for root parts, need to check
10700 // to OpenSim and are not yet complete in SL
10701 case ScriptBaseClass.OBJECT_SERVER_COST: 11639 case ScriptBaseClass.OBJECT_SERVER_COST:
10702 // The linden calculation is here 11640 // The linden calculation is here
10703 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11641 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10705,16 +11643,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10705 ret.Add(new LSL_Float(0)); 11643 ret.Add(new LSL_Float(0));
10706 break; 11644 break;
10707 case ScriptBaseClass.OBJECT_STREAMING_COST: 11645 case ScriptBaseClass.OBJECT_STREAMING_COST:
10708 // The linden calculation is here 11646 // The value returned in SL for normal prims is prim count * 0.06
10709 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11647 ret.Add(new LSL_Float(obj.StreamingCost));
10710 // The value returned in SL for normal prims looks like the prim count * 0.06
10711 ret.Add(new LSL_Float(0));
10712 break; 11648 break;
10713 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11649 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10714 // The linden calculation is here 11650 // The value returned in SL for normal prims is prim count
10715 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11651 ret.Add(new LSL_Float(obj.PhysicsCost));
10716 // The value returned in SL for normal prims looks like the prim count
10717 ret.Add(new LSL_Float(0));
10718 break; 11652 break;
10719 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11653 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10720 ret.Add(new LSL_Float(0)); 11654 ret.Add(new LSL_Float(0));
@@ -10971,15 +11905,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10971 return result; 11905 return result;
10972 } 11906 }
10973 11907
10974 public void print(string str) 11908 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10975 { 11909 {
10976 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11910 List<SceneObjectPart> parts = GetLinkParts(link);
10977 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11911 if (parts.Count < 1)
10978 if (ossl != null) 11912 return 0;
10979 { 11913
10980 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11914 return GetNumberOfSides(parts[0]);
10981 m_log.Info("LSL print():" + str);
10982 }
10983 } 11915 }
10984 11916
10985 private string Name2Username(string name) 11917 private string Name2Username(string name)
@@ -11024,7 +11956,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11024 11956
11025 return rq.ToString(); 11957 return rq.ToString();
11026 } 11958 }
11027 11959/*
11960 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11961 {
11962 m_SayShoutCount = 0;
11963 }
11964*/
11028 private struct Tri 11965 private struct Tri
11029 { 11966 {
11030 public Vector3 p1; 11967 public Vector3 p1;
@@ -11164,9 +12101,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11164 12101
11165 ContactResult result = new ContactResult (); 12102 ContactResult result = new ContactResult ();
11166 result.ConsumerID = group.LocalId; 12103 result.ConsumerID = group.LocalId;
11167 result.Depth = intersection.distance; 12104// result.Depth = intersection.distance;
11168 result.Normal = intersection.normal; 12105 result.Normal = intersection.normal;
11169 result.Pos = intersection.ipoint; 12106 result.Pos = intersection.ipoint;
12107 result.Depth = Vector3.Mag(rayStart - result.Pos);
11170 12108
11171 contacts.Add(result); 12109 contacts.Add(result);
11172 }); 12110 });
@@ -11299,6 +12237,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11299 12237
11300 return contacts[0]; 12238 return contacts[0];
11301 } 12239 }
12240/*
12241 // not done:
12242 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12243 {
12244 ContactResult[] contacts = null;
12245 World.ForEachSOG(delegate(SceneObjectGroup group)
12246 {
12247 if (m_host.ParentGroup == group)
12248 return;
12249
12250 if (group.IsAttachment)
12251 return;
12252
12253 if(group.RootPart.PhysActor != null)
12254 return;
12255
12256 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12257 });
12258 return contacts;
12259 }
12260*/
11302 12261
11303 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12262 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11304 { 12263 {
@@ -11340,32 +12299,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11340 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12299 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11341 12300
11342 12301
11343 if (checkTerrain) 12302 if (World.SuportsRayCastFiltered())
11344 { 12303 {
11345 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12304 if (dist == 0)
11346 if (groundContact != null) 12305 return list;
11347 results.Add((ContactResult)groundContact);
11348 }
11349 12306
11350 if (checkAgents) 12307 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11351 { 12308 if (checkTerrain)
11352 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12309 rayfilter |= RayFilterFlags.land;
11353 foreach (ContactResult r in agentHits) 12310// if (checkAgents)
11354 results.Add(r); 12311// rayfilter |= RayFilterFlags.agent;
11355 } 12312 if (checkPhysical)
12313 rayfilter |= RayFilterFlags.physical;
12314 if (checkNonPhysical)
12315 rayfilter |= RayFilterFlags.nonphysical;
12316 if (detectPhantom)
12317 rayfilter |= RayFilterFlags.LSLPhanton;
11356 12318
11357 if (checkPhysical || checkNonPhysical || detectPhantom) 12319 Vector3 direction = dir * ( 1/dist);
12320
12321 if(rayfilter == 0)
12322 {
12323 list.Add(new LSL_Integer(0));
12324 return list;
12325 }
12326
12327 // get some more contacts to sort ???
12328 int physcount = 4 * count;
12329 if (physcount > 20)
12330 physcount = 20;
12331
12332 object physresults;
12333 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12334
12335 if (physresults == null)
12336 {
12337 list.Add(new LSL_Integer(-3)); // timeout error
12338 return list;
12339 }
12340
12341 results = (List<ContactResult>)physresults;
12342
12343 // for now physics doesn't detect sitted avatars so do it outside physics
12344 if (checkAgents)
12345 {
12346 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12347 foreach (ContactResult r in agentHits)
12348 results.Add(r);
12349 }
12350
12351 // TODO: Replace this with a better solution. ObjectIntersection can only
12352 // detect nonphysical phantoms. They are detected by virtue of being
12353 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12354 // physicsl phantoms as done by the physics scene
12355 // We don't want anything else but phantoms here.
12356 if (detectPhantom)
12357 {
12358 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12359 foreach (ContactResult r in objectHits)
12360 results.Add(r);
12361 }
12362 }
12363 else
11358 { 12364 {
11359 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12365 if (checkTerrain)
11360 foreach (ContactResult r in objectHits) 12366 {
11361 results.Add(r); 12367 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12368 if (groundContact != null)
12369 results.Add((ContactResult)groundContact);
12370 }
12371
12372 if (checkAgents)
12373 {
12374 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12375 foreach (ContactResult r in agentHits)
12376 results.Add(r);
12377 }
12378
12379 if (checkPhysical || checkNonPhysical || detectPhantom)
12380 {
12381 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12382 foreach (ContactResult r in objectHits)
12383 results.Add(r);
12384 }
11362 } 12385 }
11363 12386
11364 results.Sort(delegate(ContactResult a, ContactResult b) 12387 results.Sort(delegate(ContactResult a, ContactResult b)
11365 { 12388 {
11366 return a.Depth.CompareTo(b.Depth); 12389 return a.Depth.CompareTo(b.Depth);
11367 }); 12390 });
11368 12391
11369 int values = 0; 12392 int values = 0;
11370 SceneObjectGroup thisgrp = m_host.ParentGroup; 12393 SceneObjectGroup thisgrp = m_host.ParentGroup;
11371 12394
@@ -11458,7 +12481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11458 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12481 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11459 if (!isAccount) return 0; 12482 if (!isAccount) return 0;
11460 if (estate.HasAccess(id)) return 1; 12483 if (estate.HasAccess(id)) return 1;
11461 if (estate.IsBanned(id)) 12484 if (estate.IsBanned(id, World.GetUserFlags(id)))
11462 estate.RemoveBan(id); 12485 estate.RemoveBan(id);
11463 estate.AddEstateUser(id); 12486 estate.AddEstateUser(id);
11464 break; 12487 break;
@@ -11477,14 +12500,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11477 break; 12500 break;
11478 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12501 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11479 if (!isAccount) return 0; 12502 if (!isAccount) return 0;
11480 if (estate.IsBanned(id)) return 1; 12503 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11481 EstateBan ban = new EstateBan(); 12504 EstateBan ban = new EstateBan();
11482 ban.EstateID = estate.EstateID; 12505 ban.EstateID = estate.EstateID;
11483 ban.BannedUserID = id; 12506 ban.BannedUserID = id;
11484 estate.AddBan(ban); 12507 estate.AddBan(ban);
11485 break; 12508 break;
11486 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12509 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11487 if (!isAccount || !estate.IsBanned(id)) return 0; 12510 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11488 estate.RemoveBan(id); 12511 estate.RemoveBan(id);
11489 break; 12512 break;
11490 default: return 0; 12513 default: return 0;
@@ -11513,7 +12536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11513 return 16384; 12536 return 16384;
11514 } 12537 }
11515 12538
11516 public LSL_Integer llGetUsedMemory() 12539 public virtual LSL_Integer llGetUsedMemory()
11517 { 12540 {
11518 m_host.AddScriptLPS(1); 12541 m_host.AddScriptLPS(1);
11519 // The value returned for LSO scripts in SL 12542 // The value returned for LSO scripts in SL
@@ -11541,19 +12564,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11541 public void llSetSoundQueueing(int queue) 12564 public void llSetSoundQueueing(int queue)
11542 { 12565 {
11543 m_host.AddScriptLPS(1); 12566 m_host.AddScriptLPS(1);
11544 NotImplemented("llSetSoundQueueing");
11545 } 12567 }
11546 12568
11547 public void llCollisionSprite(string impact_sprite) 12569 public void llCollisionSprite(string impact_sprite)
11548 { 12570 {
11549 m_host.AddScriptLPS(1); 12571 m_host.AddScriptLPS(1);
11550 NotImplemented("llCollisionSprite"); 12572 // Viewer 2.0 broke this and it's likely LL has no intention
12573 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11551 } 12574 }
11552 12575
11553 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12576 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11554 { 12577 {
11555 m_host.AddScriptLPS(1); 12578 m_host.AddScriptLPS(1);
11556 NotImplemented("llGodLikeRezObject"); 12579
12580 if (!World.Permissions.IsGod(m_host.OwnerID))
12581 NotImplemented("llGodLikeRezObject");
12582
12583 AssetBase rezAsset = World.AssetService.Get(inventory);
12584 if (rezAsset == null)
12585 {
12586 llSay(0, "Asset not found");
12587 return;
12588 }
12589
12590 SceneObjectGroup group = null;
12591
12592 try
12593 {
12594 string xmlData = Utils.BytesToString(rezAsset.Data);
12595 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12596 }
12597 catch
12598 {
12599 llSay(0, "Asset not found");
12600 return;
12601 }
12602
12603 if (group == null)
12604 {
12605 llSay(0, "Asset not found");
12606 return;
12607 }
12608
12609 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12610 group.RootPart.AttachOffset = group.AbsolutePosition;
12611
12612 group.ResetIDs();
12613
12614 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12615 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12616 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12617 group.ScheduleGroupForFullUpdate();
12618
12619 // objects rezzed with this method are die_at_edge by default.
12620 group.RootPart.SetDieAtEdge(true);
12621
12622 group.ResumeScripts();
12623
12624 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12625 "object_rez", new Object[] {
12626 new LSL_String(
12627 group.RootPart.UUID.ToString()) },
12628 new DetectParams[0]));
11557 } 12629 }
11558 12630
11559 public LSL_String llTransferLindenDollars(string destination, int amount) 12631 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11605,7 +12677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11605 } 12677 }
11606 12678
11607 bool result = money.ObjectGiveMoney( 12679 bool result = money.ObjectGiveMoney(
11608 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12680 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11609 12681
11610 if (result) 12682 if (result)
11611 { 12683 {
@@ -11630,6 +12702,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11630 } 12702 }
11631 12703
11632 #endregion 12704 #endregion
12705
12706 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12707 {
12708 SceneObjectGroup group = m_host.ParentGroup;
12709
12710 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12711 return;
12712 if (group.IsAttachment)
12713 return;
12714
12715 if (frames.Data.Length > 0) // We are getting a new motion
12716 {
12717 if (group.RootPart.KeyframeMotion != null)
12718 group.RootPart.KeyframeMotion.Delete();
12719 group.RootPart.KeyframeMotion = null;
12720
12721 int idx = 0;
12722
12723 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12724 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12725
12726 while (idx < options.Data.Length)
12727 {
12728 int option = (int)options.GetLSLIntegerItem(idx++);
12729 int remain = options.Data.Length - idx;
12730
12731 switch (option)
12732 {
12733 case ScriptBaseClass.KFM_MODE:
12734 if (remain < 1)
12735 break;
12736 int modeval = (int)options.GetLSLIntegerItem(idx++);
12737 switch(modeval)
12738 {
12739 case ScriptBaseClass.KFM_FORWARD:
12740 mode = KeyframeMotion.PlayMode.Forward;
12741 break;
12742 case ScriptBaseClass.KFM_REVERSE:
12743 mode = KeyframeMotion.PlayMode.Reverse;
12744 break;
12745 case ScriptBaseClass.KFM_LOOP:
12746 mode = KeyframeMotion.PlayMode.Loop;
12747 break;
12748 case ScriptBaseClass.KFM_PING_PONG:
12749 mode = KeyframeMotion.PlayMode.PingPong;
12750 break;
12751 }
12752 break;
12753 case ScriptBaseClass.KFM_DATA:
12754 if (remain < 1)
12755 break;
12756 int dataval = (int)options.GetLSLIntegerItem(idx++);
12757 data = (KeyframeMotion.DataFormat)dataval;
12758 break;
12759 }
12760 }
12761
12762 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12763
12764 idx = 0;
12765
12766 int elemLength = 2;
12767 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12768 elemLength = 3;
12769
12770 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12771 while (idx < frames.Data.Length)
12772 {
12773 int remain = frames.Data.Length - idx;
12774
12775 if (remain < elemLength)
12776 break;
12777
12778 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12779 frame.Position = null;
12780 frame.Rotation = null;
12781
12782 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12783 {
12784 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12785 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12786 }
12787 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12788 {
12789 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12790 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12791 q.Normalize();
12792 frame.Rotation = q;
12793 }
12794
12795 float tempf = (float)frames.GetLSLFloatItem(idx++);
12796 frame.TimeMS = (int)(tempf * 1000.0f);
12797
12798 keyframes.Add(frame);
12799 }
12800
12801 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12802 group.RootPart.KeyframeMotion.Start();
12803 }
12804 else
12805 {
12806 if (group.RootPart.KeyframeMotion == null)
12807 return;
12808
12809 if (options.Data.Length == 0)
12810 {
12811 group.RootPart.KeyframeMotion.Stop();
12812 return;
12813 }
12814
12815 int code = (int)options.GetLSLIntegerItem(0);
12816
12817 int idx = 0;
12818
12819 while (idx < options.Data.Length)
12820 {
12821 int option = (int)options.GetLSLIntegerItem(idx++);
12822 int remain = options.Data.Length - idx;
12823
12824 switch (option)
12825 {
12826 case ScriptBaseClass.KFM_COMMAND:
12827 int cmd = (int)options.GetLSLIntegerItem(idx++);
12828 switch (cmd)
12829 {
12830 case ScriptBaseClass.KFM_CMD_PLAY:
12831 group.RootPart.KeyframeMotion.Start();
12832 break;
12833 case ScriptBaseClass.KFM_CMD_STOP:
12834 group.RootPart.KeyframeMotion.Stop();
12835 break;
12836 case ScriptBaseClass.KFM_CMD_PAUSE:
12837 group.RootPart.KeyframeMotion.Pause();
12838 break;
12839 }
12840 break;
12841 }
12842 }
12843 }
12844 }
12845
12846 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12847 {
12848 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12849
12850 int idx = 0;
12851 int idxStart = 0;
12852
12853 bool positionChanged = false;
12854 Vector3 finalPos = Vector3.Zero;
12855
12856 try
12857 {
12858 while (idx < rules.Length)
12859 {
12860 ++rulesParsed;
12861 int code = rules.GetLSLIntegerItem(idx++);
12862
12863 int remain = rules.Length - idx;
12864 idxStart = idx;
12865
12866 switch (code)
12867 {
12868 case (int)ScriptBaseClass.PRIM_POSITION:
12869 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12870 {
12871 if (remain < 1)
12872 return null;
12873
12874 LSL_Vector v;
12875 v = rules.GetVector3Item(idx++);
12876
12877 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12878 if (part == null)
12879 break;
12880
12881 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12882 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12883 if (part.LinkNum > 1)
12884 {
12885 localRot = GetPartLocalRot(part);
12886 localPos = GetPartLocalPos(part);
12887 }
12888
12889 v -= localPos;
12890 v /= localRot;
12891
12892 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12893
12894 v = v + 2 * sitOffset;
12895
12896 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12897 av.SendAvatarDataToAllAgents();
12898
12899 }
12900 break;
12901
12902 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12903 case (int)ScriptBaseClass.PRIM_ROTATION:
12904 {
12905 if (remain < 1)
12906 return null;
12907
12908 LSL_Rotation r;
12909 r = rules.GetQuaternionItem(idx++);
12910
12911 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12912 if (part == null)
12913 break;
12914
12915 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12916 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12917
12918 if (part.LinkNum > 1)
12919 localRot = GetPartLocalRot(part);
12920
12921 r = r * llGetRootRotation() / localRot;
12922 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12923 av.SendAvatarDataToAllAgents();
12924 }
12925 break;
12926
12927 // parse rest doing nothing but number of parameters error check
12928 case (int)ScriptBaseClass.PRIM_SIZE:
12929 case (int)ScriptBaseClass.PRIM_MATERIAL:
12930 case (int)ScriptBaseClass.PRIM_PHANTOM:
12931 case (int)ScriptBaseClass.PRIM_PHYSICS:
12932 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12933 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12934 case (int)ScriptBaseClass.PRIM_NAME:
12935 case (int)ScriptBaseClass.PRIM_DESC:
12936 if (remain < 1)
12937 return null;
12938 idx++;
12939 break;
12940
12941 case (int)ScriptBaseClass.PRIM_GLOW:
12942 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12943 case (int)ScriptBaseClass.PRIM_TEXGEN:
12944 if (remain < 2)
12945 return null;
12946 idx += 2;
12947 break;
12948
12949 case (int)ScriptBaseClass.PRIM_TYPE:
12950 if (remain < 3)
12951 return null;
12952 code = (int)rules.GetLSLIntegerItem(idx++);
12953 remain = rules.Length - idx;
12954 switch (code)
12955 {
12956 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12957 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12958 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12959 if (remain < 6)
12960 return null;
12961 idx += 6;
12962 break;
12963
12964 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12965 if (remain < 5)
12966 return null;
12967 idx += 5;
12968 break;
12969
12970 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12971 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12972 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12973 if (remain < 11)
12974 return null;
12975 idx += 11;
12976 break;
12977
12978 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12979 if (remain < 2)
12980 return null;
12981 idx += 2;
12982 break;
12983 }
12984 break;
12985
12986 case (int)ScriptBaseClass.PRIM_COLOR:
12987 case (int)ScriptBaseClass.PRIM_TEXT:
12988 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12989 case (int)ScriptBaseClass.PRIM_OMEGA:
12990 if (remain < 3)
12991 return null;
12992 idx += 3;
12993 break;
12994
12995 case (int)ScriptBaseClass.PRIM_TEXTURE:
12996 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12997 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12998 if (remain < 5)
12999 return null;
13000 idx += 5;
13001 break;
13002
13003 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13004 if (remain < 7)
13005 return null;
13006
13007 idx += 7;
13008 break;
13009
13010 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13011 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13012 return null;
13013
13014 return rules.GetSublist(idx, -1);
13015 }
13016 }
13017 }
13018 catch (InvalidCastException e)
13019 {
13020 ShoutError(string.Format(
13021 "{0} error running rule #{1}: arg #{2} ",
13022 originFunc, rulesParsed, idx - idxStart) + e.Message);
13023 }
13024 finally
13025 {
13026 if (positionChanged)
13027 {
13028 av.OffsetPosition = finalPos;
13029// av.SendAvatarDataToAllAgents();
13030 av.SendTerseUpdateToAllClients();
13031 positionChanged = false;
13032 }
13033 }
13034 return null;
13035 }
13036
13037 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13038 {
13039 // avatars case
13040 // replies as SL wiki
13041
13042// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13043 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13044
13045 int idx = 0;
13046 while (idx < rules.Length)
13047 {
13048 int code = (int)rules.GetLSLIntegerItem(idx++);
13049 int remain = rules.Length - idx;
13050
13051 switch (code)
13052 {
13053 case (int)ScriptBaseClass.PRIM_MATERIAL:
13054 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13055 break;
13056
13057 case (int)ScriptBaseClass.PRIM_PHYSICS:
13058 res.Add(new LSL_Integer(0));
13059 break;
13060
13061 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13062 res.Add(new LSL_Integer(0));
13063 break;
13064
13065 case (int)ScriptBaseClass.PRIM_PHANTOM:
13066 res.Add(new LSL_Integer(0));
13067 break;
13068
13069 case (int)ScriptBaseClass.PRIM_POSITION:
13070
13071 Vector3 pos = avatar.OffsetPosition;
13072
13073 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13074 pos -= sitOffset;
13075
13076 if( sitPart != null)
13077 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13078
13079 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13080 break;
13081
13082 case (int)ScriptBaseClass.PRIM_SIZE:
13083 // as in llGetAgentSize above
13084// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13085 Vector3 s = avatar.Appearance.AvatarSize;
13086 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13087
13088 break;
13089
13090 case (int)ScriptBaseClass.PRIM_ROTATION:
13091 Quaternion rot = avatar.Rotation;
13092 if (sitPart != null)
13093 {
13094 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13095 }
13096
13097 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13098 break;
13099
13100 case (int)ScriptBaseClass.PRIM_TYPE:
13101 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13102 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13103 res.Add(new LSL_Vector(0f,1.0f,0f));
13104 res.Add(new LSL_Float(0.0f));
13105 res.Add(new LSL_Vector(0, 0, 0));
13106 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13107 res.Add(new LSL_Vector(0, 0, 0));
13108 break;
13109
13110 case (int)ScriptBaseClass.PRIM_TEXTURE:
13111 if (remain < 1)
13112 return null;
13113
13114 int face = (int)rules.GetLSLIntegerItem(idx++);
13115 if (face == ScriptBaseClass.ALL_SIDES)
13116 {
13117 for (face = 0; face < 21; face++)
13118 {
13119 res.Add(new LSL_String(""));
13120 res.Add(new LSL_Vector(0,0,0));
13121 res.Add(new LSL_Vector(0,0,0));
13122 res.Add(new LSL_Float(0.0));
13123 }
13124 }
13125 else
13126 {
13127 if (face >= 0 && face < 21)
13128 {
13129 res.Add(new LSL_String(""));
13130 res.Add(new LSL_Vector(0,0,0));
13131 res.Add(new LSL_Vector(0,0,0));
13132 res.Add(new LSL_Float(0.0));
13133 }
13134 }
13135 break;
13136
13137 case (int)ScriptBaseClass.PRIM_COLOR:
13138 if (remain < 1)
13139 return null;
13140
13141 face = (int)rules.GetLSLIntegerItem(idx++);
13142
13143 if (face == ScriptBaseClass.ALL_SIDES)
13144 {
13145 for (face = 0; face < 21; face++)
13146 {
13147 res.Add(new LSL_Vector(0,0,0));
13148 res.Add(new LSL_Float(0));
13149 }
13150 }
13151 else
13152 {
13153 res.Add(new LSL_Vector(0,0,0));
13154 res.Add(new LSL_Float(0));
13155 }
13156 break;
13157
13158 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13159 if (remain < 1)
13160 return null;
13161 face = (int)rules.GetLSLIntegerItem(idx++);
13162
13163 if (face == ScriptBaseClass.ALL_SIDES)
13164 {
13165 for (face = 0; face < 21; face++)
13166 {
13167 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13168 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13169 }
13170 }
13171 else
13172 {
13173 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13174 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13175 }
13176 break;
13177
13178 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13179 if (remain < 1)
13180 return null;
13181 face = (int)rules.GetLSLIntegerItem(idx++);
13182
13183 if (face == ScriptBaseClass.ALL_SIDES)
13184 {
13185 for (face = 0; face < 21; face++)
13186 {
13187 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13188 }
13189 }
13190 else
13191 {
13192 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13193 }
13194 break;
13195
13196 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13197 res.Add(new LSL_Integer(0));
13198 res.Add(new LSL_Integer(0));// softness
13199 res.Add(new LSL_Float(0.0f)); // gravity
13200 res.Add(new LSL_Float(0.0f)); // friction
13201 res.Add(new LSL_Float(0.0f)); // wind
13202 res.Add(new LSL_Float(0.0f)); // tension
13203 res.Add(new LSL_Vector(0f,0f,0f));
13204 break;
13205
13206 case (int)ScriptBaseClass.PRIM_TEXGEN:
13207 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13208 if (remain < 1)
13209 return null;
13210 face = (int)rules.GetLSLIntegerItem(idx++);
13211
13212 if (face == ScriptBaseClass.ALL_SIDES)
13213 {
13214 for (face = 0; face < 21; face++)
13215 {
13216 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13217 }
13218 }
13219 else
13220 {
13221 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13222 }
13223 break;
13224
13225 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13226 res.Add(new LSL_Integer(0));
13227 res.Add(new LSL_Vector(0f,0f,0f));
13228 res.Add(new LSL_Float(0f)); // intensity
13229 res.Add(new LSL_Float(0f)); // radius
13230 res.Add(new LSL_Float(0f)); // falloff
13231 break;
13232
13233 case (int)ScriptBaseClass.PRIM_GLOW:
13234 if (remain < 1)
13235 return null;
13236 face = (int)rules.GetLSLIntegerItem(idx++);
13237
13238 if (face == ScriptBaseClass.ALL_SIDES)
13239 {
13240 for (face = 0; face < 21; face++)
13241 {
13242 res.Add(new LSL_Float(0f));
13243 }
13244 }
13245 else
13246 {
13247 res.Add(new LSL_Float(0f));
13248 }
13249 break;
13250
13251 case (int)ScriptBaseClass.PRIM_TEXT:
13252 res.Add(new LSL_String(""));
13253 res.Add(new LSL_Vector(0f,0f,0f));
13254 res.Add(new LSL_Float(1.0f));
13255 break;
13256
13257 case (int)ScriptBaseClass.PRIM_NAME:
13258 res.Add(new LSL_String(avatar.Name));
13259 break;
13260
13261 case (int)ScriptBaseClass.PRIM_DESC:
13262 res.Add(new LSL_String(""));
13263 break;
13264
13265 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13266 Quaternion lrot = avatar.Rotation;
13267
13268 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13269 {
13270 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13271 }
13272 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13273 break;
13274
13275 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13276 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13277 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13278 lpos -= lsitOffset;
13279
13280 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13281 {
13282 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13283 }
13284 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13285 break;
13286
13287 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13288 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13289 return null;
13290
13291 return rules.GetSublist(idx, -1);
13292 }
13293 }
13294
13295 return null;
13296 }
11633 } 13297 }
11634 13298
11635 public class NotecardCache 13299 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 5c0ff1c..10ec34d 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 protected IUrlModule m_UrlModule = null; 144 protected IUrlModule m_UrlModule = null;
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
148 m_ScriptEngine = scriptEngine; 149 m_ScriptEngine = scriptEngine;
149 m_host = host; 150 m_host = host;
150 m_item = item; 151 m_item = item;
152 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
151 153
152 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 154 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
153 155
@@ -211,7 +213,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
211 213
212 internal void OSSLError(string msg) 214 internal void OSSLError(string msg)
213 { 215 {
214 throw new ScriptException("OSSL Runtime Error: " + msg); 216 if (m_debuggerSafe)
217 {
218 OSSLShoutError(msg);
219 }
220 else
221 {
222 throw new ScriptException("OSSL Runtime Error: " + msg);
223 }
215 } 224 }
216 225
217 /// <summary> 226 /// <summary>
@@ -930,18 +939,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 939 if (target != null)
931 { 940 {
932 UUID animID=UUID.Zero; 941 UUID animID=UUID.Zero;
933 lock (m_host.TaskInventory) 942 m_host.TaskInventory.LockItemsForRead(true);
943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 944 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 945 if (inv.Value.Name == animation)
936 { 946 {
937 if (inv.Value.Name == animation) 947 if (inv.Value.Type == (int)AssetType.Animation)
938 { 948 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 949 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 950 }
944 } 951 }
952 m_host.TaskInventory.LockItemsForRead(false);
945 if (animID == UUID.Zero) 953 if (animID == UUID.Zero)
946 target.Animator.AddAnimation(animation, m_host.UUID); 954 target.Animator.AddAnimation(animation, m_host.UUID);
947 else 955 else
@@ -982,6 +990,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
982 else 990 else
983 animID = UUID.Zero; 991 animID = UUID.Zero;
984 } 992 }
993 m_host.TaskInventory.LockItemsForRead(false);
985 994
986 if (animID == UUID.Zero) 995 if (animID == UUID.Zero)
987 target.Animator.RemoveAnimation(animation); 996 target.Animator.RemoveAnimation(animation);
@@ -1848,15 +1857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1848 { 1857 {
1849 UUID assetID = UUID.Zero; 1858 UUID assetID = UUID.Zero;
1850 1859
1851 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1860 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1861
1862 if (!notecardNameIsUUID)
1852 { 1863 {
1853 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1864 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1854 {
1855 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1856 {
1857 assetID = item.AssetID;
1858 }
1859 }
1860 } 1865 }
1861 1866
1862 if (assetID == UUID.Zero) 1867 if (assetID == UUID.Zero)
@@ -1867,7 +1872,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1867 AssetBase a = World.AssetService.Get(assetID.ToString()); 1872 AssetBase a = World.AssetService.Get(assetID.ToString());
1868 1873
1869 if (a == null) 1874 if (a == null)
1870 return UUID.Zero; 1875 {
1876 // Whoops, it's still possible here that the notecard name was properly
1877 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1878 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1879 if (assetID == UUID.Zero)
1880 return UUID.Zero;
1881
1882 if (!NotecardCache.IsCached(assetID))
1883 {
1884 a = World.AssetService.Get(assetID.ToString());
1885
1886 if (a == null)
1887 {
1888 return UUID.Zero;
1889 }
1890 }
1891 }
1871 1892
1872 string data = Encoding.UTF8.GetString(a.Data); 1893 string data = Encoding.UTF8.GetString(a.Data);
1873 NotecardCache.Cache(assetID, data); 1894 NotecardCache.Cache(assetID, data);
@@ -1875,6 +1896,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 1896
1876 return assetID; 1897 return assetID;
1877 } 1898 }
1899 protected UUID SearchTaskInventoryForAssetId(string name)
1900 {
1901 UUID assetId = UUID.Zero;
1902 m_host.TaskInventory.LockItemsForRead(true);
1903 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1904 {
1905 if (item.Type == 7 && item.Name == name)
1906 {
1907 assetId = item.AssetID;
1908 }
1909 }
1910 m_host.TaskInventory.LockItemsForRead(false);
1911 return assetId;
1912 }
1878 1913
1879 /// <summary> 1914 /// <summary>
1880 /// Directly get an entire notecard at once. 1915 /// Directly get an entire notecard at once.
@@ -2342,7 +2377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2342 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2377 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2343 m_host.AddScriptLPS(1); 2378 m_host.AddScriptLPS(1);
2344 2379
2345 return NpcCreate(firstname, lastname, position, notecard, false, false); 2380 return NpcCreate(firstname, lastname, position, notecard, true, false);
2346 } 2381 }
2347 2382
2348 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2383 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2353,24 +2388,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2353 return NpcCreate( 2388 return NpcCreate(
2354 firstname, lastname, position, notecard, 2389 firstname, lastname, position, notecard,
2355 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2390 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2356 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2391 false);
2392// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2357 } 2393 }
2358 2394
2359 private LSL_Key NpcCreate( 2395 private LSL_Key NpcCreate(
2360 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2396 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2361 { 2397 {
2398 if (!owned)
2399 OSSLError("Unowned NPCs are unsupported");
2400
2401 string groupTitle = String.Empty;
2402
2403 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2404 return new LSL_Key(UUID.Zero.ToString());
2405
2406 if (firstname != String.Empty || lastname != String.Empty)
2407 {
2408 if (firstname != "Shown outfit:")
2409 groupTitle = "- NPC -";
2410 }
2411
2362 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2412 INPCModule module = World.RequestModuleInterface<INPCModule>();
2363 if (module != null) 2413 if (module != null)
2364 { 2414 {
2365 AvatarAppearance appearance = null; 2415 AvatarAppearance appearance = null;
2366 2416
2367 UUID id; 2417// UUID id;
2368 if (UUID.TryParse(notecard, out id)) 2418// if (UUID.TryParse(notecard, out id))
2369 { 2419// {
2370 ScenePresence clonePresence = World.GetScenePresence(id); 2420// ScenePresence clonePresence = World.GetScenePresence(id);
2371 if (clonePresence != null) 2421// if (clonePresence != null)
2372 appearance = clonePresence.Appearance; 2422// appearance = clonePresence.Appearance;
2373 } 2423// }
2374 2424
2375 if (appearance == null) 2425 if (appearance == null)
2376 { 2426 {
@@ -2378,9 +2428,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2378 2428
2379 if (appearanceSerialized != null) 2429 if (appearanceSerialized != null)
2380 { 2430 {
2381 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2431 try
2382 appearance = new AvatarAppearance(); 2432 {
2383 appearance.Unpack(appearanceOsd); 2433 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2434 appearance = new AvatarAppearance();
2435 appearance.Unpack(appearanceOsd);
2436 }
2437 catch
2438 {
2439 return UUID.Zero.ToString();
2440 }
2384 } 2441 }
2385 else 2442 else
2386 { 2443 {
@@ -2399,6 +2456,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2399 World, 2456 World,
2400 appearance); 2457 appearance);
2401 2458
2459 ScenePresence sp;
2460 if (World.TryGetScenePresence(x, out sp))
2461 {
2462 sp.Grouptitle = groupTitle;
2463 sp.SendAvatarDataToAllAgents();
2464 }
2402 return new LSL_Key(x.ToString()); 2465 return new LSL_Key(x.ToString());
2403 } 2466 }
2404 2467
@@ -2702,16 +2765,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2702 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2765 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2703 m_host.AddScriptLPS(1); 2766 m_host.AddScriptLPS(1);
2704 2767
2705 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2768 ManualResetEvent ev = new ManualResetEvent(false);
2706 if (module != null)
2707 {
2708 UUID npcId = new UUID(npc.m_string);
2709 2769
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2770 Util.FireAndForget(delegate(object x) {
2711 return; 2771 try
2772 {
2773 INPCModule module = World.RequestModuleInterface<INPCModule>();
2774 if (module != null)
2775 {
2776 UUID npcId = new UUID(npc.m_string);
2712 2777
2713 module.DeleteNPC(npcId, World); 2778 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2714 } 2779 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2780 {
2781 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2782 return;
2783 }
2784
2785 module.DeleteNPC(npcId, World);
2786 }
2787 }
2788 finally
2789 {
2790 ev.Set();
2791 }
2792 });
2793 ev.WaitOne();
2715 } 2794 }
2716 2795
2717 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2796 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index dd45406..d3ef378 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.Rotation * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -480,7 +481,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 481 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 482 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 483 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.Rotation * q; 484 if (avatar == null)
485 return sensedEntities;
486 fromRegionPos = avatar.AbsolutePosition;
487 q = avatar.Rotation;
484 } 488 }
485 489
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 490 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 500// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 501// presence.Name, presence.PresenceType, ts.name, ts.type);
498 502
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 503 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 504 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 505 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 506 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 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 4ac179a..8eeb4d2 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,7 +204,6 @@ 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);
@@ -331,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
331 void llSensorRemove(); 332 void llSensorRemove();
332 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
333 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
334 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
335 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
336 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -357,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
357 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
358 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
359 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
361 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
363 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
364 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
366 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
367 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -381,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
381 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
382 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
383 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
384 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
385 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
386 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -424,9 +427,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
424 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
425 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
426 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
427 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
428 432
429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
430 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
431 } 436 }
432} 437}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 51d0581..7eb347e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
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 9bf1a64..da3b31f 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;
@@ -337,6 +337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 338 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 339 public const int CHANGED_ANIMATION = 16384;
340 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 341 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 342 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 343 public const int TYPE_FLOAT = 2;
@@ -660,6 +661,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
660 public const int PRIM_MEDIA_PERM_OWNER = 1; 661 public const int PRIM_MEDIA_PERM_OWNER = 1;
661 public const int PRIM_MEDIA_PERM_GROUP = 2; 662 public const int PRIM_MEDIA_PERM_GROUP = 2;
662 public const int PRIM_MEDIA_PERM_ANYONE = 4; 663 public const int PRIM_MEDIA_PERM_ANYONE = 4;
664
665 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
666 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
667 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
668 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
669
670 public const int PRIM_PHYSICS_MATERIAL = 31;
671 public const int DENSITY = 1;
672 public const int FRICTION = 2;
673 public const int RESTITUTION = 4;
674 public const int GRAVITY_MULTIPLIER = 8;
663 675
664 // extra constants for llSetPrimMediaParams 676 // extra constants for llSetPrimMediaParams
665 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 677 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -732,7 +744,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
732 744
733 public static readonly LSLInteger RCERR_UNKNOWN = -1; 745 public static readonly LSLInteger RCERR_UNKNOWN = -1;
734 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 746 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
735 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 747 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
748
749 public const int KFM_MODE = 1;
750 public const int KFM_LOOP = 1;
751 public const int KFM_REVERSE = 3;
752 public const int KFM_FORWARD = 0;
753 public const int KFM_PING_PONG = 2;
754 public const int KFM_DATA = 2;
755 public const int KFM_TRANSLATION = 2;
756 public const int KFM_ROTATION = 1;
757 public const int KFM_COMMAND = 0;
758 public const int KFM_CMD_PLAY = 0;
759 public const int KFM_CMD_STOP = 1;
760 public const int KFM_CMD_PAUSE = 2;
736 761
737 /// <summary> 762 /// <summary>
738 /// process name parameter as regex 763 /// process name parameter as regex
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c7a7cf6..ef71d7b 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();
@@ -1488,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1488 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1489 } 1496 }
1490 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1491 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1492 { 1504 {
1493 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1613,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1613 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1614 } 1626 }
1615 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1616 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1617 { 1634 {
1618 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1628,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1628 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1629 } 1646 }
1630 1647
1631 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1632 {
1633 return m_LSL_Functions.llSetRegionPos(pos);
1634 }
1635
1636 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1637 { 1649 {
1638 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1728,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1728 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1729 } 1741 }
1730 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1731 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1732 { 1749 {
1733 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1978,9 +1995,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1978 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1979 } 1996 }
1980 1997
1981 public void print(string str) 1998 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1999 {
2000 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2001 }
2002
2003 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2004 {
2005 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2006 }
2007
2008 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1982 { 2009 {
1983 m_LSL_Functions.print(str); 2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1984 } 2011 }
1985 } 2012 }
1986} 2013}
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 e02d35e..e44a106 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -120,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
120 Type = 0; 121 Type = 0;
121 Velocity = new LSL_Types.Vector3(); 122 Velocity = new LSL_Types.Vector3();
122 initializeSurfaceTouch(); 123 initializeSurfaceTouch();
124 Country = String.Empty;
123 } 125 }
124 126
125 public UUID Key; 127 public UUID Key;
@@ -151,6 +153,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
151 private int touchFace; 153 private int touchFace;
152 public int TouchFace { get { return touchFace; } } 154 public int TouchFace { get { return touchFace; } }
153 155
156 public string Country;
157
154 // This can be done in two places including the constructor 158 // This can be done in two places including the constructor
155 // so be carefull what gets added here 159 // so be carefull what gets added here
156 private void initializeSurfaceTouch() 160 private void initializeSurfaceTouch()
@@ -198,6 +202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
198 return; 202 return;
199 203
200 Name = presence.Firstname + " " + presence.Lastname; 204 Name = presence.Firstname + " " + presence.Lastname;
205 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
206 if (account != null)
207 Country = account.UserCountry;
208
201 Owner = Key; 209 Owner = Key;
202 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 210 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
203 Rotation = new LSL_Types.Quaternion( 211 Rotation = new LSL_Types.Quaternion(
@@ -207,22 +215,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
207 presence.Rotation.W); 215 presence.Rotation.W);
208 Velocity = new LSL_Types.Vector3(presence.Velocity); 216 Velocity = new LSL_Types.Vector3(presence.Velocity);
209 217
210 if (presence.PresenceType != PresenceType.Npc) 218 Type = 0x01; // Avatar
211 { 219 if (presence.PresenceType == PresenceType.Npc)
212 Type = AGENT; 220 Type = 0x20;
213 } 221
214 else 222 // Cope Impl. We don't use OS_NPC.
215 { 223 //if (presence.PresenceType != PresenceType.Npc)
216 Type = OS_NPC; 224 //{
217 225 // Type = AGENT;
218 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 226 //}
219 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 227 //else
220 228 //{
221 if (npcData.SenseAsAgent) 229 // Type = OS_NPC;
222 { 230
223 Type |= AGENT; 231 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
224 } 232 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
225 } 233
234 // if (npcData.SenseAsAgent)
235 // {
236 // Type |= AGENT;
237 // }
238 //}
226 239
227 if (presence.Velocity != Vector3.Zero) 240 if (presence.Velocity != Vector3.Zero)
228 Type |= ACTIVE; 241 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 75aea2b..a869a6a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -165,13 +166,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
165 166
166 public UUID ItemID { get; private set; } 167 public UUID ItemID { get; private set; }
167 168
168 public UUID ObjectID { get { return Part.UUID; } } 169 public UUID ObjectID { get; private set; }
169 170
170 public uint LocalID { get { return Part.LocalId; } } 171 public uint LocalID { get; private set; }
171 172
172 public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } 173 public UUID RootObjectID { get; private set; }
173 174
174 public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } 175 public uint RootLocalID { get; private set; }
175 176
176 public UUID AssetID { get; private set; } 177 public UUID AssetID { get; private set; }
177 178
@@ -235,8 +236,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
235 StartParam = startParam; 236 StartParam = startParam;
236 m_MaxScriptQueue = maxScriptQueue; 237 m_MaxScriptQueue = maxScriptQueue;
237 m_postOnRez = postOnRez; 238 m_postOnRez = postOnRez;
238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 239 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 240 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
240 241
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") 242 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 { 243 {
@@ -433,27 +434,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
433 PostEvent(new EventParams("attach", 434 PostEvent(new EventParams("attach",
434 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 435 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
435 } 436 }
437
436 } 438 }
437 } 439 }
438 440
439 private void ReleaseControls() 441 private void ReleaseControls()
440 { 442 {
441 int permsMask; 443 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
442 UUID permsGranter; 444
443 lock (Part.TaskInventory) 445 if (part != null)
444 { 446 {
445 if (!Part.TaskInventory.ContainsKey(ItemID)) 447 int permsMask;
448 UUID permsGranter;
449 part.TaskInventory.LockItemsForRead(true);
450 if (!part.TaskInventory.ContainsKey(ItemID))
451 {
452 part.TaskInventory.LockItemsForRead(false);
446 return; 453 return;
454 }
455 permsGranter = part.TaskInventory[ItemID].PermsGranter;
456 permsMask = part.TaskInventory[ItemID].PermsMask;
457 part.TaskInventory.LockItemsForRead(false);
447 458
448 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 459 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
449 permsMask = Part.TaskInventory[ItemID].PermsMask; 460 {
450 } 461 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
451 462 if (presence != null)
452 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 463 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
453 { 464 }
454 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
455 if (presence != null)
456 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
457 } 465 }
458 } 466 }
459 467
@@ -600,6 +608,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
600 return true; 608 return true;
601 } 609 }
602 610
611 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
603 public void SetState(string state) 612 public void SetState(string state)
604 { 613 {
605 if (state == State) 614 if (state == State)
@@ -611,7 +620,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
611 new DetectParams[0])); 620 new DetectParams[0]));
612 PostEvent(new EventParams("state_entry", new Object[0], 621 PostEvent(new EventParams("state_entry", new Object[0],
613 new DetectParams[0])); 622 new DetectParams[0]));
614 623
615 throw new EventAbortException(); 624 throw new EventAbortException();
616 } 625 }
617 626
@@ -701,57 +710,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
701 /// <returns></returns> 710 /// <returns></returns>
702 public object EventProcessor() 711 public object EventProcessor()
703 { 712 {
713 EventParams data = null;
704 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 714 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
705 if (!Running) 715 if (!Running)
706 return 0; 716 return 0;
707 717
708 lock (m_Script)
709 {
710// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 718// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
711 719
712 if (Suspended) 720 if (Suspended)
713 return 0; 721 return 0;
714
715 EventParams data = null;
716 722
717 lock (EventQueue) 723 lock (EventQueue)
724 {
725 data = (EventParams) EventQueue.Dequeue();
726 if (data == null) // Shouldn't happen
718 { 727 {
719 data = (EventParams)EventQueue.Dequeue(); 728 if (EventQueue.Count > 0 && Running && !ShuttingDown)
720 if (data == null) // Shouldn't happen
721 { 729 {
722 if (EventQueue.Count > 0 && Running && !ShuttingDown) 730 m_CurrentWorkItem = Engine.QueueEventHandler(this);
723 {
724 m_CurrentWorkItem = Engine.QueueEventHandler(this);
725 }
726 else
727 {
728 m_CurrentWorkItem = null;
729 }
730 return 0;
731 } 731 }
732 732 else
733 if (data.EventName == "timer")
734 m_TimerQueued = false;
735 if (data.EventName == "control")
736 { 733 {
737 if (m_ControlEventsInQueue > 0) 734 m_CurrentWorkItem = null;
738 m_ControlEventsInQueue--;
739 } 735 }
740 if (data.EventName == "collision") 736 return 0;
741 m_CollisionInQueue = false;
742 } 737 }
743 738
739 if (data.EventName == "timer")
740 m_TimerQueued = false;
741 if (data.EventName == "control")
742 {
743 if (m_ControlEventsInQueue > 0)
744 m_ControlEventsInQueue--;
745 }
746 if (data.EventName == "collision")
747 m_CollisionInQueue = false;
748 }
749
750 lock(m_Script)
751 {
752
753// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
754 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
755
744 if (DebugLevel >= 2) 756 if (DebugLevel >= 2)
745 m_log.DebugFormat( 757 m_log.DebugFormat(
746 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 758 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
747 data.EventName, 759 data.EventName,
748 ScriptName, 760 ScriptName,
749 Part.Name, 761 part.Name,
750 Part.LocalId, 762 part.LocalId,
751 Part.ParentGroup.Name, 763 part.ParentGroup.Name,
752 Part.ParentGroup.UUID, 764 part.ParentGroup.UUID,
753 Part.AbsolutePosition, 765 part.AbsolutePosition,
754 Part.ParentGroup.Scene.Name); 766 part.ParentGroup.Scene.Name);
755 767
756 m_DetectParams = data.DetectParams; 768 m_DetectParams = data.DetectParams;
757 769
@@ -764,17 +776,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
764 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 776 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
765 State, 777 State,
766 ScriptName, 778 ScriptName,
767 Part.Name, 779 part.Name,
768 Part.LocalId, 780 part.LocalId,
769 Part.ParentGroup.Name, 781 part.ParentGroup.Name,
770 Part.ParentGroup.UUID, 782 part.ParentGroup.UUID,
771 Part.AbsolutePosition, 783 part.AbsolutePosition,
772 Part.ParentGroup.Scene.Name); 784 part.ParentGroup.Scene.Name);
773 785
774 AsyncCommandManager.RemoveScript(Engine, 786 AsyncCommandManager.RemoveScript(Engine,
775 LocalID, ItemID); 787 LocalID, ItemID);
776 788
777 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 789 if (part != null)
790 {
791 part.SetScriptEvents(ItemID,
792 (int)m_Script.GetStateEventFlags(State));
793 }
778 } 794 }
779 else 795 else
780 { 796 {
@@ -837,17 +853,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
837 text = text.Substring(0, 1000); 853 text = text.Substring(0, 1000);
838 Engine.World.SimChat(Utils.StringToBytes(text), 854 Engine.World.SimChat(Utils.StringToBytes(text),
839 ChatTypeEnum.DebugChannel, 2147483647, 855 ChatTypeEnum.DebugChannel, 2147483647,
840 Part.AbsolutePosition, 856 part.AbsolutePosition,
841 Part.Name, Part.UUID, false); 857 part.Name, part.UUID, false);
842 858
843 859
844 m_log.DebugFormat( 860 m_log.DebugFormat(
845 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 861 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
846 ScriptName, 862 ScriptName,
847 PrimName, 863 PrimName,
848 Part.UUID, 864 part.UUID,
849 Part.AbsolutePosition, 865 part.AbsolutePosition,
850 Part.ParentGroup.Scene.Name, 866 part.ParentGroup.Scene.Name,
851 text.Replace("\n", "\\n"), 867 text.Replace("\n", "\\n"),
852 e.InnerException); 868 e.InnerException);
853 } 869 }
@@ -867,12 +883,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
867 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 883 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
868 { 884 {
869 m_InSelfDelete = true; 885 m_InSelfDelete = true;
870 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 886 if (part != null)
887 Engine.World.DeleteSceneObject(part.ParentGroup, false);
871 } 888 }
872 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 889 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
873 { 890 {
874 m_InSelfDelete = true; 891 m_InSelfDelete = true;
875 Part.Inventory.RemoveInventoryItem(ItemID); 892 if (part != null)
893 part.Inventory.RemoveInventoryItem(ItemID);
876 } 894 }
877 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 895 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
878 { 896 {
@@ -925,14 +943,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
925 ReleaseControls(); 943 ReleaseControls();
926 944
927 Stop(timeout); 945 Stop(timeout);
928 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 946 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
929 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 947 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
948 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
949 part.CollisionSound = UUID.Zero;
930 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 950 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
931 EventQueue.Clear(); 951 EventQueue.Clear();
932 m_Script.ResetVars(); 952 m_Script.ResetVars();
933 State = "default"; 953 State = "default";
934 954
935 Part.SetScriptEvents(ItemID, 955 part.SetScriptEvents(ItemID,
936 (int)m_Script.GetStateEventFlags(State)); 956 (int)m_Script.GetStateEventFlags(State));
937 if (running) 957 if (running)
938 Start(); 958 Start();
@@ -941,6 +961,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
941 new Object[0], new DetectParams[0])); 961 new Object[0], new DetectParams[0]));
942 } 962 }
943 963
964 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
944 public void ApiResetScript() 965 public void ApiResetScript()
945 { 966 {
946 // bool running = Running; 967 // bool running = Running;
@@ -949,15 +970,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
949 ReleaseControls(); 970 ReleaseControls();
950 971
951 m_Script.ResetVars(); 972 m_Script.ResetVars();
952 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 973 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
953 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 974 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
975 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
976 part.CollisionSound = UUID.Zero;
954 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 977 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
955 978
956 EventQueue.Clear(); 979 EventQueue.Clear();
957 m_Script.ResetVars(); 980 m_Script.ResetVars();
958 State = "default"; 981 State = "default";
959 982
960 Part.SetScriptEvents(ItemID, 983 part.SetScriptEvents(ItemID,
961 (int)m_Script.GetStateEventFlags(State)); 984 (int)m_Script.GetStateEventFlags(State));
962 985
963 if (m_CurrentEvent != "state_entry") 986 if (m_CurrentEvent != "state_entry")
@@ -971,10 +994,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
971 994
972 public Dictionary<string, object> GetVars() 995 public Dictionary<string, object> GetVars()
973 { 996 {
974 if (m_Script != null) 997 return m_Script.GetVars();
975 return m_Script.GetVars();
976 else
977 return new Dictionary<string, object>();
978 } 998 }
979 999
980 public void SetVars(Dictionary<string, object> vars) 1000 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 44fdd1a..2e61fb8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -389,19 +389,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
389 389
390 public override string ToString() 390 public override string ToString()
391 { 391 {
392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 392 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
393 return st; 393 return st;
394 } 394 }
395 395
396 public static explicit operator string(Quaternion r) 396 public static explicit operator string(Quaternion r)
397 { 397 {
398 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 398 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
399 return s; 399 return s;
400 } 400 }
401 401
402 public static explicit operator LSLString(Quaternion r) 402 public static explicit operator LSLString(Quaternion r)
403 { 403 {
404 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 404 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
405 return new LSLString(s); 405 return new LSLString(s);
406 } 406 }
407 407
@@ -521,6 +521,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
521 size += 64; 521 size += 64;
522 else if (o is int) 522 else if (o is int)
523 size += 4; 523 size += 4;
524 else if (o is uint)
525 size += 4;
524 else if (o is string) 526 else if (o is string)
525 size += ((string)o).Length; 527 size += ((string)o).Length;
526 else if (o is float) 528 else if (o is float)
@@ -711,24 +713,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
711 713
712 public static bool operator ==(list a, list b) 714 public static bool operator ==(list a, list b)
713 { 715 {
714 int la = -1; 716 int la = a.Length;
715 int lb = -1; 717 int lb = b.Length;
716 try { la = a.Length; }
717 catch (NullReferenceException) { }
718 try { lb = b.Length; }
719 catch (NullReferenceException) { }
720 718
721 return la == lb; 719 return la == lb;
722 } 720 }
723 721
724 public static bool operator !=(list a, list b) 722 public static bool operator !=(list a, list b)
725 { 723 {
726 int la = -1; 724 int la = a.Length;
727 int lb = -1; 725 int lb = b.Length;
728 try { la = a.Length; }
729 catch (NullReferenceException) { }
730 try {lb = b.Length;}
731 catch (NullReferenceException) { }
732 726
733 return la != lb; 727 return la != lb;
734 } 728 }
@@ -962,7 +956,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
962 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 956 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
963 } 957 }
964 958
965 if (ascending == 0) 959 if (ascending != 1)
966 { 960 {
967 ret = 0 - ret; 961 ret = 0 - ret;
968 } 962 }
@@ -995,6 +989,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
995 stride = 1; 989 stride = 1;
996 } 990 }
997 991
992 if ((Data.Length % stride) != 0)
993 return new list(ret);
994
998 // we can optimize here in the case where stride == 1 and the list 995 // we can optimize here in the case where stride == 1 and the list
999 // consists of homogeneous types 996 // consists of homogeneous types
1000 997
@@ -1014,7 +1011,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1014 if (homogeneous) 1011 if (homogeneous)
1015 { 1012 {
1016 Array.Sort(ret, new HomogeneousComparer()); 1013 Array.Sort(ret, new HomogeneousComparer());
1017 if (ascending == 0) 1014 if (ascending != 1)
1018 { 1015 {
1019 Array.Reverse(ret); 1016 Array.Reverse(ret);
1020 } 1017 }