aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3191
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs105
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs37
18 files changed, 2991 insertions, 898 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 47a9cdc..94fd940 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -305,6 +305,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
305 return null; 305 return null;
306 } 306 }
307 307
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
309 {
310 // Remove a specific script
311
312 // Remove dataserver events
313 m_Dataserver[engine].RemoveEvents(localID, itemID);
314
315 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
316 if (comms != null)
317 comms.DeleteListener(itemID);
318
319 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
320 xmlrpc.DeleteChannels(itemID);
321 xmlrpc.CancelSRDRequests(itemID);
322
323 // Remove Sensors
324 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
325
326 }
327
308 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 328 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
309 { 329 {
310 List<Object> data = new List<Object>(); 330 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 52d96bc..f0d378d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -242,6 +285,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
242 } 285 }
243 } 286 }
244 287
288 public List<ScenePresence> GetLinkAvatars(int linkType)
289 {
290 List<ScenePresence> ret = new List<ScenePresence>();
291 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
292 return ret;
293
294 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
295
296 switch (linkType)
297 {
298 case ScriptBaseClass.LINK_SET:
299 return avs;
300
301 case ScriptBaseClass.LINK_ROOT:
302 return ret;
303
304 case ScriptBaseClass.LINK_ALL_OTHERS:
305 return avs;
306
307 case ScriptBaseClass.LINK_ALL_CHILDREN:
308 return avs;
309
310 case ScriptBaseClass.LINK_THIS:
311 return ret;
312
313 default:
314 if (linkType < 0)
315 return ret;
316
317 int partCount = m_host.ParentGroup.GetPartCount();
318
319 if (linkType <= partCount)
320 {
321 return ret;
322 }
323 else
324 {
325 linkType = linkType - partCount;
326 if (linkType > avs.Count)
327 {
328 return ret;
329 }
330 else
331 {
332 ret.Add(avs[linkType-1]);
333 return ret;
334 }
335 }
336 }
337 }
338
245 public List<SceneObjectPart> GetLinkParts(int linkType) 339 public List<SceneObjectPart> GetLinkParts(int linkType)
246 { 340 {
247 return GetLinkParts(m_host, linkType); 341 return GetLinkParts(m_host, linkType);
@@ -250,6 +344,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 344 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
251 { 345 {
252 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 346 List<SceneObjectPart> ret = new List<SceneObjectPart>();
347 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
348 return ret;
253 ret.Add(part); 349 ret.Add(part);
254 350
255 switch (linkType) 351 switch (linkType)
@@ -440,31 +536,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
440 536
441 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 537 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
442 538
443 /// <summary> 539 // Utility function for llRot2Euler
444 /// Convert an LSL rotation to a Euler vector. 540
445 /// </summary> 541 // normalize an angle between -PI and PI (-180 to +180 degrees)
446 /// <remarks> 542 protected double NormalizeAngle(double angle)
447 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
448 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
449 /// </remarks>
450 /// <param name="r"></param>
451 /// <returns></returns>
452 public LSL_Vector llRot2Euler(LSL_Rotation r)
453 { 543 {
454 m_host.AddScriptLPS(1); 544 if (angle > -Math.PI && angle < Math.PI)
545 return angle;
455 546
456 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 547 int numPis = (int)(Math.PI / angle);
457 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 548 double remainder = angle - Math.PI * numPis;
458 if (m == 0.0) return new LSL_Vector(); 549 if (numPis % 2 == 1)
459 double x = Math.Atan2(-v.y, v.z); 550 return Math.PI - angle;
460 double sin = v.x / m; 551 return remainder;
461 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 552 }
462 double y = Math.Asin(sin);
463 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
464 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)));
465 double z = Math.Atan2(v.y, v.x);
466 553
467 return new LSL_Vector(x, y, z); 554 public LSL_Vector llRot2Euler(LSL_Rotation q1)
555 {
556 m_host.AddScriptLPS(1);
557 LSL_Vector eul = new LSL_Vector();
558
559 double sqw = q1.s*q1.s;
560 double sqx = q1.x*q1.x;
561 double sqy = q1.z*q1.z;
562 double sqz = q1.y*q1.y;
563 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
564 double test = q1.x*q1.z + q1.y*q1.s;
565 if (test > 0.4999*unit) { // singularity at north pole
566 eul.z = 2 * Math.Atan2(q1.x,q1.s);
567 eul.y = Math.PI/2;
568 eul.x = 0;
569 return eul;
570 }
571 if (test < -0.4999*unit) { // singularity at south pole
572 eul.z = -2 * Math.Atan2(q1.x,q1.s);
573 eul.y = -Math.PI/2;
574 eul.x = 0;
575 return eul;
576 }
577 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
578 eul.y = Math.Asin(2*test/unit);
579 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
580 return eul;
468 } 581 }
469 582
470 /* From wiki: 583 /* From wiki:
@@ -517,18 +630,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
517 m_host.AddScriptLPS(1); 630 m_host.AddScriptLPS(1);
518 631
519 double x,y,z,s; 632 double x,y,z,s;
520 633 v.x *= 0.5;
521 double c1 = Math.Cos(v.x * 0.5); 634 v.y *= 0.5;
522 double c2 = Math.Cos(v.y * 0.5); 635 v.z *= 0.5;
523 double c3 = Math.Cos(v.z * 0.5); 636 double c1 = Math.Cos(v.x);
524 double s1 = Math.Sin(v.x * 0.5); 637 double c2 = Math.Cos(v.y);
525 double s2 = Math.Sin(v.y * 0.5); 638 double c1c2 = c1 * c2;
526 double s3 = Math.Sin(v.z * 0.5); 639 double s1 = Math.Sin(v.x);
527 640 double s2 = Math.Sin(v.y);
528 x = s1 * c2 * c3 + c1 * s2 * s3; 641 double s1s2 = s1 * s2;
529 y = c1 * s2 * c3 - s1 * c2 * s3; 642 double c1s2 = c1 * s2;
530 z = s1 * s2 * c3 + c1 * c2 * s3; 643 double s1c2 = s1 * c2;
531 s = c1 * c2 * c3 - s1 * s2 * s3; 644 double c3 = Math.Cos(v.z);
645 double s3 = Math.Sin(v.z);
646
647 x = s1c2 * c3 + c1s2 * s3;
648 y = c1s2 * c3 - s1c2 * s3;
649 z = s1s2 * c3 + c1c2 * s3;
650 s = c1c2 * c3 - s1s2 * s3;
532 651
533 return new LSL_Rotation(x, y, z, s); 652 return new LSL_Rotation(x, y, z, s);
534 } 653 }
@@ -666,77 +785,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
666 { 785 {
667 //A and B should both be normalized 786 //A and B should both be normalized
668 m_host.AddScriptLPS(1); 787 m_host.AddScriptLPS(1);
669 LSL_Rotation rotBetween; 788 /* This method is more accurate than the SL one, and thus causes problems
670 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 789 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
671 // continue calculation. 790
672 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 791 double dotProduct = LSL_Vector.Dot(a, b);
792 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
793 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
794 double angle = Math.Acos(dotProduct / magProduct);
795 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
796 double s = Math.Sin(angle / 2);
797
798 double x = axis.x * s;
799 double y = axis.y * s;
800 double z = axis.z * s;
801 double w = Math.Cos(angle / 2);
802
803 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
804 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
805
806 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
807 */
808
809 // This method mimics the 180 errors found in SL
810 // See www.euclideanspace.com... angleBetween
811 LSL_Vector vec_a = a;
812 LSL_Vector vec_b = b;
813
814 // Eliminate zero length
815 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
816 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
817 if (vec_a_mag < 0.00001 ||
818 vec_b_mag < 0.00001)
673 { 819 {
674 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 820 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
675 } 821 }
676 else 822
823 // Normalize
824 vec_a = llVecNorm(vec_a);
825 vec_b = llVecNorm(vec_b);
826
827 // Calculate axis and rotation angle
828 LSL_Vector axis = vec_a % vec_b;
829 LSL_Float cos_theta = vec_a * vec_b;
830
831 // Check if parallel
832 if (cos_theta > 0.99999)
677 { 833 {
678 a = LSL_Vector.Norm(a); 834 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
679 b = LSL_Vector.Norm(b); 835 }
680 double dotProduct = LSL_Vector.Dot(a, b); 836
681 // There are two degenerate cases possible. These are for vectors 180 or 837 // Check if anti-parallel
682 // 0 degrees apart. These have to be detected and handled individually. 838 else if (cos_theta < -0.99999)
683 // 839 {
684 // Check for vectors 180 degrees apart. 840 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
685 // A dot product of -1 would mean the angle between vectors is 180 degrees. 841 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
686 if (dotProduct < -0.9999999f) 842 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
687 { 843 }
688 // First assume X axis is orthogonal to the vectors. 844 else // other rotation
689 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 845 {
690 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 846 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
691 // Check for near zero vector. A very small non-zero number here will create 847 axis = llVecNorm(axis);
692 // a rotation in an undesired direction. 848 double x, y, z, s, t;
693 if (LSL_Vector.Mag(orthoVector) > 0.0001) 849 s = Math.Cos(theta);
694 { 850 t = Math.Sin(theta);
695 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 851 x = axis.x * t;
696 } 852 y = axis.y * t;
697 // If the magnitude of the vector was near zero, then assume the X axis is not 853 z = axis.z * t;
698 // orthogonal and use the Z axis instead. 854 return new LSL_Rotation(x,y,z,s);
699 else
700 {
701 // Set 180 z rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
703 }
704 }
705 // Check for parallel vectors.
706 // A dot product of 1 would mean the angle between vectors is 0 degrees.
707 else if (dotProduct > 0.9999999f)
708 {
709 // Set zero rotation.
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 }
712 else
713 {
714 // All special checks have been performed so get the axis of rotation.
715 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
716 // Quarternion s value is the length of the unit vector + dot product.
717 double qs = 1.0 + dotProduct;
718 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
719 // Normalize the rotation.
720 double mag = LSL_Rotation.Mag(rotBetween);
721 // We shouldn't have to worry about a divide by zero here. The qs value will be
722 // non-zero because we already know if we're here, then the dotProduct is not -1 so
723 // qs will not be zero. Also, we've already handled the input vectors being zero so the
724 // crossProduct vector should also not be zero.
725 rotBetween.x = rotBetween.x / mag;
726 rotBetween.y = rotBetween.y / mag;
727 rotBetween.z = rotBetween.z / mag;
728 rotBetween.s = rotBetween.s / mag;
729 // Check for undefined values and set zero rotation if any found. This code might not actually be required
730 // any longer since zero vectors are checked for at the top.
731 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
732 {
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 }
736 } 855 }
737 return rotBetween;
738 } 856 }
739 857
740 public void llWhisper(int channelID, string text) 858 public void llWhisper(int channelID, string text)
741 { 859 {
742 m_host.AddScriptLPS(1); 860 m_host.AddScriptLPS(1);
@@ -752,10 +870,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
752 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 870 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
753 } 871 }
754 872
873 private void CheckSayShoutTime()
874 {
875 DateTime now = DateTime.UtcNow;
876 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
877 {
878 m_lastSayShoutCheck = now;
879 m_SayShoutCount = 0;
880 }
881 else
882 m_SayShoutCount++;
883 }
884
755 public void llSay(int channelID, string text) 885 public void llSay(int channelID, string text)
756 { 886 {
757 m_host.AddScriptLPS(1); 887 m_host.AddScriptLPS(1);
758 888
889 if (channelID == 0)
890// m_SayShoutCount++;
891 CheckSayShoutTime();
892
893 if (m_SayShoutCount >= 11)
894 ScriptSleep(2000);
895
759 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 896 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
760 { 897 {
761 Console.WriteLine(text); 898 Console.WriteLine(text);
@@ -778,6 +915,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
778 { 915 {
779 m_host.AddScriptLPS(1); 916 m_host.AddScriptLPS(1);
780 917
918 if (channelID == 0)
919// m_SayShoutCount++;
920 CheckSayShoutTime();
921
922 if (m_SayShoutCount >= 11)
923 ScriptSleep(2000);
924
781 if (text.Length > 1023) 925 if (text.Length > 1023)
782 text = text.Substring(0, 1023); 926 text = text.Substring(0, 1023);
783 927
@@ -809,22 +953,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
809 953
810 public void llRegionSayTo(string target, int channel, string msg) 954 public void llRegionSayTo(string target, int channel, string msg)
811 { 955 {
956 string error = String.Empty;
957
812 if (msg.Length > 1023) 958 if (msg.Length > 1023)
813 msg = msg.Substring(0, 1023); 959 msg = msg.Substring(0, 1023);
814 960
815 m_host.AddScriptLPS(1); 961 m_host.AddScriptLPS(1);
816 962
817 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
818 {
819 return;
820 }
821
822 UUID TargetID; 963 UUID TargetID;
823 UUID.TryParse(target, out TargetID); 964 UUID.TryParse(target, out TargetID);
824 965
825 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 966 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
826 if (wComm != null) 967 if (wComm != null)
827 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 968 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
969 LSLError(error);
828 } 970 }
829 971
830 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 972 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1080,10 +1222,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1080 return detectedParams.TouchUV; 1222 return detectedParams.TouchUV;
1081 } 1223 }
1082 1224
1225 [DebuggerNonUserCode]
1083 public virtual void llDie() 1226 public virtual void llDie()
1084 { 1227 {
1085 m_host.AddScriptLPS(1); 1228 m_host.AddScriptLPS(1);
1086 throw new SelfDeleteException(); 1229 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1087 } 1230 }
1088 1231
1089 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
@@ -1154,6 +1297,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1154 1297
1155 public void llSetStatus(int status, int value) 1298 public void llSetStatus(int status, int value)
1156 { 1299 {
1300 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1301 return;
1157 m_host.AddScriptLPS(1); 1302 m_host.AddScriptLPS(1);
1158 1303
1159 int statusrotationaxis = 0; 1304 int statusrotationaxis = 0;
@@ -1177,6 +1322,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 if (!allow) 1322 if (!allow)
1178 return; 1323 return;
1179 1324
1325 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1326 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1327 return;
1328
1180 m_host.ScriptSetPhysicsStatus(true); 1329 m_host.ScriptSetPhysicsStatus(true);
1181 } 1330 }
1182 else 1331 else
@@ -1376,6 +1525,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1376 { 1525 {
1377 m_host.AddScriptLPS(1); 1526 m_host.AddScriptLPS(1);
1378 1527
1528 SetColor(m_host, color, face);
1529 }
1530
1531 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1532 {
1533 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1534 return;
1535
1536 Primitive.TextureEntry tex = part.Shape.Textures;
1537 Color4 texcolor;
1538 if (face >= 0 && face < GetNumberOfSides(part))
1539 {
1540 texcolor = tex.CreateFace((uint)face).RGBA;
1541 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1542 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1543 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1544 tex.FaceTextures[face].RGBA = texcolor;
1545 part.UpdateTextureEntry(tex.GetBytes());
1546 return;
1547 }
1548 else if (face == ScriptBaseClass.ALL_SIDES)
1549 {
1550 for (uint i = 0; i < GetNumberOfSides(part); i++)
1551 {
1552 if (tex.FaceTextures[i] != null)
1553 {
1554 texcolor = tex.FaceTextures[i].RGBA;
1555 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1556 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1557 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1558 tex.FaceTextures[i].RGBA = texcolor;
1559 }
1560 texcolor = tex.DefaultTexture.RGBA;
1561 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1562 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1563 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1564 tex.DefaultTexture.RGBA = texcolor;
1565 }
1566 part.UpdateTextureEntry(tex.GetBytes());
1567 return;
1568 }
1569
1379 if (face == ScriptBaseClass.ALL_SIDES) 1570 if (face == ScriptBaseClass.ALL_SIDES)
1380 face = SceneObjectPart.ALL_SIDES; 1571 face = SceneObjectPart.ALL_SIDES;
1381 1572
@@ -1384,6 +1575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1384 1575
1385 public void SetTexGen(SceneObjectPart part, int face,int style) 1576 public void SetTexGen(SceneObjectPart part, int face,int style)
1386 { 1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1387 Primitive.TextureEntry tex = part.Shape.Textures; 1581 Primitive.TextureEntry tex = part.Shape.Textures;
1388 MappingType textype; 1582 MappingType textype;
1389 textype = MappingType.Default; 1583 textype = MappingType.Default;
@@ -1414,6 +1608,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1608
1415 public void SetGlow(SceneObjectPart part, int face, float glow) 1609 public void SetGlow(SceneObjectPart part, int face, float glow)
1416 { 1610 {
1611 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return;
1613
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1614 Primitive.TextureEntry tex = part.Shape.Textures;
1418 if (face >= 0 && face < GetNumberOfSides(part)) 1615 if (face >= 0 && face < GetNumberOfSides(part))
1419 { 1616 {
@@ -1439,6 +1636,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1439 1636
1440 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1637 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1441 { 1638 {
1639 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1640 return;
1442 1641
1443 Shininess sval = new Shininess(); 1642 Shininess sval = new Shininess();
1444 1643
@@ -1489,6 +1688,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1489 1688
1490 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1689 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1491 { 1690 {
1691 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1692 return;
1693
1492 Primitive.TextureEntry tex = part.Shape.Textures; 1694 Primitive.TextureEntry tex = part.Shape.Textures;
1493 if (face >= 0 && face < GetNumberOfSides(part)) 1695 if (face >= 0 && face < GetNumberOfSides(part))
1494 { 1696 {
@@ -1549,13 +1751,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1549 m_host.AddScriptLPS(1); 1751 m_host.AddScriptLPS(1);
1550 1752
1551 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1753 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1552 1754 if (parts.Count > 0)
1553 foreach (SceneObjectPart part in parts) 1755 {
1554 SetAlpha(part, alpha, face); 1756 try
1757 {
1758 foreach (SceneObjectPart part in parts)
1759 SetAlpha(part, alpha, face);
1760 }
1761 finally
1762 {
1763 }
1764 }
1555 } 1765 }
1556 1766
1557 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1558 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1559 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1560 Color4 texcolor; 1773 Color4 texcolor;
1561 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1608,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1608 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1609 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1610 { 1823 {
1611 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1612 return; 1825 return;
1613 1826
1614 if (flexi) 1827 if (flexi)
@@ -1642,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1642 /// <param name="falloff"></param> 1855 /// <param name="falloff"></param>
1643 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1856 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1644 { 1857 {
1645 if (part == null) 1858 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1646 return; 1859 return;
1647 1860
1648 if (light) 1861 if (light)
@@ -1675,11 +1888,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1675 Primitive.TextureEntry tex = part.Shape.Textures; 1888 Primitive.TextureEntry tex = part.Shape.Textures;
1676 Color4 texcolor; 1889 Color4 texcolor;
1677 LSL_Vector rgb = new LSL_Vector(); 1890 LSL_Vector rgb = new LSL_Vector();
1891 int nsides = GetNumberOfSides(part);
1892
1678 if (face == ScriptBaseClass.ALL_SIDES) 1893 if (face == ScriptBaseClass.ALL_SIDES)
1679 { 1894 {
1680 int i; 1895 int i;
1681 1896 for (i = 0; i < nsides; i++)
1682 for (i = 0 ; i < GetNumberOfSides(part); i++)
1683 { 1897 {
1684 texcolor = tex.GetFace((uint)i).RGBA; 1898 texcolor = tex.GetFace((uint)i).RGBA;
1685 rgb.x += texcolor.R; 1899 rgb.x += texcolor.R;
@@ -1687,14 +1901,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 rgb.z += texcolor.B; 1901 rgb.z += texcolor.B;
1688 } 1902 }
1689 1903
1690 rgb.x /= (float)GetNumberOfSides(part); 1904 float invnsides = 1.0f / (float)nsides;
1691 rgb.y /= (float)GetNumberOfSides(part); 1905
1692 rgb.z /= (float)GetNumberOfSides(part); 1906 rgb.x *= invnsides;
1907 rgb.y *= invnsides;
1908 rgb.z *= invnsides;
1693 1909
1694 return rgb; 1910 return rgb;
1695 } 1911 }
1696 1912 if (face >= 0 && face < nsides)
1697 if (face >= 0 && face < GetNumberOfSides(part))
1698 { 1913 {
1699 texcolor = tex.GetFace((uint)face).RGBA; 1914 texcolor = tex.GetFace((uint)face).RGBA;
1700 rgb.x = texcolor.R; 1915 rgb.x = texcolor.R;
@@ -1721,15 +1936,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1721 m_host.AddScriptLPS(1); 1936 m_host.AddScriptLPS(1);
1722 1937
1723 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1938 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1724 1939 if (parts.Count > 0)
1725 foreach (SceneObjectPart part in parts) 1940 {
1726 SetTexture(part, texture, face); 1941 try
1727 1942 {
1943 foreach (SceneObjectPart part in parts)
1944 SetTexture(part, texture, face);
1945 }
1946 finally
1947 {
1948 }
1949 }
1728 ScriptSleep(200); 1950 ScriptSleep(200);
1729 } 1951 }
1730 1952
1731 protected void SetTexture(SceneObjectPart part, string texture, int face) 1953 protected void SetTexture(SceneObjectPart part, string texture, int face)
1732 { 1954 {
1955 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1956 return;
1957
1733 UUID textureID = new UUID(); 1958 UUID textureID = new UUID();
1734 1959
1735 textureID = InventoryKey(texture, (int)AssetType.Texture); 1960 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1774,6 +1999,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1999
1775 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2000 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1776 { 2001 {
2002 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2003 return;
2004
1777 Primitive.TextureEntry tex = part.Shape.Textures; 2005 Primitive.TextureEntry tex = part.Shape.Textures;
1778 if (face >= 0 && face < GetNumberOfSides(part)) 2006 if (face >= 0 && face < GetNumberOfSides(part))
1779 { 2007 {
@@ -1810,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1810 2038
1811 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1812 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1813 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1814 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1815 { 2046 {
@@ -1846,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1846 2077
1847 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2078 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1848 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1849 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1850 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1851 { 2085 {
@@ -2016,24 +2250,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2016 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2250 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2017 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2251 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2018 { 2252 {
2019 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2253 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2254 return;
2255
2020 LSL_Vector currentPos = GetPartLocalPos(part); 2256 LSL_Vector currentPos = GetPartLocalPos(part);
2257 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2021 2258
2022 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2023 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2024 2259
2025 if (part.ParentGroup.RootPart == part) 2260 if (part.ParentGroup.RootPart == part)
2026 { 2261 {
2027 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2028 targetPos.z = ground;
2029 SceneObjectGroup parent = part.ParentGroup; 2262 SceneObjectGroup parent = part.ParentGroup;
2030 parent.UpdateGroupPosition(!adjust ? targetPos : 2263 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2031 SetPosAdjust(currentPos, targetPos)); 2264 return;
2265 Util.FireAndForget(delegate(object x) {
2266 parent.UpdateGroupPosition((Vector3)toPos);
2267 });
2032 } 2268 }
2033 else 2269 else
2034 { 2270 {
2035 part.OffsetPosition = !adjust ? targetPos : 2271 part.OffsetPosition = (Vector3)toPos;
2036 SetPosAdjust(currentPos, targetPos);
2037 SceneObjectGroup parent = part.ParentGroup; 2272 SceneObjectGroup parent = part.ParentGroup;
2038 parent.HasGroupChanged = true; 2273 parent.HasGroupChanged = true;
2039 parent.ScheduleGroupForTerseUpdate(); 2274 parent.ScheduleGroupForTerseUpdate();
@@ -2066,13 +2301,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2066 else 2301 else
2067 { 2302 {
2068 if (part.ParentGroup.IsAttachment) 2303 if (part.ParentGroup.IsAttachment)
2069 {
2070 pos = part.AttachedPos; 2304 pos = part.AttachedPos;
2071 }
2072 else 2305 else
2073 {
2074 pos = part.AbsolutePosition; 2306 pos = part.AbsolutePosition;
2075 }
2076 } 2307 }
2077 2308
2078// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2309// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2112,25 +2343,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2112 2343
2113 protected void SetRot(SceneObjectPart part, Quaternion rot) 2344 protected void SetRot(SceneObjectPart part, Quaternion rot)
2114 { 2345 {
2115 part.UpdateRotation(rot); 2346 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2116 // Update rotation does not move the object in the physics scene if it's a linkset. 2347 return;
2117 2348
2118//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2349 bool isroot = (part == part.ParentGroup.RootPart);
2119// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2350 bool isphys;
2120 2351
2121 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2122 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2123 // It's perfectly okay when the object is not an active physical body though.
2124 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2125 // but only if the object is not physial and active. This is important for rotating doors.
2126 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2127 // scene
2128 PhysicsActor pa = part.PhysActor; 2352 PhysicsActor pa = part.PhysActor;
2129 2353
2130 if (pa != null && !pa.IsPhysical) 2354 // keep using physactor ideia of isphysical
2355 // it should be SOP ideia of that
2356 // not much of a issue with ubitODE
2357 if (pa != null && pa.IsPhysical)
2358 isphys = true;
2359 else
2360 isphys = false;
2361
2362 // SL doesn't let scripts rotate root of physical linksets
2363 if (isroot && isphys)
2364 return;
2365
2366 part.UpdateRotation(rot);
2367
2368 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2369 // so do a nasty update of parts positions if is a root part rotation
2370 if (isroot && pa != null) // with if above implies non physical root part
2131 { 2371 {
2132 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2372 part.ParentGroup.ResetChildPrimPhysicsPositions();
2133 } 2373 }
2374 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2375 {
2376 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2377 if (sittingavas.Count > 0)
2378 {
2379 foreach (ScenePresence av in sittingavas)
2380 {
2381 if (isroot || part.LocalId == av.ParentID)
2382 av.SendTerseUpdateToAllClients();
2383 }
2384 }
2385 }
2134 } 2386 }
2135 2387
2136 /// <summary> 2388 /// <summary>
@@ -2178,8 +2430,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2178 2430
2179 public LSL_Rotation llGetLocalRot() 2431 public LSL_Rotation llGetLocalRot()
2180 { 2432 {
2433 return GetPartLocalRot(m_host);
2434 }
2435
2436 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2437 {
2181 m_host.AddScriptLPS(1); 2438 m_host.AddScriptLPS(1);
2182 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2439 Quaternion rot = part.RotationOffset;
2440 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2183 } 2441 }
2184 2442
2185 public void llSetForce(LSL_Vector force, int local) 2443 public void llSetForce(LSL_Vector force, int local)
@@ -2259,16 +2517,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2259 m_host.ApplyImpulse(v, local != 0); 2517 m_host.ApplyImpulse(v, local != 0);
2260 } 2518 }
2261 2519
2520
2262 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2521 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2263 { 2522 {
2264 m_host.AddScriptLPS(1); 2523 m_host.AddScriptLPS(1);
2265 m_host.ApplyAngularImpulse(force, local != 0); 2524 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2266 } 2525 }
2267 2526
2268 public void llSetTorque(LSL_Vector torque, int local) 2527 public void llSetTorque(LSL_Vector torque, int local)
2269 { 2528 {
2270 m_host.AddScriptLPS(1); 2529 m_host.AddScriptLPS(1);
2271 m_host.SetAngularImpulse(torque, local != 0); 2530 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2272 } 2531 }
2273 2532
2274 public LSL_Vector llGetTorque() 2533 public LSL_Vector llGetTorque()
@@ -2285,20 +2544,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2285 llSetTorque(torque, local); 2544 llSetTorque(torque, local);
2286 } 2545 }
2287 2546
2547 public void llSetVelocity(LSL_Vector vel, int local)
2548 {
2549 m_host.AddScriptLPS(1);
2550 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2551 }
2552
2288 public LSL_Vector llGetVel() 2553 public LSL_Vector llGetVel()
2289 { 2554 {
2290 m_host.AddScriptLPS(1); 2555 m_host.AddScriptLPS(1);
2291 2556
2292 Vector3 vel; 2557 Vector3 vel = Vector3.Zero;
2293 2558
2294 if (m_host.ParentGroup.IsAttachment) 2559 if (m_host.ParentGroup.IsAttachment)
2295 { 2560 {
2296 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2561 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2297 vel = avatar.Velocity; 2562 if (avatar != null)
2563 vel = avatar.Velocity;
2298 } 2564 }
2299 else 2565 else
2300 { 2566 {
2301 vel = m_host.Velocity; 2567 vel = m_host.ParentGroup.RootPart.Velocity;
2302 } 2568 }
2303 2569
2304 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2570 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2310,10 +2576,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2310 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2576 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2311 } 2577 }
2312 2578
2579 public void llSetAngularVelocity(LSL_Vector avel, int local)
2580 {
2581 m_host.AddScriptLPS(1);
2582 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2583 }
2584
2313 public LSL_Vector llGetOmega() 2585 public LSL_Vector llGetOmega()
2314 { 2586 {
2315 m_host.AddScriptLPS(1); 2587 m_host.AddScriptLPS(1);
2316 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2588 Vector3 avel = m_host.AngularVelocity;
2589 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2317 } 2590 }
2318 2591
2319 public LSL_Float llGetTimeOfDay() 2592 public LSL_Float llGetTimeOfDay()
@@ -2839,16 +3112,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 new_group.RootPart.UUID.ToString()) }, 3112 new_group.RootPart.UUID.ToString()) },
2840 new DetectParams[0])); 3113 new DetectParams[0]));
2841 3114
2842 float groupmass = new_group.GetMass(); 3115 // do recoil
3116 SceneObjectGroup hostgrp = m_host.ParentGroup;
3117 if (hostgrp == null)
3118 return;
3119
3120 if (hostgrp.IsAttachment) // don't recoil avatars
3121 return;
2843 3122
2844 PhysicsActor pa = new_group.RootPart.PhysActor; 3123 PhysicsActor pa = new_group.RootPart.PhysActor;
2845 3124
2846 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3125 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2847 { 3126 {
2848 //Recoil. 3127 float groupmass = new_group.GetMass();
2849 llApplyImpulse(vel * groupmass, 0); 3128 vel *= -groupmass;
3129 llApplyImpulse(vel, 0);
2850 } 3130 }
2851 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3131 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3132 return;
3133
2852 }); 3134 });
2853 3135
2854 //ScriptSleep((int)((groupmass * velmag) / 10)); 3136 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2863,35 +3145,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2863 public void llLookAt(LSL_Vector target, double strength, double damping) 3145 public void llLookAt(LSL_Vector target, double strength, double damping)
2864 { 3146 {
2865 m_host.AddScriptLPS(1); 3147 m_host.AddScriptLPS(1);
2866 // Determine where we are looking from
2867 LSL_Vector from = llGetPos();
2868 3148
2869 // Work out the normalised vector from the source to the target 3149 // Get the normalized vector to the target
2870 LSL_Vector delta = llVecNorm(target - from); 3150 LSL_Vector d1 = llVecNorm(target - llGetPos());
2871 LSL_Vector angle = new LSL_Vector(0,0,0);
2872 3151
2873 // Calculate the yaw 3152 // Get the bearing (yaw)
2874 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3153 LSL_Vector a1 = new LSL_Vector(0,0,0);
2875 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3154 a1.z = llAtan2(d1.y, d1.x);
2876 3155
2877 // Calculate pitch 3156 // Get the elevation (pitch)
2878 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3157 LSL_Vector a2 = new LSL_Vector(0,0,0);
3158 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2879 3159
2880 // we need to convert from a vector describing 3160 LSL_Rotation r1 = llEuler2Rot(a1);
2881 // the angles of rotation in radians into rotation value 3161 LSL_Rotation r2 = llEuler2Rot(a2);
2882 LSL_Rotation rot = llEuler2Rot(angle); 3162 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2883
2884 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2885 // set the rotation of the object, copy that behavior
2886 PhysicsActor pa = m_host.PhysActor;
2887 3163
2888 if (strength == 0 || pa == null || !pa.IsPhysical) 3164 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2889 { 3165 {
2890 llSetRot(rot); 3166 // Do nothing if either value is 0 (this has been checked in SL)
3167 if (strength <= 0.0 || damping <= 0.0)
3168 return;
3169
3170 llSetRot(r3 * r2 * r1);
2891 } 3171 }
2892 else 3172 else
2893 { 3173 {
2894 m_host.StartLookAt(rot, (float)strength, (float)damping); 3174 if (strength == 0)
3175 {
3176 llSetRot(r3 * r2 * r1);
3177 return;
3178 }
3179
3180 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2895 } 3181 }
2896 } 3182 }
2897 3183
@@ -2937,17 +3223,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 } 3223 }
2938 else 3224 else
2939 { 3225 {
2940 if (m_host.IsRoot) 3226 // new SL always returns object mass
2941 { 3227// if (m_host.IsRoot)
3228// {
2942 return m_host.ParentGroup.GetMass(); 3229 return m_host.ParentGroup.GetMass();
2943 } 3230// }
2944 else 3231// else
2945 { 3232// {
2946 return m_host.GetMass(); 3233// return m_host.GetMass();
2947 } 3234// }
2948 } 3235 }
2949 } 3236 }
2950 3237
3238
3239 public LSL_Float llGetMassMKS()
3240 {
3241 return 100f * llGetMass();
3242 }
3243
2951 public void llCollisionFilter(string name, string id, int accept) 3244 public void llCollisionFilter(string name, string id, int accept)
2952 { 3245 {
2953 m_host.AddScriptLPS(1); 3246 m_host.AddScriptLPS(1);
@@ -2995,8 +3288,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 { 3288 {
2996 // Unregister controls from Presence 3289 // Unregister controls from Presence
2997 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3290 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2998 // Remove Take Control permission.
2999 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3000 } 3291 }
3001 } 3292 }
3002 } 3293 }
@@ -3022,7 +3313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3313 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3023 3314
3024 if (attachmentsModule != null) 3315 if (attachmentsModule != null)
3025 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3316 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3026 else 3317 else
3027 return false; 3318 return false;
3028 } 3319 }
@@ -3052,9 +3343,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3052 { 3343 {
3053 m_host.AddScriptLPS(1); 3344 m_host.AddScriptLPS(1);
3054 3345
3055// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3056// return;
3057
3058 if (m_item.PermsGranter != m_host.OwnerID) 3346 if (m_item.PermsGranter != m_host.OwnerID)
3059 return; 3347 return;
3060 3348
@@ -3097,6 +3385,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3097 3385
3098 public void llInstantMessage(string user, string message) 3386 public void llInstantMessage(string user, string message)
3099 { 3387 {
3388 UUID result;
3389 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3390 {
3391 ShoutError("An invalid key was passed to llInstantMessage");
3392 ScriptSleep(2000);
3393 return;
3394 }
3395
3396
3100 m_host.AddScriptLPS(1); 3397 m_host.AddScriptLPS(1);
3101 3398
3102 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3399 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3111,14 +3408,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 UUID friendTransactionID = UUID.Random(); 3408 UUID friendTransactionID = UUID.Random();
3112 3409
3113 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3410 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3114 3411
3115 GridInstantMessage msg = new GridInstantMessage(); 3412 GridInstantMessage msg = new GridInstantMessage();
3116 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3413 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3117 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3414 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3118 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3415 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3119// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3416// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3120// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3417// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3121 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3418// DateTime dt = DateTime.UtcNow;
3419//
3420// // Ticks from UtcNow, but make it look like local. Evil, huh?
3421// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3422//
3423// try
3424// {
3425// // Convert that to the PST timezone
3426// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3427// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3428// }
3429// catch
3430// {
3431// // No logging here, as it could be VERY spammy
3432// }
3433//
3434// // And make it look local again to fool the unix time util
3435// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3436
3437 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3438
3122 //if (client != null) 3439 //if (client != null)
3123 //{ 3440 //{
3124 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3441 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3132,12 +3449,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 msg.message = message.Substring(0, 1024); 3449 msg.message = message.Substring(0, 1024);
3133 else 3450 else
3134 msg.message = message; 3451 msg.message = message;
3135 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3452 msg.dialog = (byte)19; // MessageFromObject
3136 msg.fromGroup = false;// fromGroup; 3453 msg.fromGroup = false;// fromGroup;
3137 msg.offline = (byte)0; //offline; 3454 msg.offline = (byte)0; //offline;
3138 msg.ParentEstateID = 0; //ParentEstateID; 3455 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3139 msg.Position = new Vector3(m_host.AbsolutePosition); 3456 msg.Position = new Vector3(m_host.AbsolutePosition);
3140 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3457 msg.RegionID = World.RegionInfo.RegionID.Guid;
3141 msg.binaryBucket 3458 msg.binaryBucket
3142 = Util.StringToBytes256( 3459 = Util.StringToBytes256(
3143 "{0}/{1}/{2}/{3}", 3460 "{0}/{1}/{2}/{3}",
@@ -3165,7 +3482,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3165 } 3482 }
3166 3483
3167 emailModule.SendEmail(m_host.UUID, address, subject, message); 3484 emailModule.SendEmail(m_host.UUID, address, subject, message);
3168 llSleep(EMAIL_PAUSE_TIME); 3485 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3169 } 3486 }
3170 3487
3171 public void llGetNextEmail(string address, string subject) 3488 public void llGetNextEmail(string address, string subject)
@@ -3411,7 +3728,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3728 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3729 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3730 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3731 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3732 ScriptBaseClass.PERMISSION_ATTACH;
3733
3415 } 3734 }
3416 else 3735 else
3417 { 3736 {
@@ -3446,11 +3765,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3446 3765
3447 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3766 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3448 { 3767 {
3449 lock (m_host.TaskInventory) 3768 m_host.TaskInventory.LockItemsForWrite(true);
3450 { 3769 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3451 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3770 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3452 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3771 m_host.TaskInventory.LockItemsForWrite(false);
3453 }
3454 3772
3455 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3773 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3456 "run_time_permissions", new Object[] { 3774 "run_time_permissions", new Object[] {
@@ -3493,11 +3811,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 3811
3494 if (!m_waitingForScriptAnswer) 3812 if (!m_waitingForScriptAnswer)
3495 { 3813 {
3496 lock (m_host.TaskInventory) 3814 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3815 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3816 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3499 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3817 m_host.TaskInventory.LockItemsForWrite(false);
3500 }
3501 3818
3502 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3819 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3503 m_waitingForScriptAnswer=true; 3820 m_waitingForScriptAnswer=true;
@@ -3526,14 +3843,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3843 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3527 llReleaseControls(); 3844 llReleaseControls();
3528 3845
3529 lock (m_host.TaskInventory) 3846 m_host.TaskInventory.LockItemsForWrite(true);
3530 { 3847 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3531 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3848 m_host.TaskInventory.LockItemsForWrite(false);
3532 } 3849
3533 3850 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3534 m_ScriptEngine.PostScriptEvent( 3851 "run_time_permissions", new Object[] {
3535 m_item.ItemID, 3852 new LSL_Integer(answer) },
3536 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3853 new DetectParams[0]));
3537 } 3854 }
3538 3855
3539 public LSL_String llGetPermissionsKey() 3856 public LSL_String llGetPermissionsKey()
@@ -3572,14 +3889,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3889 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3573 { 3890 {
3574 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3891 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3575 3892 if (parts.Count > 0)
3576 foreach (SceneObjectPart part in parts) 3893 {
3577 part.SetFaceColorAlpha(face, color, null); 3894 try
3895 {
3896 foreach (SceneObjectPart part in parts)
3897 part.SetFaceColorAlpha(face, color, null);
3898 }
3899 finally
3900 {
3901 }
3902 }
3578 } 3903 }
3579 3904
3580 public void llCreateLink(string target, int parent) 3905 public void llCreateLink(string target, int parent)
3581 { 3906 {
3582 m_host.AddScriptLPS(1); 3907 m_host.AddScriptLPS(1);
3908
3583 UUID targetID; 3909 UUID targetID;
3584 3910
3585 if (!UUID.TryParse(target, out targetID)) 3911 if (!UUID.TryParse(target, out targetID))
@@ -3685,10 +4011,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3685 // Restructuring Multiple Prims. 4011 // Restructuring Multiple Prims.
3686 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4012 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3687 parts.Remove(parentPrim.RootPart); 4013 parts.Remove(parentPrim.RootPart);
3688 foreach (SceneObjectPart part in parts) 4014 if (parts.Count > 0)
3689 { 4015 {
3690 parentPrim.DelinkFromGroup(part.LocalId, true); 4016 try
4017 {
4018 foreach (SceneObjectPart part in parts)
4019 {
4020 parentPrim.DelinkFromGroup(part.LocalId, true);
4021 }
4022 }
4023 finally
4024 {
4025 }
3691 } 4026 }
4027
3692 parentPrim.HasGroupChanged = true; 4028 parentPrim.HasGroupChanged = true;
3693 parentPrim.ScheduleGroupForFullUpdate(); 4029 parentPrim.ScheduleGroupForFullUpdate();
3694 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4030 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3697,12 +4033,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 { 4033 {
3698 SceneObjectPart newRoot = parts[0]; 4034 SceneObjectPart newRoot = parts[0];
3699 parts.Remove(newRoot); 4035 parts.Remove(newRoot);
3700 foreach (SceneObjectPart part in parts) 4036
4037 try
3701 { 4038 {
3702 // Required for linking 4039 foreach (SceneObjectPart part in parts)
3703 part.ClearUpdateSchedule(); 4040 {
3704 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4041 part.ClearUpdateSchedule();
4042 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4043 }
3705 } 4044 }
4045 finally
4046 {
4047 }
4048
4049
3706 newRoot.ParentGroup.HasGroupChanged = true; 4050 newRoot.ParentGroup.HasGroupChanged = true;
3707 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4051 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3708 } 4052 }
@@ -3722,6 +4066,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3722 public void llBreakAllLinks() 4066 public void llBreakAllLinks()
3723 { 4067 {
3724 m_host.AddScriptLPS(1); 4068 m_host.AddScriptLPS(1);
4069
4070 TaskInventoryItem item = m_item;
4071
4072 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4073 && !m_automaticLinkPermission)
4074 {
4075 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4076 return;
4077 }
4078
3725 SceneObjectGroup parentPrim = m_host.ParentGroup; 4079 SceneObjectGroup parentPrim = m_host.ParentGroup;
3726 if (parentPrim.AttachmentPoint != 0) 4080 if (parentPrim.AttachmentPoint != 0)
3727 return; // Fail silently if attached 4081 return; // Fail silently if attached
@@ -3741,25 +4095,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3741 public LSL_String llGetLinkKey(int linknum) 4095 public LSL_String llGetLinkKey(int linknum)
3742 { 4096 {
3743 m_host.AddScriptLPS(1); 4097 m_host.AddScriptLPS(1);
3744 List<UUID> keytable = new List<UUID>();
3745 // parse for sitting avatare-uuids
3746 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3747 {
3748 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3749 keytable.Add(presence.UUID);
3750 });
3751
3752 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3753 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3754 {
3755 return keytable[totalprims - linknum].ToString();
3756 }
3757
3758 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3759 {
3760 return m_host.UUID.ToString();
3761 }
3762
3763 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4098 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3764 if (part != null) 4099 if (part != null)
3765 { 4100 {
@@ -3767,6 +4102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3767 } 4102 }
3768 else 4103 else
3769 { 4104 {
4105 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4106 {
4107 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4108
4109 if (linknum < 0)
4110 return UUID.Zero.ToString();
4111
4112 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4113 if (avatars.Count > linknum)
4114 {
4115 return avatars[linknum].UUID.ToString();
4116 }
4117 }
3770 return UUID.Zero.ToString(); 4118 return UUID.Zero.ToString();
3771 } 4119 }
3772 } 4120 }
@@ -3866,17 +4214,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
3867 int count = 0; 4215 int count = 0;
3868 4216
3869 lock (m_host.TaskInventory) 4217 m_host.TaskInventory.LockItemsForRead(true);
4218 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3870 { 4219 {
3871 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4220 if (inv.Value.Type == type || type == -1)
3872 { 4221 {
3873 if (inv.Value.Type == type || type == -1) 4222 count = count + 1;
3874 {
3875 count = count + 1;
3876 }
3877 } 4223 }
3878 } 4224 }
3879 4225
4226 m_host.TaskInventory.LockItemsForRead(false);
3880 return count; 4227 return count;
3881 } 4228 }
3882 4229
@@ -3885,16 +4232,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3885 m_host.AddScriptLPS(1); 4232 m_host.AddScriptLPS(1);
3886 ArrayList keys = new ArrayList(); 4233 ArrayList keys = new ArrayList();
3887 4234
3888 lock (m_host.TaskInventory) 4235 m_host.TaskInventory.LockItemsForRead(true);
4236 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3889 { 4237 {
3890 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4238 if (inv.Value.Type == type || type == -1)
3891 { 4239 {
3892 if (inv.Value.Type == type || type == -1) 4240 keys.Add(inv.Value.Name);
3893 {
3894 keys.Add(inv.Value.Name);
3895 }
3896 } 4241 }
3897 } 4242 }
4243 m_host.TaskInventory.LockItemsForRead(false);
3898 4244
3899 if (keys.Count == 0) 4245 if (keys.Count == 0)
3900 { 4246 {
@@ -3932,7 +4278,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3932 if (item == null) 4278 if (item == null)
3933 { 4279 {
3934 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4280 llSay(0, String.Format("Could not find object '{0}'", inventory));
3935 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4281 return;
4282// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3936 } 4283 }
3937 4284
3938 UUID objId = item.ItemID; 4285 UUID objId = item.ItemID;
@@ -3960,33 +4307,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3960 return; 4307 return;
3961 } 4308 }
3962 } 4309 }
4310
3963 // destination is an avatar 4311 // destination is an avatar
3964 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4312 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3965 4313
3966 if (agentItem == null) 4314 if (agentItem == null)
3967 return; 4315 return;
3968 4316
3969 if (m_TransferModule != null) 4317 byte[] bucket = new byte[1];
3970 { 4318 bucket[0] = (byte)item.Type;
3971 byte[] bucket = new byte[] { (byte)item.Type }; 4319 //byte[] objBytes = agentItem.ID.GetBytes();
4320 //Array.Copy(objBytes, 0, bucket, 1, 16);
3972 4321
3973 GridInstantMessage msg = new GridInstantMessage(World, 4322 GridInstantMessage msg = new GridInstantMessage(World,
3974 m_host.UUID, m_host.Name + ", an object owned by " + 4323 m_host.OwnerID, m_host.Name, destId,
3975 resolveName(m_host.OwnerID) + ",", destId, 4324 (byte)InstantMessageDialog.TaskInventoryOffered,
3976 (byte)InstantMessageDialog.TaskInventoryOffered, 4325 false, item.Name+". "+m_host.Name+" is located at "+
3977 false, item.Name + "\n" + m_host.Name + " is located at " + 4326 World.RegionInfo.RegionName+" "+
3978 World.RegionInfo.RegionName+" "+ 4327 m_host.AbsolutePosition.ToString(),
3979 m_host.AbsolutePosition.ToString(), 4328 agentItem.ID, true, m_host.AbsolutePosition,
3980 agentItem.ID, true, m_host.AbsolutePosition, 4329 bucket);
3981 bucket);
3982 4330
3983 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4331 ScenePresence sp;
3984 }
3985 4332
4333 if (World.TryGetScenePresence(destId, out sp))
4334 {
4335 sp.ControllingClient.SendInstantMessage(msg);
4336 }
4337 else
4338 {
4339 if (m_TransferModule != null)
4340 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4341 }
4342
4343 //This delay should only occur when giving inventory to avatars.
3986 ScriptSleep(3000); 4344 ScriptSleep(3000);
3987 } 4345 }
3988 } 4346 }
3989 4347
4348 [DebuggerNonUserCode]
3990 public void llRemoveInventory(string name) 4349 public void llRemoveInventory(string name)
3991 { 4350 {
3992 m_host.AddScriptLPS(1); 4351 m_host.AddScriptLPS(1);
@@ -4030,109 +4389,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4030 { 4389 {
4031 m_host.AddScriptLPS(1); 4390 m_host.AddScriptLPS(1);
4032 4391
4033 UUID uuid = (UUID)id; 4392 UUID uuid;
4034 PresenceInfo pinfo = null; 4393 if (UUID.TryParse(id, out uuid))
4035 UserAccount account;
4036
4037 UserInfoCacheEntry ce;
4038 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4039 { 4394 {
4040 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4395 PresenceInfo pinfo = null;
4041 if (account == null) 4396 UserAccount account;
4397
4398 UserInfoCacheEntry ce;
4399 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4042 { 4400 {
4043 m_userInfoCache[uuid] = null; // Cache negative 4401 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4044 return UUID.Zero.ToString(); 4402 if (account == null)
4045 } 4403 {
4404 m_userInfoCache[uuid] = null; // Cache negative
4405 return UUID.Zero.ToString();
4406 }
4046 4407
4047 4408
4048 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4409 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4049 if (pinfos != null && pinfos.Length > 0) 4410 if (pinfos != null && pinfos.Length > 0)
4050 {
4051 foreach (PresenceInfo p in pinfos)
4052 { 4411 {
4053 if (p.RegionID != UUID.Zero) 4412 foreach (PresenceInfo p in pinfos)
4054 { 4413 {
4055 pinfo = p; 4414 if (p.RegionID != UUID.Zero)
4415 {
4416 pinfo = p;
4417 }
4056 } 4418 }
4057 } 4419 }
4058 }
4059 4420
4060 ce = new UserInfoCacheEntry(); 4421 ce = new UserInfoCacheEntry();
4061 ce.time = Util.EnvironmentTickCount(); 4422 ce.time = Util.EnvironmentTickCount();
4062 ce.account = account; 4423 ce.account = account;
4063 ce.pinfo = pinfo; 4424 ce.pinfo = pinfo;
4064 } 4425 m_userInfoCache[uuid] = ce;
4065 else 4426 }
4066 { 4427 else
4067 if (ce == null) 4428 {
4068 return UUID.Zero.ToString(); 4429 if (ce == null)
4430 return UUID.Zero.ToString();
4069 4431
4070 account = ce.account; 4432 account = ce.account;
4071 pinfo = ce.pinfo; 4433 pinfo = ce.pinfo;
4072 } 4434 }
4073 4435
4074 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4436 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4075 {
4076 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4077 if (pinfos != null && pinfos.Length > 0)
4078 { 4437 {
4079 foreach (PresenceInfo p in pinfos) 4438 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4439 if (pinfos != null && pinfos.Length > 0)
4080 { 4440 {
4081 if (p.RegionID != UUID.Zero) 4441 foreach (PresenceInfo p in pinfos)
4082 { 4442 {
4083 pinfo = p; 4443 if (p.RegionID != UUID.Zero)
4444 {
4445 pinfo = p;
4446 }
4084 } 4447 }
4085 } 4448 }
4086 } 4449 else
4087 else 4450 pinfo = null;
4088 pinfo = null;
4089 4451
4090 ce.time = Util.EnvironmentTickCount(); 4452 ce.time = Util.EnvironmentTickCount();
4091 ce.pinfo = pinfo; 4453 ce.pinfo = pinfo;
4092 } 4454 }
4093 4455
4094 string reply = String.Empty; 4456 string reply = String.Empty;
4095 4457
4096 switch (data) 4458 switch (data)
4097 { 4459 {
4098 case 1: // DATA_ONLINE (0|1) 4460 case 1: // DATA_ONLINE (0|1)
4099 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4461 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4100 reply = "1"; 4462 reply = "1";
4101 else 4463 else
4102 reply = "0"; 4464 reply = "0";
4103 break; 4465 break;
4104 case 2: // DATA_NAME (First Last) 4466 case 2: // DATA_NAME (First Last)
4105 reply = account.FirstName + " " + account.LastName; 4467 reply = account.FirstName + " " + account.LastName;
4106 break; 4468 break;
4107 case 3: // DATA_BORN (YYYY-MM-DD) 4469 case 3: // DATA_BORN (YYYY-MM-DD)
4108 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4470 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4109 born = born.AddSeconds(account.Created); 4471 born = born.AddSeconds(account.Created);
4110 reply = born.ToString("yyyy-MM-dd"); 4472 reply = born.ToString("yyyy-MM-dd");
4111 break; 4473 break;
4112 case 4: // DATA_RATING (0,0,0,0,0,0) 4474 case 4: // DATA_RATING (0,0,0,0,0,0)
4113 reply = "0,0,0,0,0,0"; 4475 reply = "0,0,0,0,0,0";
4114 break; 4476 break;
4115 case 7: // DATA_USERLEVEL (integer) 4477 case 8: // DATA_PAYINFO (0|1|2|3)
4116 reply = account.UserLevel.ToString(); 4478 reply = "0";
4117 break; 4479 break;
4118 case 8: // DATA_PAYINFO (0|1|2|3) 4480 default:
4119 reply = "0"; 4481 return UUID.Zero.ToString(); // Raise no event
4120 break; 4482 }
4121 default:
4122 return UUID.Zero.ToString(); // Raise no event
4123 }
4124 4483
4125 UUID rq = UUID.Random(); 4484 UUID rq = UUID.Random();
4126 4485
4127 UUID tid = AsyncCommands. 4486 UUID tid = AsyncCommands.
4128 DataserverPlugin.RegisterRequest(m_host.LocalId, 4487 DataserverPlugin.RegisterRequest(m_host.LocalId,
4129 m_item.ItemID, rq.ToString()); 4488 m_item.ItemID, rq.ToString());
4130 4489
4131 AsyncCommands. 4490 AsyncCommands.
4132 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4491 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4133 4492
4134 ScriptSleep(100); 4493 ScriptSleep(100);
4135 return tid.ToString(); 4494 return tid.ToString();
4495 }
4496 else
4497 {
4498 ShoutError("Invalid UUID passed to llRequestAgentData.");
4499 }
4500 return "";
4136 } 4501 }
4137 4502
4138 public LSL_String llRequestInventoryData(string name) 4503 public LSL_String llRequestInventoryData(string name)
@@ -4189,13 +4554,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4189 if (UUID.TryParse(agent, out agentId)) 4554 if (UUID.TryParse(agent, out agentId))
4190 { 4555 {
4191 ScenePresence presence = World.GetScenePresence(agentId); 4556 ScenePresence presence = World.GetScenePresence(agentId);
4192 if (presence != null) 4557 if (presence != null && presence.PresenceType != PresenceType.Npc)
4193 { 4558 {
4559 // agent must not be a god
4560 if (presence.UserLevel >= 200) return;
4561
4194 // agent must be over the owners land 4562 // agent must be over the owners land
4195 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4563 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4196 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4564 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4197 { 4565 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4566 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4567 {
4568 // They can't be teleported home for some reason
4569 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4570 if (regionInfo != null)
4571 {
4572 World.RequestTeleportLocation(
4573 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4574 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4575 }
4576 }
4199 } 4577 }
4200 } 4578 }
4201 } 4579 }
@@ -4302,7 +4680,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4302 UUID av = new UUID(); 4680 UUID av = new UUID();
4303 if (!UUID.TryParse(agent,out av)) 4681 if (!UUID.TryParse(agent,out av))
4304 { 4682 {
4305 LSLError("First parameter to llDialog needs to be a key"); 4683 //LSLError("First parameter to llDialog needs to be a key");
4306 return; 4684 return;
4307 } 4685 }
4308 4686
@@ -4334,7 +4712,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 public void llCollisionSound(string impact_sound, double impact_volume) 4712 public void llCollisionSound(string impact_sound, double impact_volume)
4335 { 4713 {
4336 m_host.AddScriptLPS(1); 4714 m_host.AddScriptLPS(1);
4337 4715
4716 if(impact_sound == "")
4717 {
4718 m_host.CollisionSoundVolume = (float)impact_volume;
4719 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4720 m_host.CollisionSoundType = 0;
4721 return;
4722 }
4338 // TODO: Parameter check logic required. 4723 // TODO: Parameter check logic required.
4339 UUID soundId = UUID.Zero; 4724 UUID soundId = UUID.Zero;
4340 if (!UUID.TryParse(impact_sound, out soundId)) 4725 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4347,6 +4732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4347 4732
4348 m_host.CollisionSound = soundId; 4733 m_host.CollisionSound = soundId;
4349 m_host.CollisionSoundVolume = (float)impact_volume; 4734 m_host.CollisionSoundVolume = (float)impact_volume;
4735 m_host.CollisionSoundType = 1;
4350 } 4736 }
4351 4737
4352 public LSL_String llGetAnimation(string id) 4738 public LSL_String llGetAnimation(string id)
@@ -4360,14 +4746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4360 4746
4361 if (m_host.RegionHandle == presence.RegionHandle) 4747 if (m_host.RegionHandle == presence.RegionHandle)
4362 { 4748 {
4363 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4364
4365 if (presence != null) 4749 if (presence != null)
4366 { 4750 {
4367 AnimationSet currentAnims = presence.Animator.Animations; 4751 if (presence.SitGround)
4368 string currentAnimationState = String.Empty; 4752 return "Sitting on Ground";
4369 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4753 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4370 return currentAnimationState; 4754 return "Sitting";
4755
4756 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4757 string lslMovementAnimation;
4758
4759 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4760 return lslMovementAnimation;
4371 } 4761 }
4372 } 4762 }
4373 4763
@@ -4514,7 +4904,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4514 { 4904 {
4515 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4905 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4516 float distance_term = distance * distance * distance; // Script Energy 4906 float distance_term = distance * distance * distance; // Script Energy
4517 float pusher_mass = m_host.GetMass(); 4907 // use total object mass and not part
4908 float pusher_mass = m_host.ParentGroup.GetMass();
4518 4909
4519 float PUSH_ATTENUATION_DISTANCE = 17f; 4910 float PUSH_ATTENUATION_DISTANCE = 17f;
4520 float PUSH_ATTENUATION_SCALE = 5f; 4911 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4764,6 +5155,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4764 { 5155 {
4765 return item.AssetID.ToString(); 5156 return item.AssetID.ToString();
4766 } 5157 }
5158 m_host.TaskInventory.LockItemsForRead(false);
4767 5159
4768 return UUID.Zero.ToString(); 5160 return UUID.Zero.ToString();
4769 } 5161 }
@@ -4897,7 +5289,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 public LSL_Vector llGetCenterOfMass() 5289 public LSL_Vector llGetCenterOfMass()
4898 { 5290 {
4899 m_host.AddScriptLPS(1); 5291 m_host.AddScriptLPS(1);
4900 Vector3 center = m_host.GetGeometricCenter(); 5292 Vector3 center = m_host.GetCenterOfMass();
4901 return new LSL_Vector(center.X,center.Y,center.Z); 5293 return new LSL_Vector(center.X,center.Y,center.Z);
4902 } 5294 }
4903 5295
@@ -4916,14 +5308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4916 { 5308 {
4917 m_host.AddScriptLPS(1); 5309 m_host.AddScriptLPS(1);
4918 5310
4919 if (src == null) 5311 return src.Length;
4920 {
4921 return 0;
4922 }
4923 else
4924 {
4925 return src.Length;
4926 }
4927 } 5312 }
4928 5313
4929 public LSL_Integer llList2Integer(LSL_List src, int index) 5314 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4994,7 +5379,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4994 else if (src.Data[index] is LSL_Float) 5379 else if (src.Data[index] is LSL_Float)
4995 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5380 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4996 else if (src.Data[index] is LSL_String) 5381 else if (src.Data[index] is LSL_String)
4997 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5382 {
5383 string str = ((LSL_String) src.Data[index]).m_string;
5384 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5385 if (m != Match.Empty)
5386 {
5387 str = m.Value;
5388 double d = 0.0;
5389 if (!Double.TryParse(str, out d))
5390 return 0.0;
5391
5392 return d;
5393 }
5394 return 0.0;
5395 }
4998 return Convert.ToDouble(src.Data[index]); 5396 return Convert.ToDouble(src.Data[index]);
4999 } 5397 }
5000 catch (FormatException) 5398 catch (FormatException)
@@ -5036,7 +5434,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5036 // for completion and should LSL_Key ever be implemented 5434 // for completion and should LSL_Key ever be implemented
5037 // as it's own struct 5435 // as it's own struct
5038 else if (!(src.Data[index] is LSL_String || 5436 else if (!(src.Data[index] is LSL_String ||
5039 src.Data[index] is LSL_Key)) 5437 src.Data[index] is LSL_Key ||
5438 src.Data[index] is String))
5040 { 5439 {
5041 return ""; 5440 return "";
5042 } 5441 }
@@ -5294,7 +5693,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5294 } 5693 }
5295 } 5694 }
5296 } 5695 }
5297 else { 5696 else
5697 {
5298 object[] array = new object[src.Length]; 5698 object[] array = new object[src.Length];
5299 Array.Copy(src.Data, 0, array, 0, src.Length); 5699 Array.Copy(src.Data, 0, array, 0, src.Length);
5300 result = new LSL_List(array); 5700 result = new LSL_List(array);
@@ -5401,7 +5801,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5401 public LSL_Integer llGetRegionAgentCount() 5801 public LSL_Integer llGetRegionAgentCount()
5402 { 5802 {
5403 m_host.AddScriptLPS(1); 5803 m_host.AddScriptLPS(1);
5404 return new LSL_Integer(World.GetRootAgentCount()); 5804
5805 int count = 0;
5806 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5807 count++;
5808 });
5809
5810 return new LSL_Integer(count);
5405 } 5811 }
5406 5812
5407 public LSL_Vector llGetRegionCorner() 5813 public LSL_Vector llGetRegionCorner()
@@ -5642,6 +6048,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5642 flags |= ScriptBaseClass.AGENT_AWAY; 6048 flags |= ScriptBaseClass.AGENT_AWAY;
5643 } 6049 }
5644 6050
6051 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6052 UUID[] anims = agent.Animator.GetAnimationArray();
6053 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6054 {
6055 flags |= ScriptBaseClass.AGENT_BUSY;
6056 }
6057
5645 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6058 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5646 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6059 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5647 { 6060 {
@@ -5689,6 +6102,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5689 flags |= ScriptBaseClass.AGENT_SITTING; 6102 flags |= ScriptBaseClass.AGENT_SITTING;
5690 } 6103 }
5691 6104
6105 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6106 {
6107 flags |= ScriptBaseClass.AGENT_MALE;
6108 }
6109
5692 return flags; 6110 return flags;
5693 } 6111 }
5694 6112
@@ -5836,9 +6254,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5836 6254
5837 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6255 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5838 6256
5839 foreach (SceneObjectPart part in parts) 6257 try
6258 {
6259 foreach (SceneObjectPart part in parts)
6260 {
6261 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6262 }
6263 }
6264 finally
5840 { 6265 {
5841 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5842 } 6266 }
5843 } 6267 }
5844 6268
@@ -5890,13 +6314,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5890 6314
5891 if (m_host.OwnerID == land.LandData.OwnerID) 6315 if (m_host.OwnerID == land.LandData.OwnerID)
5892 { 6316 {
5893 World.TeleportClientHome(agentID, presence.ControllingClient); 6317 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6318 presence.TeleportWithMomentum(pos, null);
6319 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5894 } 6320 }
5895 } 6321 }
5896 } 6322 }
5897 ScriptSleep(5000); 6323 ScriptSleep(5000);
5898 } 6324 }
5899 6325
6326 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6327 {
6328 return ParseString2List(str, separators, in_spacers, false);
6329 }
6330
5900 public LSL_Integer llOverMyLand(string id) 6331 public LSL_Integer llOverMyLand(string id)
5901 { 6332 {
5902 m_host.AddScriptLPS(1); 6333 m_host.AddScriptLPS(1);
@@ -5955,20 +6386,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5955 return agentSize; 6386 return agentSize;
5956 } 6387 }
5957 6388
5958 public LSL_Integer llSameGroup(string agent) 6389 public LSL_Integer llSameGroup(string id)
5959 { 6390 {
5960 m_host.AddScriptLPS(1); 6391 m_host.AddScriptLPS(1);
5961 UUID agentId = new UUID(); 6392 UUID uuid = new UUID();
5962 if (!UUID.TryParse(agent, out agentId)) 6393 if (!UUID.TryParse(id, out uuid))
5963 return new LSL_Integer(0);
5964 ScenePresence presence = World.GetScenePresence(agentId);
5965 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5966 return new LSL_Integer(0); 6394 return new LSL_Integer(0);
5967 IClientAPI client = presence.ControllingClient; 6395
5968 if (m_host.GroupID == client.ActiveGroupId) 6396 // Check if it's a group key
6397 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5969 return new LSL_Integer(1); 6398 return new LSL_Integer(1);
5970 else 6399
6400 // We got passed a UUID.Zero
6401 if (uuid == UUID.Zero)
5971 return new LSL_Integer(0); 6402 return new LSL_Integer(0);
6403
6404 // Handle the case where id names an avatar
6405 ScenePresence presence = World.GetScenePresence(uuid);
6406 if (presence != null)
6407 {
6408 if (presence.IsChildAgent)
6409 return new LSL_Integer(0);
6410
6411 IClientAPI client = presence.ControllingClient;
6412 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6413 return new LSL_Integer(1);
6414
6415 return new LSL_Integer(0);
6416 }
6417
6418 // Handle object case
6419 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6420 if (part != null)
6421 {
6422 // This will handle both deed and non-deed and also the no
6423 // group case
6424 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6425 return new LSL_Integer(1);
6426
6427 return new LSL_Integer(0);
6428 }
6429
6430 return new LSL_Integer(0);
5972 } 6431 }
5973 6432
5974 public void llUnSit(string id) 6433 public void llUnSit(string id)
@@ -6093,7 +6552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6093 return m_host.ParentGroup.AttachmentPoint; 6552 return m_host.ParentGroup.AttachmentPoint;
6094 } 6553 }
6095 6554
6096 public LSL_Integer llGetFreeMemory() 6555 public virtual LSL_Integer llGetFreeMemory()
6097 { 6556 {
6098 m_host.AddScriptLPS(1); 6557 m_host.AddScriptLPS(1);
6099 // Make scripts designed for LSO happy 6558 // Make scripts designed for LSO happy
@@ -6210,7 +6669,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6210 SetParticleSystem(m_host, rules); 6669 SetParticleSystem(m_host, rules);
6211 } 6670 }
6212 6671
6213 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6672 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6673 {
6214 6674
6215 6675
6216 if (rules.Length == 0) 6676 if (rules.Length == 0)
@@ -6524,6 +6984,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6524 6984
6525 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6985 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6526 { 6986 {
6987 // LSL quaternions can normalize to 0, normal Quaternions can't.
6988 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6989 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6990
6527 part.SitTargetPosition = offset; 6991 part.SitTargetPosition = offset;
6528 part.SitTargetOrientation = rot; 6992 part.SitTargetOrientation = rot;
6529 part.ParentGroup.HasGroupChanged = true; 6993 part.ParentGroup.HasGroupChanged = true;
@@ -6679,13 +7143,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6679 UUID av = new UUID(); 7143 UUID av = new UUID();
6680 if (!UUID.TryParse(avatar,out av)) 7144 if (!UUID.TryParse(avatar,out av))
6681 { 7145 {
6682 LSLError("First parameter to llDialog needs to be a key"); 7146 //LSLError("First parameter to llDialog needs to be a key");
6683 return; 7147 return;
6684 } 7148 }
6685 if (buttons.Length < 1) 7149 if (buttons.Length < 1)
6686 { 7150 {
6687 LSLError("No less than 1 button can be shown"); 7151 buttons.Add("OK");
6688 return;
6689 } 7152 }
6690 if (buttons.Length > 12) 7153 if (buttons.Length > 12)
6691 { 7154 {
@@ -6702,7 +7165,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6702 } 7165 }
6703 if (buttons.Data[i].ToString().Length > 24) 7166 if (buttons.Data[i].ToString().Length > 24)
6704 { 7167 {
6705 LSLError("button label cannot be longer than 24 characters"); 7168 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6706 return; 7169 return;
6707 } 7170 }
6708 buts[i] = buttons.Data[i].ToString(); 7171 buts[i] = buttons.Data[i].ToString();
@@ -6769,9 +7232,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6769 return; 7232 return;
6770 } 7233 }
6771 7234
6772 // the rest of the permission checks are done in RezScript, so check the pin there as well 7235 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6773 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7236 if (dest != null)
7237 {
7238 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7239 {
7240 // the rest of the permission checks are done in RezScript, so check the pin there as well
7241 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6774 7242
7243 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7244 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7245 }
7246 }
6775 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7247 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6776 ScriptSleep(3000); 7248 ScriptSleep(3000);
6777 } 7249 }
@@ -6834,19 +7306,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6834 public LSL_String llMD5String(string src, int nonce) 7306 public LSL_String llMD5String(string src, int nonce)
6835 { 7307 {
6836 m_host.AddScriptLPS(1); 7308 m_host.AddScriptLPS(1);
6837 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7309 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6838 } 7310 }
6839 7311
6840 public LSL_String llSHA1String(string src) 7312 public LSL_String llSHA1String(string src)
6841 { 7313 {
6842 m_host.AddScriptLPS(1); 7314 m_host.AddScriptLPS(1);
6843 return Util.SHA1Hash(src).ToLower(); 7315 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6844 } 7316 }
6845 7317
6846 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7318 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6847 { 7319 {
6848 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7320 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6849 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7321 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7322 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7323 return shapeBlock;
6850 7324
6851 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7325 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6852 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7326 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6951,6 +7425,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 // Prim type box, cylinder and prism. 7425 // Prim type box, cylinder and prism.
6952 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) 7426 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)
6953 { 7427 {
7428 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7429 return;
7430
6954 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7431 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6955 ObjectShapePacket.ObjectDataBlock shapeBlock; 7432 ObjectShapePacket.ObjectDataBlock shapeBlock;
6956 7433
@@ -7004,6 +7481,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7004 // Prim type sphere. 7481 // Prim type sphere.
7005 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7482 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7006 { 7483 {
7484 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7485 return;
7486
7007 ObjectShapePacket.ObjectDataBlock shapeBlock; 7487 ObjectShapePacket.ObjectDataBlock shapeBlock;
7008 7488
7009 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7489 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7045,6 +7525,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7045 // Prim type torus, tube and ring. 7525 // Prim type torus, tube and ring.
7046 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) 7526 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)
7047 { 7527 {
7528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7529 return;
7530
7048 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7531 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7049 ObjectShapePacket.ObjectDataBlock shapeBlock; 7532 ObjectShapePacket.ObjectDataBlock shapeBlock;
7050 7533
@@ -7180,6 +7663,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7180 // Prim type sculpt. 7663 // Prim type sculpt.
7181 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7664 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7182 { 7665 {
7666 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7667 return;
7668
7183 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7669 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7184 UUID sculptId; 7670 UUID sculptId;
7185 7671
@@ -7204,7 +7690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7204 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7690 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7205 { 7691 {
7206 // default 7692 // default
7207 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7693 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7208 } 7694 }
7209 7695
7210 part.Shape.SetSculptProperties((byte)type, sculptId); 7696 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7221,48 +7707,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7221 ScriptSleep(200); 7707 ScriptSleep(200);
7222 } 7708 }
7223 7709
7224 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7710 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7225 { 7711 {
7226 m_host.AddScriptLPS(1); 7712 m_host.AddScriptLPS(1);
7227 7713
7228 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7714 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7229 7715
7230 ScriptSleep(200); 7716 ScriptSleep(200);
7231 } 7717 }
7232 7718
7233 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7719 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7234 { 7720 {
7235 m_host.AddScriptLPS(1); 7721 List<object> parts = new List<object>();
7722 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7723 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7724 foreach (SceneObjectPart p in prims)
7725 parts.Add(p);
7726 foreach (ScenePresence p in avatars)
7727 parts.Add(p);
7236 7728
7237 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7729 LSL_List remaining = null;
7730 uint rulesParsed = 0;
7731
7732 if (parts.Count > 0)
7733 {
7734 foreach (object part in parts)
7735 {
7736 if (part is SceneObjectPart)
7737 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7738 else
7739 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7740 }
7741
7742 while ((object)remaining != null && remaining.Length > 2)
7743 {
7744 linknumber = remaining.GetLSLIntegerItem(0);
7745 rules = remaining.GetSublist(1, -1);
7746 parts.Clear();
7747 prims = GetLinkParts(linknumber);
7748 avatars = GetLinkAvatars(linknumber);
7749 foreach (SceneObjectPart p in prims)
7750 parts.Add(p);
7751 foreach (ScenePresence p in avatars)
7752 parts.Add(p);
7753
7754 remaining = null;
7755 foreach (object part in parts)
7756 {
7757 if (part is SceneObjectPart)
7758 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7759 else
7760 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7761 }
7762 }
7763 }
7238 } 7764 }
7239 7765
7240 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7766 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7767 float material_density, float material_friction,
7768 float material_restitution, float material_gravity_modifier)
7241 { 7769 {
7242 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7770 ExtraPhysicsData physdata = new ExtraPhysicsData();
7771 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7772 physdata.Density = part.Density;
7773 physdata.Friction = part.Friction;
7774 physdata.Bounce = part.Bounciness;
7775 physdata.GravitationModifier = part.GravityModifier;
7243 7776
7244 LSL_List remaining = null; 7777 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7245 uint rulesParsed = 0; 7778 physdata.Density = material_density;
7779 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7780 physdata.Friction = material_friction;
7781 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7782 physdata.Bounce = material_restitution;
7783 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7784 physdata.GravitationModifier = material_gravity_modifier;
7246 7785
7247 foreach (SceneObjectPart part in parts) 7786 part.UpdateExtraPhysics(physdata);
7248 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7787 }
7249 7788
7250 while (remaining != null && remaining.Length > 2) 7789 public void llSetPhysicsMaterial(int material_bits,
7251 { 7790 float material_gravity_modifier, float material_restitution,
7252 linknumber = remaining.GetLSLIntegerItem(0); 7791 float material_friction, float material_density)
7253 rules = remaining.GetSublist(1, -1); 7792 {
7254 parts = GetLinkParts(linknumber); 7793 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7794 }
7255 7795
7256 foreach (SceneObjectPart part in parts) 7796 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7257 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7797 {
7798 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7799 llSetLinkPrimitiveParamsFast(linknumber, rules);
7800 ScriptSleep(200);
7801 }
7802
7803 // vector up using libomv (c&p from sop )
7804 // vector up rotated by r
7805 private Vector3 Zrot(Quaternion r)
7806 {
7807 double x, y, z, m;
7808
7809 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7810 if (Math.Abs(1.0 - m) > 0.000001)
7811 {
7812 m = 1.0 / Math.Sqrt(m);
7813 r.X *= (float)m;
7814 r.Y *= (float)m;
7815 r.Z *= (float)m;
7816 r.W *= (float)m;
7258 } 7817 }
7818
7819 x = 2 * (r.X * r.Z + r.Y * r.W);
7820 y = 2 * (-r.X * r.W + r.Y * r.Z);
7821 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7822
7823 return new Vector3((float)x, (float)y, (float)z);
7259 } 7824 }
7260 7825
7261 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7826 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7262 { 7827 {
7828 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7829 return null;
7830
7263 int idx = 0; 7831 int idx = 0;
7264 int idxStart = 0; 7832 int idxStart = 0;
7265 7833
7834 SceneObjectGroup parentgrp = part.ParentGroup;
7835
7266 bool positionChanged = false; 7836 bool positionChanged = false;
7267 LSL_Vector currentPosition = GetPartLocalPos(part); 7837 LSL_Vector currentPosition = GetPartLocalPos(part);
7268 7838
@@ -7287,8 +7857,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7287 return null; 7857 return null;
7288 7858
7289 v=rules.GetVector3Item(idx++); 7859 v=rules.GetVector3Item(idx++);
7290 positionChanged = true;
7291 currentPosition = GetSetPosTarget(part, v, currentPosition); 7860 currentPosition = GetSetPosTarget(part, v, currentPosition);
7861 positionChanged = true;
7292 7862
7293 break; 7863 break;
7294 case (int)ScriptBaseClass.PRIM_SIZE: 7864 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7565,7 +8135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7565 return null; 8135 return null;
7566 8136
7567 string ph = rules.Data[idx++].ToString(); 8137 string ph = rules.Data[idx++].ToString();
7568 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8138 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7569 8139
7570 break; 8140 break;
7571 8141
@@ -7583,12 +8153,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7583 part.ScriptSetPhysicsStatus(physics); 8153 part.ScriptSetPhysicsStatus(physics);
7584 break; 8154 break;
7585 8155
8156 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8157 if (remain < 1)
8158 return null;
8159
8160 int shape_type = rules.GetLSLIntegerItem(idx++);
8161
8162 ExtraPhysicsData physdata = new ExtraPhysicsData();
8163 physdata.Density = part.Density;
8164 physdata.Bounce = part.Bounciness;
8165 physdata.GravitationModifier = part.GravityModifier;
8166 physdata.PhysShapeType = (PhysShapeType)shape_type;
8167
8168 part.UpdateExtraPhysics(physdata);
8169
8170 break;
8171
8172 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8173 if (remain < 5)
8174 return null;
8175
8176 int material_bits = rules.GetLSLIntegerItem(idx++);
8177 float material_density = (float)rules.GetLSLFloatItem(idx++);
8178 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8179 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8180 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8181
8182 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8183
8184 break;
8185
7586 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8186 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7587 if (remain < 1) 8187 if (remain < 1)
7588 return null; 8188 return null;
7589 string temp = rules.Data[idx++].ToString(); 8189 string temp = rules.Data[idx++].ToString();
7590 8190
7591 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8191 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7592 8192
7593 break; 8193 break;
7594 8194
@@ -7662,7 +8262,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7662 if (part.ParentGroup.RootPart == part) 8262 if (part.ParentGroup.RootPart == part)
7663 { 8263 {
7664 SceneObjectGroup parent = part.ParentGroup; 8264 SceneObjectGroup parent = part.ParentGroup;
7665 parent.UpdateGroupPosition(currentPosition); 8265 Util.FireAndForget(delegate(object x) {
8266 parent.UpdateGroupPosition(currentPosition);
8267 });
7666 } 8268 }
7667 else 8269 else
7668 { 8270 {
@@ -7707,10 +8309,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7707 8309
7708 public LSL_String llXorBase64Strings(string str1, string str2) 8310 public LSL_String llXorBase64Strings(string str1, string str2)
7709 { 8311 {
7710 m_host.AddScriptLPS(1); 8312 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7711 Deprecated("llXorBase64Strings"); 8313
7712 ScriptSleep(300); 8314 ScriptSleep(300);
7713 return String.Empty; 8315 m_host.AddScriptLPS(1);
8316
8317 if (str1 == String.Empty)
8318 return String.Empty;
8319 if (str2 == String.Empty)
8320 return str1;
8321
8322 int len = str2.Length;
8323 if ((len % 4) != 0) // LL is EVIL!!!!
8324 {
8325 while (str2.EndsWith("="))
8326 str2 = str2.Substring(0, str2.Length - 1);
8327
8328 len = str2.Length;
8329 int mod = len % 4;
8330
8331 if (mod == 1)
8332 str2 = str2.Substring(0, str2.Length - 1);
8333 else if (mod == 2)
8334 str2 += "==";
8335 else if (mod == 3)
8336 str2 += "=";
8337 }
8338
8339 byte[] data1;
8340 byte[] data2;
8341 try
8342 {
8343 data1 = Convert.FromBase64String(str1);
8344 data2 = Convert.FromBase64String(str2);
8345 }
8346 catch (Exception)
8347 {
8348 return new LSL_String(String.Empty);
8349 }
8350
8351 // For cases where the decoded length of s2 is greater
8352 // than the decoded length of s1, simply perform a normal
8353 // decode and XOR
8354 //
8355 if (data2.Length >= data1.Length)
8356 {
8357 for (int pos = 0 ; pos < data1.Length ; pos++ )
8358 data1[pos] ^= data2[pos];
8359
8360 return Convert.ToBase64String(data1);
8361 }
8362
8363 // Remove padding
8364 while (str1.EndsWith("="))
8365 str1 = str1.Substring(0, str1.Length - 1);
8366 while (str2.EndsWith("="))
8367 str2 = str2.Substring(0, str2.Length - 1);
8368
8369 byte[] d1 = new byte[str1.Length];
8370 byte[] d2 = new byte[str2.Length];
8371
8372 for (int i = 0 ; i < str1.Length ; i++)
8373 {
8374 int idx = b64.IndexOf(str1.Substring(i, 1));
8375 if (idx == -1)
8376 idx = 0;
8377 d1[i] = (byte)idx;
8378 }
8379
8380 for (int i = 0 ; i < str2.Length ; i++)
8381 {
8382 int idx = b64.IndexOf(str2.Substring(i, 1));
8383 if (idx == -1)
8384 idx = 0;
8385 d2[i] = (byte)idx;
8386 }
8387
8388 string output = String.Empty;
8389
8390 for (int pos = 0 ; pos < d1.Length ; pos++)
8391 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8392
8393 while (output.Length % 3 > 0)
8394 output += "=";
8395
8396 return output;
7714 } 8397 }
7715 8398
7716 public void llRemoteDataSetRegion() 8399 public void llRemoteDataSetRegion()
@@ -7834,13 +8517,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7834 public LSL_Integer llGetNumberOfPrims() 8517 public LSL_Integer llGetNumberOfPrims()
7835 { 8518 {
7836 m_host.AddScriptLPS(1); 8519 m_host.AddScriptLPS(1);
7837 int avatarCount = 0; 8520 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7838 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8521
7839 {
7840 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7841 avatarCount++;
7842 });
7843
7844 return m_host.ParentGroup.PrimCount + avatarCount; 8522 return m_host.ParentGroup.PrimCount + avatarCount;
7845 } 8523 }
7846 8524
@@ -7856,55 +8534,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7856 m_host.AddScriptLPS(1); 8534 m_host.AddScriptLPS(1);
7857 UUID objID = UUID.Zero; 8535 UUID objID = UUID.Zero;
7858 LSL_List result = new LSL_List(); 8536 LSL_List result = new LSL_List();
8537
8538 // If the ID is not valid, return null result
7859 if (!UUID.TryParse(obj, out objID)) 8539 if (!UUID.TryParse(obj, out objID))
7860 { 8540 {
7861 result.Add(new LSL_Vector()); 8541 result.Add(new LSL_Vector());
7862 result.Add(new LSL_Vector()); 8542 result.Add(new LSL_Vector());
7863 return result; 8543 return result;
7864 } 8544 }
8545
8546 // Check if this is an attached prim. If so, replace
8547 // the UUID with the avatar UUID and report it's bounding box
8548 SceneObjectPart part = World.GetSceneObjectPart(objID);
8549 if (part != null && part.ParentGroup.IsAttachment)
8550 objID = part.ParentGroup.AttachedAvatar;
8551
8552 // Find out if this is an avatar ID. If so, return it's box
7865 ScenePresence presence = World.GetScenePresence(objID); 8553 ScenePresence presence = World.GetScenePresence(objID);
7866 if (presence != null) 8554 if (presence != null)
7867 { 8555 {
7868 if (presence.ParentID == 0) // not sat on an object 8556 // As per LSL Wiki, there is no difference between sitting
8557 // and standing avatar since server 1.36
8558 LSL_Vector lower;
8559 LSL_Vector upper;
8560 if (presence.Animator.Animations.DefaultAnimation.AnimID
8561 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7869 { 8562 {
7870 LSL_Vector lower; 8563 // This is for ground sitting avatars
7871 LSL_Vector upper; 8564 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7872 if (presence.Animator.Animations.DefaultAnimation.AnimID 8565 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7873 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8566 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7874 {
7875 // This is for ground sitting avatars
7876 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7877 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7878 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7879 }
7880 else
7881 {
7882 // This is for standing/flying avatars
7883 float height = presence.Appearance.AvatarHeight / 2.0f;
7884 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7885 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7886 }
7887 result.Add(lower);
7888 result.Add(upper);
7889 return result;
7890 } 8567 }
7891 else 8568 else
7892 { 8569 {
7893 // sitting on an object so we need the bounding box of that 8570 // This is for standing/flying avatars
7894 // which should include the avatar so set the UUID to the 8571 float height = presence.Appearance.AvatarHeight / 2.0f;
7895 // UUID of the object the avatar is sat on and allow it to fall through 8572 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7896 // to processing an object 8573 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7897 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7898 objID = p.UUID;
7899 } 8574 }
8575
8576 // Adjust to the documented error offsets (see LSL Wiki)
8577 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8578 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8579
8580 if (lower.x > upper.x)
8581 lower.x = upper.x;
8582 if (lower.y > upper.y)
8583 lower.y = upper.y;
8584 if (lower.z > upper.z)
8585 lower.z = upper.z;
8586
8587 result.Add(lower);
8588 result.Add(upper);
8589 return result;
7900 } 8590 }
7901 SceneObjectPart part = World.GetSceneObjectPart(objID); 8591
8592 part = World.GetSceneObjectPart(objID);
7902 // Currently only works for single prims without a sitting avatar 8593 // Currently only works for single prims without a sitting avatar
7903 if (part != null) 8594 if (part != null)
7904 { 8595 {
7905 Vector3 halfSize = part.Scale / 2.0f; 8596 float minX;
7906 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8597 float maxX;
7907 LSL_Vector upper = new LSL_Vector(halfSize); 8598 float minY;
8599 float maxY;
8600 float minZ;
8601 float maxZ;
8602
8603 // This BBox is in sim coordinates, with the offset being
8604 // a contained point.
8605 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8606 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8607
8608 minX -= offsets[0].X;
8609 maxX -= offsets[0].X;
8610 minY -= offsets[0].Y;
8611 maxY -= offsets[0].Y;
8612 minZ -= offsets[0].Z;
8613 maxZ -= offsets[0].Z;
8614
8615 LSL_Vector lower;
8616 LSL_Vector upper;
8617
8618 // Adjust to the documented error offsets (see LSL Wiki)
8619 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8620 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8621
8622 if (lower.x > upper.x)
8623 lower.x = upper.x;
8624 if (lower.y > upper.y)
8625 lower.y = upper.y;
8626 if (lower.z > upper.z)
8627 lower.z = upper.z;
8628
7908 result.Add(lower); 8629 result.Add(lower);
7909 result.Add(upper); 8630 result.Add(upper);
7910 return result; 8631 return result;
@@ -7918,7 +8639,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7918 8639
7919 public LSL_Vector llGetGeometricCenter() 8640 public LSL_Vector llGetGeometricCenter()
7920 { 8641 {
7921 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8642 Vector3 tmp = m_host.GetGeometricCenter();
8643 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7922 } 8644 }
7923 8645
7924 public LSL_List llGetPrimitiveParams(LSL_List rules) 8646 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7946,24 +8668,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7946 { 8668 {
7947 m_host.AddScriptLPS(1); 8669 m_host.AddScriptLPS(1);
7948 8670
7949 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8671 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8672 // keep other options as before
7950 8673
8674 List<SceneObjectPart> parts;
8675 List<ScenePresence> avatars;
8676
7951 LSL_List res = new LSL_List(); 8677 LSL_List res = new LSL_List();
7952 LSL_List remaining = null; 8678 LSL_List remaining = null;
7953 8679
7954 foreach (SceneObjectPart part in parts) 8680 while (rules.Length > 0)
7955 { 8681 {
7956 remaining = GetPrimParams(part, rules, ref res);
7957 }
7958
7959 while (remaining != null && remaining.Length > 2)
7960 {
7961 linknumber = remaining.GetLSLIntegerItem(0);
7962 rules = remaining.GetSublist(1, -1);
7963 parts = GetLinkParts(linknumber); 8682 parts = GetLinkParts(linknumber);
8683 avatars = GetLinkAvatars(linknumber);
7964 8684
8685 remaining = null;
7965 foreach (SceneObjectPart part in parts) 8686 foreach (SceneObjectPart part in parts)
8687 {
7966 remaining = GetPrimParams(part, rules, ref res); 8688 remaining = GetPrimParams(part, rules, ref res);
8689 }
8690 foreach (ScenePresence avatar in avatars)
8691 {
8692 remaining = GetPrimParams(avatar, rules, ref res);
8693 }
8694
8695 if (remaining != null && remaining.Length > 0)
8696 {
8697 linknumber = remaining.GetLSLIntegerItem(0);
8698 rules = remaining.GetSublist(1, -1);
8699 }
7967 } 8700 }
7968 8701
7969 return res; 8702 return res;
@@ -8008,13 +8741,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8741 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8009 part.AbsolutePosition.Y, 8742 part.AbsolutePosition.Y,
8010 part.AbsolutePosition.Z); 8743 part.AbsolutePosition.Z);
8011 // For some reason, the part.AbsolutePosition.* values do not change if the
8012 // linkset is rotated; they always reflect the child prim's world position
8013 // as though the linkset is unrotated. This is incompatible behavior with SL's
8014 // implementation, so will break scripts imported from there (not to mention it
8015 // makes it more difficult to determine a child prim's actual inworld position).
8016 if (part.ParentID != 0)
8017 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8018 res.Add(v); 8744 res.Add(v);
8019 break; 8745 break;
8020 8746
@@ -8186,30 +8912,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8186 if (remain < 1) 8912 if (remain < 1)
8187 return null; 8913 return null;
8188 8914
8189 face=(int)rules.GetLSLIntegerItem(idx++); 8915 face = (int)rules.GetLSLIntegerItem(idx++);
8190 8916
8191 tex = part.Shape.Textures; 8917 tex = part.Shape.Textures;
8918 int shiny;
8192 if (face == ScriptBaseClass.ALL_SIDES) 8919 if (face == ScriptBaseClass.ALL_SIDES)
8193 { 8920 {
8194 for (face = 0; face < GetNumberOfSides(part); face++) 8921 for (face = 0; face < GetNumberOfSides(part); face++)
8195 { 8922 {
8196 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8923 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8197 // Convert Shininess to PRIM_SHINY_* 8924 if (shinyness == Shininess.High)
8198 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8925 {
8199 // PRIM_BUMP_* 8926 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8200 res.Add(new LSL_Integer((int)texface.Bump)); 8927 }
8928 else if (shinyness == Shininess.Medium)
8929 {
8930 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8931 }
8932 else if (shinyness == Shininess.Low)
8933 {
8934 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8935 }
8936 else
8937 {
8938 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8939 }
8940 res.Add(new LSL_Integer(shiny));
8941 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8201 } 8942 }
8202 } 8943 }
8203 else 8944 else
8204 { 8945 {
8205 if (face >= 0 && face < GetNumberOfSides(part)) 8946 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8947 if (shinyness == Shininess.High)
8206 { 8948 {
8207 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8949 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8208 // Convert Shininess to PRIM_SHINY_* 8950 }
8209 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8951 else if (shinyness == Shininess.Medium)
8210 // PRIM_BUMP_* 8952 {
8211 res.Add(new LSL_Integer((int)texface.Bump)); 8953 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8954 }
8955 else if (shinyness == Shininess.Low)
8956 {
8957 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8958 }
8959 else
8960 {
8961 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8212 } 8962 }
8963 res.Add(new LSL_Integer(shiny));
8964 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8213 } 8965 }
8214 break; 8966 break;
8215 8967
@@ -8217,24 +8969,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8217 if (remain < 1) 8969 if (remain < 1)
8218 return null; 8970 return null;
8219 8971
8220 face=(int)rules.GetLSLIntegerItem(idx++); 8972 face = (int)rules.GetLSLIntegerItem(idx++);
8221 8973
8222 tex = part.Shape.Textures; 8974 tex = part.Shape.Textures;
8975 int fullbright;
8223 if (face == ScriptBaseClass.ALL_SIDES) 8976 if (face == ScriptBaseClass.ALL_SIDES)
8224 { 8977 {
8225 for (face = 0; face < GetNumberOfSides(part); face++) 8978 for (face = 0; face < GetNumberOfSides(part); face++)
8226 { 8979 {
8227 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8980 if (tex.GetFace((uint)face).Fullbright == true)
8228 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8981 {
8982 fullbright = ScriptBaseClass.TRUE;
8983 }
8984 else
8985 {
8986 fullbright = ScriptBaseClass.FALSE;
8987 }
8988 res.Add(new LSL_Integer(fullbright));
8229 } 8989 }
8230 } 8990 }
8231 else 8991 else
8232 { 8992 {
8233 if (face >= 0 && face < GetNumberOfSides(part)) 8993 if (tex.GetFace((uint)face).Fullbright == true)
8234 { 8994 {
8235 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8995 fullbright = ScriptBaseClass.TRUE;
8236 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8996 }
8997 else
8998 {
8999 fullbright = ScriptBaseClass.FALSE;
8237 } 9000 }
9001 res.Add(new LSL_Integer(fullbright));
8238 } 9002 }
8239 break; 9003 break;
8240 9004
@@ -8256,27 +9020,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8256 break; 9020 break;
8257 9021
8258 case (int)ScriptBaseClass.PRIM_TEXGEN: 9022 case (int)ScriptBaseClass.PRIM_TEXGEN:
9023 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8259 if (remain < 1) 9024 if (remain < 1)
8260 return null; 9025 return null;
8261 9026
8262 face=(int)rules.GetLSLIntegerItem(idx++); 9027 face = (int)rules.GetLSLIntegerItem(idx++);
8263 9028
8264 tex = part.Shape.Textures; 9029 tex = part.Shape.Textures;
8265 if (face == ScriptBaseClass.ALL_SIDES) 9030 if (face == ScriptBaseClass.ALL_SIDES)
8266 { 9031 {
8267 for (face = 0; face < GetNumberOfSides(part); face++) 9032 for (face = 0; face < GetNumberOfSides(part); face++)
8268 { 9033 {
8269 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9034 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8270 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9035 {
8271 res.Add(new LSL_Integer((uint)texgen >> 1)); 9036 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9037 }
9038 else
9039 {
9040 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9041 }
8272 } 9042 }
8273 } 9043 }
8274 else 9044 else
8275 { 9045 {
8276 if (face >= 0 && face < GetNumberOfSides(part)) 9046 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8277 { 9047 {
8278 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9048 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8279 res.Add(new LSL_Integer((uint)texgen >> 1)); 9049 }
9050 else
9051 {
9052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8280 } 9053 }
8281 } 9054 }
8282 break; 9055 break;
@@ -8300,24 +9073,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8300 if (remain < 1) 9073 if (remain < 1)
8301 return null; 9074 return null;
8302 9075
8303 face=(int)rules.GetLSLIntegerItem(idx++); 9076 face = (int)rules.GetLSLIntegerItem(idx++);
8304 9077
8305 tex = part.Shape.Textures; 9078 tex = part.Shape.Textures;
9079 float primglow;
8306 if (face == ScriptBaseClass.ALL_SIDES) 9080 if (face == ScriptBaseClass.ALL_SIDES)
8307 { 9081 {
8308 for (face = 0; face < GetNumberOfSides(part); face++) 9082 for (face = 0; face < GetNumberOfSides(part); face++)
8309 { 9083 {
8310 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9084 primglow = tex.GetFace((uint)face).Glow;
8311 res.Add(new LSL_Float(texface.Glow)); 9085 res.Add(new LSL_Float(primglow));
8312 } 9086 }
8313 } 9087 }
8314 else 9088 else
8315 { 9089 {
8316 if (face >= 0 && face < GetNumberOfSides(part)) 9090 primglow = tex.GetFace((uint)face).Glow;
8317 { 9091 res.Add(new LSL_Float(primglow));
8318 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8319 res.Add(new LSL_Float(texface.Glow));
8320 }
8321 } 9092 }
8322 break; 9093 break;
8323 9094
@@ -8329,15 +9100,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8329 textColor.B)); 9100 textColor.B));
8330 res.Add(new LSL_Float(textColor.A)); 9101 res.Add(new LSL_Float(textColor.A));
8331 break; 9102 break;
9103
8332 case (int)ScriptBaseClass.PRIM_NAME: 9104 case (int)ScriptBaseClass.PRIM_NAME:
8333 res.Add(new LSL_String(part.Name)); 9105 res.Add(new LSL_String(part.Name));
8334 break; 9106 break;
9107
8335 case (int)ScriptBaseClass.PRIM_DESC: 9108 case (int)ScriptBaseClass.PRIM_DESC:
8336 res.Add(new LSL_String(part.Description)); 9109 res.Add(new LSL_String(part.Description));
8337 break; 9110 break;
9111
8338 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9112 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8339 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9113 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8340 break; 9114 break;
9115
8341 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9116 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8342 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9117 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8343 break; 9118 break;
@@ -8948,8 +9723,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8948 // The function returns an ordered list 9723 // The function returns an ordered list
8949 // representing the tokens found in the supplied 9724 // representing the tokens found in the supplied
8950 // sources string. If two successive tokenizers 9725 // sources string. If two successive tokenizers
8951 // are encountered, then a NULL entry is added 9726 // are encountered, then a null-string entry is
8952 // to the list. 9727 // added to the list.
8953 // 9728 //
8954 // It is a precondition that the source and 9729 // It is a precondition that the source and
8955 // toekizer lisst are non-null. If they are null, 9730 // toekizer lisst are non-null. If they are null,
@@ -8957,7 +9732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8957 // while their lengths are being determined. 9732 // while their lengths are being determined.
8958 // 9733 //
8959 // A small amount of working memoryis required 9734 // A small amount of working memoryis required
8960 // of approximately 8*#tokenizers. 9735 // of approximately 8*#tokenizers + 8*srcstrlen.
8961 // 9736 //
8962 // There are many ways in which this function 9737 // There are many ways in which this function
8963 // can be implemented, this implementation is 9738 // can be implemented, this implementation is
@@ -8973,155 +9748,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8973 // and eliminates redundant tokenizers as soon 9748 // and eliminates redundant tokenizers as soon
8974 // as is possible. 9749 // as is possible.
8975 // 9750 //
8976 // The implementation tries to avoid any copying 9751 // The implementation tries to minimize temporary
8977 // of arrays or other objects. 9752 // garbage generation.
8978 // </remarks> 9753 // </remarks>
8979 9754
8980 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9755 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8981 { 9756 {
8982 int beginning = 0; 9757 return ParseString2List(src, separators, spacers, true);
8983 int srclen = src.Length; 9758 }
8984 int seplen = separators.Length;
8985 object[] separray = separators.Data;
8986 int spclen = spacers.Length;
8987 object[] spcarray = spacers.Data;
8988 int mlen = seplen+spclen;
8989
8990 int[] offset = new int[mlen+1];
8991 bool[] active = new bool[mlen];
8992
8993 int best;
8994 int j;
8995
8996 // Initial capacity reduces resize cost
8997 9759
8998 LSL_List tokens = new LSL_List(); 9760 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9761 {
9762 int srclen = src.Length;
9763 int seplen = separators.Length;
9764 object[] separray = separators.Data;
9765 int spclen = spacers.Length;
9766 object[] spcarray = spacers.Data;
9767 int dellen = 0;
9768 string[] delarray = new string[seplen+spclen];
8999 9769
9000 // All entries are initially valid 9770 int outlen = 0;
9771 string[] outarray = new string[srclen*2+1];
9001 9772
9002 for (int i = 0; i < mlen; i++) 9773 int i, j;
9003 active[i] = true; 9774 string d;
9004 9775
9005 offset[mlen] = srclen; 9776 m_host.AddScriptLPS(1);
9006 9777
9007 while (beginning < srclen) 9778 /*
9779 * Convert separator and spacer lists to C# strings.
9780 * Also filter out null strings so we don't hang.
9781 */
9782 for (i = 0; i < seplen; i ++)
9008 { 9783 {
9784 d = separray[i].ToString();
9785 if (d.Length > 0)
9786 {
9787 delarray[dellen++] = d;
9788 }
9789 }
9790 seplen = dellen;
9009 9791
9010 best = mlen; // as bad as it gets 9792 for (i = 0; i < spclen; i ++)
9793 {
9794 d = spcarray[i].ToString();
9795 if (d.Length > 0)
9796 {
9797 delarray[dellen++] = d;
9798 }
9799 }
9011 9800
9012 // Scan for separators 9801 /*
9802 * Scan through source string from beginning to end.
9803 */
9804 for (i = 0;;)
9805 {
9013 9806
9014 for (j = 0; j < seplen; j++) 9807 /*
9808 * Find earliest delimeter in src starting at i (if any).
9809 */
9810 int earliestDel = -1;
9811 int earliestSrc = srclen;
9812 string earliestStr = null;
9813 for (j = 0; j < dellen; j ++)
9015 { 9814 {
9016 if (separray[j].ToString() == String.Empty) 9815 d = delarray[j];
9017 active[j] = false; 9816 if (d != null)
9018
9019 if (active[j])
9020 { 9817 {
9021 // scan all of the markers 9818 int index = src.IndexOf(d, i);
9022 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9819 if (index < 0)
9023 { 9820 {
9024 // not present at all 9821 delarray[j] = null; // delim nowhere in src, don't check it anymore
9025 active[j] = false;
9026 } 9822 }
9027 else 9823 else if (index < earliestSrc)
9028 { 9824 {
9029 // present and correct 9825 earliestSrc = index; // where delimeter starts in source string
9030 if (offset[j] < offset[best]) 9826 earliestDel = j; // where delimeter is in delarray[]
9031 { 9827 earliestStr = d; // the delimeter string from delarray[]
9032 // closest so far 9828 if (index == i) break; // can't do any better than found at beg of string
9033 best = j;
9034 if (offset[best] == beginning)
9035 break;
9036 }
9037 } 9829 }
9038 } 9830 }
9039 } 9831 }
9040 9832
9041 // Scan for spacers 9833 /*
9042 9834 * Output source string starting at i through start of earliest delimeter.
9043 if (offset[best] != beginning) 9835 */
9836 if (keepNulls || (earliestSrc > i))
9044 { 9837 {
9045 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9838 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9046 {
9047 if (spcarray[j-seplen].ToString() == String.Empty)
9048 active[j] = false;
9049
9050 if (active[j])
9051 {
9052 // scan all of the markers
9053 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9054 {
9055 // not present at all
9056 active[j] = false;
9057 }
9058 else
9059 {
9060 // present and correct
9061 if (offset[j] < offset[best])
9062 {
9063 // closest so far
9064 best = j;
9065 }
9066 }
9067 }
9068 }
9069 } 9839 }
9070 9840
9071 // This is the normal exit from the scanning loop 9841 /*
9842 * If no delimeter found at or after i, we're done scanning.
9843 */
9844 if (earliestDel < 0) break;
9072 9845
9073 if (best == mlen) 9846 /*
9847 * If delimeter was a spacer, output the spacer.
9848 */
9849 if (earliestDel >= seplen)
9074 { 9850 {
9075 // no markers were found on this pass 9851 outarray[outlen++] = earliestStr;
9076 // so we're pretty much done
9077 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9078 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9079 break;
9080 } 9852 }
9081 9853
9082 // Otherwise we just add the newly delimited token 9854 /*
9083 // and recalculate where the search should continue. 9855 * Look at rest of src string following delimeter.
9084 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9856 */
9085 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9857 i = earliestSrc + earliestStr.Length;
9086
9087 if (best < seplen)
9088 {
9089 beginning = offset[best] + (separray[best].ToString()).Length;
9090 }
9091 else
9092 {
9093 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9094 string str = spcarray[best - seplen].ToString();
9095 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9096 tokens.Add(new LSL_String(str));
9097 }
9098 } 9858 }
9099 9859
9100 // This an awkward an not very intuitive boundary case. If the 9860 /*
9101 // last substring is a tokenizer, then there is an implied trailing 9861 * Make up an exact-sized output array suitable for an LSL_List object.
9102 // null list entry. Hopefully the single comparison will not be too 9862 */
9103 // arduous. Alternatively the 'break' could be replced with a return 9863 object[] outlist = new object[outlen];
9104 // but that's shabby programming. 9864 for (i = 0; i < outlen; i ++)
9105
9106 if ((beginning == srclen) && (keepNulls))
9107 { 9865 {
9108 if (srclen != 0) 9866 outlist[i] = new LSL_String(outarray[i]);
9109 tokens.Add(new LSL_String(""));
9110 } 9867 }
9111 9868 return new LSL_List(outlist);
9112 return tokens;
9113 }
9114
9115 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9116 {
9117 m_host.AddScriptLPS(1);
9118 return this.ParseString(src, separators, spacers, false);
9119 }
9120
9121 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9122 {
9123 m_host.AddScriptLPS(1);
9124 return this.ParseString(src, separators, spacers, true);
9125 } 9869 }
9126 9870
9127 public LSL_Integer llGetObjectPermMask(int mask) 9871 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9216,6 +9960,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9216 case 4: 9960 case 4:
9217 return (int)item.NextPermissions; 9961 return (int)item.NextPermissions;
9218 } 9962 }
9963 m_host.TaskInventory.LockItemsForRead(false);
9219 9964
9220 return -1; 9965 return -1;
9221 } 9966 }
@@ -9404,31 +10149,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9404 UUID key = new UUID(); 10149 UUID key = new UUID();
9405 if (UUID.TryParse(id, out key)) 10150 if (UUID.TryParse(id, out key))
9406 { 10151 {
9407 try 10152 // return total object mass
9408 { 10153 SceneObjectPart part = World.GetSceneObjectPart(key);
9409 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10154 if (part != null)
9410 if (obj != null) 10155 return part.ParentGroup.GetMass();
9411 return (double)obj.GetMass(); 10156
9412 // the object is null so the key is for an avatar 10157 // the object is null so the key is for an avatar
9413 ScenePresence avatar = World.GetScenePresence(key); 10158 ScenePresence avatar = World.GetScenePresence(key);
9414 if (avatar != null) 10159 if (avatar != null)
9415 if (avatar.IsChildAgent)
9416 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9417 // child agents have a mass of 1.0
9418 return 1;
9419 else
9420 return (double)avatar.GetMass();
9421 }
9422 catch (KeyNotFoundException)
9423 { 10160 {
9424 return 0; // The Object/Agent not in the region so just return zero 10161 if (avatar.IsChildAgent)
10162 {
10163 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10164 // child agents have a mass of 1.0
10165 return 1;
10166 }
10167 else
10168 {
10169 return (double)avatar.GetMass();
10170 }
9425 } 10171 }
9426 } 10172 }
9427 return 0; 10173 return 0;
9428 } 10174 }
9429 10175
9430 /// <summary> 10176 /// <summary>
9431 /// illListReplaceList removes the sub-list defined by the inclusive indices 10177 /// llListReplaceList removes the sub-list defined by the inclusive indices
9432 /// start and end and inserts the src list in its place. The inclusive 10178 /// start and end and inserts the src list in its place. The inclusive
9433 /// nature of the indices means that at least one element must be deleted 10179 /// nature of the indices means that at least one element must be deleted
9434 /// if the indices are within the bounds of the existing list. I.e. 2,2 10180 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9485,16 +10231,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9485 // based upon end. Note that if end exceeds the upper 10231 // based upon end. Note that if end exceeds the upper
9486 // bound in this case, the entire destination list 10232 // bound in this case, the entire destination list
9487 // is removed. 10233 // is removed.
9488 else 10234 else if (start == 0)
9489 { 10235 {
9490 if (end + 1 < dest.Length) 10236 if (end + 1 < dest.Length)
9491 {
9492 return src + dest.GetSublist(end + 1, -1); 10237 return src + dest.GetSublist(end + 1, -1);
9493 }
9494 else 10238 else
9495 {
9496 return src; 10239 return src;
9497 } 10240 }
10241 else // Start < 0
10242 {
10243 if (end + 1 < dest.Length)
10244 return dest.GetSublist(end + 1, -1);
10245 else
10246 return new LSL_List();
9498 } 10247 }
9499 } 10248 }
9500 // Finally, if start > end, we strip away a prefix and 10249 // Finally, if start > end, we strip away a prefix and
@@ -9545,17 +10294,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9545 int width = 0; 10294 int width = 0;
9546 int height = 0; 10295 int height = 0;
9547 10296
9548 ParcelMediaCommandEnum? commandToSend = null; 10297 uint commandToSend = 0;
9549 float time = 0.0f; // default is from start 10298 float time = 0.0f; // default is from start
9550 10299
9551 ScenePresence presence = null; 10300 ScenePresence presence = null;
9552 10301
9553 for (int i = 0; i < commandList.Data.Length; i++) 10302 for (int i = 0; i < commandList.Data.Length; i++)
9554 { 10303 {
9555 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10304 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9556 switch (command) 10305 switch (command)
9557 { 10306 {
9558 case ParcelMediaCommandEnum.Agent: 10307 case (uint)ParcelMediaCommandEnum.Agent:
9559 // we send only to one agent 10308 // we send only to one agent
9560 if ((i + 1) < commandList.Length) 10309 if ((i + 1) < commandList.Length)
9561 { 10310 {
@@ -9572,25 +10321,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 } 10321 }
9573 break; 10322 break;
9574 10323
9575 case ParcelMediaCommandEnum.Loop: 10324 case (uint)ParcelMediaCommandEnum.Loop:
9576 loop = 1; 10325 loop = 1;
9577 commandToSend = command; 10326 commandToSend = command;
9578 update = true; //need to send the media update packet to set looping 10327 update = true; //need to send the media update packet to set looping
9579 break; 10328 break;
9580 10329
9581 case ParcelMediaCommandEnum.Play: 10330 case (uint)ParcelMediaCommandEnum.Play:
9582 loop = 0; 10331 loop = 0;
9583 commandToSend = command; 10332 commandToSend = command;
9584 update = true; //need to send the media update packet to make sure it doesn't loop 10333 update = true; //need to send the media update packet to make sure it doesn't loop
9585 break; 10334 break;
9586 10335
9587 case ParcelMediaCommandEnum.Pause: 10336 case (uint)ParcelMediaCommandEnum.Pause:
9588 case ParcelMediaCommandEnum.Stop: 10337 case (uint)ParcelMediaCommandEnum.Stop:
9589 case ParcelMediaCommandEnum.Unload: 10338 case (uint)ParcelMediaCommandEnum.Unload:
9590 commandToSend = command; 10339 commandToSend = command;
9591 break; 10340 break;
9592 10341
9593 case ParcelMediaCommandEnum.Url: 10342 case (uint)ParcelMediaCommandEnum.Url:
9594 if ((i + 1) < commandList.Length) 10343 if ((i + 1) < commandList.Length)
9595 { 10344 {
9596 if (commandList.Data[i + 1] is LSL_String) 10345 if (commandList.Data[i + 1] is LSL_String)
@@ -9603,7 +10352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9603 } 10352 }
9604 break; 10353 break;
9605 10354
9606 case ParcelMediaCommandEnum.Texture: 10355 case (uint)ParcelMediaCommandEnum.Texture:
9607 if ((i + 1) < commandList.Length) 10356 if ((i + 1) < commandList.Length)
9608 { 10357 {
9609 if (commandList.Data[i + 1] is LSL_String) 10358 if (commandList.Data[i + 1] is LSL_String)
@@ -9616,7 +10365,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9616 } 10365 }
9617 break; 10366 break;
9618 10367
9619 case ParcelMediaCommandEnum.Time: 10368 case (uint)ParcelMediaCommandEnum.Time:
9620 if ((i + 1) < commandList.Length) 10369 if ((i + 1) < commandList.Length)
9621 { 10370 {
9622 if (commandList.Data[i + 1] is LSL_Float) 10371 if (commandList.Data[i + 1] is LSL_Float)
@@ -9628,7 +10377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9628 } 10377 }
9629 break; 10378 break;
9630 10379
9631 case ParcelMediaCommandEnum.AutoAlign: 10380 case (uint)ParcelMediaCommandEnum.AutoAlign:
9632 if ((i + 1) < commandList.Length) 10381 if ((i + 1) < commandList.Length)
9633 { 10382 {
9634 if (commandList.Data[i + 1] is LSL_Integer) 10383 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9642,7 +10391,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9642 } 10391 }
9643 break; 10392 break;
9644 10393
9645 case ParcelMediaCommandEnum.Type: 10394 case (uint)ParcelMediaCommandEnum.Type:
9646 if ((i + 1) < commandList.Length) 10395 if ((i + 1) < commandList.Length)
9647 { 10396 {
9648 if (commandList.Data[i + 1] is LSL_String) 10397 if (commandList.Data[i + 1] is LSL_String)
@@ -9655,7 +10404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9655 } 10404 }
9656 break; 10405 break;
9657 10406
9658 case ParcelMediaCommandEnum.Desc: 10407 case (uint)ParcelMediaCommandEnum.Desc:
9659 if ((i + 1) < commandList.Length) 10408 if ((i + 1) < commandList.Length)
9660 { 10409 {
9661 if (commandList.Data[i + 1] is LSL_String) 10410 if (commandList.Data[i + 1] is LSL_String)
@@ -9668,7 +10417,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9668 } 10417 }
9669 break; 10418 break;
9670 10419
9671 case ParcelMediaCommandEnum.Size: 10420 case (uint)ParcelMediaCommandEnum.Size:
9672 if ((i + 2) < commandList.Length) 10421 if ((i + 2) < commandList.Length)
9673 { 10422 {
9674 if (commandList.Data[i + 1] is LSL_Integer) 10423 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9738,7 +10487,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9738 } 10487 }
9739 } 10488 }
9740 10489
9741 if (commandToSend != null) 10490 if (commandToSend != 0)
9742 { 10491 {
9743 // the commandList contained a start/stop/... command, too 10492 // the commandList contained a start/stop/... command, too
9744 if (presence == null) 10493 if (presence == null)
@@ -9775,7 +10524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9775 10524
9776 if (aList.Data[i] != null) 10525 if (aList.Data[i] != null)
9777 { 10526 {
9778 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10527 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9779 { 10528 {
9780 case ParcelMediaCommandEnum.Url: 10529 case ParcelMediaCommandEnum.Url:
9781 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10530 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9832,15 +10581,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9832 10581
9833 if (quick_pay_buttons.Data.Length < 4) 10582 if (quick_pay_buttons.Data.Length < 4)
9834 { 10583 {
9835 LSLError("List must have at least 4 elements"); 10584 int x;
9836 return; 10585 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10586 {
10587 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10588 }
9837 } 10589 }
9838 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10590 int[] nPrice = new int[5];
9839 10591 nPrice[0] = price;
9840 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10592 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9841 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10593 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9842 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10594 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9843 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10595 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10596 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9844 m_host.ParentGroup.HasGroupChanged = true; 10597 m_host.ParentGroup.HasGroupChanged = true;
9845 } 10598 }
9846 10599
@@ -9857,7 +10610,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9857 return new LSL_Vector(); 10610 return new LSL_Vector();
9858 } 10611 }
9859 10612
9860 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10613// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10614 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9861 if (presence != null) 10615 if (presence != null)
9862 { 10616 {
9863 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10617 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9879,7 +10633,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9879 return new LSL_Rotation(); 10633 return new LSL_Rotation();
9880 } 10634 }
9881 10635
9882 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10636// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10637 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9883 if (presence != null) 10638 if (presence != null)
9884 { 10639 {
9885 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10640 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9939,14 +10694,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9939 { 10694 {
9940 m_host.AddScriptLPS(1); 10695 m_host.AddScriptLPS(1);
9941 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10696 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9942 if (detectedParams == null) return; // only works on the first detected avatar 10697 if (detectedParams == null)
9943 10698 {
10699 if (m_host.ParentGroup.IsAttachment == true)
10700 {
10701 detectedParams = new DetectParams();
10702 detectedParams.Key = m_host.OwnerID;
10703 }
10704 else
10705 {
10706 return;
10707 }
10708 }
10709
9944 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10710 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9945 if (avatar != null) 10711 if (avatar != null)
9946 { 10712 {
9947 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10713 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9948 simname, pos, lookAt); 10714 simname, pos, lookAt);
9949 } 10715 }
10716
9950 ScriptSleep(1000); 10717 ScriptSleep(1000);
9951 } 10718 }
9952 10719
@@ -10070,12 +10837,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10070 10837
10071 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10838 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10072 object[] data = rules.Data; 10839 object[] data = rules.Data;
10073 for (int i = 0; i < data.Length; ++i) { 10840 for (int i = 0; i < data.Length; ++i)
10841 {
10074 int type = Convert.ToInt32(data[i++].ToString()); 10842 int type = Convert.ToInt32(data[i++].ToString());
10075 if (i >= data.Length) break; // odd number of entries => ignore the last 10843 if (i >= data.Length) break; // odd number of entries => ignore the last
10076 10844
10077 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10845 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10078 switch (type) { 10846 switch (type)
10847 {
10079 case ScriptBaseClass.CAMERA_FOCUS: 10848 case ScriptBaseClass.CAMERA_FOCUS:
10080 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10849 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10081 case ScriptBaseClass.CAMERA_POSITION: 10850 case ScriptBaseClass.CAMERA_POSITION:
@@ -10180,19 +10949,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10180 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10949 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10181 { 10950 {
10182 m_host.AddScriptLPS(1); 10951 m_host.AddScriptLPS(1);
10183 string ret = String.Empty; 10952
10184 string src1 = llBase64ToString(str1); 10953 if (str1 == String.Empty)
10185 string src2 = llBase64ToString(str2); 10954 return String.Empty;
10186 int c = 0; 10955 if (str2 == String.Empty)
10187 for (int i = 0; i < src1.Length; i++) 10956 return str1;
10957
10958 int len = str2.Length;
10959 if ((len % 4) != 0) // LL is EVIL!!!!
10188 { 10960 {
10189 ret += (char) (src1[i] ^ src2[c]); 10961 while (str2.EndsWith("="))
10962 str2 = str2.Substring(0, str2.Length - 1);
10963
10964 len = str2.Length;
10965 int mod = len % 4;
10190 10966
10191 c++; 10967 if (mod == 1)
10192 if (c >= src2.Length) 10968 str2 = str2.Substring(0, str2.Length - 1);
10193 c = 0; 10969 else if (mod == 2)
10970 str2 += "==";
10971 else if (mod == 3)
10972 str2 += "=";
10973 }
10974
10975 byte[] data1;
10976 byte[] data2;
10977 try
10978 {
10979 data1 = Convert.FromBase64String(str1);
10980 data2 = Convert.FromBase64String(str2);
10981 }
10982 catch (Exception)
10983 {
10984 return new LSL_String(String.Empty);
10985 }
10986
10987 byte[] d2 = new Byte[data1.Length];
10988 int pos = 0;
10989
10990 if (data1.Length <= data2.Length)
10991 {
10992 Array.Copy(data2, 0, d2, 0, data1.Length);
10993 }
10994 else
10995 {
10996 while (pos < data1.Length)
10997 {
10998 len = data1.Length - pos;
10999 if (len > data2.Length)
11000 len = data2.Length;
11001
11002 Array.Copy(data2, 0, d2, pos, len);
11003 pos += len;
11004 }
10194 } 11005 }
10195 return llStringToBase64(ret); 11006
11007 for (pos = 0 ; pos < data1.Length ; pos++ )
11008 data1[pos] ^= d2[pos];
11009
11010 return Convert.ToBase64String(data1);
10196 } 11011 }
10197 11012
10198 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11013 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10245,16 +11060,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10245 if (userAgent != null) 11060 if (userAgent != null)
10246 httpHeaders["User-Agent"] = userAgent; 11061 httpHeaders["User-Agent"] = userAgent;
10247 11062
11063 // See if the URL contains any header hacks
11064 string[] urlParts = url.Split(new char[] {'\n'});
11065 if (urlParts.Length > 1)
11066 {
11067 // Iterate the passed headers and parse them
11068 for (int i = 1 ; i < urlParts.Length ; i++ )
11069 {
11070 // The rest of those would be added to the body in SL.
11071 // Let's not do that.
11072 if (urlParts[i] == String.Empty)
11073 break;
11074
11075 // See if this could be a valid header
11076 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11077 if (headerParts.Length != 2)
11078 continue;
11079
11080 string headerName = headerParts[0].Trim();
11081 string headerValue = headerParts[1].Trim();
11082
11083 // Filter out headers that could be used to abuse
11084 // another system or cloak the request
11085 if (headerName.ToLower() == "x-secondlife-shard" ||
11086 headerName.ToLower() == "x-secondlife-object-name" ||
11087 headerName.ToLower() == "x-secondlife-object-key" ||
11088 headerName.ToLower() == "x-secondlife-region" ||
11089 headerName.ToLower() == "x-secondlife-local-position" ||
11090 headerName.ToLower() == "x-secondlife-local-velocity" ||
11091 headerName.ToLower() == "x-secondlife-local-rotation" ||
11092 headerName.ToLower() == "x-secondlife-owner-name" ||
11093 headerName.ToLower() == "x-secondlife-owner-key" ||
11094 headerName.ToLower() == "connection" ||
11095 headerName.ToLower() == "content-length" ||
11096 headerName.ToLower() == "from" ||
11097 headerName.ToLower() == "host" ||
11098 headerName.ToLower() == "proxy-authorization" ||
11099 headerName.ToLower() == "referer" ||
11100 headerName.ToLower() == "trailer" ||
11101 headerName.ToLower() == "transfer-encoding" ||
11102 headerName.ToLower() == "via" ||
11103 headerName.ToLower() == "authorization")
11104 continue;
11105
11106 httpHeaders[headerName] = headerValue;
11107 }
11108
11109 // Finally, strip any protocol specifier from the URL
11110 url = urlParts[0].Trim();
11111 int idx = url.IndexOf(" HTTP/");
11112 if (idx != -1)
11113 url = url.Substring(0, idx);
11114 }
11115
10248 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11116 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10249 Regex r = new Regex(authregex); 11117 Regex r = new Regex(authregex);
10250 int[] gnums = r.GetGroupNumbers(); 11118 int[] gnums = r.GetGroupNumbers();
10251 Match m = r.Match(url); 11119 Match m = r.Match(url);
10252 if (m.Success) { 11120 if (m.Success)
10253 for (int i = 1; i < gnums.Length; i++) { 11121 {
11122 for (int i = 1; i < gnums.Length; i++)
11123 {
10254 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11124 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10255 //CaptureCollection cc = g.Captures; 11125 //CaptureCollection cc = g.Captures;
10256 } 11126 }
10257 if (m.Groups.Count == 5) { 11127 if (m.Groups.Count == 5)
11128 {
10258 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11129 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10259 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11130 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10260 } 11131 }
@@ -10457,6 +11328,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10457 11328
10458 LSL_List ret = new LSL_List(); 11329 LSL_List ret = new LSL_List();
10459 UUID key = new UUID(); 11330 UUID key = new UUID();
11331
11332
10460 if (UUID.TryParse(id, out key)) 11333 if (UUID.TryParse(id, out key))
10461 { 11334 {
10462 ScenePresence av = World.GetScenePresence(key); 11335 ScenePresence av = World.GetScenePresence(key);
@@ -10474,13 +11347,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10474 ret.Add(new LSL_String("")); 11347 ret.Add(new LSL_String(""));
10475 break; 11348 break;
10476 case ScriptBaseClass.OBJECT_POS: 11349 case ScriptBaseClass.OBJECT_POS:
10477 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11350 Vector3 avpos;
11351
11352 if (av.ParentID != 0 && av.ParentPart != null)
11353 {
11354 avpos = av.OffsetPosition;
11355
11356 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11357 avpos -= sitOffset;
11358
11359 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11360 }
11361 else
11362 avpos = av.AbsolutePosition;
11363
11364 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10478 break; 11365 break;
10479 case ScriptBaseClass.OBJECT_ROT: 11366 case ScriptBaseClass.OBJECT_ROT:
10480 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11367 Quaternion avrot = av.Rotation;
11368 if (av.ParentID != 0 && av.ParentPart != null)
11369 {
11370 avrot = av.ParentPart.GetWorldRotation() * avrot;
11371 }
11372 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10481 break; 11373 break;
10482 case ScriptBaseClass.OBJECT_VELOCITY: 11374 case ScriptBaseClass.OBJECT_VELOCITY:
10483 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11375 Vector3 avvel = av.Velocity;
11376 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10484 break; 11377 break;
10485 case ScriptBaseClass.OBJECT_OWNER: 11378 case ScriptBaseClass.OBJECT_OWNER:
10486 ret.Add(new LSL_String(id)); 11379 ret.Add(new LSL_String(id));
@@ -10536,11 +11429,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10536 case ScriptBaseClass.OBJECT_NAME: 11429 case ScriptBaseClass.OBJECT_NAME:
10537 ret.Add(new LSL_String(obj.Name)); 11430 ret.Add(new LSL_String(obj.Name));
10538 break; 11431 break;
10539 case ScriptBaseClass.OBJECT_DESC: 11432 case ScriptBaseClass.OBJECT_DESC:
10540 ret.Add(new LSL_String(obj.Description)); 11433 ret.Add(new LSL_String(obj.Description));
10541 break; 11434 break;
10542 case ScriptBaseClass.OBJECT_POS: 11435 case ScriptBaseClass.OBJECT_POS:
10543 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11436 Vector3 opos = obj.AbsolutePosition;
11437 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10544 break; 11438 break;
10545 case ScriptBaseClass.OBJECT_ROT: 11439 case ScriptBaseClass.OBJECT_ROT:
10546 { 11440 {
@@ -10590,9 +11484,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10590 // The value returned in SL for normal prims is prim count 11484 // The value returned in SL for normal prims is prim count
10591 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11485 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10592 break; 11486 break;
10593 // The following 3 costs I have intentionaly coded to return zero. They are part of 11487
10594 // "Land Impact" calculations. These calculations are probably not applicable 11488 // costs below may need to be diferent for root parts, need to check
10595 // to OpenSim and are not yet complete in SL
10596 case ScriptBaseClass.OBJECT_SERVER_COST: 11489 case ScriptBaseClass.OBJECT_SERVER_COST:
10597 // The linden calculation is here 11490 // The linden calculation is here
10598 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11491 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10600,16 +11493,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10600 ret.Add(new LSL_Float(0)); 11493 ret.Add(new LSL_Float(0));
10601 break; 11494 break;
10602 case ScriptBaseClass.OBJECT_STREAMING_COST: 11495 case ScriptBaseClass.OBJECT_STREAMING_COST:
10603 // The linden calculation is here 11496 // The value returned in SL for normal prims is prim count * 0.06
10604 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11497 ret.Add(new LSL_Float(obj.StreamingCost));
10605 // The value returned in SL for normal prims looks like the prim count * 0.06
10606 ret.Add(new LSL_Float(0));
10607 break; 11498 break;
10608 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11499 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10609 // The linden calculation is here 11500 // The value returned in SL for normal prims is prim count
10610 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11501 ret.Add(new LSL_Float(obj.PhysicsCost));
10611 // The value returned in SL for normal prims looks like the prim count
10612 ret.Add(new LSL_Float(0));
10613 break; 11502 break;
10614 default: 11503 default:
10615 // Invalid or unhandled constant. 11504 // Invalid or unhandled constant.
@@ -10820,15 +11709,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10820 return result; 11709 return result;
10821 } 11710 }
10822 11711
10823 public void print(string str) 11712 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10824 { 11713 {
10825 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11714 List<SceneObjectPart> parts = GetLinkParts(link);
10826 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11715 if (parts.Count < 1)
10827 if (ossl != null) 11716 return 0;
10828 { 11717
10829 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11718 return GetNumberOfSides(parts[0]);
10830 m_log.Info("LSL print():" + str);
10831 }
10832 } 11719 }
10833 11720
10834 private string Name2Username(string name) 11721 private string Name2Username(string name)
@@ -10873,7 +11760,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10873 11760
10874 return rq.ToString(); 11761 return rq.ToString();
10875 } 11762 }
10876 11763/*
11764 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11765 {
11766 m_SayShoutCount = 0;
11767 }
11768*/
10877 private struct Tri 11769 private struct Tri
10878 { 11770 {
10879 public Vector3 p1; 11771 public Vector3 p1;
@@ -11013,9 +11905,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11013 11905
11014 ContactResult result = new ContactResult (); 11906 ContactResult result = new ContactResult ();
11015 result.ConsumerID = group.LocalId; 11907 result.ConsumerID = group.LocalId;
11016 result.Depth = intersection.distance; 11908// result.Depth = intersection.distance;
11017 result.Normal = intersection.normal; 11909 result.Normal = intersection.normal;
11018 result.Pos = intersection.ipoint; 11910 result.Pos = intersection.ipoint;
11911 result.Depth = Vector3.Mag(rayStart - result.Pos);
11019 11912
11020 contacts.Add(result); 11913 contacts.Add(result);
11021 }); 11914 });
@@ -11148,6 +12041,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11148 12041
11149 return contacts[0]; 12042 return contacts[0];
11150 } 12043 }
12044/*
12045 // not done:
12046 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12047 {
12048 ContactResult[] contacts = null;
12049 World.ForEachSOG(delegate(SceneObjectGroup group)
12050 {
12051 if (m_host.ParentGroup == group)
12052 return;
12053
12054 if (group.IsAttachment)
12055 return;
12056
12057 if(group.RootPart.PhysActor != null)
12058 return;
12059
12060 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12061 });
12062 return contacts;
12063 }
12064*/
11151 12065
11152 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12066 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11153 { 12067 {
@@ -11189,32 +12103,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11189 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12103 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11190 12104
11191 12105
11192 if (checkTerrain) 12106 if (World.SuportsRayCastFiltered())
11193 { 12107 {
11194 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12108 if (dist == 0)
11195 if (groundContact != null) 12109 return list;
11196 results.Add((ContactResult)groundContact);
11197 }
11198 12110
11199 if (checkAgents) 12111 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11200 { 12112 if (checkTerrain)
11201 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12113 rayfilter |= RayFilterFlags.land;
11202 foreach (ContactResult r in agentHits) 12114// if (checkAgents)
11203 results.Add(r); 12115// rayfilter |= RayFilterFlags.agent;
11204 } 12116 if (checkPhysical)
12117 rayfilter |= RayFilterFlags.physical;
12118 if (checkNonPhysical)
12119 rayfilter |= RayFilterFlags.nonphysical;
12120 if (detectPhantom)
12121 rayfilter |= RayFilterFlags.LSLPhanton;
12122
12123 Vector3 direction = dir * ( 1/dist);
12124
12125 if(rayfilter == 0)
12126 {
12127 list.Add(new LSL_Integer(0));
12128 return list;
12129 }
12130
12131 // get some more contacts to sort ???
12132 int physcount = 4 * count;
12133 if (physcount > 20)
12134 physcount = 20;
12135
12136 object physresults;
12137 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12138
12139 if (physresults == null)
12140 {
12141 list.Add(new LSL_Integer(-3)); // timeout error
12142 return list;
12143 }
11205 12144
11206 if (checkPhysical || checkNonPhysical || detectPhantom) 12145 results = (List<ContactResult>)physresults;
12146
12147 // for now physics doesn't detect sitted avatars so do it outside physics
12148 if (checkAgents)
12149 {
12150 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12151 foreach (ContactResult r in agentHits)
12152 results.Add(r);
12153 }
12154
12155 // TODO: Replace this with a better solution. ObjectIntersection can only
12156 // detect nonphysical phantoms. They are detected by virtue of being
12157 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12158 // physicsl phantoms as done by the physics scene
12159 // We don't want anything else but phantoms here.
12160 if (detectPhantom)
12161 {
12162 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12163 foreach (ContactResult r in objectHits)
12164 results.Add(r);
12165 }
12166 }
12167 else
11207 { 12168 {
11208 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12169 if (checkTerrain)
11209 foreach (ContactResult r in objectHits) 12170 {
11210 results.Add(r); 12171 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12172 if (groundContact != null)
12173 results.Add((ContactResult)groundContact);
12174 }
12175
12176 if (checkAgents)
12177 {
12178 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12179 foreach (ContactResult r in agentHits)
12180 results.Add(r);
12181 }
12182
12183 if (checkPhysical || checkNonPhysical || detectPhantom)
12184 {
12185 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12186 foreach (ContactResult r in objectHits)
12187 results.Add(r);
12188 }
11211 } 12189 }
11212 12190
11213 results.Sort(delegate(ContactResult a, ContactResult b) 12191 results.Sort(delegate(ContactResult a, ContactResult b)
11214 { 12192 {
11215 return a.Depth.CompareTo(b.Depth); 12193 return a.Depth.CompareTo(b.Depth);
11216 }); 12194 });
11217 12195
11218 int values = 0; 12196 int values = 0;
11219 SceneObjectGroup thisgrp = m_host.ParentGroup; 12197 SceneObjectGroup thisgrp = m_host.ParentGroup;
11220 12198
@@ -11307,7 +12285,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11307 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12285 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11308 if (!isAccount) return 0; 12286 if (!isAccount) return 0;
11309 if (estate.HasAccess(id)) return 1; 12287 if (estate.HasAccess(id)) return 1;
11310 if (estate.IsBanned(id)) 12288 if (estate.IsBanned(id, World.GetUserFlags(id)))
11311 estate.RemoveBan(id); 12289 estate.RemoveBan(id);
11312 estate.AddEstateUser(id); 12290 estate.AddEstateUser(id);
11313 break; 12291 break;
@@ -11326,14 +12304,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11326 break; 12304 break;
11327 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12305 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11328 if (!isAccount) return 0; 12306 if (!isAccount) return 0;
11329 if (estate.IsBanned(id)) return 1; 12307 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11330 EstateBan ban = new EstateBan(); 12308 EstateBan ban = new EstateBan();
11331 ban.EstateID = estate.EstateID; 12309 ban.EstateID = estate.EstateID;
11332 ban.BannedUserID = id; 12310 ban.BannedUserID = id;
11333 estate.AddBan(ban); 12311 estate.AddBan(ban);
11334 break; 12312 break;
11335 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12313 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11336 if (!isAccount || !estate.IsBanned(id)) return 0; 12314 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11337 estate.RemoveBan(id); 12315 estate.RemoveBan(id);
11338 break; 12316 break;
11339 default: return 0; 12317 default: return 0;
@@ -11362,7 +12340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11362 return 16384; 12340 return 16384;
11363 } 12341 }
11364 12342
11365 public LSL_Integer llGetUsedMemory() 12343 public virtual LSL_Integer llGetUsedMemory()
11366 { 12344 {
11367 m_host.AddScriptLPS(1); 12345 m_host.AddScriptLPS(1);
11368 // The value returned for LSO scripts in SL 12346 // The value returned for LSO scripts in SL
@@ -11390,22 +12368,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11390 public void llSetSoundQueueing(int queue) 12368 public void llSetSoundQueueing(int queue)
11391 { 12369 {
11392 m_host.AddScriptLPS(1); 12370 m_host.AddScriptLPS(1);
11393 NotImplemented("llSetSoundQueueing");
11394 } 12371 }
11395 12372
11396 public void llCollisionSprite(string impact_sprite) 12373 public void llCollisionSprite(string impact_sprite)
11397 { 12374 {
11398 m_host.AddScriptLPS(1); 12375 m_host.AddScriptLPS(1);
11399 NotImplemented("llCollisionSprite"); 12376 // Viewer 2.0 broke this and it's likely LL has no intention
12377 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11400 } 12378 }
11401 12379
11402 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12380 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11403 { 12381 {
11404 m_host.AddScriptLPS(1); 12382 m_host.AddScriptLPS(1);
11405 NotImplemented("llGodLikeRezObject"); 12383
12384 if (!World.Permissions.IsGod(m_host.OwnerID))
12385 NotImplemented("llGodLikeRezObject");
12386
12387 AssetBase rezAsset = World.AssetService.Get(inventory);
12388 if (rezAsset == null)
12389 {
12390 llSay(0, "Asset not found");
12391 return;
12392 }
12393
12394 SceneObjectGroup group = null;
12395
12396 try
12397 {
12398 string xmlData = Utils.BytesToString(rezAsset.Data);
12399 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12400 }
12401 catch
12402 {
12403 llSay(0, "Asset not found");
12404 return;
12405 }
12406
12407 if (group == null)
12408 {
12409 llSay(0, "Asset not found");
12410 return;
12411 }
12412
12413 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12414 group.RootPart.AttachOffset = group.AbsolutePosition;
12415
12416 group.ResetIDs();
12417
12418 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12419 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12420 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12421 group.ScheduleGroupForFullUpdate();
12422
12423 // objects rezzed with this method are die_at_edge by default.
12424 group.RootPart.SetDieAtEdge(true);
12425
12426 group.ResumeScripts();
12427
12428 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12429 "object_rez", new Object[] {
12430 new LSL_String(
12431 group.RootPart.UUID.ToString()) },
12432 new DetectParams[0]));
12433 }
12434
12435 public LSL_String llTransferLindenDollars(string destination, int amount)
12436 {
12437 UUID txn = UUID.Random();
12438
12439 Util.FireAndForget(delegate(object x)
12440 {
12441 int replycode = 0;
12442 string replydata = destination + "," + amount.ToString();
12443
12444 try
12445 {
12446 TaskInventoryItem item = m_item;
12447 if (item == null)
12448 {
12449 replydata = "SERVICE_ERROR";
12450 return;
12451 }
12452
12453 m_host.AddScriptLPS(1);
12454
12455 if (item.PermsGranter == UUID.Zero)
12456 {
12457 replydata = "MISSING_PERMISSION_DEBIT";
12458 return;
12459 }
12460
12461 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12462 {
12463 replydata = "MISSING_PERMISSION_DEBIT";
12464 return;
12465 }
12466
12467 UUID toID = new UUID();
12468
12469 if (!UUID.TryParse(destination, out toID))
12470 {
12471 replydata = "INVALID_AGENT";
12472 return;
12473 }
12474
12475 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12476
12477 if (money == null)
12478 {
12479 replydata = "TRANSFERS_DISABLED";
12480 return;
12481 }
12482
12483 bool result = money.ObjectGiveMoney(
12484 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12485
12486 if (result)
12487 {
12488 replycode = 1;
12489 return;
12490 }
12491
12492 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12493 }
12494 finally
12495 {
12496 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12497 "transaction_result", new Object[] {
12498 new LSL_String(txn.ToString()),
12499 new LSL_Integer(replycode),
12500 new LSL_String(replydata) },
12501 new DetectParams[0]));
12502 }
12503 });
12504
12505 return txn.ToString();
11406 } 12506 }
11407 12507
11408 #endregion 12508 #endregion
12509
12510 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12511 {
12512 SceneObjectGroup group = m_host.ParentGroup;
12513
12514 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12515 return;
12516 if (group.IsAttachment)
12517 return;
12518
12519 if (frames.Data.Length > 0) // We are getting a new motion
12520 {
12521 if (group.RootPart.KeyframeMotion != null)
12522 group.RootPart.KeyframeMotion.Delete();
12523 group.RootPart.KeyframeMotion = null;
12524
12525 int idx = 0;
12526
12527 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12528 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12529
12530 while (idx < options.Data.Length)
12531 {
12532 int option = (int)options.GetLSLIntegerItem(idx++);
12533 int remain = options.Data.Length - idx;
12534
12535 switch (option)
12536 {
12537 case ScriptBaseClass.KFM_MODE:
12538 if (remain < 1)
12539 break;
12540 int modeval = (int)options.GetLSLIntegerItem(idx++);
12541 switch(modeval)
12542 {
12543 case ScriptBaseClass.KFM_FORWARD:
12544 mode = KeyframeMotion.PlayMode.Forward;
12545 break;
12546 case ScriptBaseClass.KFM_REVERSE:
12547 mode = KeyframeMotion.PlayMode.Reverse;
12548 break;
12549 case ScriptBaseClass.KFM_LOOP:
12550 mode = KeyframeMotion.PlayMode.Loop;
12551 break;
12552 case ScriptBaseClass.KFM_PING_PONG:
12553 mode = KeyframeMotion.PlayMode.PingPong;
12554 break;
12555 }
12556 break;
12557 case ScriptBaseClass.KFM_DATA:
12558 if (remain < 1)
12559 break;
12560 int dataval = (int)options.GetLSLIntegerItem(idx++);
12561 data = (KeyframeMotion.DataFormat)dataval;
12562 break;
12563 }
12564 }
12565
12566 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12567
12568 idx = 0;
12569
12570 int elemLength = 2;
12571 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12572 elemLength = 3;
12573
12574 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12575 while (idx < frames.Data.Length)
12576 {
12577 int remain = frames.Data.Length - idx;
12578
12579 if (remain < elemLength)
12580 break;
12581
12582 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12583 frame.Position = null;
12584 frame.Rotation = null;
12585
12586 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12587 {
12588 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12589 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12590 }
12591 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12592 {
12593 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12594 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12595 }
12596
12597 float tempf = (float)frames.GetLSLFloatItem(idx++);
12598 frame.TimeMS = (int)(tempf * 1000.0f);
12599
12600 keyframes.Add(frame);
12601 }
12602
12603 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12604 group.RootPart.KeyframeMotion.Start();
12605 }
12606 else
12607 {
12608 if (group.RootPart.KeyframeMotion == null)
12609 return;
12610
12611 if (options.Data.Length == 0)
12612 {
12613 group.RootPart.KeyframeMotion.Stop();
12614 return;
12615 }
12616
12617 int code = (int)options.GetLSLIntegerItem(0);
12618
12619 int idx = 0;
12620
12621 while (idx < options.Data.Length)
12622 {
12623 int option = (int)options.GetLSLIntegerItem(idx++);
12624 int remain = options.Data.Length - idx;
12625
12626 switch (option)
12627 {
12628 case ScriptBaseClass.KFM_COMMAND:
12629 int cmd = (int)options.GetLSLIntegerItem(idx++);
12630 switch (cmd)
12631 {
12632 case ScriptBaseClass.KFM_CMD_PLAY:
12633 group.RootPart.KeyframeMotion.Start();
12634 break;
12635 case ScriptBaseClass.KFM_CMD_STOP:
12636 group.RootPart.KeyframeMotion.Stop();
12637 break;
12638 case ScriptBaseClass.KFM_CMD_PAUSE:
12639 group.RootPart.KeyframeMotion.Pause();
12640 break;
12641 }
12642 break;
12643 }
12644 }
12645 }
12646 }
12647
12648 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12649 {
12650 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12651
12652 int idx = 0;
12653 int idxStart = 0;
12654
12655 bool positionChanged = false;
12656 Vector3 finalPos = Vector3.Zero;
12657
12658 try
12659 {
12660 while (idx < rules.Length)
12661 {
12662 ++rulesParsed;
12663 int code = rules.GetLSLIntegerItem(idx++);
12664
12665 int remain = rules.Length - idx;
12666 idxStart = idx;
12667
12668 switch (code)
12669 {
12670 case (int)ScriptBaseClass.PRIM_POSITION:
12671 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12672 {
12673 if (remain < 1)
12674 return null;
12675
12676 LSL_Vector v;
12677 v = rules.GetVector3Item(idx++);
12678
12679 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12680 if (part == null)
12681 break;
12682
12683 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12684 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12685 if (part.LinkNum > 1)
12686 {
12687 localRot = GetPartLocalRot(part);
12688 localPos = GetPartLocalPos(part);
12689 }
12690
12691 v -= localPos;
12692 v /= localRot;
12693
12694 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12695
12696 v = v + 2 * sitOffset;
12697
12698 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12699 av.SendAvatarDataToAllAgents();
12700
12701 }
12702 break;
12703
12704 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12705 case (int)ScriptBaseClass.PRIM_ROTATION:
12706 {
12707 if (remain < 1)
12708 return null;
12709
12710 LSL_Rotation r;
12711 r = rules.GetQuaternionItem(idx++);
12712
12713 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12714 if (part == null)
12715 break;
12716
12717 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12718 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12719
12720 if (part.LinkNum > 1)
12721 localRot = GetPartLocalRot(part);
12722
12723 r = r * llGetRootRotation() / localRot;
12724 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12725 av.SendAvatarDataToAllAgents();
12726 }
12727 break;
12728
12729 // parse rest doing nothing but number of parameters error check
12730 case (int)ScriptBaseClass.PRIM_SIZE:
12731 case (int)ScriptBaseClass.PRIM_MATERIAL:
12732 case (int)ScriptBaseClass.PRIM_PHANTOM:
12733 case (int)ScriptBaseClass.PRIM_PHYSICS:
12734 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12735 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12736 case (int)ScriptBaseClass.PRIM_NAME:
12737 case (int)ScriptBaseClass.PRIM_DESC:
12738 if (remain < 1)
12739 return null;
12740 idx++;
12741 break;
12742
12743 case (int)ScriptBaseClass.PRIM_GLOW:
12744 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12745 case (int)ScriptBaseClass.PRIM_TEXGEN:
12746 if (remain < 2)
12747 return null;
12748 idx += 2;
12749 break;
12750
12751 case (int)ScriptBaseClass.PRIM_TYPE:
12752 if (remain < 3)
12753 return null;
12754 code = (int)rules.GetLSLIntegerItem(idx++);
12755 remain = rules.Length - idx;
12756 switch (code)
12757 {
12758 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12759 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12760 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12761 if (remain < 6)
12762 return null;
12763 idx += 6;
12764 break;
12765
12766 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12767 if (remain < 5)
12768 return null;
12769 idx += 5;
12770 break;
12771
12772 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12773 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12774 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12775 if (remain < 11)
12776 return null;
12777 idx += 11;
12778 break;
12779
12780 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12781 if (remain < 2)
12782 return null;
12783 idx += 2;
12784 break;
12785 }
12786 break;
12787
12788 case (int)ScriptBaseClass.PRIM_COLOR:
12789 case (int)ScriptBaseClass.PRIM_TEXT:
12790 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12791 case (int)ScriptBaseClass.PRIM_OMEGA:
12792 if (remain < 3)
12793 return null;
12794 idx += 3;
12795 break;
12796
12797 case (int)ScriptBaseClass.PRIM_TEXTURE:
12798 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12799 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12800 if (remain < 5)
12801 return null;
12802 idx += 5;
12803 break;
12804
12805 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12806 if (remain < 7)
12807 return null;
12808
12809 idx += 7;
12810 break;
12811
12812 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12813 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12814 return null;
12815
12816 return rules.GetSublist(idx, -1);
12817 }
12818 }
12819 }
12820 catch (InvalidCastException e)
12821 {
12822 ShoutError(string.Format(
12823 "{0} error running rule #{1}: arg #{2} ",
12824 originFunc, rulesParsed, idx - idxStart) + e.Message);
12825 }
12826 finally
12827 {
12828 if (positionChanged)
12829 {
12830 av.OffsetPosition = finalPos;
12831// av.SendAvatarDataToAllAgents();
12832 av.SendTerseUpdateToAllClients();
12833 positionChanged = false;
12834 }
12835 }
12836 return null;
12837 }
12838
12839 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12840 {
12841 // avatars case
12842 // replies as SL wiki
12843
12844// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12845 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12846
12847 int idx = 0;
12848 while (idx < rules.Length)
12849 {
12850 int code = (int)rules.GetLSLIntegerItem(idx++);
12851 int remain = rules.Length - idx;
12852
12853 switch (code)
12854 {
12855 case (int)ScriptBaseClass.PRIM_MATERIAL:
12856 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12857 break;
12858
12859 case (int)ScriptBaseClass.PRIM_PHYSICS:
12860 res.Add(new LSL_Integer(0));
12861 break;
12862
12863 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12864 res.Add(new LSL_Integer(0));
12865 break;
12866
12867 case (int)ScriptBaseClass.PRIM_PHANTOM:
12868 res.Add(new LSL_Integer(0));
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_POSITION:
12872
12873 Vector3 pos = avatar.OffsetPosition;
12874
12875 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12876 pos -= sitOffset;
12877
12878 if( sitPart != null)
12879 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12880
12881 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12882 break;
12883
12884 case (int)ScriptBaseClass.PRIM_SIZE:
12885 // as in llGetAgentSize above
12886 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12887 break;
12888
12889 case (int)ScriptBaseClass.PRIM_ROTATION:
12890 Quaternion rot = avatar.Rotation;
12891 if (sitPart != null)
12892 {
12893 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12894 }
12895
12896 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12897 break;
12898
12899 case (int)ScriptBaseClass.PRIM_TYPE:
12900 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12901 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12902 res.Add(new LSL_Vector(0f,1.0f,0f));
12903 res.Add(new LSL_Float(0.0f));
12904 res.Add(new LSL_Vector(0, 0, 0));
12905 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12906 res.Add(new LSL_Vector(0, 0, 0));
12907 break;
12908
12909 case (int)ScriptBaseClass.PRIM_TEXTURE:
12910 if (remain < 1)
12911 return null;
12912
12913 int face = (int)rules.GetLSLIntegerItem(idx++);
12914 if (face == ScriptBaseClass.ALL_SIDES)
12915 {
12916 for (face = 0; face < 21; face++)
12917 {
12918 res.Add(new LSL_String(""));
12919 res.Add(new LSL_Vector(0,0,0));
12920 res.Add(new LSL_Vector(0,0,0));
12921 res.Add(new LSL_Float(0.0));
12922 }
12923 }
12924 else
12925 {
12926 if (face >= 0 && face < 21)
12927 {
12928 res.Add(new LSL_String(""));
12929 res.Add(new LSL_Vector(0,0,0));
12930 res.Add(new LSL_Vector(0,0,0));
12931 res.Add(new LSL_Float(0.0));
12932 }
12933 }
12934 break;
12935
12936 case (int)ScriptBaseClass.PRIM_COLOR:
12937 if (remain < 1)
12938 return null;
12939
12940 face = (int)rules.GetLSLIntegerItem(idx++);
12941
12942 if (face == ScriptBaseClass.ALL_SIDES)
12943 {
12944 for (face = 0; face < 21; face++)
12945 {
12946 res.Add(new LSL_Vector(0,0,0));
12947 res.Add(new LSL_Float(0));
12948 }
12949 }
12950 else
12951 {
12952 res.Add(new LSL_Vector(0,0,0));
12953 res.Add(new LSL_Float(0));
12954 }
12955 break;
12956
12957 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12958 if (remain < 1)
12959 return null;
12960 face = (int)rules.GetLSLIntegerItem(idx++);
12961
12962 if (face == ScriptBaseClass.ALL_SIDES)
12963 {
12964 for (face = 0; face < 21; face++)
12965 {
12966 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12967 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12968 }
12969 }
12970 else
12971 {
12972 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12973 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12974 }
12975 break;
12976
12977 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12978 if (remain < 1)
12979 return null;
12980 face = (int)rules.GetLSLIntegerItem(idx++);
12981
12982 if (face == ScriptBaseClass.ALL_SIDES)
12983 {
12984 for (face = 0; face < 21; face++)
12985 {
12986 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12987 }
12988 }
12989 else
12990 {
12991 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12992 }
12993 break;
12994
12995 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12996 res.Add(new LSL_Integer(0));
12997 res.Add(new LSL_Integer(0));// softness
12998 res.Add(new LSL_Float(0.0f)); // gravity
12999 res.Add(new LSL_Float(0.0f)); // friction
13000 res.Add(new LSL_Float(0.0f)); // wind
13001 res.Add(new LSL_Float(0.0f)); // tension
13002 res.Add(new LSL_Vector(0f,0f,0f));
13003 break;
13004
13005 case (int)ScriptBaseClass.PRIM_TEXGEN:
13006 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13007 if (remain < 1)
13008 return null;
13009 face = (int)rules.GetLSLIntegerItem(idx++);
13010
13011 if (face == ScriptBaseClass.ALL_SIDES)
13012 {
13013 for (face = 0; face < 21; face++)
13014 {
13015 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13016 }
13017 }
13018 else
13019 {
13020 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13021 }
13022 break;
13023
13024 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13025 res.Add(new LSL_Integer(0));
13026 res.Add(new LSL_Vector(0f,0f,0f));
13027 res.Add(new LSL_Float(0f)); // intensity
13028 res.Add(new LSL_Float(0f)); // radius
13029 res.Add(new LSL_Float(0f)); // falloff
13030 break;
13031
13032 case (int)ScriptBaseClass.PRIM_GLOW:
13033 if (remain < 1)
13034 return null;
13035 face = (int)rules.GetLSLIntegerItem(idx++);
13036
13037 if (face == ScriptBaseClass.ALL_SIDES)
13038 {
13039 for (face = 0; face < 21; face++)
13040 {
13041 res.Add(new LSL_Float(0f));
13042 }
13043 }
13044 else
13045 {
13046 res.Add(new LSL_Float(0f));
13047 }
13048 break;
13049
13050 case (int)ScriptBaseClass.PRIM_TEXT:
13051 res.Add(new LSL_String(""));
13052 res.Add(new LSL_Vector(0f,0f,0f));
13053 res.Add(new LSL_Float(1.0f));
13054 break;
13055
13056 case (int)ScriptBaseClass.PRIM_NAME:
13057 res.Add(new LSL_String(avatar.Name));
13058 break;
13059
13060 case (int)ScriptBaseClass.PRIM_DESC:
13061 res.Add(new LSL_String(""));
13062 break;
13063
13064 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13065 Quaternion lrot = avatar.Rotation;
13066
13067 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13068 {
13069 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13070 }
13071 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13072 break;
13073
13074 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13075 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13076 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13077 lpos -= lsitOffset;
13078
13079 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13080 {
13081 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13082 }
13083 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13084 break;
13085
13086 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13087 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13088 return null;
13089
13090 return rules.GetSublist(idx, -1);
13091 }
13092 }
13093
13094 return null;
13095 }
11409 } 13096 }
11410 13097
11411 public class NotecardCache 13098 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 8b73cd9..160e2df 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;
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
147 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
148 m_host = host; 149 m_host = host;
149 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
150 152
151 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
152 154
@@ -210,7 +212,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
210 212
211 internal void OSSLError(string msg) 213 internal void OSSLError(string msg)
212 { 214 {
213 throw new Exception("OSSL Runtime Error: " + msg); 215 if (m_debuggerSafe)
216 {
217 OSSLShoutError(msg);
218 }
219 else
220 {
221 throw new Exception("OSSL Runtime Error: " + msg);
222 }
214 } 223 }
215 224
216 /// <summary> 225 /// <summary>
@@ -918,18 +927,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 if (target != null) 927 if (target != null)
919 { 928 {
920 UUID animID=UUID.Zero; 929 UUID animID=UUID.Zero;
921 lock (m_host.TaskInventory) 930 m_host.TaskInventory.LockItemsForRead(true);
931 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
922 { 932 {
923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 933 if (inv.Value.Name == animation)
924 { 934 {
925 if (inv.Value.Name == animation) 935 if (inv.Value.Type == (int)AssetType.Animation)
926 { 936 animID = inv.Value.AssetID;
927 if (inv.Value.Type == (int)AssetType.Animation) 937 continue;
928 animID = inv.Value.AssetID;
929 continue;
930 }
931 } 938 }
932 } 939 }
940 m_host.TaskInventory.LockItemsForRead(false);
933 if (animID == UUID.Zero) 941 if (animID == UUID.Zero)
934 target.Animator.AddAnimation(animation, m_host.UUID); 942 target.Animator.AddAnimation(animation, m_host.UUID);
935 else 943 else
@@ -970,6 +978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
970 else 978 else
971 animID = UUID.Zero; 979 animID = UUID.Zero;
972 } 980 }
981 m_host.TaskInventory.LockItemsForRead(false);
973 982
974 if (animID == UUID.Zero) 983 if (animID == UUID.Zero)
975 target.Animator.RemoveAnimation(animation); 984 target.Animator.RemoveAnimation(animation);
@@ -1808,6 +1817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 1817
1809 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1818 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1810 { 1819 {
1820 m_host.TaskInventory.LockItemsForRead(true);
1811 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1821 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1812 { 1822 {
1813 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1823 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1815,6 +1825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1815 assetID = item.AssetID; 1825 assetID = item.AssetID;
1816 } 1826 }
1817 } 1827 }
1828 m_host.TaskInventory.LockItemsForRead(false);
1818 } 1829 }
1819 1830
1820 if (assetID == UUID.Zero) 1831 if (assetID == UUID.Zero)
@@ -2300,7 +2311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2300 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2311 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2301 m_host.AddScriptLPS(1); 2312 m_host.AddScriptLPS(1);
2302 2313
2303 return NpcCreate(firstname, lastname, position, notecard, false, false); 2314 return NpcCreate(firstname, lastname, position, notecard, true, false);
2304 } 2315 }
2305 2316
2306 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2317 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2311,24 +2322,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2311 return NpcCreate( 2322 return NpcCreate(
2312 firstname, lastname, position, notecard, 2323 firstname, lastname, position, notecard,
2313 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2324 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2314 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2325 false);
2326// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2315 } 2327 }
2316 2328
2317 private LSL_Key NpcCreate( 2329 private LSL_Key NpcCreate(
2318 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2330 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2319 { 2331 {
2332 if (!owned)
2333 OSSLError("Unowned NPCs are unsupported");
2334
2335 string groupTitle = String.Empty;
2336
2337 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2338 return new LSL_Key(UUID.Zero.ToString());
2339
2340 if (firstname != String.Empty || lastname != String.Empty)
2341 {
2342 if (firstname != "Shown outfit:")
2343 groupTitle = "- NPC -";
2344 }
2345
2320 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2346 INPCModule module = World.RequestModuleInterface<INPCModule>();
2321 if (module != null) 2347 if (module != null)
2322 { 2348 {
2323 AvatarAppearance appearance = null; 2349 AvatarAppearance appearance = null;
2324 2350
2325 UUID id; 2351// UUID id;
2326 if (UUID.TryParse(notecard, out id)) 2352// if (UUID.TryParse(notecard, out id))
2327 { 2353// {
2328 ScenePresence clonePresence = World.GetScenePresence(id); 2354// ScenePresence clonePresence = World.GetScenePresence(id);
2329 if (clonePresence != null) 2355// if (clonePresence != null)
2330 appearance = clonePresence.Appearance; 2356// appearance = clonePresence.Appearance;
2331 } 2357// }
2332 2358
2333 if (appearance == null) 2359 if (appearance == null)
2334 { 2360 {
@@ -2356,6 +2382,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2356 World, 2382 World,
2357 appearance); 2383 appearance);
2358 2384
2385 ScenePresence sp;
2386 if (World.TryGetScenePresence(x, out sp))
2387 {
2388 sp.Grouptitle = groupTitle;
2389 sp.SendAvatarDataToAllAgents();
2390 }
2359 return new LSL_Key(x.ToString()); 2391 return new LSL_Key(x.ToString());
2360 } 2392 }
2361 2393
@@ -2655,16 +2687,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2655 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2687 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2656 m_host.AddScriptLPS(1); 2688 m_host.AddScriptLPS(1);
2657 2689
2658 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2690 ManualResetEvent ev = new ManualResetEvent(false);
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2662 2691
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2692 Util.FireAndForget(delegate(object x) {
2664 return; 2693 try
2694 {
2695 INPCModule module = World.RequestModuleInterface<INPCModule>();
2696 if (module != null)
2697 {
2698 UUID npcId = new UUID(npc.m_string);
2665 2699
2666 module.DeleteNPC(npcId, World); 2700 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2667 } 2701 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2702 {
2703 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2704 return;
2705 }
2706
2707 module.DeleteNPC(npcId, World);
2708 }
2709 }
2710 finally
2711 {
2712 ev.Set();
2713 }
2714 });
2715 ev.WaitOne();
2668 } 2716 }
2669 2717
2670 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2718 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3549,6 +3597,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3549 if (m_UrlModule != null) 3597 if (m_UrlModule != null)
3550 m_UrlModule.HttpContentType(new UUID(id),type); 3598 m_UrlModule.HttpContentType(new UUID(id),type);
3551 } 3599 }
3552 3600 }
3553 } 3601}
3554} \ No newline at end of file
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 24cceea..4dd795d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -475,7 +476,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
475 // Position of a sensor in a child prim attached to an avatar 476 // Position of a sensor in a child prim attached to an avatar
476 // will be still wrong. 477 // will be still wrong.
477 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
478 q = avatar.Rotation * q; 479 if (avatar == null)
480 return sensedEntities;
481 fromRegionPos = avatar.AbsolutePosition;
482 q = avatar.Rotation;
479 } 483 }
480 484
481 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 485 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -491,7 +495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
491// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 495// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
492// presence.Name, presence.PresenceType, ts.name, ts.type); 496// presence.Name, presence.PresenceType, ts.name, ts.type);
493 497
494 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 498 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
495 { 499 {
496 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 500 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
497 if (npcData == null || !npcData.SenseAsAgent) 501 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index e97ff9d..05c20f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
428 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 3985e66..0ea363a 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 60a7e14..c788407 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;
@@ -642,6 +643,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
642 public const int PRIM_MEDIA_PERM_OWNER = 1; 643 public const int PRIM_MEDIA_PERM_OWNER = 1;
643 public const int PRIM_MEDIA_PERM_GROUP = 2; 644 public const int PRIM_MEDIA_PERM_GROUP = 2;
644 public const int PRIM_MEDIA_PERM_ANYONE = 4; 645 public const int PRIM_MEDIA_PERM_ANYONE = 4;
646
647 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
648 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
649 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
650 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
651
652 public const int PRIM_PHYSICS_MATERIAL = 31;
653 public const int DENSITY = 1;
654 public const int FRICTION = 2;
655 public const int RESTITUTION = 4;
656 public const int GRAVITY_MULTIPLIER = 8;
645 657
646 // extra constants for llSetPrimMediaParams 658 // extra constants for llSetPrimMediaParams
647 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 659 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -714,6 +726,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
714 726
715 public static readonly LSLInteger RCERR_UNKNOWN = -1; 727 public static readonly LSLInteger RCERR_UNKNOWN = -1;
716 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 728 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
717 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 729 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
730
731 public const int KFM_MODE = 1;
732 public const int KFM_LOOP = 1;
733 public const int KFM_REVERSE = 3;
734 public const int KFM_FORWARD = 0;
735 public const int KFM_PING_PONG = 2;
736 public const int KFM_DATA = 2;
737 public const int KFM_TRANSLATION = 2;
738 public const int KFM_ROTATION = 1;
739 public const int KFM_COMMAND = 0;
740 public const int KFM_CMD_PLAY = 0;
741 public const int KFM_CMD_STOP = 1;
742 public const int KFM_CMD_PAUSE = 2;
718 } 743 }
719} 744}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 5a58f73..22804f5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -102,6 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 Type = 0; 103 Type = 0;
103 Velocity = new LSL_Types.Vector3(); 104 Velocity = new LSL_Types.Vector3();
104 initializeSurfaceTouch(); 105 initializeSurfaceTouch();
106 Country = String.Empty;
105 } 107 }
106 108
107 public UUID Key; 109 public UUID Key;
@@ -133,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
133 private int touchFace; 135 private int touchFace;
134 public int TouchFace { get { return touchFace; } } 136 public int TouchFace { get { return touchFace; } }
135 137
138 public string Country;
139
136 // This can be done in two places including the constructor 140 // This can be done in two places including the constructor
137 // so be carefull what gets added here 141 // so be carefull what gets added here
138 private void initializeSurfaceTouch() 142 private void initializeSurfaceTouch()
@@ -180,6 +184,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
180 return; 184 return;
181 185
182 Name = presence.Firstname + " " + presence.Lastname; 186 Name = presence.Firstname + " " + presence.Lastname;
187 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
188 if (account != null)
189 Country = account.UserCountry;
190
183 Owner = Key; 191 Owner = Key;
184 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 192 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
185 Rotation = new LSL_Types.Quaternion( 193 Rotation = new LSL_Types.Quaternion(
@@ -189,22 +197,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 presence.Rotation.W); 197 presence.Rotation.W);
190 Velocity = new LSL_Types.Vector3(presence.Velocity); 198 Velocity = new LSL_Types.Vector3(presence.Velocity);
191 199
192 if (presence.PresenceType != PresenceType.Npc) 200 Type = 0x01; // Avatar
193 { 201 if (presence.PresenceType == PresenceType.Npc)
194 Type = AGENT; 202 Type = 0x20;
195 } 203
196 else 204 // Cope Impl. We don't use OS_NPC.
197 { 205 //if (presence.PresenceType != PresenceType.Npc)
198 Type = OS_NPC; 206 //{
199 207 // Type = AGENT;
200 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 208 //}
201 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 209 //else
202 210 //{
203 if (npcData.SenseAsAgent) 211 // Type = OS_NPC;
204 { 212
205 Type |= AGENT; 213 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
206 } 214 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
207 } 215
216 // if (npcData.SenseAsAgent)
217 // {
218 // Type |= AGENT;
219 // }
220 //}
208 221
209 if (presence.Velocity != Vector3.Zero) 222 if (presence.Velocity != Vector3.Zero)
210 Type |= ACTIVE; 223 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5793cc9..771db0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -417,14 +417,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
417 { 417 {
418 int permsMask; 418 int permsMask;
419 UUID permsGranter; 419 UUID permsGranter;
420 lock (part.TaskInventory) 420 part.TaskInventory.LockItemsForRead(true);
421 if (!part.TaskInventory.ContainsKey(ItemID))
421 { 422 {
422 if (!part.TaskInventory.ContainsKey(ItemID)) 423 part.TaskInventory.LockItemsForRead(false);
423 return; 424 return;
424
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 } 425 }
426 permsGranter = part.TaskInventory[ItemID].PermsGranter;
427 permsMask = part.TaskInventory[ItemID].PermsMask;
428 part.TaskInventory.LockItemsForRead(false);
428 429
429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 430 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
430 { 431 {
@@ -552,6 +553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 return true; 553 return true;
553 } 554 }
554 555
556 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
555 public void SetState(string state) 557 public void SetState(string state)
556 { 558 {
557 if (state == State) 559 if (state == State)
@@ -563,7 +565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 new DetectParams[0])); 565 new DetectParams[0]));
564 PostEvent(new EventParams("state_entry", new Object[0], 566 PostEvent(new EventParams("state_entry", new Object[0],
565 new DetectParams[0])); 567 new DetectParams[0]));
566 568
567 throw new EventAbortException(); 569 throw new EventAbortException();
568 } 570 }
569 571
@@ -653,45 +655,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
653 /// <returns></returns> 655 /// <returns></returns>
654 public object EventProcessor() 656 public object EventProcessor()
655 { 657 {
658 EventParams data = null;
656 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 659 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
657 if (!Running) 660 if (!Running)
658 return 0; 661 return 0;
659 662
660 lock (m_Script)
661 {
662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 663// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
663 664
664 if (Suspended) 665 if (Suspended)
665 return 0; 666 return 0;
666
667 EventParams data = null;
668 667
669 lock (EventQueue) 668 lock (EventQueue)
669 {
670 data = (EventParams) EventQueue.Dequeue();
671 if (data == null) // Shouldn't happen
670 { 672 {
671 data = (EventParams)EventQueue.Dequeue(); 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
672 if (data == null) // Shouldn't happen
673 { 674 {
674 if (EventQueue.Count > 0 && Running && !ShuttingDown) 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 {
676 m_CurrentWorkItem = Engine.QueueEventHandler(this);
677 }
678 else
679 {
680 m_CurrentWorkItem = null;
681 }
682 return 0;
683 } 676 }
684 677 else
685 if (data.EventName == "timer")
686 m_TimerQueued = false;
687 if (data.EventName == "control")
688 { 678 {
689 if (m_ControlEventsInQueue > 0) 679 m_CurrentWorkItem = null;
690 m_ControlEventsInQueue--;
691 } 680 }
692 if (data.EventName == "collision") 681 return 0;
693 m_CollisionInQueue = false;
694 } 682 }
683
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 {
688 if (m_ControlEventsInQueue > 0)
689 m_ControlEventsInQueue--;
690 }
691 if (data.EventName == "collision")
692 m_CollisionInQueue = false;
693 }
694
695 lock(m_Script)
696 {
695 697
696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 698// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
697 699
@@ -846,6 +848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
851 part.CollisionSound = UUID.Zero;
849 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 852 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
850 EventQueue.Clear(); 853 EventQueue.Clear();
851 m_Script.ResetVars(); 854 m_Script.ResetVars();
@@ -860,6 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 863 new Object[0], new DetectParams[0]));
861 } 864 }
862 865
866 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 867 public void ApiResetScript()
864 { 868 {
865 // bool running = Running; 869 // bool running = Running;
@@ -871,6 +875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
871 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 875 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
872 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 876 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
873 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 877 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
878 part.CollisionSound = UUID.Zero;
874 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 879 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
875 880
876 EventQueue.Clear(); 881 EventQueue.Clear();
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index fcb98a5..c9c4753 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)
@@ -686,24 +688,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
686 688
687 public static bool operator ==(list a, list b) 689 public static bool operator ==(list a, list b)
688 { 690 {
689 int la = -1; 691 int la = a.Length;
690 int lb = -1; 692 int lb = b.Length;
691 try { la = a.Length; }
692 catch (NullReferenceException) { }
693 try { lb = b.Length; }
694 catch (NullReferenceException) { }
695 693
696 return la == lb; 694 return la == lb;
697 } 695 }
698 696
699 public static bool operator !=(list a, list b) 697 public static bool operator !=(list a, list b)
700 { 698 {
701 int la = -1; 699 int la = a.Length;
702 int lb = -1; 700 int lb = b.Length;
703 try { la = a.Length; }
704 catch (NullReferenceException) { }
705 try {lb = b.Length;}
706 catch (NullReferenceException) { }
707 701
708 return la != lb; 702 return la != lb;
709 } 703 }
@@ -937,7 +931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
937 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 931 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
938 } 932 }
939 933
940 if (ascending == 0) 934 if (ascending != 1)
941 { 935 {
942 ret = 0 - ret; 936 ret = 0 - ret;
943 } 937 }
@@ -970,6 +964,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
970 stride = 1; 964 stride = 1;
971 } 965 }
972 966
967 if ((Data.Length % stride) != 0)
968 return new list(ret);
969
973 // we can optimize here in the case where stride == 1 and the list 970 // we can optimize here in the case where stride == 1 and the list
974 // consists of homogeneous types 971 // consists of homogeneous types
975 972
@@ -989,7 +986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
989 if (homogeneous) 986 if (homogeneous)
990 { 987 {
991 Array.Sort(ret, new HomogeneousComparer()); 988 Array.Sort(ret, new HomogeneousComparer());
992 if (ascending == 0) 989 if (ascending != 1)
993 { 990 {
994 Array.Reverse(ret); 991 Array.Reverse(ret);
995 } 992 }