aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-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.cs116
-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
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs378
19 files changed, 3236 insertions, 1042 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 7fa6f05..d8da173 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);
@@ -4041,109 +4400,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4041 { 4400 {
4042 m_host.AddScriptLPS(1); 4401 m_host.AddScriptLPS(1);
4043 4402
4044 UUID uuid = (UUID)id; 4403 UUID uuid;
4045 PresenceInfo pinfo = null; 4404 if (UUID.TryParse(id, out uuid))
4046 UserAccount account;
4047
4048 UserInfoCacheEntry ce;
4049 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4050 { 4405 {
4051 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4406 PresenceInfo pinfo = null;
4052 if (account == null) 4407 UserAccount account;
4408
4409 UserInfoCacheEntry ce;
4410 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4053 { 4411 {
4054 m_userInfoCache[uuid] = null; // Cache negative 4412 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4055 return UUID.Zero.ToString(); 4413 if (account == null)
4056 } 4414 {
4415 m_userInfoCache[uuid] = null; // Cache negative
4416 return UUID.Zero.ToString();
4417 }
4057 4418
4058 4419
4059 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4420 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4060 if (pinfos != null && pinfos.Length > 0) 4421 if (pinfos != null && pinfos.Length > 0)
4061 {
4062 foreach (PresenceInfo p in pinfos)
4063 { 4422 {
4064 if (p.RegionID != UUID.Zero) 4423 foreach (PresenceInfo p in pinfos)
4065 { 4424 {
4066 pinfo = p; 4425 if (p.RegionID != UUID.Zero)
4426 {
4427 pinfo = p;
4428 }
4067 } 4429 }
4068 } 4430 }
4069 }
4070 4431
4071 ce = new UserInfoCacheEntry(); 4432 ce = new UserInfoCacheEntry();
4072 ce.time = Util.EnvironmentTickCount(); 4433 ce.time = Util.EnvironmentTickCount();
4073 ce.account = account; 4434 ce.account = account;
4074 ce.pinfo = pinfo; 4435 ce.pinfo = pinfo;
4075 } 4436 m_userInfoCache[uuid] = ce;
4076 else 4437 }
4077 { 4438 else
4078 if (ce == null) 4439 {
4079 return UUID.Zero.ToString(); 4440 if (ce == null)
4441 return UUID.Zero.ToString();
4080 4442
4081 account = ce.account; 4443 account = ce.account;
4082 pinfo = ce.pinfo; 4444 pinfo = ce.pinfo;
4083 } 4445 }
4084 4446
4085 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4447 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4086 {
4087 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4088 if (pinfos != null && pinfos.Length > 0)
4089 { 4448 {
4090 foreach (PresenceInfo p in pinfos) 4449 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4450 if (pinfos != null && pinfos.Length > 0)
4091 { 4451 {
4092 if (p.RegionID != UUID.Zero) 4452 foreach (PresenceInfo p in pinfos)
4093 { 4453 {
4094 pinfo = p; 4454 if (p.RegionID != UUID.Zero)
4455 {
4456 pinfo = p;
4457 }
4095 } 4458 }
4096 } 4459 }
4097 } 4460 else
4098 else 4461 pinfo = null;
4099 pinfo = null;
4100 4462
4101 ce.time = Util.EnvironmentTickCount(); 4463 ce.time = Util.EnvironmentTickCount();
4102 ce.pinfo = pinfo; 4464 ce.pinfo = pinfo;
4103 } 4465 }
4104 4466
4105 string reply = String.Empty; 4467 string reply = String.Empty;
4106 4468
4107 switch (data) 4469 switch (data)
4108 { 4470 {
4109 case 1: // DATA_ONLINE (0|1) 4471 case 1: // DATA_ONLINE (0|1)
4110 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4472 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4111 reply = "1"; 4473 reply = "1";
4112 else 4474 else
4113 reply = "0"; 4475 reply = "0";
4114 break; 4476 break;
4115 case 2: // DATA_NAME (First Last) 4477 case 2: // DATA_NAME (First Last)
4116 reply = account.FirstName + " " + account.LastName; 4478 reply = account.FirstName + " " + account.LastName;
4117 break; 4479 break;
4118 case 3: // DATA_BORN (YYYY-MM-DD) 4480 case 3: // DATA_BORN (YYYY-MM-DD)
4119 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4481 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4120 born = born.AddSeconds(account.Created); 4482 born = born.AddSeconds(account.Created);
4121 reply = born.ToString("yyyy-MM-dd"); 4483 reply = born.ToString("yyyy-MM-dd");
4122 break; 4484 break;
4123 case 4: // DATA_RATING (0,0,0,0,0,0) 4485 case 4: // DATA_RATING (0,0,0,0,0,0)
4124 reply = "0,0,0,0,0,0"; 4486 reply = "0,0,0,0,0,0";
4125 break; 4487 break;
4126 case 7: // DATA_USERLEVEL (integer) 4488 case 8: // DATA_PAYINFO (0|1|2|3)
4127 reply = account.UserLevel.ToString(); 4489 reply = "0";
4128 break; 4490 break;
4129 case 8: // DATA_PAYINFO (0|1|2|3) 4491 default:
4130 reply = "0"; 4492 return UUID.Zero.ToString(); // Raise no event
4131 break; 4493 }
4132 default:
4133 return UUID.Zero.ToString(); // Raise no event
4134 }
4135 4494
4136 UUID rq = UUID.Random(); 4495 UUID rq = UUID.Random();
4137 4496
4138 UUID tid = AsyncCommands. 4497 UUID tid = AsyncCommands.
4139 DataserverPlugin.RegisterRequest(m_host.LocalId, 4498 DataserverPlugin.RegisterRequest(m_host.LocalId,
4140 m_item.ItemID, rq.ToString()); 4499 m_item.ItemID, rq.ToString());
4141 4500
4142 AsyncCommands. 4501 AsyncCommands.
4143 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4502 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4144 4503
4145 ScriptSleep(100); 4504 ScriptSleep(100);
4146 return tid.ToString(); 4505 return tid.ToString();
4506 }
4507 else
4508 {
4509 ShoutError("Invalid UUID passed to llRequestAgentData.");
4510 }
4511 return "";
4147 } 4512 }
4148 4513
4149 public LSL_String llRequestInventoryData(string name) 4514 public LSL_String llRequestInventoryData(string name)
@@ -4200,13 +4565,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4200 if (UUID.TryParse(agent, out agentId)) 4565 if (UUID.TryParse(agent, out agentId))
4201 { 4566 {
4202 ScenePresence presence = World.GetScenePresence(agentId); 4567 ScenePresence presence = World.GetScenePresence(agentId);
4203 if (presence != null) 4568 if (presence != null && presence.PresenceType != PresenceType.Npc)
4204 { 4569 {
4570 // agent must not be a god
4571 if (presence.UserLevel >= 200) return;
4572
4205 // agent must be over the owners land 4573 // agent must be over the owners land
4206 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4574 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4207 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4575 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4208 { 4576 {
4209 World.TeleportClientHome(agentId, presence.ControllingClient); 4577 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4578 {
4579 // They can't be teleported home for some reason
4580 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4581 if (regionInfo != null)
4582 {
4583 World.RequestTeleportLocation(
4584 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4585 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4586 }
4587 }
4210 } 4588 }
4211 } 4589 }
4212 } 4590 }
@@ -4313,7 +4691,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4313 UUID av = new UUID(); 4691 UUID av = new UUID();
4314 if (!UUID.TryParse(agent,out av)) 4692 if (!UUID.TryParse(agent,out av))
4315 { 4693 {
4316 LSLError("First parameter to llDialog needs to be a key"); 4694 //LSLError("First parameter to llDialog needs to be a key");
4317 return; 4695 return;
4318 } 4696 }
4319 4697
@@ -4345,7 +4723,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4345 public void llCollisionSound(string impact_sound, double impact_volume) 4723 public void llCollisionSound(string impact_sound, double impact_volume)
4346 { 4724 {
4347 m_host.AddScriptLPS(1); 4725 m_host.AddScriptLPS(1);
4348 4726
4727 if(impact_sound == "")
4728 {
4729 m_host.CollisionSoundVolume = (float)impact_volume;
4730 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4731 m_host.CollisionSoundType = 0;
4732 return;
4733 }
4349 // TODO: Parameter check logic required. 4734 // TODO: Parameter check logic required.
4350 UUID soundId = UUID.Zero; 4735 UUID soundId = UUID.Zero;
4351 if (!UUID.TryParse(impact_sound, out soundId)) 4736 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4358,6 +4743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4358 4743
4359 m_host.CollisionSound = soundId; 4744 m_host.CollisionSound = soundId;
4360 m_host.CollisionSoundVolume = (float)impact_volume; 4745 m_host.CollisionSoundVolume = (float)impact_volume;
4746 m_host.CollisionSoundType = 1;
4361 } 4747 }
4362 4748
4363 public LSL_String llGetAnimation(string id) 4749 public LSL_String llGetAnimation(string id)
@@ -4371,14 +4757,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4371 4757
4372 if (m_host.RegionHandle == presence.RegionHandle) 4758 if (m_host.RegionHandle == presence.RegionHandle)
4373 { 4759 {
4374 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4375
4376 if (presence != null) 4760 if (presence != null)
4377 { 4761 {
4378 AnimationSet currentAnims = presence.Animator.Animations; 4762 if (presence.SitGround)
4379 string currentAnimationState = String.Empty; 4763 return "Sitting on Ground";
4380 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4764 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4381 return currentAnimationState; 4765 return "Sitting";
4766
4767 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4768 string lslMovementAnimation;
4769
4770 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4771 return lslMovementAnimation;
4382 } 4772 }
4383 } 4773 }
4384 4774
@@ -4525,7 +4915,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4525 { 4915 {
4526 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4916 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4527 float distance_term = distance * distance * distance; // Script Energy 4917 float distance_term = distance * distance * distance; // Script Energy
4528 float pusher_mass = m_host.GetMass(); 4918 // use total object mass and not part
4919 float pusher_mass = m_host.ParentGroup.GetMass();
4529 4920
4530 float PUSH_ATTENUATION_DISTANCE = 17f; 4921 float PUSH_ATTENUATION_DISTANCE = 17f;
4531 float PUSH_ATTENUATION_SCALE = 5f; 4922 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4775,6 +5166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4775 { 5166 {
4776 return item.AssetID.ToString(); 5167 return item.AssetID.ToString();
4777 } 5168 }
5169 m_host.TaskInventory.LockItemsForRead(false);
4778 5170
4779 return UUID.Zero.ToString(); 5171 return UUID.Zero.ToString();
4780 } 5172 }
@@ -4908,7 +5300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4908 public LSL_Vector llGetCenterOfMass() 5300 public LSL_Vector llGetCenterOfMass()
4909 { 5301 {
4910 m_host.AddScriptLPS(1); 5302 m_host.AddScriptLPS(1);
4911 Vector3 center = m_host.GetGeometricCenter(); 5303 Vector3 center = m_host.GetCenterOfMass();
4912 return new LSL_Vector(center.X,center.Y,center.Z); 5304 return new LSL_Vector(center.X,center.Y,center.Z);
4913 } 5305 }
4914 5306
@@ -4927,14 +5319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4927 { 5319 {
4928 m_host.AddScriptLPS(1); 5320 m_host.AddScriptLPS(1);
4929 5321
4930 if (src == null) 5322 return src.Length;
4931 {
4932 return 0;
4933 }
4934 else
4935 {
4936 return src.Length;
4937 }
4938 } 5323 }
4939 5324
4940 public LSL_Integer llList2Integer(LSL_List src, int index) 5325 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5005,7 +5390,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5005 else if (src.Data[index] is LSL_Float) 5390 else if (src.Data[index] is LSL_Float)
5006 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5391 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5007 else if (src.Data[index] is LSL_String) 5392 else if (src.Data[index] is LSL_String)
5008 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5393 {
5394 string str = ((LSL_String) src.Data[index]).m_string;
5395 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5396 if (m != Match.Empty)
5397 {
5398 str = m.Value;
5399 double d = 0.0;
5400 if (!Double.TryParse(str, out d))
5401 return 0.0;
5402
5403 return d;
5404 }
5405 return 0.0;
5406 }
5009 return Convert.ToDouble(src.Data[index]); 5407 return Convert.ToDouble(src.Data[index]);
5010 } 5408 }
5011 catch (FormatException) 5409 catch (FormatException)
@@ -5047,7 +5445,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5047 // for completion and should LSL_Key ever be implemented 5445 // for completion and should LSL_Key ever be implemented
5048 // as it's own struct 5446 // as it's own struct
5049 else if (!(src.Data[index] is LSL_String || 5447 else if (!(src.Data[index] is LSL_String ||
5050 src.Data[index] is LSL_Key)) 5448 src.Data[index] is LSL_Key ||
5449 src.Data[index] is String))
5051 { 5450 {
5052 return ""; 5451 return "";
5053 } 5452 }
@@ -5305,7 +5704,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5305 } 5704 }
5306 } 5705 }
5307 } 5706 }
5308 else { 5707 else
5708 {
5309 object[] array = new object[src.Length]; 5709 object[] array = new object[src.Length];
5310 Array.Copy(src.Data, 0, array, 0, src.Length); 5710 Array.Copy(src.Data, 0, array, 0, src.Length);
5311 result = new LSL_List(array); 5711 result = new LSL_List(array);
@@ -5412,7 +5812,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5412 public LSL_Integer llGetRegionAgentCount() 5812 public LSL_Integer llGetRegionAgentCount()
5413 { 5813 {
5414 m_host.AddScriptLPS(1); 5814 m_host.AddScriptLPS(1);
5415 return new LSL_Integer(World.GetRootAgentCount()); 5815
5816 int count = 0;
5817 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5818 count++;
5819 });
5820
5821 return new LSL_Integer(count);
5416 } 5822 }
5417 5823
5418 public LSL_Vector llGetRegionCorner() 5824 public LSL_Vector llGetRegionCorner()
@@ -5653,6 +6059,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5653 flags |= ScriptBaseClass.AGENT_AWAY; 6059 flags |= ScriptBaseClass.AGENT_AWAY;
5654 } 6060 }
5655 6061
6062 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6063 UUID[] anims = agent.Animator.GetAnimationArray();
6064 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6065 {
6066 flags |= ScriptBaseClass.AGENT_BUSY;
6067 }
6068
5656 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6069 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5657 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6070 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5658 { 6071 {
@@ -5700,6 +6113,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5700 flags |= ScriptBaseClass.AGENT_SITTING; 6113 flags |= ScriptBaseClass.AGENT_SITTING;
5701 } 6114 }
5702 6115
6116 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6117 {
6118 flags |= ScriptBaseClass.AGENT_MALE;
6119 }
6120
5703 return flags; 6121 return flags;
5704 } 6122 }
5705 6123
@@ -5847,9 +6265,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5847 6265
5848 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6266 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5849 6267
5850 foreach (SceneObjectPart part in parts) 6268 try
6269 {
6270 foreach (SceneObjectPart part in parts)
6271 {
6272 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6273 }
6274 }
6275 finally
5851 { 6276 {
5852 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5853 } 6277 }
5854 } 6278 }
5855 6279
@@ -5901,13 +6325,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5901 6325
5902 if (m_host.OwnerID == land.LandData.OwnerID) 6326 if (m_host.OwnerID == land.LandData.OwnerID)
5903 { 6327 {
5904 World.TeleportClientHome(agentID, presence.ControllingClient); 6328 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6329 presence.TeleportWithMomentum(pos, null);
6330 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5905 } 6331 }
5906 } 6332 }
5907 } 6333 }
5908 ScriptSleep(5000); 6334 ScriptSleep(5000);
5909 } 6335 }
5910 6336
6337 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6338 {
6339 return ParseString2List(str, separators, in_spacers, false);
6340 }
6341
5911 public LSL_Integer llOverMyLand(string id) 6342 public LSL_Integer llOverMyLand(string id)
5912 { 6343 {
5913 m_host.AddScriptLPS(1); 6344 m_host.AddScriptLPS(1);
@@ -5966,20 +6397,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5966 return agentSize; 6397 return agentSize;
5967 } 6398 }
5968 6399
5969 public LSL_Integer llSameGroup(string agent) 6400 public LSL_Integer llSameGroup(string id)
5970 { 6401 {
5971 m_host.AddScriptLPS(1); 6402 m_host.AddScriptLPS(1);
5972 UUID agentId = new UUID(); 6403 UUID uuid = new UUID();
5973 if (!UUID.TryParse(agent, out agentId)) 6404 if (!UUID.TryParse(id, out uuid))
5974 return new LSL_Integer(0);
5975 ScenePresence presence = World.GetScenePresence(agentId);
5976 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5977 return new LSL_Integer(0); 6405 return new LSL_Integer(0);
5978 IClientAPI client = presence.ControllingClient; 6406
5979 if (m_host.GroupID == client.ActiveGroupId) 6407 // Check if it's a group key
6408 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5980 return new LSL_Integer(1); 6409 return new LSL_Integer(1);
5981 else 6410
6411 // We got passed a UUID.Zero
6412 if (uuid == UUID.Zero)
5982 return new LSL_Integer(0); 6413 return new LSL_Integer(0);
6414
6415 // Handle the case where id names an avatar
6416 ScenePresence presence = World.GetScenePresence(uuid);
6417 if (presence != null)
6418 {
6419 if (presence.IsChildAgent)
6420 return new LSL_Integer(0);
6421
6422 IClientAPI client = presence.ControllingClient;
6423 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6424 return new LSL_Integer(1);
6425
6426 return new LSL_Integer(0);
6427 }
6428
6429 // Handle object case
6430 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6431 if (part != null)
6432 {
6433 // This will handle both deed and non-deed and also the no
6434 // group case
6435 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6436 return new LSL_Integer(1);
6437
6438 return new LSL_Integer(0);
6439 }
6440
6441 return new LSL_Integer(0);
5983 } 6442 }
5984 6443
5985 public void llUnSit(string id) 6444 public void llUnSit(string id)
@@ -6104,7 +6563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6104 return m_host.ParentGroup.AttachmentPoint; 6563 return m_host.ParentGroup.AttachmentPoint;
6105 } 6564 }
6106 6565
6107 public LSL_Integer llGetFreeMemory() 6566 public virtual LSL_Integer llGetFreeMemory()
6108 { 6567 {
6109 m_host.AddScriptLPS(1); 6568 m_host.AddScriptLPS(1);
6110 // Make scripts designed for LSO happy 6569 // Make scripts designed for LSO happy
@@ -6221,7 +6680,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6221 SetParticleSystem(m_host, rules); 6680 SetParticleSystem(m_host, rules);
6222 } 6681 }
6223 6682
6224 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6683 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6684 {
6225 6685
6226 6686
6227 if (rules.Length == 0) 6687 if (rules.Length == 0)
@@ -6535,6 +6995,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6535 6995
6536 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6996 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6537 { 6997 {
6998 // LSL quaternions can normalize to 0, normal Quaternions can't.
6999 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7000 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7001
6538 part.SitTargetPosition = offset; 7002 part.SitTargetPosition = offset;
6539 part.SitTargetOrientation = rot; 7003 part.SitTargetOrientation = rot;
6540 part.ParentGroup.HasGroupChanged = true; 7004 part.ParentGroup.HasGroupChanged = true;
@@ -6690,13 +7154,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6690 UUID av = new UUID(); 7154 UUID av = new UUID();
6691 if (!UUID.TryParse(avatar,out av)) 7155 if (!UUID.TryParse(avatar,out av))
6692 { 7156 {
6693 LSLError("First parameter to llDialog needs to be a key"); 7157 //LSLError("First parameter to llDialog needs to be a key");
6694 return; 7158 return;
6695 } 7159 }
6696 if (buttons.Length < 1) 7160 if (buttons.Length < 1)
6697 { 7161 {
6698 LSLError("No less than 1 button can be shown"); 7162 buttons.Add("OK");
6699 return;
6700 } 7163 }
6701 if (buttons.Length > 12) 7164 if (buttons.Length > 12)
6702 { 7165 {
@@ -6713,7 +7176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6713 } 7176 }
6714 if (buttons.Data[i].ToString().Length > 24) 7177 if (buttons.Data[i].ToString().Length > 24)
6715 { 7178 {
6716 LSLError("button label cannot be longer than 24 characters"); 7179 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6717 return; 7180 return;
6718 } 7181 }
6719 buts[i] = buttons.Data[i].ToString(); 7182 buts[i] = buttons.Data[i].ToString();
@@ -6780,9 +7243,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6780 return; 7243 return;
6781 } 7244 }
6782 7245
6783 // the rest of the permission checks are done in RezScript, so check the pin there as well 7246 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6784 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7247 if (dest != null)
7248 {
7249 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7250 {
7251 // the rest of the permission checks are done in RezScript, so check the pin there as well
7252 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6785 7253
7254 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7255 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7256 }
7257 }
6786 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7258 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6787 ScriptSleep(3000); 7259 ScriptSleep(3000);
6788 } 7260 }
@@ -6845,19 +7317,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6845 public LSL_String llMD5String(string src, int nonce) 7317 public LSL_String llMD5String(string src, int nonce)
6846 { 7318 {
6847 m_host.AddScriptLPS(1); 7319 m_host.AddScriptLPS(1);
6848 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7320 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6849 } 7321 }
6850 7322
6851 public LSL_String llSHA1String(string src) 7323 public LSL_String llSHA1String(string src)
6852 { 7324 {
6853 m_host.AddScriptLPS(1); 7325 m_host.AddScriptLPS(1);
6854 return Util.SHA1Hash(src).ToLower(); 7326 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6855 } 7327 }
6856 7328
6857 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7329 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6858 { 7330 {
6859 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7331 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6860 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7332 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7333 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7334 return shapeBlock;
6861 7335
6862 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7336 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6863 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7337 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6962,6 +7436,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6962 // Prim type box, cylinder and prism. 7436 // Prim type box, cylinder and prism.
6963 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) 7437 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)
6964 { 7438 {
7439 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7440 return;
7441
6965 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7442 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6966 ObjectShapePacket.ObjectDataBlock shapeBlock; 7443 ObjectShapePacket.ObjectDataBlock shapeBlock;
6967 7444
@@ -7015,6 +7492,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7015 // Prim type sphere. 7492 // Prim type sphere.
7016 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7493 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7017 { 7494 {
7495 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7496 return;
7497
7018 ObjectShapePacket.ObjectDataBlock shapeBlock; 7498 ObjectShapePacket.ObjectDataBlock shapeBlock;
7019 7499
7020 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7500 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7056,6 +7536,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7056 // Prim type torus, tube and ring. 7536 // Prim type torus, tube and ring.
7057 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) 7537 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)
7058 { 7538 {
7539 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7540 return;
7541
7059 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7542 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7060 ObjectShapePacket.ObjectDataBlock shapeBlock; 7543 ObjectShapePacket.ObjectDataBlock shapeBlock;
7061 7544
@@ -7191,6 +7674,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7191 // Prim type sculpt. 7674 // Prim type sculpt.
7192 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7675 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7193 { 7676 {
7677 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7678 return;
7679
7194 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7680 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7195 UUID sculptId; 7681 UUID sculptId;
7196 7682
@@ -7215,7 +7701,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7215 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7701 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7216 { 7702 {
7217 // default 7703 // default
7218 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7704 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7219 } 7705 }
7220 7706
7221 part.Shape.SetSculptProperties((byte)type, sculptId); 7707 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7232,48 +7718,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7232 ScriptSleep(200); 7718 ScriptSleep(200);
7233 } 7719 }
7234 7720
7235 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7721 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7236 { 7722 {
7237 m_host.AddScriptLPS(1); 7723 m_host.AddScriptLPS(1);
7238 7724
7239 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7725 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7240 7726
7241 ScriptSleep(200); 7727 ScriptSleep(200);
7242 } 7728 }
7243 7729
7244 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7730 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7245 { 7731 {
7246 m_host.AddScriptLPS(1); 7732 List<object> parts = new List<object>();
7733 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7734 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7735 foreach (SceneObjectPart p in prims)
7736 parts.Add(p);
7737 foreach (ScenePresence p in avatars)
7738 parts.Add(p);
7247 7739
7248 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7740 LSL_List remaining = null;
7741 uint rulesParsed = 0;
7742
7743 if (parts.Count > 0)
7744 {
7745 foreach (object part in parts)
7746 {
7747 if (part is SceneObjectPart)
7748 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7749 else
7750 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7751 }
7752
7753 while ((object)remaining != null && remaining.Length > 2)
7754 {
7755 linknumber = remaining.GetLSLIntegerItem(0);
7756 rules = remaining.GetSublist(1, -1);
7757 parts.Clear();
7758 prims = GetLinkParts(linknumber);
7759 avatars = GetLinkAvatars(linknumber);
7760 foreach (SceneObjectPart p in prims)
7761 parts.Add(p);
7762 foreach (ScenePresence p in avatars)
7763 parts.Add(p);
7764
7765 remaining = null;
7766 foreach (object part in parts)
7767 {
7768 if (part is SceneObjectPart)
7769 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7770 else
7771 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7772 }
7773 }
7774 }
7249 } 7775 }
7250 7776
7251 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7777 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7778 float material_density, float material_friction,
7779 float material_restitution, float material_gravity_modifier)
7252 { 7780 {
7253 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7781 ExtraPhysicsData physdata = new ExtraPhysicsData();
7782 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7783 physdata.Density = part.Density;
7784 physdata.Friction = part.Friction;
7785 physdata.Bounce = part.Bounciness;
7786 physdata.GravitationModifier = part.GravityModifier;
7254 7787
7255 LSL_List remaining = null; 7788 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7256 uint rulesParsed = 0; 7789 physdata.Density = material_density;
7790 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7791 physdata.Friction = material_friction;
7792 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7793 physdata.Bounce = material_restitution;
7794 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7795 physdata.GravitationModifier = material_gravity_modifier;
7257 7796
7258 foreach (SceneObjectPart part in parts) 7797 part.UpdateExtraPhysics(physdata);
7259 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7798 }
7260 7799
7261 while (remaining != null && remaining.Length > 2) 7800 public void llSetPhysicsMaterial(int material_bits,
7262 { 7801 float material_gravity_modifier, float material_restitution,
7263 linknumber = remaining.GetLSLIntegerItem(0); 7802 float material_friction, float material_density)
7264 rules = remaining.GetSublist(1, -1); 7803 {
7265 parts = GetLinkParts(linknumber); 7804 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7805 }
7266 7806
7267 foreach (SceneObjectPart part in parts) 7807 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7268 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7808 {
7809 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7810 llSetLinkPrimitiveParamsFast(linknumber, rules);
7811 ScriptSleep(200);
7812 }
7813
7814 // vector up using libomv (c&p from sop )
7815 // vector up rotated by r
7816 private Vector3 Zrot(Quaternion r)
7817 {
7818 double x, y, z, m;
7819
7820 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7821 if (Math.Abs(1.0 - m) > 0.000001)
7822 {
7823 m = 1.0 / Math.Sqrt(m);
7824 r.X *= (float)m;
7825 r.Y *= (float)m;
7826 r.Z *= (float)m;
7827 r.W *= (float)m;
7269 } 7828 }
7829
7830 x = 2 * (r.X * r.Z + r.Y * r.W);
7831 y = 2 * (-r.X * r.W + r.Y * r.Z);
7832 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7833
7834 return new Vector3((float)x, (float)y, (float)z);
7270 } 7835 }
7271 7836
7272 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7837 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7273 { 7838 {
7839 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7840 return null;
7841
7274 int idx = 0; 7842 int idx = 0;
7275 int idxStart = 0; 7843 int idxStart = 0;
7276 7844
7845 SceneObjectGroup parentgrp = part.ParentGroup;
7846
7277 bool positionChanged = false; 7847 bool positionChanged = false;
7278 LSL_Vector currentPosition = GetPartLocalPos(part); 7848 LSL_Vector currentPosition = GetPartLocalPos(part);
7279 7849
@@ -7298,8 +7868,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7298 return null; 7868 return null;
7299 7869
7300 v=rules.GetVector3Item(idx++); 7870 v=rules.GetVector3Item(idx++);
7301 positionChanged = true;
7302 currentPosition = GetSetPosTarget(part, v, currentPosition); 7871 currentPosition = GetSetPosTarget(part, v, currentPosition);
7872 positionChanged = true;
7303 7873
7304 break; 7874 break;
7305 case (int)ScriptBaseClass.PRIM_SIZE: 7875 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7576,7 +8146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7576 return null; 8146 return null;
7577 8147
7578 string ph = rules.Data[idx++].ToString(); 8148 string ph = rules.Data[idx++].ToString();
7579 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8149 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7580 8150
7581 break; 8151 break;
7582 8152
@@ -7594,12 +8164,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7594 part.ScriptSetPhysicsStatus(physics); 8164 part.ScriptSetPhysicsStatus(physics);
7595 break; 8165 break;
7596 8166
8167 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8168 if (remain < 1)
8169 return null;
8170
8171 int shape_type = rules.GetLSLIntegerItem(idx++);
8172
8173 ExtraPhysicsData physdata = new ExtraPhysicsData();
8174 physdata.Density = part.Density;
8175 physdata.Bounce = part.Bounciness;
8176 physdata.GravitationModifier = part.GravityModifier;
8177 physdata.PhysShapeType = (PhysShapeType)shape_type;
8178
8179 part.UpdateExtraPhysics(physdata);
8180
8181 break;
8182
8183 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8184 if (remain < 5)
8185 return null;
8186
8187 int material_bits = rules.GetLSLIntegerItem(idx++);
8188 float material_density = (float)rules.GetLSLFloatItem(idx++);
8189 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8190 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8191 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8192
8193 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8194
8195 break;
8196
7597 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8197 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7598 if (remain < 1) 8198 if (remain < 1)
7599 return null; 8199 return null;
7600 string temp = rules.Data[idx++].ToString(); 8200 string temp = rules.Data[idx++].ToString();
7601 8201
7602 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8202 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7603 8203
7604 break; 8204 break;
7605 8205
@@ -7673,7 +8273,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7673 if (part.ParentGroup.RootPart == part) 8273 if (part.ParentGroup.RootPart == part)
7674 { 8274 {
7675 SceneObjectGroup parent = part.ParentGroup; 8275 SceneObjectGroup parent = part.ParentGroup;
7676 parent.UpdateGroupPosition(currentPosition); 8276 Util.FireAndForget(delegate(object x) {
8277 parent.UpdateGroupPosition(currentPosition);
8278 });
7677 } 8279 }
7678 else 8280 else
7679 { 8281 {
@@ -7718,10 +8320,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7718 8320
7719 public LSL_String llXorBase64Strings(string str1, string str2) 8321 public LSL_String llXorBase64Strings(string str1, string str2)
7720 { 8322 {
7721 m_host.AddScriptLPS(1); 8323 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7722 Deprecated("llXorBase64Strings"); 8324
7723 ScriptSleep(300); 8325 ScriptSleep(300);
7724 return String.Empty; 8326 m_host.AddScriptLPS(1);
8327
8328 if (str1 == String.Empty)
8329 return String.Empty;
8330 if (str2 == String.Empty)
8331 return str1;
8332
8333 int len = str2.Length;
8334 if ((len % 4) != 0) // LL is EVIL!!!!
8335 {
8336 while (str2.EndsWith("="))
8337 str2 = str2.Substring(0, str2.Length - 1);
8338
8339 len = str2.Length;
8340 int mod = len % 4;
8341
8342 if (mod == 1)
8343 str2 = str2.Substring(0, str2.Length - 1);
8344 else if (mod == 2)
8345 str2 += "==";
8346 else if (mod == 3)
8347 str2 += "=";
8348 }
8349
8350 byte[] data1;
8351 byte[] data2;
8352 try
8353 {
8354 data1 = Convert.FromBase64String(str1);
8355 data2 = Convert.FromBase64String(str2);
8356 }
8357 catch (Exception)
8358 {
8359 return new LSL_String(String.Empty);
8360 }
8361
8362 // For cases where the decoded length of s2 is greater
8363 // than the decoded length of s1, simply perform a normal
8364 // decode and XOR
8365 //
8366 if (data2.Length >= data1.Length)
8367 {
8368 for (int pos = 0 ; pos < data1.Length ; pos++ )
8369 data1[pos] ^= data2[pos];
8370
8371 return Convert.ToBase64String(data1);
8372 }
8373
8374 // Remove padding
8375 while (str1.EndsWith("="))
8376 str1 = str1.Substring(0, str1.Length - 1);
8377 while (str2.EndsWith("="))
8378 str2 = str2.Substring(0, str2.Length - 1);
8379
8380 byte[] d1 = new byte[str1.Length];
8381 byte[] d2 = new byte[str2.Length];
8382
8383 for (int i = 0 ; i < str1.Length ; i++)
8384 {
8385 int idx = b64.IndexOf(str1.Substring(i, 1));
8386 if (idx == -1)
8387 idx = 0;
8388 d1[i] = (byte)idx;
8389 }
8390
8391 for (int i = 0 ; i < str2.Length ; i++)
8392 {
8393 int idx = b64.IndexOf(str2.Substring(i, 1));
8394 if (idx == -1)
8395 idx = 0;
8396 d2[i] = (byte)idx;
8397 }
8398
8399 string output = String.Empty;
8400
8401 for (int pos = 0 ; pos < d1.Length ; pos++)
8402 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8403
8404 while (output.Length % 3 > 0)
8405 output += "=";
8406
8407 return output;
7725 } 8408 }
7726 8409
7727 public void llRemoteDataSetRegion() 8410 public void llRemoteDataSetRegion()
@@ -7845,13 +8528,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7845 public LSL_Integer llGetNumberOfPrims() 8528 public LSL_Integer llGetNumberOfPrims()
7846 { 8529 {
7847 m_host.AddScriptLPS(1); 8530 m_host.AddScriptLPS(1);
7848 int avatarCount = 0; 8531 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7849 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8532
7850 {
7851 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7852 avatarCount++;
7853 });
7854
7855 return m_host.ParentGroup.PrimCount + avatarCount; 8533 return m_host.ParentGroup.PrimCount + avatarCount;
7856 } 8534 }
7857 8535
@@ -7867,55 +8545,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7867 m_host.AddScriptLPS(1); 8545 m_host.AddScriptLPS(1);
7868 UUID objID = UUID.Zero; 8546 UUID objID = UUID.Zero;
7869 LSL_List result = new LSL_List(); 8547 LSL_List result = new LSL_List();
8548
8549 // If the ID is not valid, return null result
7870 if (!UUID.TryParse(obj, out objID)) 8550 if (!UUID.TryParse(obj, out objID))
7871 { 8551 {
7872 result.Add(new LSL_Vector()); 8552 result.Add(new LSL_Vector());
7873 result.Add(new LSL_Vector()); 8553 result.Add(new LSL_Vector());
7874 return result; 8554 return result;
7875 } 8555 }
8556
8557 // Check if this is an attached prim. If so, replace
8558 // the UUID with the avatar UUID and report it's bounding box
8559 SceneObjectPart part = World.GetSceneObjectPart(objID);
8560 if (part != null && part.ParentGroup.IsAttachment)
8561 objID = part.ParentGroup.AttachedAvatar;
8562
8563 // Find out if this is an avatar ID. If so, return it's box
7876 ScenePresence presence = World.GetScenePresence(objID); 8564 ScenePresence presence = World.GetScenePresence(objID);
7877 if (presence != null) 8565 if (presence != null)
7878 { 8566 {
7879 if (presence.ParentID == 0) // not sat on an object 8567 // As per LSL Wiki, there is no difference between sitting
8568 // and standing avatar since server 1.36
8569 LSL_Vector lower;
8570 LSL_Vector upper;
8571 if (presence.Animator.Animations.DefaultAnimation.AnimID
8572 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7880 { 8573 {
7881 LSL_Vector lower; 8574 // This is for ground sitting avatars
7882 LSL_Vector upper; 8575 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7883 if (presence.Animator.Animations.DefaultAnimation.AnimID 8576 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7884 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8577 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7885 {
7886 // This is for ground sitting avatars
7887 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7888 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7889 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7890 }
7891 else
7892 {
7893 // This is for standing/flying avatars
7894 float height = presence.Appearance.AvatarHeight / 2.0f;
7895 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7896 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7897 }
7898 result.Add(lower);
7899 result.Add(upper);
7900 return result;
7901 } 8578 }
7902 else 8579 else
7903 { 8580 {
7904 // sitting on an object so we need the bounding box of that 8581 // This is for standing/flying avatars
7905 // which should include the avatar so set the UUID to the 8582 float height = presence.Appearance.AvatarHeight / 2.0f;
7906 // UUID of the object the avatar is sat on and allow it to fall through 8583 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7907 // to processing an object 8584 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7908 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7909 objID = p.UUID;
7910 } 8585 }
8586
8587 // Adjust to the documented error offsets (see LSL Wiki)
8588 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8589 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8590
8591 if (lower.x > upper.x)
8592 lower.x = upper.x;
8593 if (lower.y > upper.y)
8594 lower.y = upper.y;
8595 if (lower.z > upper.z)
8596 lower.z = upper.z;
8597
8598 result.Add(lower);
8599 result.Add(upper);
8600 return result;
7911 } 8601 }
7912 SceneObjectPart part = World.GetSceneObjectPart(objID); 8602
8603 part = World.GetSceneObjectPart(objID);
7913 // Currently only works for single prims without a sitting avatar 8604 // Currently only works for single prims without a sitting avatar
7914 if (part != null) 8605 if (part != null)
7915 { 8606 {
7916 Vector3 halfSize = part.Scale / 2.0f; 8607 float minX;
7917 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8608 float maxX;
7918 LSL_Vector upper = new LSL_Vector(halfSize); 8609 float minY;
8610 float maxY;
8611 float minZ;
8612 float maxZ;
8613
8614 // This BBox is in sim coordinates, with the offset being
8615 // a contained point.
8616 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8617 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8618
8619 minX -= offsets[0].X;
8620 maxX -= offsets[0].X;
8621 minY -= offsets[0].Y;
8622 maxY -= offsets[0].Y;
8623 minZ -= offsets[0].Z;
8624 maxZ -= offsets[0].Z;
8625
8626 LSL_Vector lower;
8627 LSL_Vector upper;
8628
8629 // Adjust to the documented error offsets (see LSL Wiki)
8630 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8631 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8632
8633 if (lower.x > upper.x)
8634 lower.x = upper.x;
8635 if (lower.y > upper.y)
8636 lower.y = upper.y;
8637 if (lower.z > upper.z)
8638 lower.z = upper.z;
8639
7919 result.Add(lower); 8640 result.Add(lower);
7920 result.Add(upper); 8641 result.Add(upper);
7921 return result; 8642 return result;
@@ -7929,7 +8650,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7929 8650
7930 public LSL_Vector llGetGeometricCenter() 8651 public LSL_Vector llGetGeometricCenter()
7931 { 8652 {
7932 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8653 Vector3 tmp = m_host.GetGeometricCenter();
8654 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7933 } 8655 }
7934 8656
7935 public LSL_List llGetPrimitiveParams(LSL_List rules) 8657 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7957,24 +8679,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7957 { 8679 {
7958 m_host.AddScriptLPS(1); 8680 m_host.AddScriptLPS(1);
7959 8681
7960 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8682 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8683 // keep other options as before
7961 8684
8685 List<SceneObjectPart> parts;
8686 List<ScenePresence> avatars;
8687
7962 LSL_List res = new LSL_List(); 8688 LSL_List res = new LSL_List();
7963 LSL_List remaining = null; 8689 LSL_List remaining = null;
7964 8690
7965 foreach (SceneObjectPart part in parts) 8691 while (rules.Length > 0)
7966 { 8692 {
7967 remaining = GetPrimParams(part, rules, ref res);
7968 }
7969
7970 while (remaining != null && remaining.Length > 2)
7971 {
7972 linknumber = remaining.GetLSLIntegerItem(0);
7973 rules = remaining.GetSublist(1, -1);
7974 parts = GetLinkParts(linknumber); 8693 parts = GetLinkParts(linknumber);
8694 avatars = GetLinkAvatars(linknumber);
7975 8695
8696 remaining = null;
7976 foreach (SceneObjectPart part in parts) 8697 foreach (SceneObjectPart part in parts)
8698 {
7977 remaining = GetPrimParams(part, rules, ref res); 8699 remaining = GetPrimParams(part, rules, ref res);
8700 }
8701 foreach (ScenePresence avatar in avatars)
8702 {
8703 remaining = GetPrimParams(avatar, rules, ref res);
8704 }
8705
8706 if (remaining != null && remaining.Length > 0)
8707 {
8708 linknumber = remaining.GetLSLIntegerItem(0);
8709 rules = remaining.GetSublist(1, -1);
8710 }
7978 } 8711 }
7979 8712
7980 return res; 8713 return res;
@@ -8019,13 +8752,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8019 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8752 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8020 part.AbsolutePosition.Y, 8753 part.AbsolutePosition.Y,
8021 part.AbsolutePosition.Z); 8754 part.AbsolutePosition.Z);
8022 // For some reason, the part.AbsolutePosition.* values do not change if the
8023 // linkset is rotated; they always reflect the child prim's world position
8024 // as though the linkset is unrotated. This is incompatible behavior with SL's
8025 // implementation, so will break scripts imported from there (not to mention it
8026 // makes it more difficult to determine a child prim's actual inworld position).
8027 if (part.ParentID != 0)
8028 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8029 res.Add(v); 8755 res.Add(v);
8030 break; 8756 break;
8031 8757
@@ -8197,30 +8923,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8197 if (remain < 1) 8923 if (remain < 1)
8198 return null; 8924 return null;
8199 8925
8200 face=(int)rules.GetLSLIntegerItem(idx++); 8926 face = (int)rules.GetLSLIntegerItem(idx++);
8201 8927
8202 tex = part.Shape.Textures; 8928 tex = part.Shape.Textures;
8929 int shiny;
8203 if (face == ScriptBaseClass.ALL_SIDES) 8930 if (face == ScriptBaseClass.ALL_SIDES)
8204 { 8931 {
8205 for (face = 0; face < GetNumberOfSides(part); face++) 8932 for (face = 0; face < GetNumberOfSides(part); face++)
8206 { 8933 {
8207 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8934 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8208 // Convert Shininess to PRIM_SHINY_* 8935 if (shinyness == Shininess.High)
8209 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8936 {
8210 // PRIM_BUMP_* 8937 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8211 res.Add(new LSL_Integer((int)texface.Bump)); 8938 }
8939 else if (shinyness == Shininess.Medium)
8940 {
8941 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8942 }
8943 else if (shinyness == Shininess.Low)
8944 {
8945 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8946 }
8947 else
8948 {
8949 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8950 }
8951 res.Add(new LSL_Integer(shiny));
8952 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8212 } 8953 }
8213 } 8954 }
8214 else 8955 else
8215 { 8956 {
8216 if (face >= 0 && face < GetNumberOfSides(part)) 8957 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8958 if (shinyness == Shininess.High)
8217 { 8959 {
8218 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8960 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8219 // Convert Shininess to PRIM_SHINY_* 8961 }
8220 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8962 else if (shinyness == Shininess.Medium)
8221 // PRIM_BUMP_* 8963 {
8222 res.Add(new LSL_Integer((int)texface.Bump)); 8964 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8965 }
8966 else if (shinyness == Shininess.Low)
8967 {
8968 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8969 }
8970 else
8971 {
8972 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8223 } 8973 }
8974 res.Add(new LSL_Integer(shiny));
8975 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8224 } 8976 }
8225 break; 8977 break;
8226 8978
@@ -8228,24 +8980,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8228 if (remain < 1) 8980 if (remain < 1)
8229 return null; 8981 return null;
8230 8982
8231 face=(int)rules.GetLSLIntegerItem(idx++); 8983 face = (int)rules.GetLSLIntegerItem(idx++);
8232 8984
8233 tex = part.Shape.Textures; 8985 tex = part.Shape.Textures;
8986 int fullbright;
8234 if (face == ScriptBaseClass.ALL_SIDES) 8987 if (face == ScriptBaseClass.ALL_SIDES)
8235 { 8988 {
8236 for (face = 0; face < GetNumberOfSides(part); face++) 8989 for (face = 0; face < GetNumberOfSides(part); face++)
8237 { 8990 {
8238 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8991 if (tex.GetFace((uint)face).Fullbright == true)
8239 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8992 {
8993 fullbright = ScriptBaseClass.TRUE;
8994 }
8995 else
8996 {
8997 fullbright = ScriptBaseClass.FALSE;
8998 }
8999 res.Add(new LSL_Integer(fullbright));
8240 } 9000 }
8241 } 9001 }
8242 else 9002 else
8243 { 9003 {
8244 if (face >= 0 && face < GetNumberOfSides(part)) 9004 if (tex.GetFace((uint)face).Fullbright == true)
8245 { 9005 {
8246 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9006 fullbright = ScriptBaseClass.TRUE;
8247 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9007 }
9008 else
9009 {
9010 fullbright = ScriptBaseClass.FALSE;
8248 } 9011 }
9012 res.Add(new LSL_Integer(fullbright));
8249 } 9013 }
8250 break; 9014 break;
8251 9015
@@ -8267,27 +9031,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8267 break; 9031 break;
8268 9032
8269 case (int)ScriptBaseClass.PRIM_TEXGEN: 9033 case (int)ScriptBaseClass.PRIM_TEXGEN:
9034 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8270 if (remain < 1) 9035 if (remain < 1)
8271 return null; 9036 return null;
8272 9037
8273 face=(int)rules.GetLSLIntegerItem(idx++); 9038 face = (int)rules.GetLSLIntegerItem(idx++);
8274 9039
8275 tex = part.Shape.Textures; 9040 tex = part.Shape.Textures;
8276 if (face == ScriptBaseClass.ALL_SIDES) 9041 if (face == ScriptBaseClass.ALL_SIDES)
8277 { 9042 {
8278 for (face = 0; face < GetNumberOfSides(part); face++) 9043 for (face = 0; face < GetNumberOfSides(part); face++)
8279 { 9044 {
8280 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9045 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8281 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9046 {
8282 res.Add(new LSL_Integer((uint)texgen >> 1)); 9047 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9048 }
9049 else
9050 {
9051 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9052 }
8283 } 9053 }
8284 } 9054 }
8285 else 9055 else
8286 { 9056 {
8287 if (face >= 0 && face < GetNumberOfSides(part)) 9057 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8288 { 9058 {
8289 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9059 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8290 res.Add(new LSL_Integer((uint)texgen >> 1)); 9060 }
9061 else
9062 {
9063 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8291 } 9064 }
8292 } 9065 }
8293 break; 9066 break;
@@ -8311,24 +9084,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8311 if (remain < 1) 9084 if (remain < 1)
8312 return null; 9085 return null;
8313 9086
8314 face=(int)rules.GetLSLIntegerItem(idx++); 9087 face = (int)rules.GetLSLIntegerItem(idx++);
8315 9088
8316 tex = part.Shape.Textures; 9089 tex = part.Shape.Textures;
9090 float primglow;
8317 if (face == ScriptBaseClass.ALL_SIDES) 9091 if (face == ScriptBaseClass.ALL_SIDES)
8318 { 9092 {
8319 for (face = 0; face < GetNumberOfSides(part); face++) 9093 for (face = 0; face < GetNumberOfSides(part); face++)
8320 { 9094 {
8321 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9095 primglow = tex.GetFace((uint)face).Glow;
8322 res.Add(new LSL_Float(texface.Glow)); 9096 res.Add(new LSL_Float(primglow));
8323 } 9097 }
8324 } 9098 }
8325 else 9099 else
8326 { 9100 {
8327 if (face >= 0 && face < GetNumberOfSides(part)) 9101 primglow = tex.GetFace((uint)face).Glow;
8328 { 9102 res.Add(new LSL_Float(primglow));
8329 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8330 res.Add(new LSL_Float(texface.Glow));
8331 }
8332 } 9103 }
8333 break; 9104 break;
8334 9105
@@ -8340,15 +9111,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8340 textColor.B)); 9111 textColor.B));
8341 res.Add(new LSL_Float(textColor.A)); 9112 res.Add(new LSL_Float(textColor.A));
8342 break; 9113 break;
9114
8343 case (int)ScriptBaseClass.PRIM_NAME: 9115 case (int)ScriptBaseClass.PRIM_NAME:
8344 res.Add(new LSL_String(part.Name)); 9116 res.Add(new LSL_String(part.Name));
8345 break; 9117 break;
9118
8346 case (int)ScriptBaseClass.PRIM_DESC: 9119 case (int)ScriptBaseClass.PRIM_DESC:
8347 res.Add(new LSL_String(part.Description)); 9120 res.Add(new LSL_String(part.Description));
8348 break; 9121 break;
9122
8349 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9123 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8350 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9124 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8351 break; 9125 break;
9126
8352 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9127 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8353 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9128 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8354 break; 9129 break;
@@ -8959,8 +9734,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8959 // The function returns an ordered list 9734 // The function returns an ordered list
8960 // representing the tokens found in the supplied 9735 // representing the tokens found in the supplied
8961 // sources string. If two successive tokenizers 9736 // sources string. If two successive tokenizers
8962 // are encountered, then a NULL entry is added 9737 // are encountered, then a null-string entry is
8963 // to the list. 9738 // added to the list.
8964 // 9739 //
8965 // It is a precondition that the source and 9740 // It is a precondition that the source and
8966 // toekizer lisst are non-null. If they are null, 9741 // toekizer lisst are non-null. If they are null,
@@ -8968,7 +9743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8968 // while their lengths are being determined. 9743 // while their lengths are being determined.
8969 // 9744 //
8970 // A small amount of working memoryis required 9745 // A small amount of working memoryis required
8971 // of approximately 8*#tokenizers. 9746 // of approximately 8*#tokenizers + 8*srcstrlen.
8972 // 9747 //
8973 // There are many ways in which this function 9748 // There are many ways in which this function
8974 // can be implemented, this implementation is 9749 // can be implemented, this implementation is
@@ -8984,155 +9759,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8984 // and eliminates redundant tokenizers as soon 9759 // and eliminates redundant tokenizers as soon
8985 // as is possible. 9760 // as is possible.
8986 // 9761 //
8987 // The implementation tries to avoid any copying 9762 // The implementation tries to minimize temporary
8988 // of arrays or other objects. 9763 // garbage generation.
8989 // </remarks> 9764 // </remarks>
8990 9765
8991 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9766 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8992 { 9767 {
8993 int beginning = 0; 9768 return ParseString2List(src, separators, spacers, true);
8994 int srclen = src.Length; 9769 }
8995 int seplen = separators.Length;
8996 object[] separray = separators.Data;
8997 int spclen = spacers.Length;
8998 object[] spcarray = spacers.Data;
8999 int mlen = seplen+spclen;
9000
9001 int[] offset = new int[mlen+1];
9002 bool[] active = new bool[mlen];
9003
9004 int best;
9005 int j;
9006
9007 // Initial capacity reduces resize cost
9008 9770
9009 LSL_List tokens = new LSL_List(); 9771 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9772 {
9773 int srclen = src.Length;
9774 int seplen = separators.Length;
9775 object[] separray = separators.Data;
9776 int spclen = spacers.Length;
9777 object[] spcarray = spacers.Data;
9778 int dellen = 0;
9779 string[] delarray = new string[seplen+spclen];
9010 9780
9011 // All entries are initially valid 9781 int outlen = 0;
9782 string[] outarray = new string[srclen*2+1];
9012 9783
9013 for (int i = 0; i < mlen; i++) 9784 int i, j;
9014 active[i] = true; 9785 string d;
9015 9786
9016 offset[mlen] = srclen; 9787 m_host.AddScriptLPS(1);
9017 9788
9018 while (beginning < srclen) 9789 /*
9790 * Convert separator and spacer lists to C# strings.
9791 * Also filter out null strings so we don't hang.
9792 */
9793 for (i = 0; i < seplen; i ++)
9019 { 9794 {
9795 d = separray[i].ToString();
9796 if (d.Length > 0)
9797 {
9798 delarray[dellen++] = d;
9799 }
9800 }
9801 seplen = dellen;
9020 9802
9021 best = mlen; // as bad as it gets 9803 for (i = 0; i < spclen; i ++)
9804 {
9805 d = spcarray[i].ToString();
9806 if (d.Length > 0)
9807 {
9808 delarray[dellen++] = d;
9809 }
9810 }
9022 9811
9023 // Scan for separators 9812 /*
9813 * Scan through source string from beginning to end.
9814 */
9815 for (i = 0;;)
9816 {
9024 9817
9025 for (j = 0; j < seplen; j++) 9818 /*
9819 * Find earliest delimeter in src starting at i (if any).
9820 */
9821 int earliestDel = -1;
9822 int earliestSrc = srclen;
9823 string earliestStr = null;
9824 for (j = 0; j < dellen; j ++)
9026 { 9825 {
9027 if (separray[j].ToString() == String.Empty) 9826 d = delarray[j];
9028 active[j] = false; 9827 if (d != null)
9029
9030 if (active[j])
9031 { 9828 {
9032 // scan all of the markers 9829 int index = src.IndexOf(d, i);
9033 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9830 if (index < 0)
9034 { 9831 {
9035 // not present at all 9832 delarray[j] = null; // delim nowhere in src, don't check it anymore
9036 active[j] = false;
9037 } 9833 }
9038 else 9834 else if (index < earliestSrc)
9039 { 9835 {
9040 // present and correct 9836 earliestSrc = index; // where delimeter starts in source string
9041 if (offset[j] < offset[best]) 9837 earliestDel = j; // where delimeter is in delarray[]
9042 { 9838 earliestStr = d; // the delimeter string from delarray[]
9043 // closest so far 9839 if (index == i) break; // can't do any better than found at beg of string
9044 best = j;
9045 if (offset[best] == beginning)
9046 break;
9047 }
9048 } 9840 }
9049 } 9841 }
9050 } 9842 }
9051 9843
9052 // Scan for spacers 9844 /*
9053 9845 * Output source string starting at i through start of earliest delimeter.
9054 if (offset[best] != beginning) 9846 */
9847 if (keepNulls || (earliestSrc > i))
9055 { 9848 {
9056 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9849 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9057 {
9058 if (spcarray[j-seplen].ToString() == String.Empty)
9059 active[j] = false;
9060
9061 if (active[j])
9062 {
9063 // scan all of the markers
9064 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9065 {
9066 // not present at all
9067 active[j] = false;
9068 }
9069 else
9070 {
9071 // present and correct
9072 if (offset[j] < offset[best])
9073 {
9074 // closest so far
9075 best = j;
9076 }
9077 }
9078 }
9079 }
9080 } 9850 }
9081 9851
9082 // This is the normal exit from the scanning loop 9852 /*
9853 * If no delimeter found at or after i, we're done scanning.
9854 */
9855 if (earliestDel < 0) break;
9083 9856
9084 if (best == mlen) 9857 /*
9858 * If delimeter was a spacer, output the spacer.
9859 */
9860 if (earliestDel >= seplen)
9085 { 9861 {
9086 // no markers were found on this pass 9862 outarray[outlen++] = earliestStr;
9087 // so we're pretty much done
9088 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9089 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9090 break;
9091 } 9863 }
9092 9864
9093 // Otherwise we just add the newly delimited token 9865 /*
9094 // and recalculate where the search should continue. 9866 * Look at rest of src string following delimeter.
9095 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9867 */
9096 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9868 i = earliestSrc + earliestStr.Length;
9097
9098 if (best < seplen)
9099 {
9100 beginning = offset[best] + (separray[best].ToString()).Length;
9101 }
9102 else
9103 {
9104 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9105 string str = spcarray[best - seplen].ToString();
9106 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9107 tokens.Add(new LSL_String(str));
9108 }
9109 } 9869 }
9110 9870
9111 // This an awkward an not very intuitive boundary case. If the 9871 /*
9112 // last substring is a tokenizer, then there is an implied trailing 9872 * Make up an exact-sized output array suitable for an LSL_List object.
9113 // null list entry. Hopefully the single comparison will not be too 9873 */
9114 // arduous. Alternatively the 'break' could be replced with a return 9874 object[] outlist = new object[outlen];
9115 // but that's shabby programming. 9875 for (i = 0; i < outlen; i ++)
9116
9117 if ((beginning == srclen) && (keepNulls))
9118 { 9876 {
9119 if (srclen != 0) 9877 outlist[i] = new LSL_String(outarray[i]);
9120 tokens.Add(new LSL_String(""));
9121 } 9878 }
9122 9879 return new LSL_List(outlist);
9123 return tokens;
9124 }
9125
9126 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9127 {
9128 m_host.AddScriptLPS(1);
9129 return this.ParseString(src, separators, spacers, false);
9130 }
9131
9132 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9133 {
9134 m_host.AddScriptLPS(1);
9135 return this.ParseString(src, separators, spacers, true);
9136 } 9880 }
9137 9881
9138 public LSL_Integer llGetObjectPermMask(int mask) 9882 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9227,6 +9971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9227 case 4: 9971 case 4:
9228 return (int)item.NextPermissions; 9972 return (int)item.NextPermissions;
9229 } 9973 }
9974 m_host.TaskInventory.LockItemsForRead(false);
9230 9975
9231 return -1; 9976 return -1;
9232 } 9977 }
@@ -9415,31 +10160,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9415 UUID key = new UUID(); 10160 UUID key = new UUID();
9416 if (UUID.TryParse(id, out key)) 10161 if (UUID.TryParse(id, out key))
9417 { 10162 {
9418 try 10163 // return total object mass
9419 { 10164 SceneObjectPart part = World.GetSceneObjectPart(key);
9420 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10165 if (part != null)
9421 if (obj != null) 10166 return part.ParentGroup.GetMass();
9422 return (double)obj.GetMass(); 10167
9423 // the object is null so the key is for an avatar 10168 // the object is null so the key is for an avatar
9424 ScenePresence avatar = World.GetScenePresence(key); 10169 ScenePresence avatar = World.GetScenePresence(key);
9425 if (avatar != null) 10170 if (avatar != null)
9426 if (avatar.IsChildAgent)
9427 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9428 // child agents have a mass of 1.0
9429 return 1;
9430 else
9431 return (double)avatar.GetMass();
9432 }
9433 catch (KeyNotFoundException)
9434 { 10171 {
9435 return 0; // The Object/Agent not in the region so just return zero 10172 if (avatar.IsChildAgent)
10173 {
10174 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10175 // child agents have a mass of 1.0
10176 return 1;
10177 }
10178 else
10179 {
10180 return (double)avatar.GetMass();
10181 }
9436 } 10182 }
9437 } 10183 }
9438 return 0; 10184 return 0;
9439 } 10185 }
9440 10186
9441 /// <summary> 10187 /// <summary>
9442 /// illListReplaceList removes the sub-list defined by the inclusive indices 10188 /// llListReplaceList removes the sub-list defined by the inclusive indices
9443 /// start and end and inserts the src list in its place. The inclusive 10189 /// start and end and inserts the src list in its place. The inclusive
9444 /// nature of the indices means that at least one element must be deleted 10190 /// nature of the indices means that at least one element must be deleted
9445 /// if the indices are within the bounds of the existing list. I.e. 2,2 10191 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9496,16 +10242,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9496 // based upon end. Note that if end exceeds the upper 10242 // based upon end. Note that if end exceeds the upper
9497 // bound in this case, the entire destination list 10243 // bound in this case, the entire destination list
9498 // is removed. 10244 // is removed.
9499 else 10245 else if (start == 0)
9500 { 10246 {
9501 if (end + 1 < dest.Length) 10247 if (end + 1 < dest.Length)
9502 {
9503 return src + dest.GetSublist(end + 1, -1); 10248 return src + dest.GetSublist(end + 1, -1);
9504 }
9505 else 10249 else
9506 {
9507 return src; 10250 return src;
9508 } 10251 }
10252 else // Start < 0
10253 {
10254 if (end + 1 < dest.Length)
10255 return dest.GetSublist(end + 1, -1);
10256 else
10257 return new LSL_List();
9509 } 10258 }
9510 } 10259 }
9511 // Finally, if start > end, we strip away a prefix and 10260 // Finally, if start > end, we strip away a prefix and
@@ -9556,17 +10305,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9556 int width = 0; 10305 int width = 0;
9557 int height = 0; 10306 int height = 0;
9558 10307
9559 ParcelMediaCommandEnum? commandToSend = null; 10308 uint commandToSend = 0;
9560 float time = 0.0f; // default is from start 10309 float time = 0.0f; // default is from start
9561 10310
9562 ScenePresence presence = null; 10311 ScenePresence presence = null;
9563 10312
9564 for (int i = 0; i < commandList.Data.Length; i++) 10313 for (int i = 0; i < commandList.Data.Length; i++)
9565 { 10314 {
9566 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10315 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9567 switch (command) 10316 switch (command)
9568 { 10317 {
9569 case ParcelMediaCommandEnum.Agent: 10318 case (uint)ParcelMediaCommandEnum.Agent:
9570 // we send only to one agent 10319 // we send only to one agent
9571 if ((i + 1) < commandList.Length) 10320 if ((i + 1) < commandList.Length)
9572 { 10321 {
@@ -9583,25 +10332,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9583 } 10332 }
9584 break; 10333 break;
9585 10334
9586 case ParcelMediaCommandEnum.Loop: 10335 case (uint)ParcelMediaCommandEnum.Loop:
9587 loop = 1; 10336 loop = 1;
9588 commandToSend = command; 10337 commandToSend = command;
9589 update = true; //need to send the media update packet to set looping 10338 update = true; //need to send the media update packet to set looping
9590 break; 10339 break;
9591 10340
9592 case ParcelMediaCommandEnum.Play: 10341 case (uint)ParcelMediaCommandEnum.Play:
9593 loop = 0; 10342 loop = 0;
9594 commandToSend = command; 10343 commandToSend = command;
9595 update = true; //need to send the media update packet to make sure it doesn't loop 10344 update = true; //need to send the media update packet to make sure it doesn't loop
9596 break; 10345 break;
9597 10346
9598 case ParcelMediaCommandEnum.Pause: 10347 case (uint)ParcelMediaCommandEnum.Pause:
9599 case ParcelMediaCommandEnum.Stop: 10348 case (uint)ParcelMediaCommandEnum.Stop:
9600 case ParcelMediaCommandEnum.Unload: 10349 case (uint)ParcelMediaCommandEnum.Unload:
9601 commandToSend = command; 10350 commandToSend = command;
9602 break; 10351 break;
9603 10352
9604 case ParcelMediaCommandEnum.Url: 10353 case (uint)ParcelMediaCommandEnum.Url:
9605 if ((i + 1) < commandList.Length) 10354 if ((i + 1) < commandList.Length)
9606 { 10355 {
9607 if (commandList.Data[i + 1] is LSL_String) 10356 if (commandList.Data[i + 1] is LSL_String)
@@ -9614,7 +10363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9614 } 10363 }
9615 break; 10364 break;
9616 10365
9617 case ParcelMediaCommandEnum.Texture: 10366 case (uint)ParcelMediaCommandEnum.Texture:
9618 if ((i + 1) < commandList.Length) 10367 if ((i + 1) < commandList.Length)
9619 { 10368 {
9620 if (commandList.Data[i + 1] is LSL_String) 10369 if (commandList.Data[i + 1] is LSL_String)
@@ -9627,7 +10376,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9627 } 10376 }
9628 break; 10377 break;
9629 10378
9630 case ParcelMediaCommandEnum.Time: 10379 case (uint)ParcelMediaCommandEnum.Time:
9631 if ((i + 1) < commandList.Length) 10380 if ((i + 1) < commandList.Length)
9632 { 10381 {
9633 if (commandList.Data[i + 1] is LSL_Float) 10382 if (commandList.Data[i + 1] is LSL_Float)
@@ -9639,7 +10388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9639 } 10388 }
9640 break; 10389 break;
9641 10390
9642 case ParcelMediaCommandEnum.AutoAlign: 10391 case (uint)ParcelMediaCommandEnum.AutoAlign:
9643 if ((i + 1) < commandList.Length) 10392 if ((i + 1) < commandList.Length)
9644 { 10393 {
9645 if (commandList.Data[i + 1] is LSL_Integer) 10394 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9653,7 +10402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9653 } 10402 }
9654 break; 10403 break;
9655 10404
9656 case ParcelMediaCommandEnum.Type: 10405 case (uint)ParcelMediaCommandEnum.Type:
9657 if ((i + 1) < commandList.Length) 10406 if ((i + 1) < commandList.Length)
9658 { 10407 {
9659 if (commandList.Data[i + 1] is LSL_String) 10408 if (commandList.Data[i + 1] is LSL_String)
@@ -9666,7 +10415,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9666 } 10415 }
9667 break; 10416 break;
9668 10417
9669 case ParcelMediaCommandEnum.Desc: 10418 case (uint)ParcelMediaCommandEnum.Desc:
9670 if ((i + 1) < commandList.Length) 10419 if ((i + 1) < commandList.Length)
9671 { 10420 {
9672 if (commandList.Data[i + 1] is LSL_String) 10421 if (commandList.Data[i + 1] is LSL_String)
@@ -9679,7 +10428,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9679 } 10428 }
9680 break; 10429 break;
9681 10430
9682 case ParcelMediaCommandEnum.Size: 10431 case (uint)ParcelMediaCommandEnum.Size:
9683 if ((i + 2) < commandList.Length) 10432 if ((i + 2) < commandList.Length)
9684 { 10433 {
9685 if (commandList.Data[i + 1] is LSL_Integer) 10434 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9749,7 +10498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9749 } 10498 }
9750 } 10499 }
9751 10500
9752 if (commandToSend != null) 10501 if (commandToSend != 0)
9753 { 10502 {
9754 // the commandList contained a start/stop/... command, too 10503 // the commandList contained a start/stop/... command, too
9755 if (presence == null) 10504 if (presence == null)
@@ -9786,7 +10535,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9786 10535
9787 if (aList.Data[i] != null) 10536 if (aList.Data[i] != null)
9788 { 10537 {
9789 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10538 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9790 { 10539 {
9791 case ParcelMediaCommandEnum.Url: 10540 case ParcelMediaCommandEnum.Url:
9792 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10541 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9843,15 +10592,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9843 10592
9844 if (quick_pay_buttons.Data.Length < 4) 10593 if (quick_pay_buttons.Data.Length < 4)
9845 { 10594 {
9846 LSLError("List must have at least 4 elements"); 10595 int x;
9847 return; 10596 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10597 {
10598 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10599 }
9848 } 10600 }
9849 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10601 int[] nPrice = new int[5];
9850 10602 nPrice[0] = price;
9851 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10603 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9852 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10604 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9853 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10605 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9854 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10606 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10607 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9855 m_host.ParentGroup.HasGroupChanged = true; 10608 m_host.ParentGroup.HasGroupChanged = true;
9856 } 10609 }
9857 10610
@@ -9868,7 +10621,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9868 return new LSL_Vector(); 10621 return new LSL_Vector();
9869 } 10622 }
9870 10623
9871 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10624// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10625 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9872 if (presence != null) 10626 if (presence != null)
9873 { 10627 {
9874 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10628 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9890,7 +10644,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9890 return new LSL_Rotation(); 10644 return new LSL_Rotation();
9891 } 10645 }
9892 10646
9893 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10647// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10648 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9894 if (presence != null) 10649 if (presence != null)
9895 { 10650 {
9896 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10651 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9950,14 +10705,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9950 { 10705 {
9951 m_host.AddScriptLPS(1); 10706 m_host.AddScriptLPS(1);
9952 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10707 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9953 if (detectedParams == null) return; // only works on the first detected avatar 10708 if (detectedParams == null)
9954 10709 {
10710 if (m_host.ParentGroup.IsAttachment == true)
10711 {
10712 detectedParams = new DetectParams();
10713 detectedParams.Key = m_host.OwnerID;
10714 }
10715 else
10716 {
10717 return;
10718 }
10719 }
10720
9955 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10721 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9956 if (avatar != null) 10722 if (avatar != null)
9957 { 10723 {
9958 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10724 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9959 simname, pos, lookAt); 10725 simname, pos, lookAt);
9960 } 10726 }
10727
9961 ScriptSleep(1000); 10728 ScriptSleep(1000);
9962 } 10729 }
9963 10730
@@ -10081,12 +10848,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10081 10848
10082 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10849 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10083 object[] data = rules.Data; 10850 object[] data = rules.Data;
10084 for (int i = 0; i < data.Length; ++i) { 10851 for (int i = 0; i < data.Length; ++i)
10852 {
10085 int type = Convert.ToInt32(data[i++].ToString()); 10853 int type = Convert.ToInt32(data[i++].ToString());
10086 if (i >= data.Length) break; // odd number of entries => ignore the last 10854 if (i >= data.Length) break; // odd number of entries => ignore the last
10087 10855
10088 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10856 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10089 switch (type) { 10857 switch (type)
10858 {
10090 case ScriptBaseClass.CAMERA_FOCUS: 10859 case ScriptBaseClass.CAMERA_FOCUS:
10091 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10860 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10092 case ScriptBaseClass.CAMERA_POSITION: 10861 case ScriptBaseClass.CAMERA_POSITION:
@@ -10191,19 +10960,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10191 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10960 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10192 { 10961 {
10193 m_host.AddScriptLPS(1); 10962 m_host.AddScriptLPS(1);
10194 string ret = String.Empty; 10963
10195 string src1 = llBase64ToString(str1); 10964 if (str1 == String.Empty)
10196 string src2 = llBase64ToString(str2); 10965 return String.Empty;
10197 int c = 0; 10966 if (str2 == String.Empty)
10198 for (int i = 0; i < src1.Length; i++) 10967 return str1;
10968
10969 int len = str2.Length;
10970 if ((len % 4) != 0) // LL is EVIL!!!!
10199 { 10971 {
10200 ret += (char) (src1[i] ^ src2[c]); 10972 while (str2.EndsWith("="))
10973 str2 = str2.Substring(0, str2.Length - 1);
10974
10975 len = str2.Length;
10976 int mod = len % 4;
10201 10977
10202 c++; 10978 if (mod == 1)
10203 if (c >= src2.Length) 10979 str2 = str2.Substring(0, str2.Length - 1);
10204 c = 0; 10980 else if (mod == 2)
10981 str2 += "==";
10982 else if (mod == 3)
10983 str2 += "=";
10984 }
10985
10986 byte[] data1;
10987 byte[] data2;
10988 try
10989 {
10990 data1 = Convert.FromBase64String(str1);
10991 data2 = Convert.FromBase64String(str2);
10992 }
10993 catch (Exception)
10994 {
10995 return new LSL_String(String.Empty);
10996 }
10997
10998 byte[] d2 = new Byte[data1.Length];
10999 int pos = 0;
11000
11001 if (data1.Length <= data2.Length)
11002 {
11003 Array.Copy(data2, 0, d2, 0, data1.Length);
11004 }
11005 else
11006 {
11007 while (pos < data1.Length)
11008 {
11009 len = data1.Length - pos;
11010 if (len > data2.Length)
11011 len = data2.Length;
11012
11013 Array.Copy(data2, 0, d2, pos, len);
11014 pos += len;
11015 }
10205 } 11016 }
10206 return llStringToBase64(ret); 11017
11018 for (pos = 0 ; pos < data1.Length ; pos++ )
11019 data1[pos] ^= d2[pos];
11020
11021 return Convert.ToBase64String(data1);
10207 } 11022 }
10208 11023
10209 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11024 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10256,16 +11071,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10256 if (userAgent != null) 11071 if (userAgent != null)
10257 httpHeaders["User-Agent"] = userAgent; 11072 httpHeaders["User-Agent"] = userAgent;
10258 11073
11074 // See if the URL contains any header hacks
11075 string[] urlParts = url.Split(new char[] {'\n'});
11076 if (urlParts.Length > 1)
11077 {
11078 // Iterate the passed headers and parse them
11079 for (int i = 1 ; i < urlParts.Length ; i++ )
11080 {
11081 // The rest of those would be added to the body in SL.
11082 // Let's not do that.
11083 if (urlParts[i] == String.Empty)
11084 break;
11085
11086 // See if this could be a valid header
11087 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11088 if (headerParts.Length != 2)
11089 continue;
11090
11091 string headerName = headerParts[0].Trim();
11092 string headerValue = headerParts[1].Trim();
11093
11094 // Filter out headers that could be used to abuse
11095 // another system or cloak the request
11096 if (headerName.ToLower() == "x-secondlife-shard" ||
11097 headerName.ToLower() == "x-secondlife-object-name" ||
11098 headerName.ToLower() == "x-secondlife-object-key" ||
11099 headerName.ToLower() == "x-secondlife-region" ||
11100 headerName.ToLower() == "x-secondlife-local-position" ||
11101 headerName.ToLower() == "x-secondlife-local-velocity" ||
11102 headerName.ToLower() == "x-secondlife-local-rotation" ||
11103 headerName.ToLower() == "x-secondlife-owner-name" ||
11104 headerName.ToLower() == "x-secondlife-owner-key" ||
11105 headerName.ToLower() == "connection" ||
11106 headerName.ToLower() == "content-length" ||
11107 headerName.ToLower() == "from" ||
11108 headerName.ToLower() == "host" ||
11109 headerName.ToLower() == "proxy-authorization" ||
11110 headerName.ToLower() == "referer" ||
11111 headerName.ToLower() == "trailer" ||
11112 headerName.ToLower() == "transfer-encoding" ||
11113 headerName.ToLower() == "via" ||
11114 headerName.ToLower() == "authorization")
11115 continue;
11116
11117 httpHeaders[headerName] = headerValue;
11118 }
11119
11120 // Finally, strip any protocol specifier from the URL
11121 url = urlParts[0].Trim();
11122 int idx = url.IndexOf(" HTTP/");
11123 if (idx != -1)
11124 url = url.Substring(0, idx);
11125 }
11126
10259 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11127 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10260 Regex r = new Regex(authregex); 11128 Regex r = new Regex(authregex);
10261 int[] gnums = r.GetGroupNumbers(); 11129 int[] gnums = r.GetGroupNumbers();
10262 Match m = r.Match(url); 11130 Match m = r.Match(url);
10263 if (m.Success) { 11131 if (m.Success)
10264 for (int i = 1; i < gnums.Length; i++) { 11132 {
11133 for (int i = 1; i < gnums.Length; i++)
11134 {
10265 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11135 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10266 //CaptureCollection cc = g.Captures; 11136 //CaptureCollection cc = g.Captures;
10267 } 11137 }
10268 if (m.Groups.Count == 5) { 11138 if (m.Groups.Count == 5)
11139 {
10269 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11140 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10270 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11141 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10271 } 11142 }
@@ -10468,6 +11339,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10468 11339
10469 LSL_List ret = new LSL_List(); 11340 LSL_List ret = new LSL_List();
10470 UUID key = new UUID(); 11341 UUID key = new UUID();
11342
11343
10471 if (UUID.TryParse(id, out key)) 11344 if (UUID.TryParse(id, out key))
10472 { 11345 {
10473 ScenePresence av = World.GetScenePresence(key); 11346 ScenePresence av = World.GetScenePresence(key);
@@ -10485,13 +11358,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10485 ret.Add(new LSL_String("")); 11358 ret.Add(new LSL_String(""));
10486 break; 11359 break;
10487 case ScriptBaseClass.OBJECT_POS: 11360 case ScriptBaseClass.OBJECT_POS:
10488 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11361 Vector3 avpos;
11362
11363 if (av.ParentID != 0 && av.ParentPart != null)
11364 {
11365 avpos = av.OffsetPosition;
11366
11367 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11368 avpos -= sitOffset;
11369
11370 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11371 }
11372 else
11373 avpos = av.AbsolutePosition;
11374
11375 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10489 break; 11376 break;
10490 case ScriptBaseClass.OBJECT_ROT: 11377 case ScriptBaseClass.OBJECT_ROT:
10491 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11378 Quaternion avrot = av.Rotation;
11379 if (av.ParentID != 0 && av.ParentPart != null)
11380 {
11381 avrot = av.ParentPart.GetWorldRotation() * avrot;
11382 }
11383 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10492 break; 11384 break;
10493 case ScriptBaseClass.OBJECT_VELOCITY: 11385 case ScriptBaseClass.OBJECT_VELOCITY:
10494 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11386 Vector3 avvel = av.Velocity;
11387 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10495 break; 11388 break;
10496 case ScriptBaseClass.OBJECT_OWNER: 11389 case ScriptBaseClass.OBJECT_OWNER:
10497 ret.Add(new LSL_String(id)); 11390 ret.Add(new LSL_String(id));
@@ -10547,11 +11440,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10547 case ScriptBaseClass.OBJECT_NAME: 11440 case ScriptBaseClass.OBJECT_NAME:
10548 ret.Add(new LSL_String(obj.Name)); 11441 ret.Add(new LSL_String(obj.Name));
10549 break; 11442 break;
10550 case ScriptBaseClass.OBJECT_DESC: 11443 case ScriptBaseClass.OBJECT_DESC:
10551 ret.Add(new LSL_String(obj.Description)); 11444 ret.Add(new LSL_String(obj.Description));
10552 break; 11445 break;
10553 case ScriptBaseClass.OBJECT_POS: 11446 case ScriptBaseClass.OBJECT_POS:
10554 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11447 Vector3 opos = obj.AbsolutePosition;
11448 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10555 break; 11449 break;
10556 case ScriptBaseClass.OBJECT_ROT: 11450 case ScriptBaseClass.OBJECT_ROT:
10557 { 11451 {
@@ -10601,9 +11495,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10601 // The value returned in SL for normal prims is prim count 11495 // The value returned in SL for normal prims is prim count
10602 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11496 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10603 break; 11497 break;
10604 // The following 3 costs I have intentionaly coded to return zero. They are part of 11498
10605 // "Land Impact" calculations. These calculations are probably not applicable 11499 // costs below may need to be diferent for root parts, need to check
10606 // to OpenSim and are not yet complete in SL
10607 case ScriptBaseClass.OBJECT_SERVER_COST: 11500 case ScriptBaseClass.OBJECT_SERVER_COST:
10608 // The linden calculation is here 11501 // The linden calculation is here
10609 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11502 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10611,16 +11504,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10611 ret.Add(new LSL_Float(0)); 11504 ret.Add(new LSL_Float(0));
10612 break; 11505 break;
10613 case ScriptBaseClass.OBJECT_STREAMING_COST: 11506 case ScriptBaseClass.OBJECT_STREAMING_COST:
10614 // The linden calculation is here 11507 // The value returned in SL for normal prims is prim count * 0.06
10615 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11508 ret.Add(new LSL_Float(obj.StreamingCost));
10616 // The value returned in SL for normal prims looks like the prim count * 0.06
10617 ret.Add(new LSL_Float(0));
10618 break; 11509 break;
10619 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11510 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10620 // The linden calculation is here 11511 // The value returned in SL for normal prims is prim count
10621 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11512 ret.Add(new LSL_Float(obj.PhysicsCost));
10622 // The value returned in SL for normal prims looks like the prim count
10623 ret.Add(new LSL_Float(0));
10624 break; 11513 break;
10625 default: 11514 default:
10626 // Invalid or unhandled constant. 11515 // Invalid or unhandled constant.
@@ -10831,15 +11720,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10831 return result; 11720 return result;
10832 } 11721 }
10833 11722
10834 public void print(string str) 11723 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10835 { 11724 {
10836 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11725 List<SceneObjectPart> parts = GetLinkParts(link);
10837 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11726 if (parts.Count < 1)
10838 if (ossl != null) 11727 return 0;
10839 { 11728
10840 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11729 return GetNumberOfSides(parts[0]);
10841 m_log.Info("LSL print():" + str);
10842 }
10843 } 11730 }
10844 11731
10845 private string Name2Username(string name) 11732 private string Name2Username(string name)
@@ -10884,7 +11771,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10884 11771
10885 return rq.ToString(); 11772 return rq.ToString();
10886 } 11773 }
10887 11774/*
11775 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11776 {
11777 m_SayShoutCount = 0;
11778 }
11779*/
10888 private struct Tri 11780 private struct Tri
10889 { 11781 {
10890 public Vector3 p1; 11782 public Vector3 p1;
@@ -11024,9 +11916,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11024 11916
11025 ContactResult result = new ContactResult (); 11917 ContactResult result = new ContactResult ();
11026 result.ConsumerID = group.LocalId; 11918 result.ConsumerID = group.LocalId;
11027 result.Depth = intersection.distance; 11919// result.Depth = intersection.distance;
11028 result.Normal = intersection.normal; 11920 result.Normal = intersection.normal;
11029 result.Pos = intersection.ipoint; 11921 result.Pos = intersection.ipoint;
11922 result.Depth = Vector3.Mag(rayStart - result.Pos);
11030 11923
11031 contacts.Add(result); 11924 contacts.Add(result);
11032 }); 11925 });
@@ -11159,6 +12052,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11159 12052
11160 return contacts[0]; 12053 return contacts[0];
11161 } 12054 }
12055/*
12056 // not done:
12057 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12058 {
12059 ContactResult[] contacts = null;
12060 World.ForEachSOG(delegate(SceneObjectGroup group)
12061 {
12062 if (m_host.ParentGroup == group)
12063 return;
12064
12065 if (group.IsAttachment)
12066 return;
12067
12068 if(group.RootPart.PhysActor != null)
12069 return;
12070
12071 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12072 });
12073 return contacts;
12074 }
12075*/
11162 12076
11163 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12077 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11164 { 12078 {
@@ -11200,32 +12114,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11200 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12114 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11201 12115
11202 12116
11203 if (checkTerrain) 12117 if (World.SuportsRayCastFiltered())
11204 { 12118 {
11205 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12119 if (dist == 0)
11206 if (groundContact != null) 12120 return list;
11207 results.Add((ContactResult)groundContact);
11208 }
11209 12121
11210 if (checkAgents) 12122 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11211 { 12123 if (checkTerrain)
11212 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12124 rayfilter |= RayFilterFlags.land;
11213 foreach (ContactResult r in agentHits) 12125// if (checkAgents)
11214 results.Add(r); 12126// rayfilter |= RayFilterFlags.agent;
11215 } 12127 if (checkPhysical)
12128 rayfilter |= RayFilterFlags.physical;
12129 if (checkNonPhysical)
12130 rayfilter |= RayFilterFlags.nonphysical;
12131 if (detectPhantom)
12132 rayfilter |= RayFilterFlags.LSLPhanton;
12133
12134 Vector3 direction = dir * ( 1/dist);
12135
12136 if(rayfilter == 0)
12137 {
12138 list.Add(new LSL_Integer(0));
12139 return list;
12140 }
12141
12142 // get some more contacts to sort ???
12143 int physcount = 4 * count;
12144 if (physcount > 20)
12145 physcount = 20;
12146
12147 object physresults;
12148 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12149
12150 if (physresults == null)
12151 {
12152 list.Add(new LSL_Integer(-3)); // timeout error
12153 return list;
12154 }
11216 12155
11217 if (checkPhysical || checkNonPhysical || detectPhantom) 12156 results = (List<ContactResult>)physresults;
12157
12158 // for now physics doesn't detect sitted avatars so do it outside physics
12159 if (checkAgents)
12160 {
12161 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12162 foreach (ContactResult r in agentHits)
12163 results.Add(r);
12164 }
12165
12166 // TODO: Replace this with a better solution. ObjectIntersection can only
12167 // detect nonphysical phantoms. They are detected by virtue of being
12168 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12169 // physicsl phantoms as done by the physics scene
12170 // We don't want anything else but phantoms here.
12171 if (detectPhantom)
12172 {
12173 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12174 foreach (ContactResult r in objectHits)
12175 results.Add(r);
12176 }
12177 }
12178 else
11218 { 12179 {
11219 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12180 if (checkTerrain)
11220 foreach (ContactResult r in objectHits) 12181 {
11221 results.Add(r); 12182 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12183 if (groundContact != null)
12184 results.Add((ContactResult)groundContact);
12185 }
12186
12187 if (checkAgents)
12188 {
12189 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12190 foreach (ContactResult r in agentHits)
12191 results.Add(r);
12192 }
12193
12194 if (checkPhysical || checkNonPhysical || detectPhantom)
12195 {
12196 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12197 foreach (ContactResult r in objectHits)
12198 results.Add(r);
12199 }
11222 } 12200 }
11223 12201
11224 results.Sort(delegate(ContactResult a, ContactResult b) 12202 results.Sort(delegate(ContactResult a, ContactResult b)
11225 { 12203 {
11226 return a.Depth.CompareTo(b.Depth); 12204 return a.Depth.CompareTo(b.Depth);
11227 }); 12205 });
11228 12206
11229 int values = 0; 12207 int values = 0;
11230 SceneObjectGroup thisgrp = m_host.ParentGroup; 12208 SceneObjectGroup thisgrp = m_host.ParentGroup;
11231 12209
@@ -11318,7 +12296,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11318 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12296 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11319 if (!isAccount) return 0; 12297 if (!isAccount) return 0;
11320 if (estate.HasAccess(id)) return 1; 12298 if (estate.HasAccess(id)) return 1;
11321 if (estate.IsBanned(id)) 12299 if (estate.IsBanned(id, World.GetUserFlags(id)))
11322 estate.RemoveBan(id); 12300 estate.RemoveBan(id);
11323 estate.AddEstateUser(id); 12301 estate.AddEstateUser(id);
11324 break; 12302 break;
@@ -11337,14 +12315,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11337 break; 12315 break;
11338 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12316 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11339 if (!isAccount) return 0; 12317 if (!isAccount) return 0;
11340 if (estate.IsBanned(id)) return 1; 12318 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11341 EstateBan ban = new EstateBan(); 12319 EstateBan ban = new EstateBan();
11342 ban.EstateID = estate.EstateID; 12320 ban.EstateID = estate.EstateID;
11343 ban.BannedUserID = id; 12321 ban.BannedUserID = id;
11344 estate.AddBan(ban); 12322 estate.AddBan(ban);
11345 break; 12323 break;
11346 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12324 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11347 if (!isAccount || !estate.IsBanned(id)) return 0; 12325 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11348 estate.RemoveBan(id); 12326 estate.RemoveBan(id);
11349 break; 12327 break;
11350 default: return 0; 12328 default: return 0;
@@ -11373,7 +12351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11373 return 16384; 12351 return 16384;
11374 } 12352 }
11375 12353
11376 public LSL_Integer llGetUsedMemory() 12354 public virtual LSL_Integer llGetUsedMemory()
11377 { 12355 {
11378 m_host.AddScriptLPS(1); 12356 m_host.AddScriptLPS(1);
11379 // The value returned for LSO scripts in SL 12357 // The value returned for LSO scripts in SL
@@ -11401,22 +12379,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11401 public void llSetSoundQueueing(int queue) 12379 public void llSetSoundQueueing(int queue)
11402 { 12380 {
11403 m_host.AddScriptLPS(1); 12381 m_host.AddScriptLPS(1);
11404 NotImplemented("llSetSoundQueueing");
11405 } 12382 }
11406 12383
11407 public void llCollisionSprite(string impact_sprite) 12384 public void llCollisionSprite(string impact_sprite)
11408 { 12385 {
11409 m_host.AddScriptLPS(1); 12386 m_host.AddScriptLPS(1);
11410 NotImplemented("llCollisionSprite"); 12387 // Viewer 2.0 broke this and it's likely LL has no intention
12388 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11411 } 12389 }
11412 12390
11413 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12391 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11414 { 12392 {
11415 m_host.AddScriptLPS(1); 12393 m_host.AddScriptLPS(1);
11416 NotImplemented("llGodLikeRezObject"); 12394
12395 if (!World.Permissions.IsGod(m_host.OwnerID))
12396 NotImplemented("llGodLikeRezObject");
12397
12398 AssetBase rezAsset = World.AssetService.Get(inventory);
12399 if (rezAsset == null)
12400 {
12401 llSay(0, "Asset not found");
12402 return;
12403 }
12404
12405 SceneObjectGroup group = null;
12406
12407 try
12408 {
12409 string xmlData = Utils.BytesToString(rezAsset.Data);
12410 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12411 }
12412 catch
12413 {
12414 llSay(0, "Asset not found");
12415 return;
12416 }
12417
12418 if (group == null)
12419 {
12420 llSay(0, "Asset not found");
12421 return;
12422 }
12423
12424 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12425 group.RootPart.AttachOffset = group.AbsolutePosition;
12426
12427 group.ResetIDs();
12428
12429 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12430 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12431 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12432 group.ScheduleGroupForFullUpdate();
12433
12434 // objects rezzed with this method are die_at_edge by default.
12435 group.RootPart.SetDieAtEdge(true);
12436
12437 group.ResumeScripts();
12438
12439 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12440 "object_rez", new Object[] {
12441 new LSL_String(
12442 group.RootPart.UUID.ToString()) },
12443 new DetectParams[0]));
12444 }
12445
12446 public LSL_String llTransferLindenDollars(string destination, int amount)
12447 {
12448 UUID txn = UUID.Random();
12449
12450 Util.FireAndForget(delegate(object x)
12451 {
12452 int replycode = 0;
12453 string replydata = destination + "," + amount.ToString();
12454
12455 try
12456 {
12457 TaskInventoryItem item = m_item;
12458 if (item == null)
12459 {
12460 replydata = "SERVICE_ERROR";
12461 return;
12462 }
12463
12464 m_host.AddScriptLPS(1);
12465
12466 if (item.PermsGranter == UUID.Zero)
12467 {
12468 replydata = "MISSING_PERMISSION_DEBIT";
12469 return;
12470 }
12471
12472 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12473 {
12474 replydata = "MISSING_PERMISSION_DEBIT";
12475 return;
12476 }
12477
12478 UUID toID = new UUID();
12479
12480 if (!UUID.TryParse(destination, out toID))
12481 {
12482 replydata = "INVALID_AGENT";
12483 return;
12484 }
12485
12486 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12487
12488 if (money == null)
12489 {
12490 replydata = "TRANSFERS_DISABLED";
12491 return;
12492 }
12493
12494 bool result = money.ObjectGiveMoney(
12495 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12496
12497 if (result)
12498 {
12499 replycode = 1;
12500 return;
12501 }
12502
12503 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12504 }
12505 finally
12506 {
12507 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12508 "transaction_result", new Object[] {
12509 new LSL_String(txn.ToString()),
12510 new LSL_Integer(replycode),
12511 new LSL_String(replydata) },
12512 new DetectParams[0]));
12513 }
12514 });
12515
12516 return txn.ToString();
11417 } 12517 }
11418 12518
11419 #endregion 12519 #endregion
12520
12521 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12522 {
12523 SceneObjectGroup group = m_host.ParentGroup;
12524
12525 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12526 return;
12527 if (group.IsAttachment)
12528 return;
12529
12530 if (frames.Data.Length > 0) // We are getting a new motion
12531 {
12532 if (group.RootPart.KeyframeMotion != null)
12533 group.RootPart.KeyframeMotion.Delete();
12534 group.RootPart.KeyframeMotion = null;
12535
12536 int idx = 0;
12537
12538 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12539 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12540
12541 while (idx < options.Data.Length)
12542 {
12543 int option = (int)options.GetLSLIntegerItem(idx++);
12544 int remain = options.Data.Length - idx;
12545
12546 switch (option)
12547 {
12548 case ScriptBaseClass.KFM_MODE:
12549 if (remain < 1)
12550 break;
12551 int modeval = (int)options.GetLSLIntegerItem(idx++);
12552 switch(modeval)
12553 {
12554 case ScriptBaseClass.KFM_FORWARD:
12555 mode = KeyframeMotion.PlayMode.Forward;
12556 break;
12557 case ScriptBaseClass.KFM_REVERSE:
12558 mode = KeyframeMotion.PlayMode.Reverse;
12559 break;
12560 case ScriptBaseClass.KFM_LOOP:
12561 mode = KeyframeMotion.PlayMode.Loop;
12562 break;
12563 case ScriptBaseClass.KFM_PING_PONG:
12564 mode = KeyframeMotion.PlayMode.PingPong;
12565 break;
12566 }
12567 break;
12568 case ScriptBaseClass.KFM_DATA:
12569 if (remain < 1)
12570 break;
12571 int dataval = (int)options.GetLSLIntegerItem(idx++);
12572 data = (KeyframeMotion.DataFormat)dataval;
12573 break;
12574 }
12575 }
12576
12577 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12578
12579 idx = 0;
12580
12581 int elemLength = 2;
12582 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12583 elemLength = 3;
12584
12585 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12586 while (idx < frames.Data.Length)
12587 {
12588 int remain = frames.Data.Length - idx;
12589
12590 if (remain < elemLength)
12591 break;
12592
12593 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12594 frame.Position = null;
12595 frame.Rotation = null;
12596
12597 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12598 {
12599 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12600 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12601 }
12602 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12603 {
12604 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12605 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12606 }
12607
12608 float tempf = (float)frames.GetLSLFloatItem(idx++);
12609 frame.TimeMS = (int)(tempf * 1000.0f);
12610
12611 keyframes.Add(frame);
12612 }
12613
12614 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12615 group.RootPart.KeyframeMotion.Start();
12616 }
12617 else
12618 {
12619 if (group.RootPart.KeyframeMotion == null)
12620 return;
12621
12622 if (options.Data.Length == 0)
12623 {
12624 group.RootPart.KeyframeMotion.Stop();
12625 return;
12626 }
12627
12628 int code = (int)options.GetLSLIntegerItem(0);
12629
12630 int idx = 0;
12631
12632 while (idx < options.Data.Length)
12633 {
12634 int option = (int)options.GetLSLIntegerItem(idx++);
12635 int remain = options.Data.Length - idx;
12636
12637 switch (option)
12638 {
12639 case ScriptBaseClass.KFM_COMMAND:
12640 int cmd = (int)options.GetLSLIntegerItem(idx++);
12641 switch (cmd)
12642 {
12643 case ScriptBaseClass.KFM_CMD_PLAY:
12644 group.RootPart.KeyframeMotion.Start();
12645 break;
12646 case ScriptBaseClass.KFM_CMD_STOP:
12647 group.RootPart.KeyframeMotion.Stop();
12648 break;
12649 case ScriptBaseClass.KFM_CMD_PAUSE:
12650 group.RootPart.KeyframeMotion.Pause();
12651 break;
12652 }
12653 break;
12654 }
12655 }
12656 }
12657 }
12658
12659 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12660 {
12661 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12662
12663 int idx = 0;
12664 int idxStart = 0;
12665
12666 bool positionChanged = false;
12667 Vector3 finalPos = Vector3.Zero;
12668
12669 try
12670 {
12671 while (idx < rules.Length)
12672 {
12673 ++rulesParsed;
12674 int code = rules.GetLSLIntegerItem(idx++);
12675
12676 int remain = rules.Length - idx;
12677 idxStart = idx;
12678
12679 switch (code)
12680 {
12681 case (int)ScriptBaseClass.PRIM_POSITION:
12682 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12683 {
12684 if (remain < 1)
12685 return null;
12686
12687 LSL_Vector v;
12688 v = rules.GetVector3Item(idx++);
12689
12690 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12691 if (part == null)
12692 break;
12693
12694 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12695 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12696 if (part.LinkNum > 1)
12697 {
12698 localRot = GetPartLocalRot(part);
12699 localPos = GetPartLocalPos(part);
12700 }
12701
12702 v -= localPos;
12703 v /= localRot;
12704
12705 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12706
12707 v = v + 2 * sitOffset;
12708
12709 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12710 av.SendAvatarDataToAllAgents();
12711
12712 }
12713 break;
12714
12715 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12716 case (int)ScriptBaseClass.PRIM_ROTATION:
12717 {
12718 if (remain < 1)
12719 return null;
12720
12721 LSL_Rotation r;
12722 r = rules.GetQuaternionItem(idx++);
12723
12724 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12725 if (part == null)
12726 break;
12727
12728 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12729 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12730
12731 if (part.LinkNum > 1)
12732 localRot = GetPartLocalRot(part);
12733
12734 r = r * llGetRootRotation() / localRot;
12735 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12736 av.SendAvatarDataToAllAgents();
12737 }
12738 break;
12739
12740 // parse rest doing nothing but number of parameters error check
12741 case (int)ScriptBaseClass.PRIM_SIZE:
12742 case (int)ScriptBaseClass.PRIM_MATERIAL:
12743 case (int)ScriptBaseClass.PRIM_PHANTOM:
12744 case (int)ScriptBaseClass.PRIM_PHYSICS:
12745 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12746 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12747 case (int)ScriptBaseClass.PRIM_NAME:
12748 case (int)ScriptBaseClass.PRIM_DESC:
12749 if (remain < 1)
12750 return null;
12751 idx++;
12752 break;
12753
12754 case (int)ScriptBaseClass.PRIM_GLOW:
12755 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12756 case (int)ScriptBaseClass.PRIM_TEXGEN:
12757 if (remain < 2)
12758 return null;
12759 idx += 2;
12760 break;
12761
12762 case (int)ScriptBaseClass.PRIM_TYPE:
12763 if (remain < 3)
12764 return null;
12765 code = (int)rules.GetLSLIntegerItem(idx++);
12766 remain = rules.Length - idx;
12767 switch (code)
12768 {
12769 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12770 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12771 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12772 if (remain < 6)
12773 return null;
12774 idx += 6;
12775 break;
12776
12777 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12778 if (remain < 5)
12779 return null;
12780 idx += 5;
12781 break;
12782
12783 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12784 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12785 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12786 if (remain < 11)
12787 return null;
12788 idx += 11;
12789 break;
12790
12791 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12792 if (remain < 2)
12793 return null;
12794 idx += 2;
12795 break;
12796 }
12797 break;
12798
12799 case (int)ScriptBaseClass.PRIM_COLOR:
12800 case (int)ScriptBaseClass.PRIM_TEXT:
12801 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12802 case (int)ScriptBaseClass.PRIM_OMEGA:
12803 if (remain < 3)
12804 return null;
12805 idx += 3;
12806 break;
12807
12808 case (int)ScriptBaseClass.PRIM_TEXTURE:
12809 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12810 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12811 if (remain < 5)
12812 return null;
12813 idx += 5;
12814 break;
12815
12816 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12817 if (remain < 7)
12818 return null;
12819
12820 idx += 7;
12821 break;
12822
12823 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12824 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12825 return null;
12826
12827 return rules.GetSublist(idx, -1);
12828 }
12829 }
12830 }
12831 catch (InvalidCastException e)
12832 {
12833 ShoutError(string.Format(
12834 "{0} error running rule #{1}: arg #{2} ",
12835 originFunc, rulesParsed, idx - idxStart) + e.Message);
12836 }
12837 finally
12838 {
12839 if (positionChanged)
12840 {
12841 av.OffsetPosition = finalPos;
12842// av.SendAvatarDataToAllAgents();
12843 av.SendTerseUpdateToAllClients();
12844 positionChanged = false;
12845 }
12846 }
12847 return null;
12848 }
12849
12850 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12851 {
12852 // avatars case
12853 // replies as SL wiki
12854
12855// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12856 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12857
12858 int idx = 0;
12859 while (idx < rules.Length)
12860 {
12861 int code = (int)rules.GetLSLIntegerItem(idx++);
12862 int remain = rules.Length - idx;
12863
12864 switch (code)
12865 {
12866 case (int)ScriptBaseClass.PRIM_MATERIAL:
12867 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12868 break;
12869
12870 case (int)ScriptBaseClass.PRIM_PHYSICS:
12871 res.Add(new LSL_Integer(0));
12872 break;
12873
12874 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12875 res.Add(new LSL_Integer(0));
12876 break;
12877
12878 case (int)ScriptBaseClass.PRIM_PHANTOM:
12879 res.Add(new LSL_Integer(0));
12880 break;
12881
12882 case (int)ScriptBaseClass.PRIM_POSITION:
12883
12884 Vector3 pos = avatar.OffsetPosition;
12885
12886 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12887 pos -= sitOffset;
12888
12889 if( sitPart != null)
12890 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12891
12892 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12893 break;
12894
12895 case (int)ScriptBaseClass.PRIM_SIZE:
12896 // as in llGetAgentSize above
12897 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12898 break;
12899
12900 case (int)ScriptBaseClass.PRIM_ROTATION:
12901 Quaternion rot = avatar.Rotation;
12902 if (sitPart != null)
12903 {
12904 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12905 }
12906
12907 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12908 break;
12909
12910 case (int)ScriptBaseClass.PRIM_TYPE:
12911 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12912 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12913 res.Add(new LSL_Vector(0f,1.0f,0f));
12914 res.Add(new LSL_Float(0.0f));
12915 res.Add(new LSL_Vector(0, 0, 0));
12916 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12917 res.Add(new LSL_Vector(0, 0, 0));
12918 break;
12919
12920 case (int)ScriptBaseClass.PRIM_TEXTURE:
12921 if (remain < 1)
12922 return null;
12923
12924 int face = (int)rules.GetLSLIntegerItem(idx++);
12925 if (face == ScriptBaseClass.ALL_SIDES)
12926 {
12927 for (face = 0; face < 21; face++)
12928 {
12929 res.Add(new LSL_String(""));
12930 res.Add(new LSL_Vector(0,0,0));
12931 res.Add(new LSL_Vector(0,0,0));
12932 res.Add(new LSL_Float(0.0));
12933 }
12934 }
12935 else
12936 {
12937 if (face >= 0 && face < 21)
12938 {
12939 res.Add(new LSL_String(""));
12940 res.Add(new LSL_Vector(0,0,0));
12941 res.Add(new LSL_Vector(0,0,0));
12942 res.Add(new LSL_Float(0.0));
12943 }
12944 }
12945 break;
12946
12947 case (int)ScriptBaseClass.PRIM_COLOR:
12948 if (remain < 1)
12949 return null;
12950
12951 face = (int)rules.GetLSLIntegerItem(idx++);
12952
12953 if (face == ScriptBaseClass.ALL_SIDES)
12954 {
12955 for (face = 0; face < 21; face++)
12956 {
12957 res.Add(new LSL_Vector(0,0,0));
12958 res.Add(new LSL_Float(0));
12959 }
12960 }
12961 else
12962 {
12963 res.Add(new LSL_Vector(0,0,0));
12964 res.Add(new LSL_Float(0));
12965 }
12966 break;
12967
12968 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12969 if (remain < 1)
12970 return null;
12971 face = (int)rules.GetLSLIntegerItem(idx++);
12972
12973 if (face == ScriptBaseClass.ALL_SIDES)
12974 {
12975 for (face = 0; face < 21; face++)
12976 {
12977 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12978 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12979 }
12980 }
12981 else
12982 {
12983 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
12984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
12985 }
12986 break;
12987
12988 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12989 if (remain < 1)
12990 return null;
12991 face = (int)rules.GetLSLIntegerItem(idx++);
12992
12993 if (face == ScriptBaseClass.ALL_SIDES)
12994 {
12995 for (face = 0; face < 21; face++)
12996 {
12997 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
12998 }
12999 }
13000 else
13001 {
13002 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13003 }
13004 break;
13005
13006 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13007 res.Add(new LSL_Integer(0));
13008 res.Add(new LSL_Integer(0));// softness
13009 res.Add(new LSL_Float(0.0f)); // gravity
13010 res.Add(new LSL_Float(0.0f)); // friction
13011 res.Add(new LSL_Float(0.0f)); // wind
13012 res.Add(new LSL_Float(0.0f)); // tension
13013 res.Add(new LSL_Vector(0f,0f,0f));
13014 break;
13015
13016 case (int)ScriptBaseClass.PRIM_TEXGEN:
13017 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13018 if (remain < 1)
13019 return null;
13020 face = (int)rules.GetLSLIntegerItem(idx++);
13021
13022 if (face == ScriptBaseClass.ALL_SIDES)
13023 {
13024 for (face = 0; face < 21; face++)
13025 {
13026 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13027 }
13028 }
13029 else
13030 {
13031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13032 }
13033 break;
13034
13035 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13036 res.Add(new LSL_Integer(0));
13037 res.Add(new LSL_Vector(0f,0f,0f));
13038 res.Add(new LSL_Float(0f)); // intensity
13039 res.Add(new LSL_Float(0f)); // radius
13040 res.Add(new LSL_Float(0f)); // falloff
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_GLOW:
13044 if (remain < 1)
13045 return null;
13046 face = (int)rules.GetLSLIntegerItem(idx++);
13047
13048 if (face == ScriptBaseClass.ALL_SIDES)
13049 {
13050 for (face = 0; face < 21; face++)
13051 {
13052 res.Add(new LSL_Float(0f));
13053 }
13054 }
13055 else
13056 {
13057 res.Add(new LSL_Float(0f));
13058 }
13059 break;
13060
13061 case (int)ScriptBaseClass.PRIM_TEXT:
13062 res.Add(new LSL_String(""));
13063 res.Add(new LSL_Vector(0f,0f,0f));
13064 res.Add(new LSL_Float(1.0f));
13065 break;
13066
13067 case (int)ScriptBaseClass.PRIM_NAME:
13068 res.Add(new LSL_String(avatar.Name));
13069 break;
13070
13071 case (int)ScriptBaseClass.PRIM_DESC:
13072 res.Add(new LSL_String(""));
13073 break;
13074
13075 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13076 Quaternion lrot = avatar.Rotation;
13077
13078 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13079 {
13080 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13081 }
13082 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13083 break;
13084
13085 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13086 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13087 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13088 lpos -= lsitOffset;
13089
13090 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13091 {
13092 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13093 }
13094 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13095 break;
13096
13097 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13098 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13099 return null;
13100
13101 return rules.GetSublist(idx, -1);
13102 }
13103 }
13104
13105 return null;
13106 }
11420 } 13107 }
11421 13108
11422 public class NotecardCache 13109 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 31be450..2c682d4 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 {
@@ -2336,9 +2362,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2336 2362
2337 if (appearanceSerialized != null) 2363 if (appearanceSerialized != null)
2338 { 2364 {
2339 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2365 try
2340 appearance = new AvatarAppearance(); 2366 {
2341 appearance.Unpack(appearanceOsd); 2367 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2368 appearance = new AvatarAppearance();
2369 appearance.Unpack(appearanceOsd);
2370 }
2371 catch
2372 {
2373 return UUID.Zero.ToString();
2374 }
2342 } 2375 }
2343 } 2376 }
2344 2377
@@ -2356,6 +2389,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2356 World, 2389 World,
2357 appearance); 2390 appearance);
2358 2391
2392 ScenePresence sp;
2393 if (World.TryGetScenePresence(x, out sp))
2394 {
2395 sp.Grouptitle = groupTitle;
2396 sp.SendAvatarDataToAllAgents();
2397 }
2359 return new LSL_Key(x.ToString()); 2398 return new LSL_Key(x.ToString());
2360 } 2399 }
2361 2400
@@ -2655,16 +2694,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2655 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2694 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2656 m_host.AddScriptLPS(1); 2695 m_host.AddScriptLPS(1);
2657 2696
2658 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2697 ManualResetEvent ev = new ManualResetEvent(false);
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2662 2698
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2699 Util.FireAndForget(delegate(object x) {
2664 return; 2700 try
2701 {
2702 INPCModule module = World.RequestModuleInterface<INPCModule>();
2703 if (module != null)
2704 {
2705 UUID npcId = new UUID(npc.m_string);
2665 2706
2666 module.DeleteNPC(npcId, World); 2707 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2667 } 2708 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2709 {
2710 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2711 return;
2712 }
2713
2714 module.DeleteNPC(npcId, World);
2715 }
2716 }
2717 finally
2718 {
2719 ev.Set();
2720 }
2721 });
2722 ev.WaitOne();
2668 } 2723 }
2669 2724
2670 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2725 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3549,6 +3604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3549 if (m_UrlModule != null) 3604 if (m_UrlModule != null)
3550 m_UrlModule.HttpContentType(new UUID(id),type); 3605 m_UrlModule.HttpContentType(new UUID(id),type);
3551 } 3606 }
3607
3552 /// Shout an error if the object owner did not grant the script the specified permissions. 3608 /// Shout an error if the object owner did not grant the script the specified permissions.
3553 /// </summary> 3609 /// </summary>
3554 /// <param name="perms"></param> 3610 /// <param name="perms"></param>
@@ -3636,4 +3692,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3636 DropAttachmentAt(false, pos, rot); 3692 DropAttachmentAt(false, pos, rot);
3637 } 3693 }
3638 } 3694 }
3639} \ No newline at end of file 3695}
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 93188c9..b1fbed5 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 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 0460f22..9f05666 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
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.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -128,6 +129,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
128 private Dictionary<UUID, IScriptInstance> m_Scripts = 129 private Dictionary<UUID, IScriptInstance> m_Scripts =
129 new Dictionary<UUID, IScriptInstance>(); 130 new Dictionary<UUID, IScriptInstance>();
130 131
132 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
133
131 // Maps the asset ID to the assembly 134 // Maps the asset ID to the assembly
132 135
133 private Dictionary<UUID, string> m_Assemblies = 136 private Dictionary<UUID, string> m_Assemblies =
@@ -150,6 +153,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
150 IWorkItemResult m_CurrentCompile = null; 153 IWorkItemResult m_CurrentCompile = null;
151 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 154 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
152 155
156 private void lockScriptsForRead(bool locked)
157 {
158 if (locked)
159 {
160 if (m_scriptsLock.RecursiveReadCount > 0)
161 {
162 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
163 m_scriptsLock.ExitReadLock();
164 }
165 if (m_scriptsLock.RecursiveWriteCount > 0)
166 {
167 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
168 m_scriptsLock.ExitWriteLock();
169 }
170
171 while (!m_scriptsLock.TryEnterReadLock(60000))
172 {
173 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
174 if (m_scriptsLock.IsWriteLockHeld)
175 {
176 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
177 }
178 }
179 }
180 else
181 {
182 if (m_scriptsLock.RecursiveReadCount > 0)
183 {
184 m_scriptsLock.ExitReadLock();
185 }
186 }
187 }
188 private void lockScriptsForWrite(bool locked)
189 {
190 if (locked)
191 {
192 if (m_scriptsLock.RecursiveReadCount > 0)
193 {
194 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
195 m_scriptsLock.ExitReadLock();
196 }
197 if (m_scriptsLock.RecursiveWriteCount > 0)
198 {
199 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
200 m_scriptsLock.ExitWriteLock();
201 }
202
203 while (!m_scriptsLock.TryEnterWriteLock(60000))
204 {
205 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
206 if (m_scriptsLock.IsWriteLockHeld)
207 {
208 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
209 }
210 }
211 }
212 else
213 {
214 if (m_scriptsLock.RecursiveWriteCount > 0)
215 {
216 m_scriptsLock.ExitWriteLock();
217 }
218 }
219 }
220
153 public string ScriptEngineName 221 public string ScriptEngineName
154 { 222 {
155 get { return "XEngine"; } 223 get { return "XEngine"; }
@@ -576,64 +644,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
576 { 644 {
577 if (!m_Enabled) 645 if (!m_Enabled)
578 return; 646 return;
647 lockScriptsForRead(true);
579 648
580 lock (m_Scripts) 649 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
581 {
582 m_log.InfoFormat(
583 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
584 650
585 foreach (IScriptInstance instance in m_Scripts.Values) 651// foreach (IScriptInstance instance in m_Scripts.Values)
652 foreach (IScriptInstance instance in instancesToDel)
653 {
654 // Force a final state save
655 //
656 if (m_Assemblies.ContainsKey(instance.AssetID))
586 { 657 {
587 // Force a final state save 658 string assembly = m_Assemblies[instance.AssetID];
588 //
589 if (m_Assemblies.ContainsKey(instance.AssetID))
590 {
591 string assembly = m_Assemblies[instance.AssetID];
592 659
593 try 660 try
594 { 661 {
595 instance.SaveState(assembly); 662 instance.SaveState(assembly);
596 }
597 catch (Exception e)
598 {
599 m_log.Error(
600 string.Format(
601 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
602 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
603 , e);
604 }
605 } 663 }
664 catch (Exception e)
665 {
666 m_log.Error(
667 string.Format(
668 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
669 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
670 , e);
671 }
672 }
606 673
607 // Clear the event queue and abort the instance thread 674 // Clear the event queue and abort the instance thread
608 // 675 //
609 instance.ClearQueue(); 676 instance.ClearQueue();
610 instance.Stop(0); 677 instance.Stop(0);
611 678
612 // Release events, timer, etc 679 // Release events, timer, etc
613 // 680 //
614 instance.DestroyScriptInstance(); 681 instance.DestroyScriptInstance();
615 682
616 // Unload scripts and app domains. 683 // Unload scripts and app domains
617 // Must be done explicitly because they have infinite 684 // Must be done explicitly because they have infinite
618 // lifetime. 685 // lifetime
619 // However, don't bother to do this if the simulator is shutting 686 //
620 // down since it takes a long time with many scripts. 687// if (!m_SimulatorShuttingDown)
621 if (!m_SimulatorShuttingDown) 688 {
689 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
690 if (m_DomainScripts[instance.AppDomain].Count == 0)
622 { 691 {
623 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 692 m_DomainScripts.Remove(instance.AppDomain);
624 if (m_DomainScripts[instance.AppDomain].Count == 0) 693 UnloadAppDomain(instance.AppDomain);
625 {
626 m_DomainScripts.Remove(instance.AppDomain);
627 UnloadAppDomain(instance.AppDomain);
628 }
629 } 694 }
630 } 695 }
631 696
632 m_Scripts.Clear(); 697// m_Scripts.Clear();
633 m_PrimObjects.Clear(); 698// m_PrimObjects.Clear();
634 m_Assemblies.Clear(); 699// m_Assemblies.Clear();
635 m_DomainScripts.Clear(); 700// m_DomainScripts.Clear();
636 } 701 }
702 lockScriptsForRead(false);
703 lockScriptsForWrite(true);
704 m_Scripts.Clear();
705 lockScriptsForWrite(false);
706 m_PrimObjects.Clear();
707 m_Assemblies.Clear();
708 m_DomainScripts.Clear();
709
637 lock (m_ScriptEngines) 710 lock (m_ScriptEngines)
638 { 711 {
639 m_ScriptEngines.Remove(this); 712 m_ScriptEngines.Remove(this);
@@ -702,22 +775,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
702 775
703 List<IScriptInstance> instances = new List<IScriptInstance>(); 776 List<IScriptInstance> instances = new List<IScriptInstance>();
704 777
705 lock (m_Scripts) 778 lockScriptsForRead(true);
706 { 779 foreach (IScriptInstance instance in m_Scripts.Values)
707 foreach (IScriptInstance instance in m_Scripts.Values)
708 instances.Add(instance); 780 instances.Add(instance);
709 } 781 lockScriptsForRead(false);
710 782
711 foreach (IScriptInstance i in instances) 783 foreach (IScriptInstance i in instances)
712 { 784 {
713 string assembly = String.Empty; 785 string assembly = String.Empty;
714 786
715 lock (m_Scripts) 787
716 {
717 if (!m_Assemblies.ContainsKey(i.AssetID)) 788 if (!m_Assemblies.ContainsKey(i.AssetID))
718 continue; 789 continue;
719 assembly = m_Assemblies[i.AssetID]; 790 assembly = m_Assemblies[i.AssetID];
720 } 791
721 792
722 try 793 try
723 { 794 {
@@ -1119,96 +1190,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1119 } 1190 }
1120 1191
1121 ScriptInstance instance = null; 1192 ScriptInstance instance = null;
1122 lock (m_Scripts) 1193 // Create the object record
1194 lockScriptsForRead(true);
1195 if ((!m_Scripts.ContainsKey(itemID)) ||
1196 (m_Scripts[itemID].AssetID != assetID))
1123 { 1197 {
1124 // Create the object record 1198 lockScriptsForRead(false);
1125 if ((!m_Scripts.ContainsKey(itemID)) ||
1126 (m_Scripts[itemID].AssetID != assetID))
1127 {
1128 UUID appDomain = assetID;
1129 1199
1130 if (part.ParentGroup.IsAttachment) 1200 UUID appDomain = assetID;
1131 appDomain = part.ParentGroup.RootPart.UUID;
1132 1201
1133 if (!m_AppDomains.ContainsKey(appDomain)) 1202 if (part.ParentGroup.IsAttachment)
1134 { 1203 appDomain = part.ParentGroup.RootPart.UUID;
1135 try
1136 {
1137 AppDomainSetup appSetup = new AppDomainSetup();
1138 appSetup.PrivateBinPath = Path.Combine(
1139 m_ScriptEnginesPath,
1140 m_Scene.RegionInfo.RegionID.ToString());
1141 1204
1142 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1205 if (!m_AppDomains.ContainsKey(appDomain))
1143 Evidence evidence = new Evidence(baseEvidence); 1206 {
1207 try
1208 {
1209 AppDomainSetup appSetup = new AppDomainSetup();
1210 appSetup.PrivateBinPath = Path.Combine(
1211 m_ScriptEnginesPath,
1212 m_Scene.RegionInfo.RegionID.ToString());
1144 1213
1145 AppDomain sandbox; 1214 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1146 if (m_AppDomainLoading) 1215 Evidence evidence = new Evidence(baseEvidence);
1147 {
1148 sandbox = AppDomain.CreateDomain(
1149 m_Scene.RegionInfo.RegionID.ToString(),
1150 evidence, appSetup);
1151 sandbox.AssemblyResolve +=
1152 new ResolveEventHandler(
1153 AssemblyResolver.OnAssemblyResolve);
1154 }
1155 else
1156 {
1157 sandbox = AppDomain.CurrentDomain;
1158 }
1159
1160 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1161 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1162 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1163 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1164 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1165 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1166 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1167
1168 m_AppDomains[appDomain] = sandbox;
1169 1216
1170 m_DomainScripts[appDomain] = new List<UUID>(); 1217 AppDomain sandbox;
1218 if (m_AppDomainLoading)
1219 {
1220 sandbox = AppDomain.CreateDomain(
1221 m_Scene.RegionInfo.RegionID.ToString(),
1222 evidence, appSetup);
1223 m_AppDomains[appDomain].AssemblyResolve +=
1224 new ResolveEventHandler(
1225 AssemblyResolver.OnAssemblyResolve);
1171 } 1226 }
1172 catch (Exception e) 1227 else
1173 { 1228 {
1174 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1229 sandbox = AppDomain.CurrentDomain;
1175 m_ScriptErrorMessage += "Exception creating app domain:\n";
1176 m_ScriptFailCount++;
1177 lock (m_AddingAssemblies)
1178 {
1179 m_AddingAssemblies[assembly]--;
1180 }
1181 return false;
1182 } 1230 }
1183 }
1184 m_DomainScripts[appDomain].Add(itemID);
1185
1186 instance = new ScriptInstance(this, part,
1187 itemID, assetID, assembly,
1188 m_AppDomains[appDomain],
1189 part.ParentGroup.RootPart.Name,
1190 item.Name, startParam, postOnRez,
1191 stateSource, m_MaxScriptQueue);
1192
1193// if (DebugLevel >= 1)
1194// m_log.DebugFormat(
1195// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1196// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1197// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1198 1231
1199 if (presence != null) 1232 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1233 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1234 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1235 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1236 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1237 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1238 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1239
1240 m_AppDomains[appDomain] = sandbox;
1241
1242 m_DomainScripts[appDomain] = new List<UUID>();
1243 }
1244 catch (Exception e)
1200 { 1245 {
1201 ShowScriptSaveResponse(item.OwnerID, 1246 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1202 assetID, "Compile successful", true); 1247 m_ScriptErrorMessage += "Exception creating app domain:\n";
1248 m_ScriptFailCount++;
1249 lock (m_AddingAssemblies)
1250 {
1251 m_AddingAssemblies[assembly]--;
1252 }
1253 return false;
1203 } 1254 }
1255 }
1256 m_DomainScripts[appDomain].Add(itemID);
1257
1258 instance = new ScriptInstance(this, part,
1259 itemID, assetID, assembly,
1260 m_AppDomains[appDomain],
1261 part.ParentGroup.RootPart.Name,
1262 item.Name, startParam, postOnRez,
1263 stateSource, m_MaxScriptQueue);
1264
1265// m_log.DebugFormat(
1266// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1267// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1268// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1204 1269
1205 instance.AppDomain = appDomain; 1270 if (presence != null)
1206 instance.LineMap = linemap; 1271 {
1207 1272 ShowScriptSaveResponse(item.OwnerID,
1208 m_Scripts[itemID] = instance; 1273 assetID, "Compile successful", true);
1209 } 1274 }
1210 }
1211 1275
1276 instance.AppDomain = appDomain;
1277 instance.LineMap = linemap;
1278 lockScriptsForWrite(true);
1279 m_Scripts[itemID] = instance;
1280 lockScriptsForWrite(false);
1281 }
1282 else
1283 {
1284 lockScriptsForRead(false);
1285 }
1212 lock (m_PrimObjects) 1286 lock (m_PrimObjects)
1213 { 1287 {
1214 if (!m_PrimObjects.ContainsKey(localID)) 1288 if (!m_PrimObjects.ContainsKey(localID))
@@ -1226,7 +1300,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1226 m_AddingAssemblies[assembly]--; 1300 m_AddingAssemblies[assembly]--;
1227 } 1301 }
1228 1302
1229 if (instance != null) 1303 if (instance!=null)
1230 instance.Init(); 1304 instance.Init();
1231 1305
1232 bool runIt; 1306 bool runIt;
@@ -1249,18 +1323,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1249 m_CompileDict.Remove(itemID); 1323 m_CompileDict.Remove(itemID);
1250 } 1324 }
1251 1325
1252 IScriptInstance instance = null; 1326 lockScriptsForRead(true);
1253 1327 // Do we even have it?
1254 lock (m_Scripts) 1328 if (!m_Scripts.ContainsKey(itemID))
1255 { 1329 {
1256 // Do we even have it? 1330 // Do we even have it?
1257 if (!m_Scripts.ContainsKey(itemID)) 1331 if (!m_Scripts.ContainsKey(itemID))
1258 return; 1332 return;
1259 1333
1260 instance = m_Scripts[itemID]; 1334 lockScriptsForRead(false);
1335 lockScriptsForWrite(true);
1261 m_Scripts.Remove(itemID); 1336 m_Scripts.Remove(itemID);
1337 lockScriptsForWrite(false);
1338
1339 return;
1262 } 1340 }
1341
1263 1342
1343 IScriptInstance instance=m_Scripts[itemID];
1344 lockScriptsForRead(false);
1345 lockScriptsForWrite(true);
1346 m_Scripts.Remove(itemID);
1347 lockScriptsForWrite(false);
1264 instance.ClearQueue(); 1348 instance.ClearQueue();
1265 1349
1266 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1350 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1299,8 +1383,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1299 1383
1300 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1384 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1301 if (handlerObjectRemoved != null) 1385 if (handlerObjectRemoved != null)
1302 handlerObjectRemoved(instance.ObjectID); 1386 {
1387 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1388 handlerObjectRemoved(part.UUID);
1389 }
1303 1390
1391 CleanAssemblies();
1392
1304 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1393 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1305 if (handlerScriptRemoved != null) 1394 if (handlerScriptRemoved != null)
1306 handlerScriptRemoved(itemID); 1395 handlerScriptRemoved(itemID);
@@ -1561,12 +1650,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1561 private IScriptInstance GetInstance(UUID itemID) 1650 private IScriptInstance GetInstance(UUID itemID)
1562 { 1651 {
1563 IScriptInstance instance; 1652 IScriptInstance instance;
1564 lock (m_Scripts) 1653 lockScriptsForRead(true);
1654 if (!m_Scripts.ContainsKey(itemID))
1565 { 1655 {
1566 if (!m_Scripts.ContainsKey(itemID)) 1656 lockScriptsForRead(false);
1567 return null; 1657 return null;
1568 instance = m_Scripts[itemID];
1569 } 1658 }
1659 instance = m_Scripts[itemID];
1660 lockScriptsForRead(false);
1570 return instance; 1661 return instance;
1571 } 1662 }
1572 1663
@@ -1590,6 +1681,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1590 return false; 1681 return false;
1591 } 1682 }
1592 1683
1684 [DebuggerNonUserCode]
1593 public void ApiResetScript(UUID itemID) 1685 public void ApiResetScript(UUID itemID)
1594 { 1686 {
1595 IScriptInstance instance = GetInstance(itemID); 1687 IScriptInstance instance = GetInstance(itemID);
@@ -1651,6 +1743,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1651 return UUID.Zero; 1743 return UUID.Zero;
1652 } 1744 }
1653 1745
1746 [DebuggerNonUserCode]
1654 public void SetState(UUID itemID, string newState) 1747 public void SetState(UUID itemID, string newState)
1655 { 1748 {
1656 IScriptInstance instance = GetInstance(itemID); 1749 IScriptInstance instance = GetInstance(itemID);
@@ -1673,11 +1766,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1673 1766
1674 List<IScriptInstance> instances = new List<IScriptInstance>(); 1767 List<IScriptInstance> instances = new List<IScriptInstance>();
1675 1768
1676 lock (m_Scripts) 1769 lockScriptsForRead(true);
1677 { 1770 foreach (IScriptInstance instance in m_Scripts.Values)
1678 foreach (IScriptInstance instance in m_Scripts.Values)
1679 instances.Add(instance); 1771 instances.Add(instance);
1680 } 1772 lockScriptsForRead(false);
1681 1773
1682 foreach (IScriptInstance i in instances) 1774 foreach (IScriptInstance i in instances)
1683 { 1775 {