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.cs3244
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs29
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs56
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs358
19 files changed, 3271 insertions, 1028 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 3591d14..7237d1d 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,9 +285,62 @@ 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 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 341 List<SceneObjectPart> ret = new List<SceneObjectPart>();
342 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
343 return ret;
248 ret.Add(m_host); 344 ret.Add(m_host);
249 345
250 switch (linkType) 346 switch (linkType)
@@ -443,31 +539,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
443 539
444 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 540 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
445 541
446 /// <summary> 542 // Utility function for llRot2Euler
447 /// Convert an LSL rotation to a Euler vector. 543
448 /// </summary> 544 // normalize an angle between -PI and PI (-180 to +180 degrees)
449 /// <remarks> 545 protected double NormalizeAngle(double angle)
450 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
451 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
452 /// </remarks>
453 /// <param name="r"></param>
454 /// <returns></returns>
455 public LSL_Vector llRot2Euler(LSL_Rotation r)
456 { 546 {
457 m_host.AddScriptLPS(1); 547 if (angle > -Math.PI && angle < Math.PI)
548 return angle;
458 549
459 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 550 int numPis = (int)(Math.PI / angle);
460 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 551 double remainder = angle - Math.PI * numPis;
461 if (m == 0.0) return new LSL_Vector(); 552 if (numPis % 2 == 1)
462 double x = Math.Atan2(-v.y, v.z); 553 return Math.PI - angle;
463 double sin = v.x / m; 554 return remainder;
464 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 555 }
465 double y = Math.Asin(sin);
466 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
467 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)));
468 double z = Math.Atan2(v.y, v.x);
469 556
470 return new LSL_Vector(x, y, z); 557 public LSL_Vector llRot2Euler(LSL_Rotation q1)
558 {
559 m_host.AddScriptLPS(1);
560 LSL_Vector eul = new LSL_Vector();
561
562 double sqw = q1.s*q1.s;
563 double sqx = q1.x*q1.x;
564 double sqy = q1.z*q1.z;
565 double sqz = q1.y*q1.y;
566 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
567 double test = q1.x*q1.z + q1.y*q1.s;
568 if (test > 0.4999*unit) { // singularity at north pole
569 eul.z = 2 * Math.Atan2(q1.x,q1.s);
570 eul.y = Math.PI/2;
571 eul.x = 0;
572 return eul;
573 }
574 if (test < -0.4999*unit) { // singularity at south pole
575 eul.z = -2 * Math.Atan2(q1.x,q1.s);
576 eul.y = -Math.PI/2;
577 eul.x = 0;
578 return eul;
579 }
580 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
581 eul.y = Math.Asin(2*test/unit);
582 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
583 return eul;
471 } 584 }
472 585
473 /* From wiki: 586 /* From wiki:
@@ -520,18 +633,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
520 m_host.AddScriptLPS(1); 633 m_host.AddScriptLPS(1);
521 634
522 double x,y,z,s; 635 double x,y,z,s;
523 636 v.x *= 0.5;
524 double c1 = Math.Cos(v.x * 0.5); 637 v.y *= 0.5;
525 double c2 = Math.Cos(v.y * 0.5); 638 v.z *= 0.5;
526 double c3 = Math.Cos(v.z * 0.5); 639 double c1 = Math.Cos(v.x);
527 double s1 = Math.Sin(v.x * 0.5); 640 double c2 = Math.Cos(v.y);
528 double s2 = Math.Sin(v.y * 0.5); 641 double c1c2 = c1 * c2;
529 double s3 = Math.Sin(v.z * 0.5); 642 double s1 = Math.Sin(v.x);
530 643 double s2 = Math.Sin(v.y);
531 x = s1 * c2 * c3 + c1 * s2 * s3; 644 double s1s2 = s1 * s2;
532 y = c1 * s2 * c3 - s1 * c2 * s3; 645 double c1s2 = c1 * s2;
533 z = s1 * s2 * c3 + c1 * c2 * s3; 646 double s1c2 = s1 * c2;
534 s = c1 * c2 * c3 - s1 * s2 * s3; 647 double c3 = Math.Cos(v.z);
648 double s3 = Math.Sin(v.z);
649
650 x = s1c2 * c3 + c1s2 * s3;
651 y = c1s2 * c3 - s1c2 * s3;
652 z = s1s2 * c3 + c1c2 * s3;
653 s = c1c2 * c3 - s1s2 * s3;
535 654
536 return new LSL_Rotation(x, y, z, s); 655 return new LSL_Rotation(x, y, z, s);
537 } 656 }
@@ -669,77 +788,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
669 { 788 {
670 //A and B should both be normalized 789 //A and B should both be normalized
671 m_host.AddScriptLPS(1); 790 m_host.AddScriptLPS(1);
672 LSL_Rotation rotBetween; 791 /* This method is more accurate than the SL one, and thus causes problems
673 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 792 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
674 // continue calculation. 793
675 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 794 double dotProduct = LSL_Vector.Dot(a, b);
795 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
796 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
797 double angle = Math.Acos(dotProduct / magProduct);
798 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
799 double s = Math.Sin(angle / 2);
800
801 double x = axis.x * s;
802 double y = axis.y * s;
803 double z = axis.z * s;
804 double w = Math.Cos(angle / 2);
805
806 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
807 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
808
809 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
810 */
811
812 // This method mimics the 180 errors found in SL
813 // See www.euclideanspace.com... angleBetween
814 LSL_Vector vec_a = a;
815 LSL_Vector vec_b = b;
816
817 // Eliminate zero length
818 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
819 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
820 if (vec_a_mag < 0.00001 ||
821 vec_b_mag < 0.00001)
676 { 822 {
677 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 823 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
678 } 824 }
679 else 825
826 // Normalize
827 vec_a = llVecNorm(vec_a);
828 vec_b = llVecNorm(vec_b);
829
830 // Calculate axis and rotation angle
831 LSL_Vector axis = vec_a % vec_b;
832 LSL_Float cos_theta = vec_a * vec_b;
833
834 // Check if parallel
835 if (cos_theta > 0.99999)
680 { 836 {
681 a = LSL_Vector.Norm(a); 837 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
682 b = LSL_Vector.Norm(b); 838 }
683 double dotProduct = LSL_Vector.Dot(a, b); 839
684 // There are two degenerate cases possible. These are for vectors 180 or 840 // Check if anti-parallel
685 // 0 degrees apart. These have to be detected and handled individually. 841 else if (cos_theta < -0.99999)
686 // 842 {
687 // Check for vectors 180 degrees apart. 843 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
688 // A dot product of -1 would mean the angle between vectors is 180 degrees. 844 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
689 if (dotProduct < -0.9999999f) 845 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
690 { 846 }
691 // First assume X axis is orthogonal to the vectors. 847 else // other rotation
692 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 848 {
693 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 849 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
694 // Check for near zero vector. A very small non-zero number here will create 850 axis = llVecNorm(axis);
695 // a rotation in an undesired direction. 851 double x, y, z, s, t;
696 if (LSL_Vector.Mag(orthoVector) > 0.0001) 852 s = Math.Cos(theta);
697 { 853 t = Math.Sin(theta);
698 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 854 x = axis.x * t;
699 } 855 y = axis.y * t;
700 // If the magnitude of the vector was near zero, then assume the X axis is not 856 z = axis.z * t;
701 // orthogonal and use the Z axis instead. 857 return new LSL_Rotation(x,y,z,s);
702 else
703 {
704 // Set 180 z rotation.
705 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
706 }
707 }
708 // Check for parallel vectors.
709 // A dot product of 1 would mean the angle between vectors is 0 degrees.
710 else if (dotProduct > 0.9999999f)
711 {
712 // Set zero rotation.
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 }
715 else
716 {
717 // All special checks have been performed so get the axis of rotation.
718 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
719 // Quarternion s value is the length of the unit vector + dot product.
720 double qs = 1.0 + dotProduct;
721 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
722 // Normalize the rotation.
723 double mag = LSL_Rotation.Mag(rotBetween);
724 // We shouldn't have to worry about a divide by zero here. The qs value will be
725 // non-zero because we already know if we're here, then the dotProduct is not -1 so
726 // qs will not be zero. Also, we've already handled the input vectors being zero so the
727 // crossProduct vector should also not be zero.
728 rotBetween.x = rotBetween.x / mag;
729 rotBetween.y = rotBetween.y / mag;
730 rotBetween.z = rotBetween.z / mag;
731 rotBetween.s = rotBetween.s / mag;
732 // Check for undefined values and set zero rotation if any found. This code might not actually be required
733 // any longer since zero vectors are checked for at the top.
734 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
735 {
736 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
737 }
738 }
739 } 858 }
740 return rotBetween;
741 } 859 }
742 860
743 public void llWhisper(int channelID, string text) 861 public void llWhisper(int channelID, string text)
744 { 862 {
745 m_host.AddScriptLPS(1); 863 m_host.AddScriptLPS(1);
@@ -755,10 +873,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
755 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 873 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
756 } 874 }
757 875
876 private void CheckSayShoutTime()
877 {
878 DateTime now = DateTime.UtcNow;
879 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
880 {
881 m_lastSayShoutCheck = now;
882 m_SayShoutCount = 0;
883 }
884 else
885 m_SayShoutCount++;
886 }
887
758 public void llSay(int channelID, string text) 888 public void llSay(int channelID, string text)
759 { 889 {
760 m_host.AddScriptLPS(1); 890 m_host.AddScriptLPS(1);
761 891
892 if (channelID == 0)
893// m_SayShoutCount++;
894 CheckSayShoutTime();
895
896 if (m_SayShoutCount >= 11)
897 ScriptSleep(2000);
898
762 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 899 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
763 { 900 {
764 Console.WriteLine(text); 901 Console.WriteLine(text);
@@ -781,6 +918,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
781 { 918 {
782 m_host.AddScriptLPS(1); 919 m_host.AddScriptLPS(1);
783 920
921 if (channelID == 0)
922// m_SayShoutCount++;
923 CheckSayShoutTime();
924
925 if (m_SayShoutCount >= 11)
926 ScriptSleep(2000);
927
784 if (text.Length > 1023) 928 if (text.Length > 1023)
785 text = text.Substring(0, 1023); 929 text = text.Substring(0, 1023);
786 930
@@ -812,22 +956,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
812 956
813 public void llRegionSayTo(string target, int channel, string msg) 957 public void llRegionSayTo(string target, int channel, string msg)
814 { 958 {
959 string error = String.Empty;
960
815 if (msg.Length > 1023) 961 if (msg.Length > 1023)
816 msg = msg.Substring(0, 1023); 962 msg = msg.Substring(0, 1023);
817 963
818 m_host.AddScriptLPS(1); 964 m_host.AddScriptLPS(1);
819 965
820 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
821 {
822 return;
823 }
824
825 UUID TargetID; 966 UUID TargetID;
826 UUID.TryParse(target, out TargetID); 967 UUID.TryParse(target, out TargetID);
827 968
828 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 969 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
829 if (wComm != null) 970 if (wComm != null)
830 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 971 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
972 LSLError(error);
831 } 973 }
832 974
833 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 975 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1083,10 +1225,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1083 return detectedParams.TouchUV; 1225 return detectedParams.TouchUV;
1084 } 1226 }
1085 1227
1228 [DebuggerNonUserCode]
1086 public virtual void llDie() 1229 public virtual void llDie()
1087 { 1230 {
1088 m_host.AddScriptLPS(1); 1231 m_host.AddScriptLPS(1);
1089 throw new SelfDeleteException(); 1232 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1090 } 1233 }
1091 1234
1092 public LSL_Float llGround(LSL_Vector offset) 1235 public LSL_Float llGround(LSL_Vector offset)
@@ -1159,6 +1302,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1159 1302
1160 public void llSetStatus(int status, int value) 1303 public void llSetStatus(int status, int value)
1161 { 1304 {
1305 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1306 return;
1162 m_host.AddScriptLPS(1); 1307 m_host.AddScriptLPS(1);
1163 1308
1164 int statusrotationaxis = 0; 1309 int statusrotationaxis = 0;
@@ -1182,6 +1327,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1182 if (!allow) 1327 if (!allow)
1183 return; 1328 return;
1184 1329
1330 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1331 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1332 return;
1333
1185 m_host.ScriptSetPhysicsStatus(true); 1334 m_host.ScriptSetPhysicsStatus(true);
1186 } 1335 }
1187 else 1336 else
@@ -1391,6 +1540,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1391 { 1540 {
1392 m_host.AddScriptLPS(1); 1541 m_host.AddScriptLPS(1);
1393 1542
1543 SetColor(m_host, color, face);
1544 }
1545
1546 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1547 {
1548 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1549 return;
1550
1551 Primitive.TextureEntry tex = part.Shape.Textures;
1552 Color4 texcolor;
1553 if (face >= 0 && face < GetNumberOfSides(part))
1554 {
1555 texcolor = tex.CreateFace((uint)face).RGBA;
1556 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1557 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1558 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1559 tex.FaceTextures[face].RGBA = texcolor;
1560 part.UpdateTextureEntry(tex.GetBytes());
1561 return;
1562 }
1563 else if (face == ScriptBaseClass.ALL_SIDES)
1564 {
1565 for (uint i = 0; i < GetNumberOfSides(part); i++)
1566 {
1567 if (tex.FaceTextures[i] != null)
1568 {
1569 texcolor = tex.FaceTextures[i].RGBA;
1570 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1571 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1572 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1573 tex.FaceTextures[i].RGBA = texcolor;
1574 }
1575 texcolor = tex.DefaultTexture.RGBA;
1576 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1577 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1578 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1579 tex.DefaultTexture.RGBA = texcolor;
1580 }
1581 part.UpdateTextureEntry(tex.GetBytes());
1582 return;
1583 }
1584
1394 if (face == ScriptBaseClass.ALL_SIDES) 1585 if (face == ScriptBaseClass.ALL_SIDES)
1395 face = SceneObjectPart.ALL_SIDES; 1586 face = SceneObjectPart.ALL_SIDES;
1396 1587
@@ -1399,6 +1590,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1399 1590
1400 public void SetTexGen(SceneObjectPart part, int face,int style) 1591 public void SetTexGen(SceneObjectPart part, int face,int style)
1401 { 1592 {
1593 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1594 return;
1595
1402 Primitive.TextureEntry tex = part.Shape.Textures; 1596 Primitive.TextureEntry tex = part.Shape.Textures;
1403 MappingType textype; 1597 MappingType textype;
1404 textype = MappingType.Default; 1598 textype = MappingType.Default;
@@ -1429,6 +1623,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1429 1623
1430 public void SetGlow(SceneObjectPart part, int face, float glow) 1624 public void SetGlow(SceneObjectPart part, int face, float glow)
1431 { 1625 {
1626 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1627 return;
1628
1432 Primitive.TextureEntry tex = part.Shape.Textures; 1629 Primitive.TextureEntry tex = part.Shape.Textures;
1433 if (face >= 0 && face < GetNumberOfSides(part)) 1630 if (face >= 0 && face < GetNumberOfSides(part))
1434 { 1631 {
@@ -1454,6 +1651,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1454 1651
1455 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1652 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1456 { 1653 {
1654 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1655 return;
1457 1656
1458 Shininess sval = new Shininess(); 1657 Shininess sval = new Shininess();
1459 1658
@@ -1504,6 +1703,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1504 1703
1505 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1704 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1506 { 1705 {
1706 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1707 return;
1708
1507 Primitive.TextureEntry tex = part.Shape.Textures; 1709 Primitive.TextureEntry tex = part.Shape.Textures;
1508 if (face >= 0 && face < GetNumberOfSides(part)) 1710 if (face >= 0 && face < GetNumberOfSides(part))
1509 { 1711 {
@@ -1564,13 +1766,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1564 m_host.AddScriptLPS(1); 1766 m_host.AddScriptLPS(1);
1565 1767
1566 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1768 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1567 1769 if (parts.Count > 0)
1568 foreach (SceneObjectPart part in parts) 1770 {
1569 SetAlpha(part, alpha, face); 1771 try
1772 {
1773 parts[0].ParentGroup.areUpdatesSuspended = true;
1774 foreach (SceneObjectPart part in parts)
1775 SetAlpha(part, alpha, face);
1776 }
1777 finally
1778 {
1779 parts[0].ParentGroup.areUpdatesSuspended = false;
1780 }
1781 }
1570 } 1782 }
1571 1783
1572 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1784 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1573 { 1785 {
1786 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1787 return;
1788
1574 Primitive.TextureEntry tex = part.Shape.Textures; 1789 Primitive.TextureEntry tex = part.Shape.Textures;
1575 Color4 texcolor; 1790 Color4 texcolor;
1576 if (face >= 0 && face < GetNumberOfSides(part)) 1791 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1623,7 +1838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1623 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1838 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1624 float wind, float tension, LSL_Vector Force) 1839 float wind, float tension, LSL_Vector Force)
1625 { 1840 {
1626 if (part == null) 1841 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1627 return; 1842 return;
1628 1843
1629 if (flexi) 1844 if (flexi)
@@ -1657,7 +1872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1657 /// <param name="falloff"></param> 1872 /// <param name="falloff"></param>
1658 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1873 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1659 { 1874 {
1660 if (part == null) 1875 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1661 return; 1876 return;
1662 1877
1663 if (light) 1878 if (light)
@@ -1690,11 +1905,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1690 Primitive.TextureEntry tex = part.Shape.Textures; 1905 Primitive.TextureEntry tex = part.Shape.Textures;
1691 Color4 texcolor; 1906 Color4 texcolor;
1692 LSL_Vector rgb = new LSL_Vector(); 1907 LSL_Vector rgb = new LSL_Vector();
1908 int nsides = GetNumberOfSides(part);
1909
1693 if (face == ScriptBaseClass.ALL_SIDES) 1910 if (face == ScriptBaseClass.ALL_SIDES)
1694 { 1911 {
1695 int i; 1912 int i;
1696 1913 for (i = 0; i < nsides; i++)
1697 for (i = 0 ; i < GetNumberOfSides(part); i++)
1698 { 1914 {
1699 texcolor = tex.GetFace((uint)i).RGBA; 1915 texcolor = tex.GetFace((uint)i).RGBA;
1700 rgb.x += texcolor.R; 1916 rgb.x += texcolor.R;
@@ -1702,14 +1918,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1702 rgb.z += texcolor.B; 1918 rgb.z += texcolor.B;
1703 } 1919 }
1704 1920
1705 rgb.x /= (float)GetNumberOfSides(part); 1921 float invnsides = 1.0f / (float)nsides;
1706 rgb.y /= (float)GetNumberOfSides(part); 1922
1707 rgb.z /= (float)GetNumberOfSides(part); 1923 rgb.x *= invnsides;
1924 rgb.y *= invnsides;
1925 rgb.z *= invnsides;
1708 1926
1709 return rgb; 1927 return rgb;
1710 } 1928 }
1711 1929 if (face >= 0 && face < nsides)
1712 if (face >= 0 && face < GetNumberOfSides(part))
1713 { 1930 {
1714 texcolor = tex.GetFace((uint)face).RGBA; 1931 texcolor = tex.GetFace((uint)face).RGBA;
1715 rgb.x = texcolor.R; 1932 rgb.x = texcolor.R;
@@ -1736,15 +1953,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1736 m_host.AddScriptLPS(1); 1953 m_host.AddScriptLPS(1);
1737 1954
1738 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1955 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1739 1956 if (parts.Count > 0)
1740 foreach (SceneObjectPart part in parts) 1957 {
1741 SetTexture(part, texture, face); 1958 try
1742 1959 {
1960 parts[0].ParentGroup.areUpdatesSuspended = true;
1961 foreach (SceneObjectPart part in parts)
1962 SetTexture(part, texture, face);
1963 }
1964 finally
1965 {
1966 parts[0].ParentGroup.areUpdatesSuspended = false;
1967 }
1968 }
1743 ScriptSleep(200); 1969 ScriptSleep(200);
1744 } 1970 }
1745 1971
1746 protected void SetTexture(SceneObjectPart part, string texture, int face) 1972 protected void SetTexture(SceneObjectPart part, string texture, int face)
1747 { 1973 {
1974 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1975 return;
1976
1748 UUID textureID = new UUID(); 1977 UUID textureID = new UUID();
1749 1978
1750 textureID = InventoryKey(texture, (int)AssetType.Texture); 1979 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1789,6 +2018,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1789 2018
1790 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2019 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1791 { 2020 {
2021 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2022 return;
2023
1792 Primitive.TextureEntry tex = part.Shape.Textures; 2024 Primitive.TextureEntry tex = part.Shape.Textures;
1793 if (face >= 0 && face < GetNumberOfSides(part)) 2025 if (face >= 0 && face < GetNumberOfSides(part))
1794 { 2026 {
@@ -1825,6 +2057,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1825 2057
1826 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2058 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1827 { 2059 {
2060 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2061 return;
2062
1828 Primitive.TextureEntry tex = part.Shape.Textures; 2063 Primitive.TextureEntry tex = part.Shape.Textures;
1829 if (face >= 0 && face < GetNumberOfSides(part)) 2064 if (face >= 0 && face < GetNumberOfSides(part))
1830 { 2065 {
@@ -1861,6 +2096,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1861 2096
1862 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2097 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1863 { 2098 {
2099 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2100 return;
2101
1864 Primitive.TextureEntry tex = part.Shape.Textures; 2102 Primitive.TextureEntry tex = part.Shape.Textures;
1865 if (face >= 0 && face < GetNumberOfSides(part)) 2103 if (face >= 0 && face < GetNumberOfSides(part))
1866 { 2104 {
@@ -1981,7 +2219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1981 2219
1982 bool sameParcel = here.GlobalID == there.GlobalID; 2220 bool sameParcel = here.GlobalID == there.GlobalID;
1983 2221
1984 if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2222 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
1985 { 2223 {
1986 return 0; 2224 return 0;
1987 } 2225 }
@@ -2030,24 +2268,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2030 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2268 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2031 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2269 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2032 { 2270 {
2033 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2271 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2272 return;
2273
2034 LSL_Vector currentPos = GetPartLocalPos(part); 2274 LSL_Vector currentPos = GetPartLocalPos(part);
2275 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2035 2276
2036 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2037 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2038 2277
2039 if (part.ParentGroup.RootPart == part) 2278 if (part.ParentGroup.RootPart == part)
2040 { 2279 {
2041 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2042 targetPos.z = ground;
2043 SceneObjectGroup parent = part.ParentGroup; 2280 SceneObjectGroup parent = part.ParentGroup;
2044 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2281 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2045 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2282 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2283 return;
2284 Util.FireAndForget(delegate(object x) {
2285 parent.UpdateGroupPosition(dest);
2286 });
2046 } 2287 }
2047 else 2288 else
2048 { 2289 {
2049 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2290 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2050 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2051 SceneObjectGroup parent = part.ParentGroup; 2291 SceneObjectGroup parent = part.ParentGroup;
2052 parent.HasGroupChanged = true; 2292 parent.HasGroupChanged = true;
2053 parent.ScheduleGroupForTerseUpdate(); 2293 parent.ScheduleGroupForTerseUpdate();
@@ -2080,17 +2320,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2080 else 2320 else
2081 { 2321 {
2082 if (part.ParentGroup.IsAttachment) 2322 if (part.ParentGroup.IsAttachment)
2083 {
2084 pos = part.AttachedPos; 2323 pos = part.AttachedPos;
2085 }
2086 else 2324 else
2087 {
2088 pos = part.AbsolutePosition; 2325 pos = part.AbsolutePosition;
2089 }
2090 } 2326 }
2091 2327
2092// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2093
2094 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2328 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2095 } 2329 }
2096 2330
@@ -2099,18 +2333,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2099 m_host.AddScriptLPS(1); 2333 m_host.AddScriptLPS(1);
2100 2334
2101 // try to let this work as in SL... 2335 // try to let this work as in SL...
2102 if (m_host.ParentID == 0) 2336 if (m_host.LinkNum < 2)
2103 { 2337 {
2104 // special case: If we are root, rotate complete SOG to new rotation 2338 // Special case: If we are root, rotate complete SOG to new
2339 // rotation.
2340 // We are root if the link number is 0 (single prim) or 1
2341 // (root prim). ParentID may be nonzero in attachments and
2342 // using it would cause attachments and HUDs to rotate
2343 // to the wrong positions.
2344
2105 SetRot(m_host, Rot2Quaternion(rot)); 2345 SetRot(m_host, Rot2Quaternion(rot));
2106 } 2346 }
2107 else 2347 else
2108 { 2348 {
2109 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2349 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2110 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2350 SceneObjectPart rootPart;
2111 if (rootPart != null) // better safe than sorry 2351 if (m_host.ParentGroup != null) // better safe than sorry
2112 { 2352 {
2113 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2353 rootPart = m_host.ParentGroup.RootPart;
2354 if (rootPart != null)
2355 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2114 } 2356 }
2115 } 2357 }
2116 2358
@@ -2120,31 +2362,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2120 public void llSetLocalRot(LSL_Rotation rot) 2362 public void llSetLocalRot(LSL_Rotation rot)
2121 { 2363 {
2122 m_host.AddScriptLPS(1); 2364 m_host.AddScriptLPS(1);
2365
2123 SetRot(m_host, Rot2Quaternion(rot)); 2366 SetRot(m_host, Rot2Quaternion(rot));
2124 ScriptSleep(200); 2367 ScriptSleep(200);
2125 } 2368 }
2126 2369
2127 protected void SetRot(SceneObjectPart part, Quaternion rot) 2370 protected void SetRot(SceneObjectPart part, Quaternion rot)
2128 { 2371 {
2129 part.UpdateRotation(rot); 2372 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2130 // Update rotation does not move the object in the physics scene if it's a linkset. 2373 return;
2131 2374
2132//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2375 bool isroot = (part == part.ParentGroup.RootPart);
2133// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2376 bool isphys;
2134 2377
2135 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2136 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2137 // It's perfectly okay when the object is not an active physical body though.
2138 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2139 // but only if the object is not physial and active. This is important for rotating doors.
2140 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2141 // scene
2142 PhysicsActor pa = part.PhysActor; 2378 PhysicsActor pa = part.PhysActor;
2143 2379
2144 if (pa != null && !pa.IsPhysical) 2380 // keep using physactor ideia of isphysical
2381 // it should be SOP ideia of that
2382 // not much of a issue with ubitODE
2383 if (pa != null && pa.IsPhysical)
2384 isphys = true;
2385 else
2386 isphys = false;
2387
2388 // SL doesn't let scripts rotate root of physical linksets
2389 if (isroot && isphys)
2390 return;
2391
2392 part.UpdateRotation(rot);
2393
2394 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2395 // so do a nasty update of parts positions if is a root part rotation
2396 if (isroot && pa != null) // with if above implies non physical root part
2145 { 2397 {
2146 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2398 part.ParentGroup.ResetChildPrimPhysicsPositions();
2147 } 2399 }
2400 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2401 {
2402 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2403 if (sittingavas.Count > 0)
2404 {
2405 foreach (ScenePresence av in sittingavas)
2406 {
2407 if (isroot || part.LocalId == av.ParentID)
2408 av.SendTerseUpdateToAllClients();
2409 }
2410 }
2411 }
2148 } 2412 }
2149 2413
2150 /// <summary> 2414 /// <summary>
@@ -2192,8 +2456,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2192 2456
2193 public LSL_Rotation llGetLocalRot() 2457 public LSL_Rotation llGetLocalRot()
2194 { 2458 {
2459 return GetPartLocalRot(m_host);
2460 }
2461
2462 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2463 {
2195 m_host.AddScriptLPS(1); 2464 m_host.AddScriptLPS(1);
2196 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2465 Quaternion rot = part.RotationOffset;
2466 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2197 } 2467 }
2198 2468
2199 public void llSetForce(LSL_Vector force, int local) 2469 public void llSetForce(LSL_Vector force, int local)
@@ -2277,16 +2547,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2277 m_host.ApplyImpulse(v, local != 0); 2547 m_host.ApplyImpulse(v, local != 0);
2278 } 2548 }
2279 2549
2550
2280 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2551 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2281 { 2552 {
2282 m_host.AddScriptLPS(1); 2553 m_host.AddScriptLPS(1);
2283 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2554 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2284 } 2555 }
2285 2556
2286 public void llSetTorque(LSL_Vector torque, int local) 2557 public void llSetTorque(LSL_Vector torque, int local)
2287 { 2558 {
2288 m_host.AddScriptLPS(1); 2559 m_host.AddScriptLPS(1);
2289 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2560 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2290 } 2561 }
2291 2562
2292 public LSL_Vector llGetTorque() 2563 public LSL_Vector llGetTorque()
@@ -2303,20 +2574,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2303 llSetTorque(torque, local); 2574 llSetTorque(torque, local);
2304 } 2575 }
2305 2576
2577 public void llSetVelocity(LSL_Vector vel, int local)
2578 {
2579 m_host.AddScriptLPS(1);
2580 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2581 }
2582
2306 public LSL_Vector llGetVel() 2583 public LSL_Vector llGetVel()
2307 { 2584 {
2308 m_host.AddScriptLPS(1); 2585 m_host.AddScriptLPS(1);
2309 2586
2310 Vector3 vel; 2587 Vector3 vel = Vector3.Zero;
2311 2588
2312 if (m_host.ParentGroup.IsAttachment) 2589 if (m_host.ParentGroup.IsAttachment)
2313 { 2590 {
2314 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2591 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2315 vel = avatar.Velocity; 2592 if (avatar != null)
2593 vel = avatar.Velocity;
2316 } 2594 }
2317 else 2595 else
2318 { 2596 {
2319 vel = m_host.Velocity; 2597 vel = m_host.ParentGroup.RootPart.Velocity;
2320 } 2598 }
2321 2599
2322 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2600 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2328,10 +2606,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2328 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2606 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2329 } 2607 }
2330 2608
2609 public void llSetAngularVelocity(LSL_Vector avel, int local)
2610 {
2611 m_host.AddScriptLPS(1);
2612 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2613 }
2614
2331 public LSL_Vector llGetOmega() 2615 public LSL_Vector llGetOmega()
2332 { 2616 {
2333 m_host.AddScriptLPS(1); 2617 m_host.AddScriptLPS(1);
2334 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2618 Vector3 avel = m_host.AngularVelocity;
2619 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2335 } 2620 }
2336 2621
2337 public LSL_Float llGetTimeOfDay() 2622 public LSL_Float llGetTimeOfDay()
@@ -2860,16 +3145,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2860 new_group.RootPart.UUID.ToString()) }, 3145 new_group.RootPart.UUID.ToString()) },
2861 new DetectParams[0])); 3146 new DetectParams[0]));
2862 3147
2863 float groupmass = new_group.GetMass(); 3148 // do recoil
3149 SceneObjectGroup hostgrp = m_host.ParentGroup;
3150 if (hostgrp == null)
3151 return;
3152
3153 if (hostgrp.IsAttachment) // don't recoil avatars
3154 return;
2864 3155
2865 PhysicsActor pa = new_group.RootPart.PhysActor; 3156 PhysicsActor pa = new_group.RootPart.PhysActor;
2866 3157
2867 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3158 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2868 { 3159 {
2869 //Recoil. 3160 float groupmass = new_group.GetMass();
2870 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3161 llvel *= -groupmass;
3162 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2871 } 3163 }
2872 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3164 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3165 return;
3166
2873 }); 3167 });
2874 3168
2875 //ScriptSleep((int)((groupmass * velmag) / 10)); 3169 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2884,35 +3178,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2884 public void llLookAt(LSL_Vector target, double strength, double damping) 3178 public void llLookAt(LSL_Vector target, double strength, double damping)
2885 { 3179 {
2886 m_host.AddScriptLPS(1); 3180 m_host.AddScriptLPS(1);
2887 // Determine where we are looking from
2888 LSL_Vector from = llGetPos();
2889 3181
2890 // Work out the normalised vector from the source to the target 3182 // Get the normalized vector to the target
2891 LSL_Vector delta = llVecNorm(target - from); 3183 LSL_Vector d1 = llVecNorm(target - llGetPos());
2892 LSL_Vector angle = new LSL_Vector(0,0,0);
2893 3184
2894 // Calculate the yaw 3185 // Get the bearing (yaw)
2895 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3186 LSL_Vector a1 = new LSL_Vector(0,0,0);
2896 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3187 a1.z = llAtan2(d1.y, d1.x);
2897 3188
2898 // Calculate pitch 3189 // Get the elevation (pitch)
2899 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3190 LSL_Vector a2 = new LSL_Vector(0,0,0);
3191 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2900 3192
2901 // we need to convert from a vector describing 3193 LSL_Rotation r1 = llEuler2Rot(a1);
2902 // the angles of rotation in radians into rotation value 3194 LSL_Rotation r2 = llEuler2Rot(a2);
2903 LSL_Rotation rot = llEuler2Rot(angle); 3195 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2904
2905 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2906 // set the rotation of the object, copy that behavior
2907 PhysicsActor pa = m_host.PhysActor;
2908 3196
2909 if (strength == 0 || pa == null || !pa.IsPhysical) 3197 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2910 { 3198 {
2911 llSetRot(rot); 3199 // Do nothing if either value is 0 (this has been checked in SL)
3200 if (strength <= 0.0 || damping <= 0.0)
3201 return;
3202
3203 llSetRot(r3 * r2 * r1);
2912 } 3204 }
2913 else 3205 else
2914 { 3206 {
2915 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3207 if (strength == 0)
3208 {
3209 llSetRot(r3 * r2 * r1);
3210 return;
3211 }
3212
3213 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2916 } 3214 }
2917 } 3215 }
2918 3216
@@ -2958,17 +3256,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2958 } 3256 }
2959 else 3257 else
2960 { 3258 {
2961 if (m_host.IsRoot) 3259 // new SL always returns object mass
2962 { 3260// if (m_host.IsRoot)
3261// {
2963 return m_host.ParentGroup.GetMass(); 3262 return m_host.ParentGroup.GetMass();
2964 } 3263// }
2965 else 3264// else
2966 { 3265// {
2967 return m_host.GetMass(); 3266// return m_host.GetMass();
2968 } 3267// }
2969 } 3268 }
2970 } 3269 }
2971 3270
3271
3272 public LSL_Float llGetMassMKS()
3273 {
3274 return 100f * llGetMass();
3275 }
3276
2972 public void llCollisionFilter(string name, string id, int accept) 3277 public void llCollisionFilter(string name, string id, int accept)
2973 { 3278 {
2974 m_host.AddScriptLPS(1); 3279 m_host.AddScriptLPS(1);
@@ -3016,8 +3321,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3016 { 3321 {
3017 // Unregister controls from Presence 3322 // Unregister controls from Presence
3018 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3323 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3019 // Remove Take Control permission.
3020 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3021 } 3324 }
3022 } 3325 }
3023 } 3326 }
@@ -3043,7 +3346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3043 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3346 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3044 3347
3045 if (attachmentsModule != null) 3348 if (attachmentsModule != null)
3046 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3349 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
3047 else 3350 else
3048 return false; 3351 return false;
3049 } 3352 }
@@ -3073,9 +3376,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3073 { 3376 {
3074 m_host.AddScriptLPS(1); 3377 m_host.AddScriptLPS(1);
3075 3378
3076// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3077// return;
3078
3079 if (m_item.PermsGranter != m_host.OwnerID) 3379 if (m_item.PermsGranter != m_host.OwnerID)
3080 return; 3380 return;
3081 3381
@@ -3118,6 +3418,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3118 3418
3119 public void llInstantMessage(string user, string message) 3419 public void llInstantMessage(string user, string message)
3120 { 3420 {
3421 UUID result;
3422 if (!UUID.TryParse(user, out result))
3423 {
3424 ShoutError("An invalid key was passed to llInstantMessage");
3425 ScriptSleep(2000);
3426 return;
3427 }
3428
3429
3121 m_host.AddScriptLPS(1); 3430 m_host.AddScriptLPS(1);
3122 3431
3123 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3432 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3132,14 +3441,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3132 UUID friendTransactionID = UUID.Random(); 3441 UUID friendTransactionID = UUID.Random();
3133 3442
3134 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3443 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3135 3444
3136 GridInstantMessage msg = new GridInstantMessage(); 3445 GridInstantMessage msg = new GridInstantMessage();
3137 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3446 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3138 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3447 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3139 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3448 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3140// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3449// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3141// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3450// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3142 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3451// DateTime dt = DateTime.UtcNow;
3452//
3453// // Ticks from UtcNow, but make it look like local. Evil, huh?
3454// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3455//
3456// try
3457// {
3458// // Convert that to the PST timezone
3459// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3460// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3461// }
3462// catch
3463// {
3464// // No logging here, as it could be VERY spammy
3465// }
3466//
3467// // And make it look local again to fool the unix time util
3468// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3469
3470 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3471
3143 //if (client != null) 3472 //if (client != null)
3144 //{ 3473 //{
3145 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3474 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3153,12 +3482,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3153 msg.message = message.Substring(0, 1024); 3482 msg.message = message.Substring(0, 1024);
3154 else 3483 else
3155 msg.message = message; 3484 msg.message = message;
3156 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3485 msg.dialog = (byte)19; // MessageFromObject
3157 msg.fromGroup = false;// fromGroup; 3486 msg.fromGroup = false;// fromGroup;
3158 msg.offline = (byte)0; //offline; 3487 msg.offline = (byte)0; //offline;
3159 msg.ParentEstateID = 0; //ParentEstateID; 3488 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3160 msg.Position = new Vector3(m_host.AbsolutePosition); 3489 msg.Position = new Vector3(m_host.AbsolutePosition);
3161 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3490 msg.RegionID = World.RegionInfo.RegionID.Guid;
3162 msg.binaryBucket 3491 msg.binaryBucket
3163 = Util.StringToBytes256( 3492 = Util.StringToBytes256(
3164 "{0}/{1}/{2}/{3}", 3493 "{0}/{1}/{2}/{3}",
@@ -3186,7 +3515,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3186 } 3515 }
3187 3516
3188 emailModule.SendEmail(m_host.UUID, address, subject, message); 3517 emailModule.SendEmail(m_host.UUID, address, subject, message);
3189 llSleep(EMAIL_PAUSE_TIME); 3518 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3190 } 3519 }
3191 3520
3192 public void llGetNextEmail(string address, string subject) 3521 public void llGetNextEmail(string address, string subject)
@@ -3430,15 +3759,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3430 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3759 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3431 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3760 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3432 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3761 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3762 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3433 ScriptBaseClass.PERMISSION_ATTACH; 3763 ScriptBaseClass.PERMISSION_ATTACH;
3434 3764
3435 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3765 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3436 { 3766 {
3437 lock (m_host.TaskInventory) 3767 m_host.TaskInventory.LockItemsForWrite(true);
3438 { 3768 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3439 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3769 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3440 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3770 m_host.TaskInventory.LockItemsForWrite(false);
3441 }
3442 3771
3443 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3772 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3444 "run_time_permissions", new Object[] { 3773 "run_time_permissions", new Object[] {
@@ -3448,28 +3777,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3448 return; 3777 return;
3449 } 3778 }
3450 } 3779 }
3451 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3780 else
3452 { 3781 {
3453 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3782 bool sitting = false;
3454 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3783 if (m_host.SitTargetAvatar == agentID)
3455 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3784 {
3456 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3785 sitting = true;
3457 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3786 }
3787 else
3788 {
3789 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3790 {
3791 if (p.SitTargetAvatar == agentID)
3792 sitting = true;
3793 }
3794 }
3458 3795
3459 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3796 if (sitting)
3460 { 3797 {
3461 lock (m_host.TaskInventory) 3798 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3799 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3800 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3801 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3802 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3803
3804 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3462 { 3805 {
3806 m_host.TaskInventory.LockItemsForWrite(true);
3463 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3807 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3464 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3808 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3465 } 3809 m_host.TaskInventory.LockItemsForWrite(false);
3466 3810
3467 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3811 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3468 "run_time_permissions", new Object[] { 3812 "run_time_permissions", new Object[] {
3469 new LSL_Integer(perm) }, 3813 new LSL_Integer(perm) },
3470 new DetectParams[0])); 3814 new DetectParams[0]));
3471 3815
3472 return; 3816 return;
3817 }
3473 } 3818 }
3474 } 3819 }
3475 3820
@@ -3506,11 +3851,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3506 3851
3507 if (!m_waitingForScriptAnswer) 3852 if (!m_waitingForScriptAnswer)
3508 { 3853 {
3509 lock (m_host.TaskInventory) 3854 m_host.TaskInventory.LockItemsForWrite(true);
3510 { 3855 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3511 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3856 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3512 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3857 m_host.TaskInventory.LockItemsForWrite(false);
3513 }
3514 3858
3515 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3859 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3516 m_waitingForScriptAnswer=true; 3860 m_waitingForScriptAnswer=true;
@@ -3539,14 +3883,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3539 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3883 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3540 llReleaseControls(); 3884 llReleaseControls();
3541 3885
3542 lock (m_host.TaskInventory) 3886 m_host.TaskInventory.LockItemsForWrite(true);
3543 { 3887 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3544 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3888 m_host.TaskInventory.LockItemsForWrite(false);
3545 } 3889
3546 3890 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3547 m_ScriptEngine.PostScriptEvent( 3891 "run_time_permissions", new Object[] {
3548 m_item.ItemID, 3892 new LSL_Integer(answer) },
3549 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3893 new DetectParams[0]));
3550 } 3894 }
3551 3895
3552 public LSL_String llGetPermissionsKey() 3896 public LSL_String llGetPermissionsKey()
@@ -3585,14 +3929,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3585 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3929 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3586 { 3930 {
3587 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3931 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3588 3932 if (parts.Count > 0)
3589 foreach (SceneObjectPart part in parts) 3933 {
3590 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3934 try
3935 {
3936 parts[0].ParentGroup.areUpdatesSuspended = true;
3937 foreach (SceneObjectPart part in parts)
3938 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3939 }
3940 finally
3941 {
3942 parts[0].ParentGroup.areUpdatesSuspended = false;
3943 }
3944 }
3591 } 3945 }
3592 3946
3593 public void llCreateLink(string target, int parent) 3947 public void llCreateLink(string target, int parent)
3594 { 3948 {
3595 m_host.AddScriptLPS(1); 3949 m_host.AddScriptLPS(1);
3950
3596 UUID targetID; 3951 UUID targetID;
3597 3952
3598 if (!UUID.TryParse(target, out targetID)) 3953 if (!UUID.TryParse(target, out targetID))
@@ -3698,10 +4053,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 // Restructuring Multiple Prims. 4053 // Restructuring Multiple Prims.
3699 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4054 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3700 parts.Remove(parentPrim.RootPart); 4055 parts.Remove(parentPrim.RootPart);
3701 foreach (SceneObjectPart part in parts) 4056 if (parts.Count > 0)
3702 { 4057 {
3703 parentPrim.DelinkFromGroup(part.LocalId, true); 4058 try
4059 {
4060 parts[0].ParentGroup.areUpdatesSuspended = true;
4061 foreach (SceneObjectPart part in parts)
4062 {
4063 parentPrim.DelinkFromGroup(part.LocalId, true);
4064 }
4065 }
4066 finally
4067 {
4068 parts[0].ParentGroup.areUpdatesSuspended = false;
4069 }
3704 } 4070 }
4071
3705 parentPrim.HasGroupChanged = true; 4072 parentPrim.HasGroupChanged = true;
3706 parentPrim.ScheduleGroupForFullUpdate(); 4073 parentPrim.ScheduleGroupForFullUpdate();
3707 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4074 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3710,12 +4077,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 4077 {
3711 SceneObjectPart newRoot = parts[0]; 4078 SceneObjectPart newRoot = parts[0];
3712 parts.Remove(newRoot); 4079 parts.Remove(newRoot);
3713 foreach (SceneObjectPart part in parts) 4080
4081 try
3714 { 4082 {
3715 // Required for linking 4083 parts[0].ParentGroup.areUpdatesSuspended = true;
3716 part.ClearUpdateSchedule(); 4084 foreach (SceneObjectPart part in parts)
3717 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4085 {
4086 part.ClearUpdateSchedule();
4087 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4088 }
3718 } 4089 }
4090 finally
4091 {
4092 parts[0].ParentGroup.areUpdatesSuspended = false;
4093 }
4094
4095
3719 newRoot.ParentGroup.HasGroupChanged = true; 4096 newRoot.ParentGroup.HasGroupChanged = true;
3720 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4097 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3721 } 4098 }
@@ -3735,6 +4112,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 public void llBreakAllLinks() 4112 public void llBreakAllLinks()
3736 { 4113 {
3737 m_host.AddScriptLPS(1); 4114 m_host.AddScriptLPS(1);
4115
4116 TaskInventoryItem item = m_item;
4117
4118 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4119 && !m_automaticLinkPermission)
4120 {
4121 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4122 return;
4123 }
4124
3738 SceneObjectGroup parentPrim = m_host.ParentGroup; 4125 SceneObjectGroup parentPrim = m_host.ParentGroup;
3739 if (parentPrim.AttachmentPoint != 0) 4126 if (parentPrim.AttachmentPoint != 0)
3740 return; // Fail silently if attached 4127 return; // Fail silently if attached
@@ -3754,25 +4141,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 public LSL_String llGetLinkKey(int linknum) 4141 public LSL_String llGetLinkKey(int linknum)
3755 { 4142 {
3756 m_host.AddScriptLPS(1); 4143 m_host.AddScriptLPS(1);
3757 List<UUID> keytable = new List<UUID>();
3758 // parse for sitting avatare-uuids
3759 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3760 {
3761 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3762 keytable.Add(presence.UUID);
3763 });
3764
3765 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3766 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3767 {
3768 return keytable[totalprims - linknum].ToString();
3769 }
3770
3771 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3772 {
3773 return m_host.UUID.ToString();
3774 }
3775
3776 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4144 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3777 if (part != null) 4145 if (part != null)
3778 { 4146 {
@@ -3780,6 +4148,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 } 4148 }
3781 else 4149 else
3782 { 4150 {
4151 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4152 {
4153 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4154
4155 if (linknum < 0)
4156 return UUID.Zero.ToString();
4157
4158 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4159 if (avatars.Count > linknum)
4160 {
4161 return avatars[linknum].UUID.ToString();
4162 }
4163 }
3783 return UUID.Zero.ToString(); 4164 return UUID.Zero.ToString();
3784 } 4165 }
3785 } 4166 }
@@ -3879,17 +4260,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3879 m_host.AddScriptLPS(1); 4260 m_host.AddScriptLPS(1);
3880 int count = 0; 4261 int count = 0;
3881 4262
3882 lock (m_host.TaskInventory) 4263 m_host.TaskInventory.LockItemsForRead(true);
4264 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3883 { 4265 {
3884 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4266 if (inv.Value.Type == type || type == -1)
3885 { 4267 {
3886 if (inv.Value.Type == type || type == -1) 4268 count = count + 1;
3887 {
3888 count = count + 1;
3889 }
3890 } 4269 }
3891 } 4270 }
3892 4271
4272 m_host.TaskInventory.LockItemsForRead(false);
3893 return count; 4273 return count;
3894 } 4274 }
3895 4275
@@ -3898,16 +4278,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3898 m_host.AddScriptLPS(1); 4278 m_host.AddScriptLPS(1);
3899 ArrayList keys = new ArrayList(); 4279 ArrayList keys = new ArrayList();
3900 4280
3901 lock (m_host.TaskInventory) 4281 m_host.TaskInventory.LockItemsForRead(true);
4282 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3902 { 4283 {
3903 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4284 if (inv.Value.Type == type || type == -1)
3904 { 4285 {
3905 if (inv.Value.Type == type || type == -1) 4286 keys.Add(inv.Value.Name);
3906 {
3907 keys.Add(inv.Value.Name);
3908 }
3909 } 4287 }
3910 } 4288 }
4289 m_host.TaskInventory.LockItemsForRead(false);
3911 4290
3912 if (keys.Count == 0) 4291 if (keys.Count == 0)
3913 { 4292 {
@@ -3945,7 +4324,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3945 if (item == null) 4324 if (item == null)
3946 { 4325 {
3947 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4326 llSay(0, String.Format("Could not find object '{0}'", inventory));
3948 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4327 return;
4328// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3949 } 4329 }
3950 4330
3951 UUID objId = item.ItemID; 4331 UUID objId = item.ItemID;
@@ -3973,33 +4353,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3973 return; 4353 return;
3974 } 4354 }
3975 } 4355 }
4356
3976 // destination is an avatar 4357 // destination is an avatar
3977 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4358 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3978 4359
3979 if (agentItem == null) 4360 if (agentItem == null)
3980 return; 4361 return;
3981 4362
3982 if (m_TransferModule != null) 4363 byte[] bucket = new byte[1];
3983 { 4364 bucket[0] = (byte)item.Type;
3984 byte[] bucket = new byte[] { (byte)item.Type }; 4365 //byte[] objBytes = agentItem.ID.GetBytes();
4366 //Array.Copy(objBytes, 0, bucket, 1, 16);
3985 4367
3986 GridInstantMessage msg = new GridInstantMessage(World, 4368 GridInstantMessage msg = new GridInstantMessage(World,
3987 m_host.UUID, m_host.Name + ", an object owned by " + 4369 m_host.OwnerID, m_host.Name, destId,
3988 resolveName(m_host.OwnerID) + ",", destId, 4370 (byte)InstantMessageDialog.TaskInventoryOffered,
3989 (byte)InstantMessageDialog.TaskInventoryOffered, 4371 false, item.Name+". "+m_host.Name+" is located at "+
3990 false, item.Name + "\n" + m_host.Name + " is located at " + 4372 World.RegionInfo.RegionName+" "+
3991 World.RegionInfo.RegionName+" "+ 4373 m_host.AbsolutePosition.ToString(),
3992 m_host.AbsolutePosition.ToString(), 4374 agentItem.ID, true, m_host.AbsolutePosition,
3993 agentItem.ID, true, m_host.AbsolutePosition, 4375 bucket);
3994 bucket);
3995 4376
3996 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4377 ScenePresence sp;
3997 }
3998 4378
4379 if (World.TryGetScenePresence(destId, out sp))
4380 {
4381 sp.ControllingClient.SendInstantMessage(msg);
4382 }
4383 else
4384 {
4385 if (m_TransferModule != null)
4386 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4387 }
4388
4389 //This delay should only occur when giving inventory to avatars.
3999 ScriptSleep(3000); 4390 ScriptSleep(3000);
4000 } 4391 }
4001 } 4392 }
4002 4393
4394 [DebuggerNonUserCode]
4003 public void llRemoveInventory(string name) 4395 public void llRemoveInventory(string name)
4004 { 4396 {
4005 m_host.AddScriptLPS(1); 4397 m_host.AddScriptLPS(1);
@@ -4045,109 +4437,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4045 { 4437 {
4046 m_host.AddScriptLPS(1); 4438 m_host.AddScriptLPS(1);
4047 4439
4048 UUID uuid = (UUID)id; 4440 UUID uuid;
4049 PresenceInfo pinfo = null; 4441 if (UUID.TryParse(id, out uuid))
4050 UserAccount account;
4051
4052 UserInfoCacheEntry ce;
4053 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4054 { 4442 {
4055 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4443 PresenceInfo pinfo = null;
4056 if (account == null) 4444 UserAccount account;
4445
4446 UserInfoCacheEntry ce;
4447 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4057 { 4448 {
4058 m_userInfoCache[uuid] = null; // Cache negative 4449 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4059 return UUID.Zero.ToString(); 4450 if (account == null)
4060 } 4451 {
4452 m_userInfoCache[uuid] = null; // Cache negative
4453 return UUID.Zero.ToString();
4454 }
4061 4455
4062 4456
4063 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4457 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4064 if (pinfos != null && pinfos.Length > 0) 4458 if (pinfos != null && pinfos.Length > 0)
4065 {
4066 foreach (PresenceInfo p in pinfos)
4067 { 4459 {
4068 if (p.RegionID != UUID.Zero) 4460 foreach (PresenceInfo p in pinfos)
4069 { 4461 {
4070 pinfo = p; 4462 if (p.RegionID != UUID.Zero)
4463 {
4464 pinfo = p;
4465 }
4071 } 4466 }
4072 } 4467 }
4073 }
4074 4468
4075 ce = new UserInfoCacheEntry(); 4469 ce = new UserInfoCacheEntry();
4076 ce.time = Util.EnvironmentTickCount(); 4470 ce.time = Util.EnvironmentTickCount();
4077 ce.account = account; 4471 ce.account = account;
4078 ce.pinfo = pinfo; 4472 ce.pinfo = pinfo;
4079 } 4473 m_userInfoCache[uuid] = ce;
4080 else 4474 }
4081 { 4475 else
4082 if (ce == null) 4476 {
4083 return UUID.Zero.ToString(); 4477 if (ce == null)
4478 return UUID.Zero.ToString();
4084 4479
4085 account = ce.account; 4480 account = ce.account;
4086 pinfo = ce.pinfo; 4481 pinfo = ce.pinfo;
4087 } 4482 }
4088 4483
4089 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4484 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4090 {
4091 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4092 if (pinfos != null && pinfos.Length > 0)
4093 { 4485 {
4094 foreach (PresenceInfo p in pinfos) 4486 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4487 if (pinfos != null && pinfos.Length > 0)
4095 { 4488 {
4096 if (p.RegionID != UUID.Zero) 4489 foreach (PresenceInfo p in pinfos)
4097 { 4490 {
4098 pinfo = p; 4491 if (p.RegionID != UUID.Zero)
4492 {
4493 pinfo = p;
4494 }
4099 } 4495 }
4100 } 4496 }
4101 } 4497 else
4102 else 4498 pinfo = null;
4103 pinfo = null;
4104 4499
4105 ce.time = Util.EnvironmentTickCount(); 4500 ce.time = Util.EnvironmentTickCount();
4106 ce.pinfo = pinfo; 4501 ce.pinfo = pinfo;
4107 } 4502 }
4108 4503
4109 string reply = String.Empty; 4504 string reply = String.Empty;
4110 4505
4111 switch (data) 4506 switch (data)
4112 { 4507 {
4113 case 1: // DATA_ONLINE (0|1) 4508 case 1: // DATA_ONLINE (0|1)
4114 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4509 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4115 reply = "1"; 4510 reply = "1";
4116 else 4511 else
4117 reply = "0"; 4512 reply = "0";
4118 break; 4513 break;
4119 case 2: // DATA_NAME (First Last) 4514 case 2: // DATA_NAME (First Last)
4120 reply = account.FirstName + " " + account.LastName; 4515 reply = account.FirstName + " " + account.LastName;
4121 break; 4516 break;
4122 case 3: // DATA_BORN (YYYY-MM-DD) 4517 case 3: // DATA_BORN (YYYY-MM-DD)
4123 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4518 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4124 born = born.AddSeconds(account.Created); 4519 born = born.AddSeconds(account.Created);
4125 reply = born.ToString("yyyy-MM-dd"); 4520 reply = born.ToString("yyyy-MM-dd");
4126 break; 4521 break;
4127 case 4: // DATA_RATING (0,0,0,0,0,0) 4522 case 4: // DATA_RATING (0,0,0,0,0,0)
4128 reply = "0,0,0,0,0,0"; 4523 reply = "0,0,0,0,0,0";
4129 break; 4524 break;
4130 case 7: // DATA_USERLEVEL (integer) 4525 case 8: // DATA_PAYINFO (0|1|2|3)
4131 reply = account.UserLevel.ToString(); 4526 reply = "0";
4132 break; 4527 break;
4133 case 8: // DATA_PAYINFO (0|1|2|3) 4528 default:
4134 reply = "0"; 4529 return UUID.Zero.ToString(); // Raise no event
4135 break; 4530 }
4136 default:
4137 return UUID.Zero.ToString(); // Raise no event
4138 }
4139 4531
4140 UUID rq = UUID.Random(); 4532 UUID rq = UUID.Random();
4141 4533
4142 UUID tid = AsyncCommands. 4534 UUID tid = AsyncCommands.
4143 DataserverPlugin.RegisterRequest(m_host.LocalId, 4535 DataserverPlugin.RegisterRequest(m_host.LocalId,
4144 m_item.ItemID, rq.ToString()); 4536 m_item.ItemID, rq.ToString());
4145 4537
4146 AsyncCommands. 4538 AsyncCommands.
4147 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4539 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4148 4540
4149 ScriptSleep(100); 4541 ScriptSleep(100);
4150 return tid.ToString(); 4542 return tid.ToString();
4543 }
4544 else
4545 {
4546 ShoutError("Invalid UUID passed to llRequestAgentData.");
4547 }
4548 return "";
4151 } 4549 }
4152 4550
4153 public LSL_String llRequestInventoryData(string name) 4551 public LSL_String llRequestInventoryData(string name)
@@ -4204,13 +4602,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4204 if (UUID.TryParse(agent, out agentId)) 4602 if (UUID.TryParse(agent, out agentId))
4205 { 4603 {
4206 ScenePresence presence = World.GetScenePresence(agentId); 4604 ScenePresence presence = World.GetScenePresence(agentId);
4207 if (presence != null) 4605 if (presence != null && presence.PresenceType != PresenceType.Npc)
4208 { 4606 {
4607 // agent must not be a god
4608 if (presence.UserLevel >= 200) return;
4609
4209 // agent must be over the owners land 4610 // agent must be over the owners land
4210 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4611 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4211 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4612 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4212 { 4613 {
4213 World.TeleportClientHome(agentId, presence.ControllingClient); 4614 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4615 {
4616 // They can't be teleported home for some reason
4617 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4618 if (regionInfo != null)
4619 {
4620 World.RequestTeleportLocation(
4621 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4622 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4623 }
4624 }
4214 } 4625 }
4215 } 4626 }
4216 } 4627 }
@@ -4322,7 +4733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4322 UUID av = new UUID(); 4733 UUID av = new UUID();
4323 if (!UUID.TryParse(agent,out av)) 4734 if (!UUID.TryParse(agent,out av))
4324 { 4735 {
4325 LSLError("First parameter to llDialog needs to be a key"); 4736 //LSLError("First parameter to llDialog needs to be a key");
4326 return; 4737 return;
4327 } 4738 }
4328 4739
@@ -4354,7 +4765,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4354 public void llCollisionSound(string impact_sound, double impact_volume) 4765 public void llCollisionSound(string impact_sound, double impact_volume)
4355 { 4766 {
4356 m_host.AddScriptLPS(1); 4767 m_host.AddScriptLPS(1);
4357 4768
4769 if(impact_sound == "")
4770 {
4771 m_host.CollisionSoundVolume = (float)impact_volume;
4772 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4773 m_host.CollisionSoundType = 0;
4774 return;
4775 }
4358 // TODO: Parameter check logic required. 4776 // TODO: Parameter check logic required.
4359 UUID soundId = UUID.Zero; 4777 UUID soundId = UUID.Zero;
4360 if (!UUID.TryParse(impact_sound, out soundId)) 4778 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4367,6 +4785,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4367 4785
4368 m_host.CollisionSound = soundId; 4786 m_host.CollisionSound = soundId;
4369 m_host.CollisionSoundVolume = (float)impact_volume; 4787 m_host.CollisionSoundVolume = (float)impact_volume;
4788 m_host.CollisionSoundType = 1;
4370 } 4789 }
4371 4790
4372 public LSL_String llGetAnimation(string id) 4791 public LSL_String llGetAnimation(string id)
@@ -4380,14 +4799,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4380 4799
4381 if (m_host.RegionHandle == presence.RegionHandle) 4800 if (m_host.RegionHandle == presence.RegionHandle)
4382 { 4801 {
4383 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4384
4385 if (presence != null) 4802 if (presence != null)
4386 { 4803 {
4387 AnimationSet currentAnims = presence.Animator.Animations; 4804 if (presence.SitGround)
4388 string currentAnimationState = String.Empty; 4805 return "Sitting on Ground";
4389 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4806 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4390 return currentAnimationState; 4807 return "Sitting";
4808
4809 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4810 string lslMovementAnimation;
4811
4812 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4813 return lslMovementAnimation;
4391 } 4814 }
4392 } 4815 }
4393 4816
@@ -4534,7 +4957,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4534 { 4957 {
4535 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4958 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4536 float distance_term = distance * distance * distance; // Script Energy 4959 float distance_term = distance * distance * distance; // Script Energy
4537 float pusher_mass = m_host.GetMass(); 4960 // use total object mass and not part
4961 float pusher_mass = m_host.ParentGroup.GetMass();
4538 4962
4539 float PUSH_ATTENUATION_DISTANCE = 17f; 4963 float PUSH_ATTENUATION_DISTANCE = 17f;
4540 float PUSH_ATTENUATION_SCALE = 5f; 4964 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4784,6 +5208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4784 { 5208 {
4785 return item.AssetID.ToString(); 5209 return item.AssetID.ToString();
4786 } 5210 }
5211 m_host.TaskInventory.LockItemsForRead(false);
4787 5212
4788 return UUID.Zero.ToString(); 5213 return UUID.Zero.ToString();
4789 } 5214 }
@@ -4917,7 +5342,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4917 public LSL_Vector llGetCenterOfMass() 5342 public LSL_Vector llGetCenterOfMass()
4918 { 5343 {
4919 m_host.AddScriptLPS(1); 5344 m_host.AddScriptLPS(1);
4920 Vector3 center = m_host.GetGeometricCenter(); 5345 Vector3 center = m_host.GetCenterOfMass();
4921 return new LSL_Vector(center.X,center.Y,center.Z); 5346 return new LSL_Vector(center.X,center.Y,center.Z);
4922 } 5347 }
4923 5348
@@ -4936,14 +5361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4936 { 5361 {
4937 m_host.AddScriptLPS(1); 5362 m_host.AddScriptLPS(1);
4938 5363
4939 if (src == null) 5364 return src.Length;
4940 {
4941 return 0;
4942 }
4943 else
4944 {
4945 return src.Length;
4946 }
4947 } 5365 }
4948 5366
4949 public LSL_Integer llList2Integer(LSL_List src, int index) 5367 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4989,7 +5407,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4989 else if (src.Data[index] is LSL_Float) 5407 else if (src.Data[index] is LSL_Float)
4990 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5408 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4991 else if (src.Data[index] is LSL_String) 5409 else if (src.Data[index] is LSL_String)
4992 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5410 {
5411 string str = ((LSL_String) src.Data[index]).m_string;
5412 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5413 if (m != Match.Empty)
5414 {
5415 str = m.Value;
5416 double d = 0.0;
5417 if (!Double.TryParse(str, out d))
5418 return 0.0;
5419
5420 return d;
5421 }
5422 return 0.0;
5423 }
4993 return Convert.ToDouble(src.Data[index]); 5424 return Convert.ToDouble(src.Data[index]);
4994 } 5425 }
4995 catch (FormatException) 5426 catch (FormatException)
@@ -5262,7 +5693,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5262 } 5693 }
5263 } 5694 }
5264 } 5695 }
5265 else { 5696 else
5697 {
5266 object[] array = new object[src.Length]; 5698 object[] array = new object[src.Length];
5267 Array.Copy(src.Data, 0, array, 0, src.Length); 5699 Array.Copy(src.Data, 0, array, 0, src.Length);
5268 result = new LSL_List(array); 5700 result = new LSL_List(array);
@@ -5369,7 +5801,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5369 public LSL_Integer llGetRegionAgentCount() 5801 public LSL_Integer llGetRegionAgentCount()
5370 { 5802 {
5371 m_host.AddScriptLPS(1); 5803 m_host.AddScriptLPS(1);
5372 return new LSL_Integer(World.GetRootAgentCount()); 5804
5805 int count = 0;
5806 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5807 count++;
5808 });
5809
5810 return new LSL_Integer(count);
5373 } 5811 }
5374 5812
5375 public LSL_Vector llGetRegionCorner() 5813 public LSL_Vector llGetRegionCorner()
@@ -5649,6 +6087,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5649 flags |= ScriptBaseClass.AGENT_SITTING; 6087 flags |= ScriptBaseClass.AGENT_SITTING;
5650 } 6088 }
5651 6089
6090 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6091 {
6092 flags |= ScriptBaseClass.AGENT_MALE;
6093 }
6094
5652 return flags; 6095 return flags;
5653 } 6096 }
5654 6097
@@ -5795,10 +6238,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5795 m_host.AddScriptLPS(1); 6238 m_host.AddScriptLPS(1);
5796 6239
5797 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6240 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5798 6241 if (parts.Count > 0)
5799 foreach (var part in parts)
5800 { 6242 {
5801 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6243 try
6244 {
6245 parts[0].ParentGroup.areUpdatesSuspended = true;
6246 foreach (var part in parts)
6247 {
6248 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6249 }
6250 }
6251 finally
6252 {
6253 parts[0].ParentGroup.areUpdatesSuspended = false;
6254 }
5802 } 6255 }
5803 } 6256 }
5804 6257
@@ -5850,13 +6303,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5850 6303
5851 if (m_host.OwnerID == land.LandData.OwnerID) 6304 if (m_host.OwnerID == land.LandData.OwnerID)
5852 { 6305 {
5853 World.TeleportClientHome(agentID, presence.ControllingClient); 6306 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6307 presence.TeleportWithMomentum(pos, null);
6308 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5854 } 6309 }
5855 } 6310 }
5856 } 6311 }
5857 ScriptSleep(5000); 6312 ScriptSleep(5000);
5858 } 6313 }
5859 6314
6315 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6316 {
6317 return ParseString2List(str, separators, in_spacers, false);
6318 }
6319
5860 public LSL_Integer llOverMyLand(string id) 6320 public LSL_Integer llOverMyLand(string id)
5861 { 6321 {
5862 m_host.AddScriptLPS(1); 6322 m_host.AddScriptLPS(1);
@@ -5915,20 +6375,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5915 return agentSize; 6375 return agentSize;
5916 } 6376 }
5917 6377
5918 public LSL_Integer llSameGroup(string agent) 6378 public LSL_Integer llSameGroup(string id)
5919 { 6379 {
5920 m_host.AddScriptLPS(1); 6380 m_host.AddScriptLPS(1);
5921 UUID agentId = new UUID(); 6381 UUID uuid = new UUID();
5922 if (!UUID.TryParse(agent, out agentId)) 6382 if (!UUID.TryParse(id, out uuid))
5923 return new LSL_Integer(0); 6383 return new LSL_Integer(0);
5924 ScenePresence presence = World.GetScenePresence(agentId); 6384
5925 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6385 // Check if it's a group key
5926 return new LSL_Integer(0); 6386 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5927 IClientAPI client = presence.ControllingClient;
5928 if (m_host.GroupID == client.ActiveGroupId)
5929 return new LSL_Integer(1); 6387 return new LSL_Integer(1);
5930 else 6388
6389 // We got passed a UUID.Zero
6390 if (uuid == UUID.Zero)
5931 return new LSL_Integer(0); 6391 return new LSL_Integer(0);
6392
6393 // Handle the case where id names an avatar
6394 ScenePresence presence = World.GetScenePresence(uuid);
6395 if (presence != null)
6396 {
6397 if (presence.IsChildAgent)
6398 return new LSL_Integer(0);
6399
6400 IClientAPI client = presence.ControllingClient;
6401 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6402 return new LSL_Integer(1);
6403
6404 return new LSL_Integer(0);
6405 }
6406
6407 // Handle object case
6408 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6409 if (part != null)
6410 {
6411 // This will handle both deed and non-deed and also the no
6412 // group case
6413 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6414 return new LSL_Integer(1);
6415
6416 return new LSL_Integer(0);
6417 }
6418
6419 return new LSL_Integer(0);
5932 } 6420 }
5933 6421
5934 public void llUnSit(string id) 6422 public void llUnSit(string id)
@@ -6057,7 +6545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6057 return m_host.ParentGroup.AttachmentPoint; 6545 return m_host.ParentGroup.AttachmentPoint;
6058 } 6546 }
6059 6547
6060 public LSL_Integer llGetFreeMemory() 6548 public virtual LSL_Integer llGetFreeMemory()
6061 { 6549 {
6062 m_host.AddScriptLPS(1); 6550 m_host.AddScriptLPS(1);
6063 // Make scripts designed for LSO happy 6551 // Make scripts designed for LSO happy
@@ -6174,7 +6662,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6174 SetParticleSystem(m_host, rules); 6662 SetParticleSystem(m_host, rules);
6175 } 6663 }
6176 6664
6177 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6665 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6666 {
6178 6667
6179 6668
6180 if (rules.Length == 0) 6669 if (rules.Length == 0)
@@ -6491,7 +6980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6491 { 6980 {
6492 // LSL quaternions can normalize to 0, normal Quaternions can't. 6981 // LSL quaternions can normalize to 0, normal Quaternions can't.
6493 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6982 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6494 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6983 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6495 6984
6496 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6985 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6497 part.SitTargetOrientation = Rot2Quaternion(rot); 6986 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6648,13 +7137,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6648 UUID av = new UUID(); 7137 UUID av = new UUID();
6649 if (!UUID.TryParse(avatar,out av)) 7138 if (!UUID.TryParse(avatar,out av))
6650 { 7139 {
6651 LSLError("First parameter to llDialog needs to be a key"); 7140 //LSLError("First parameter to llDialog needs to be a key");
6652 return; 7141 return;
6653 } 7142 }
6654 if (buttons.Length < 1) 7143 if (buttons.Length < 1)
6655 { 7144 {
6656 LSLError("No less than 1 button can be shown"); 7145 buttons.Add("OK");
6657 return;
6658 } 7146 }
6659 if (buttons.Length > 12) 7147 if (buttons.Length > 12)
6660 { 7148 {
@@ -6671,7 +7159,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6671 } 7159 }
6672 if (buttons.Data[i].ToString().Length > 24) 7160 if (buttons.Data[i].ToString().Length > 24)
6673 { 7161 {
6674 LSLError("button label cannot be longer than 24 characters"); 7162 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6675 return; 7163 return;
6676 } 7164 }
6677 buts[i] = buttons.Data[i].ToString(); 7165 buts[i] = buttons.Data[i].ToString();
@@ -6738,9 +7226,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6738 return; 7226 return;
6739 } 7227 }
6740 7228
6741 // the rest of the permission checks are done in RezScript, so check the pin there as well 7229 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6742 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7230 if (dest != null)
7231 {
7232 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7233 {
7234 // the rest of the permission checks are done in RezScript, so check the pin there as well
7235 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6743 7236
7237 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7238 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7239 }
7240 }
6744 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7241 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6745 ScriptSleep(3000); 7242 ScriptSleep(3000);
6746 } 7243 }
@@ -6803,19 +7300,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6803 public LSL_String llMD5String(string src, int nonce) 7300 public LSL_String llMD5String(string src, int nonce)
6804 { 7301 {
6805 m_host.AddScriptLPS(1); 7302 m_host.AddScriptLPS(1);
6806 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7303 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6807 } 7304 }
6808 7305
6809 public LSL_String llSHA1String(string src) 7306 public LSL_String llSHA1String(string src)
6810 { 7307 {
6811 m_host.AddScriptLPS(1); 7308 m_host.AddScriptLPS(1);
6812 return Util.SHA1Hash(src).ToLower(); 7309 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6813 } 7310 }
6814 7311
6815 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7312 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6816 { 7313 {
6817 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7314 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6818 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7315 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7316 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7317 return shapeBlock;
6819 7318
6820 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7319 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6821 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7320 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6920,6 +7419,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6920 // Prim type box, cylinder and prism. 7419 // Prim type box, cylinder and prism.
6921 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) 7420 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)
6922 { 7421 {
7422 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7423 return;
7424
6923 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7425 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6924 ObjectShapePacket.ObjectDataBlock shapeBlock; 7426 ObjectShapePacket.ObjectDataBlock shapeBlock;
6925 7427
@@ -6973,6 +7475,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6973 // Prim type sphere. 7475 // Prim type sphere.
6974 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7476 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6975 { 7477 {
7478 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7479 return;
7480
6976 ObjectShapePacket.ObjectDataBlock shapeBlock; 7481 ObjectShapePacket.ObjectDataBlock shapeBlock;
6977 7482
6978 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7483 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7014,6 +7519,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7014 // Prim type torus, tube and ring. 7519 // Prim type torus, tube and ring.
7015 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) 7520 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)
7016 { 7521 {
7522 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7523 return;
7524
7017 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7525 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7018 ObjectShapePacket.ObjectDataBlock shapeBlock; 7526 ObjectShapePacket.ObjectDataBlock shapeBlock;
7019 7527
@@ -7149,6 +7657,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7149 // Prim type sculpt. 7657 // Prim type sculpt.
7150 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7658 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7151 { 7659 {
7660 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7661 return;
7662
7152 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7663 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7153 UUID sculptId; 7664 UUID sculptId;
7154 7665
@@ -7173,7 +7684,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7173 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7684 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7174 { 7685 {
7175 // default 7686 // default
7176 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7687 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7177 } 7688 }
7178 7689
7179 part.Shape.SetSculptProperties((byte)type, sculptId); 7690 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7189,34 +7700,298 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7189 ScriptSleep(200); 7700 ScriptSleep(200);
7190 } 7701 }
7191 7702
7192 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7703 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7193 { 7704 {
7194 m_host.AddScriptLPS(1); 7705 m_host.AddScriptLPS(1);
7195 7706
7196 setLinkPrimParams(linknumber, rules); 7707 setLinkPrimParams(linknumber, rules);
7708 }
7709
7710 private void setLinkPrimParams(int linknumber, LSL_List rules)
7711 {
7712 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7713 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7714 if (parts.Count>0)
7715 {
7716 try
7717 {
7718 parts[0].ParentGroup.areUpdatesSuspended = true;
7719 foreach (SceneObjectPart part in parts)
7720 SetPrimParams(part, rules);
7721 }
7722 finally
7723 {
7724 parts[0].ParentGroup.areUpdatesSuspended = false;
7725 }
7726 }
7727 if (avatars.Count > 0)
7728 {
7729 foreach (ScenePresence avatar in avatars)
7730 SetPrimParams(avatar, rules);
7731 }
7732 }
7197 7733
7734 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7735 float material_density, float material_friction,
7736 float material_restitution, float material_gravity_modifier)
7737 {
7738 ExtraPhysicsData physdata = new ExtraPhysicsData();
7739 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7740 physdata.Density = part.Density;
7741 physdata.Friction = part.Friction;
7742 physdata.Bounce = part.Bounciness;
7743 physdata.GravitationModifier = part.GravityModifier;
7744
7745 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7746 physdata.Density = material_density;
7747 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7748 physdata.Friction = material_friction;
7749 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7750 physdata.Bounce = material_restitution;
7751 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7752 physdata.GravitationModifier = material_gravity_modifier;
7753
7754 part.UpdateExtraPhysics(physdata);
7755 }
7756
7757 public void llSetPhysicsMaterial(int material_bits,
7758 float material_gravity_modifier, float material_restitution,
7759 float material_friction, float material_density)
7760 {
7761 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7762 }
7763
7764 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7765 {
7766 llSetLinkPrimitiveParamsFast(linknumber, rules);
7198 ScriptSleep(200); 7767 ScriptSleep(200);
7199 } 7768 }
7200 7769
7201 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7770 // vector up using libomv (c&p from sop )
7771 // vector up rotated by r
7772 private Vector3 Zrot(Quaternion r)
7202 { 7773 {
7203 m_host.AddScriptLPS(1); 7774 double x, y, z, m;
7204 7775
7205 setLinkPrimParams(linknumber, rules); 7776 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7777 if (Math.Abs(1.0 - m) > 0.000001)
7778 {
7779 m = 1.0 / Math.Sqrt(m);
7780 r.X *= (float)m;
7781 r.Y *= (float)m;
7782 r.Z *= (float)m;
7783 r.W *= (float)m;
7784 }
7785
7786 x = 2 * (r.X * r.Z + r.Y * r.W);
7787 y = 2 * (-r.X * r.W + r.Y * r.Z);
7788 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7789
7790 return new Vector3((float)x, (float)y, (float)z);
7206 } 7791 }
7207 7792
7208 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7793 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7209 { 7794 {
7210 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7795 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7211 7796
7212 foreach (SceneObjectPart part in parts) 7797 int idx = 0;
7213 SetPrimParams(part, rules); 7798
7799 bool positionChanged = false;
7800 Vector3 finalPos = Vector3.Zero;
7801
7802 try
7803 {
7804 while (idx < rules.Length)
7805 {
7806 int code = rules.GetLSLIntegerItem(idx++);
7807
7808 int remain = rules.Length - idx;
7809
7810 switch (code)
7811 {
7812 case (int)ScriptBaseClass.PRIM_POSITION:
7813 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7814 {
7815 if (remain < 1)
7816 return;
7817
7818 LSL_Vector v;
7819 v = rules.GetVector3Item(idx++);
7820
7821 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7822 if (part == null)
7823 break;
7824
7825 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7826 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7827 if (part.LinkNum > 1)
7828 {
7829 localRot = GetPartLocalRot(part);
7830 localPos = GetPartLocalPos(part);
7831 }
7832
7833 v -= localPos;
7834 v /= localRot;
7835
7836 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7837
7838 v = v + 2 * sitOffset;
7839
7840 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7841 av.SendAvatarDataToAllAgents();
7842
7843 }
7844 break;
7845
7846 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7847 case (int)ScriptBaseClass.PRIM_ROTATION:
7848 {
7849 if (remain < 1)
7850 return;
7851
7852 LSL_Rotation r;
7853 r = rules.GetQuaternionItem(idx++);
7854
7855 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7856 if (part == null)
7857 break;
7858
7859 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7860 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7861
7862 if (part.LinkNum > 1)
7863 localRot = GetPartLocalRot(part);
7864
7865 r = r * llGetRootRotation() / localRot;
7866 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7867 av.SendAvatarDataToAllAgents();
7868 }
7869 break;
7870
7871 // parse rest doing nothing but number of parameters error check
7872 case (int)ScriptBaseClass.PRIM_SIZE:
7873 case (int)ScriptBaseClass.PRIM_MATERIAL:
7874 case (int)ScriptBaseClass.PRIM_PHANTOM:
7875 case (int)ScriptBaseClass.PRIM_PHYSICS:
7876 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7877 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7878 case (int)ScriptBaseClass.PRIM_NAME:
7879 case (int)ScriptBaseClass.PRIM_DESC:
7880 if (remain < 1)
7881 return;
7882 idx++;
7883 break;
7884
7885 case (int)ScriptBaseClass.PRIM_GLOW:
7886 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7887 case (int)ScriptBaseClass.PRIM_TEXGEN:
7888 if (remain < 2)
7889 return;
7890 idx += 2;
7891 break;
7892
7893 case (int)ScriptBaseClass.PRIM_TYPE:
7894 if (remain < 3)
7895 return;
7896 code = (int)rules.GetLSLIntegerItem(idx++);
7897 remain = rules.Length - idx;
7898 switch (code)
7899 {
7900 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7901 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7902 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7903 if (remain < 6)
7904 return;
7905 idx += 6;
7906 break;
7907
7908 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7909 if (remain < 5)
7910 return;
7911 idx += 5;
7912 break;
7913
7914 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7915 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7916 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7917 if (remain < 11)
7918 return;
7919 idx += 11;
7920 break;
7921
7922 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7923 if (remain < 2)
7924 return;
7925 idx += 2;
7926 break;
7927 }
7928 break;
7929
7930 case (int)ScriptBaseClass.PRIM_COLOR:
7931 case (int)ScriptBaseClass.PRIM_TEXT:
7932 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7933 case (int)ScriptBaseClass.PRIM_OMEGA:
7934 if (remain < 3)
7935 return;
7936 idx += 3;
7937 break;
7938
7939 case (int)ScriptBaseClass.PRIM_TEXTURE:
7940 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7941 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7942 if (remain < 5)
7943 return;
7944 idx += 5;
7945 break;
7946
7947 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7948 if (remain < 7)
7949 return;
7950
7951 idx += 7;
7952 break;
7953
7954 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7955 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7956 return;
7957
7958 if (positionChanged)
7959 {
7960 positionChanged = false;
7961 av.OffsetPosition = finalPos;
7962// av.SendAvatarDataToAllAgents();
7963 av.SendTerseUpdateToAllClients();
7964 }
7965
7966 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7967 LSL_List new_rules = rules.GetSublist(idx, -1);
7968 setLinkPrimParams((int)new_linknumber, new_rules);
7969 return;
7970 }
7971 }
7972 }
7973
7974 finally
7975 {
7976 if (positionChanged)
7977 {
7978 av.OffsetPosition = finalPos;
7979// av.SendAvatarDataToAllAgents();
7980 av.SendTerseUpdateToAllClients();
7981 positionChanged = false;
7982 }
7983 }
7214 } 7984 }
7215 7985
7216 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7986 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7217 { 7987 {
7988 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7989 return;
7990
7218 int idx = 0; 7991 int idx = 0;
7219 7992
7993 SceneObjectGroup parentgrp = part.ParentGroup;
7994
7220 bool positionChanged = false; 7995 bool positionChanged = false;
7221 LSL_Vector currentPosition = GetPartLocalPos(part); 7996 LSL_Vector currentPosition = GetPartLocalPos(part);
7222 7997
@@ -7239,8 +8014,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7239 return; 8014 return;
7240 8015
7241 v=rules.GetVector3Item(idx++); 8016 v=rules.GetVector3Item(idx++);
7242 positionChanged = true;
7243 currentPosition = GetSetPosTarget(part, v, currentPosition); 8017 currentPosition = GetSetPosTarget(part, v, currentPosition);
8018 positionChanged = true;
7244 8019
7245 break; 8020 break;
7246 case (int)ScriptBaseClass.PRIM_SIZE: 8021 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7256,8 +8031,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7256 return; 8031 return;
7257 8032
7258 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8033 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8034 SceneObjectPart rootPart = parentgrp.RootPart;
7259 // try to let this work as in SL... 8035 // try to let this work as in SL...
7260 if (part.ParentID == 0) 8036 if (rootPart == part)
7261 { 8037 {
7262 // special case: If we are root, rotate complete SOG to new rotation 8038 // special case: If we are root, rotate complete SOG to new rotation
7263 SetRot(part, Rot2Quaternion(q)); 8039 SetRot(part, Rot2Quaternion(q));
@@ -7265,7 +8041,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7265 else 8041 else
7266 { 8042 {
7267 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8043 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7268 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8044 // sounds like sl bug that we need to replicate
7269 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8045 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7270 } 8046 }
7271 8047
@@ -7518,7 +8294,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7518 return; 8294 return;
7519 8295
7520 string ph = rules.Data[idx++].ToString(); 8296 string ph = rules.Data[idx++].ToString();
7521 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8297 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7522 8298
7523 break; 8299 break;
7524 8300
@@ -7536,12 +8312,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7536 part.ScriptSetPhysicsStatus(physics); 8312 part.ScriptSetPhysicsStatus(physics);
7537 break; 8313 break;
7538 8314
8315 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8316 if (remain < 1)
8317 return;
8318
8319 int shape_type = rules.GetLSLIntegerItem(idx++);
8320
8321 ExtraPhysicsData physdata = new ExtraPhysicsData();
8322 physdata.Density = part.Density;
8323 physdata.Bounce = part.Bounciness;
8324 physdata.GravitationModifier = part.GravityModifier;
8325 physdata.PhysShapeType = (PhysShapeType)shape_type;
8326
8327 part.UpdateExtraPhysics(physdata);
8328
8329 break;
8330
8331 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8332 if (remain < 5)
8333 return;
8334
8335 int material_bits = rules.GetLSLIntegerItem(idx++);
8336 float material_density = (float)rules.GetLSLFloatItem(idx++);
8337 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8338 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8339 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8340
8341 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8342
8343 break;
8344
7539 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8345 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7540 if (remain < 1) 8346 if (remain < 1)
7541 return; 8347 return;
7542 string temp = rules.Data[idx++].ToString(); 8348 string temp = rules.Data[idx++].ToString();
7543 8349
7544 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8350 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7545 8351
7546 break; 8352 break;
7547 8353
@@ -7580,6 +8386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7580 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8386 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7581 if (remain < 1) 8387 if (remain < 1)
7582 return; 8388 return;
8389
7583 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8390 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7584 SetRot(part, Rot2Quaternion(lr)); 8391 SetRot(part, Rot2Quaternion(lr));
7585 break; 8392 break;
@@ -7591,13 +8398,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7591 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8398 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7592 TargetOmega(part, axis, (double)spinrate, (double)gain); 8399 TargetOmega(part, axis, (double)spinrate, (double)gain);
7593 break; 8400 break;
8401
7594 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8402 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7595 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8403 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7596 return; 8404 return;
8405
8406 // do a pending position change before jumping to other part/avatar
8407 if (positionChanged)
8408 {
8409 positionChanged = false;
8410 if (parentgrp == null)
8411 return;
8412
8413 if (parentgrp.RootPart == part)
8414 {
8415
8416 Util.FireAndForget(delegate(object x)
8417 {
8418 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8419 });
8420 }
8421 else
8422 {
8423 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8424 parentgrp.HasGroupChanged = true;
8425 parentgrp.ScheduleGroupForTerseUpdate();
8426 }
8427 }
8428
7597 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8429 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7598 LSL_List new_rules = rules.GetSublist(idx, -1); 8430 LSL_List new_rules = rules.GetSublist(idx, -1);
7599 setLinkPrimParams((int)new_linknumber, new_rules); 8431 setLinkPrimParams((int)new_linknumber, new_rules);
7600
7601 return; 8432 return;
7602 } 8433 }
7603 } 8434 }
@@ -7609,7 +8440,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7609 if (part.ParentGroup.RootPart == part) 8440 if (part.ParentGroup.RootPart == part)
7610 { 8441 {
7611 SceneObjectGroup parent = part.ParentGroup; 8442 SceneObjectGroup parent = part.ParentGroup;
7612 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8443 Util.FireAndForget(delegate(object x) {
8444 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8445 });
7613 } 8446 }
7614 else 8447 else
7615 { 8448 {
@@ -7653,10 +8486,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7653 8486
7654 public LSL_String llXorBase64Strings(string str1, string str2) 8487 public LSL_String llXorBase64Strings(string str1, string str2)
7655 { 8488 {
7656 m_host.AddScriptLPS(1); 8489 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7657 Deprecated("llXorBase64Strings"); 8490
7658 ScriptSleep(300); 8491 ScriptSleep(300);
7659 return String.Empty; 8492 m_host.AddScriptLPS(1);
8493
8494 if (str1 == String.Empty)
8495 return String.Empty;
8496 if (str2 == String.Empty)
8497 return str1;
8498
8499 int len = str2.Length;
8500 if ((len % 4) != 0) // LL is EVIL!!!!
8501 {
8502 while (str2.EndsWith("="))
8503 str2 = str2.Substring(0, str2.Length - 1);
8504
8505 len = str2.Length;
8506 int mod = len % 4;
8507
8508 if (mod == 1)
8509 str2 = str2.Substring(0, str2.Length - 1);
8510 else if (mod == 2)
8511 str2 += "==";
8512 else if (mod == 3)
8513 str2 += "=";
8514 }
8515
8516 byte[] data1;
8517 byte[] data2;
8518 try
8519 {
8520 data1 = Convert.FromBase64String(str1);
8521 data2 = Convert.FromBase64String(str2);
8522 }
8523 catch (Exception)
8524 {
8525 return new LSL_String(String.Empty);
8526 }
8527
8528 // For cases where the decoded length of s2 is greater
8529 // than the decoded length of s1, simply perform a normal
8530 // decode and XOR
8531 //
8532 if (data2.Length >= data1.Length)
8533 {
8534 for (int pos = 0 ; pos < data1.Length ; pos++ )
8535 data1[pos] ^= data2[pos];
8536
8537 return Convert.ToBase64String(data1);
8538 }
8539
8540 // Remove padding
8541 while (str1.EndsWith("="))
8542 str1 = str1.Substring(0, str1.Length - 1);
8543 while (str2.EndsWith("="))
8544 str2 = str2.Substring(0, str2.Length - 1);
8545
8546 byte[] d1 = new byte[str1.Length];
8547 byte[] d2 = new byte[str2.Length];
8548
8549 for (int i = 0 ; i < str1.Length ; i++)
8550 {
8551 int idx = b64.IndexOf(str1.Substring(i, 1));
8552 if (idx == -1)
8553 idx = 0;
8554 d1[i] = (byte)idx;
8555 }
8556
8557 for (int i = 0 ; i < str2.Length ; i++)
8558 {
8559 int idx = b64.IndexOf(str2.Substring(i, 1));
8560 if (idx == -1)
8561 idx = 0;
8562 d2[i] = (byte)idx;
8563 }
8564
8565 string output = String.Empty;
8566
8567 for (int pos = 0 ; pos < d1.Length ; pos++)
8568 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8569
8570 while (output.Length % 3 > 0)
8571 output += "=";
8572
8573 return output;
7660 } 8574 }
7661 8575
7662 public void llRemoteDataSetRegion() 8576 public void llRemoteDataSetRegion()
@@ -7780,13 +8694,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7780 public LSL_Integer llGetNumberOfPrims() 8694 public LSL_Integer llGetNumberOfPrims()
7781 { 8695 {
7782 m_host.AddScriptLPS(1); 8696 m_host.AddScriptLPS(1);
7783 int avatarCount = 0; 8697 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7784 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8698
7785 {
7786 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7787 avatarCount++;
7788 });
7789
7790 return m_host.ParentGroup.PrimCount + avatarCount; 8699 return m_host.ParentGroup.PrimCount + avatarCount;
7791 } 8700 }
7792 8701
@@ -7802,55 +8711,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7802 m_host.AddScriptLPS(1); 8711 m_host.AddScriptLPS(1);
7803 UUID objID = UUID.Zero; 8712 UUID objID = UUID.Zero;
7804 LSL_List result = new LSL_List(); 8713 LSL_List result = new LSL_List();
8714
8715 // If the ID is not valid, return null result
7805 if (!UUID.TryParse(obj, out objID)) 8716 if (!UUID.TryParse(obj, out objID))
7806 { 8717 {
7807 result.Add(new LSL_Vector()); 8718 result.Add(new LSL_Vector());
7808 result.Add(new LSL_Vector()); 8719 result.Add(new LSL_Vector());
7809 return result; 8720 return result;
7810 } 8721 }
8722
8723 // Check if this is an attached prim. If so, replace
8724 // the UUID with the avatar UUID and report it's bounding box
8725 SceneObjectPart part = World.GetSceneObjectPart(objID);
8726 if (part != null && part.ParentGroup.IsAttachment)
8727 objID = part.ParentGroup.AttachedAvatar;
8728
8729 // Find out if this is an avatar ID. If so, return it's box
7811 ScenePresence presence = World.GetScenePresence(objID); 8730 ScenePresence presence = World.GetScenePresence(objID);
7812 if (presence != null) 8731 if (presence != null)
7813 { 8732 {
7814 if (presence.ParentID == 0) // not sat on an object 8733 // As per LSL Wiki, there is no difference between sitting
8734 // and standing avatar since server 1.36
8735 LSL_Vector lower;
8736 LSL_Vector upper;
8737 if (presence.Animator.Animations.DefaultAnimation.AnimID
8738 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7815 { 8739 {
7816 LSL_Vector lower; 8740 // This is for ground sitting avatars
7817 LSL_Vector upper; 8741 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7818 if (presence.Animator.Animations.DefaultAnimation.AnimID 8742 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7819 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8743 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7820 {
7821 // This is for ground sitting avatars
7822 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7823 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7824 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7825 }
7826 else
7827 {
7828 // This is for standing/flying avatars
7829 float height = presence.Appearance.AvatarHeight / 2.0f;
7830 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7831 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7832 }
7833 result.Add(lower);
7834 result.Add(upper);
7835 return result;
7836 } 8744 }
7837 else 8745 else
7838 { 8746 {
7839 // sitting on an object so we need the bounding box of that 8747 // This is for standing/flying avatars
7840 // which should include the avatar so set the UUID to the 8748 float height = presence.Appearance.AvatarHeight / 2.0f;
7841 // UUID of the object the avatar is sat on and allow it to fall through 8749 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7842 // to processing an object 8750 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7843 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7844 objID = p.UUID;
7845 } 8751 }
8752
8753 // Adjust to the documented error offsets (see LSL Wiki)
8754 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8755 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8756
8757 if (lower.x > upper.x)
8758 lower.x = upper.x;
8759 if (lower.y > upper.y)
8760 lower.y = upper.y;
8761 if (lower.z > upper.z)
8762 lower.z = upper.z;
8763
8764 result.Add(lower);
8765 result.Add(upper);
8766 return result;
7846 } 8767 }
7847 SceneObjectPart part = World.GetSceneObjectPart(objID); 8768
8769 part = World.GetSceneObjectPart(objID);
7848 // Currently only works for single prims without a sitting avatar 8770 // Currently only works for single prims without a sitting avatar
7849 if (part != null) 8771 if (part != null)
7850 { 8772 {
7851 Vector3 halfSize = part.Scale / 2.0f; 8773 float minX;
7852 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8774 float maxX;
7853 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8775 float minY;
8776 float maxY;
8777 float minZ;
8778 float maxZ;
8779
8780 // This BBox is in sim coordinates, with the offset being
8781 // a contained point.
8782 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8783 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8784
8785 minX -= offsets[0].X;
8786 maxX -= offsets[0].X;
8787 minY -= offsets[0].Y;
8788 maxY -= offsets[0].Y;
8789 minZ -= offsets[0].Z;
8790 maxZ -= offsets[0].Z;
8791
8792 LSL_Vector lower;
8793 LSL_Vector upper;
8794
8795 // Adjust to the documented error offsets (see LSL Wiki)
8796 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8797 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8798
8799 if (lower.x > upper.x)
8800 lower.x = upper.x;
8801 if (lower.y > upper.y)
8802 lower.y = upper.y;
8803 if (lower.z > upper.z)
8804 lower.z = upper.z;
8805
7854 result.Add(lower); 8806 result.Add(lower);
7855 result.Add(upper); 8807 result.Add(upper);
7856 return result; 8808 return result;
@@ -7864,7 +8816,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7864 8816
7865 public LSL_Vector llGetGeometricCenter() 8817 public LSL_Vector llGetGeometricCenter()
7866 { 8818 {
7867 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8819 Vector3 tmp = m_host.GetGeometricCenter();
8820 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7868 } 8821 }
7869 8822
7870 public LSL_List llGetPrimitiveParams(LSL_List rules) 8823 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7877,16 +8830,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7877 { 8830 {
7878 m_host.AddScriptLPS(1); 8831 m_host.AddScriptLPS(1);
7879 8832
8833 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8834 // keep other options as before
8835
7880 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8836 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8837 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7881 8838
7882 LSL_List res = new LSL_List(); 8839 LSL_List res = new LSL_List();
7883 8840
7884 foreach (var part in parts) 8841 if (parts.Count > 0)
7885 { 8842 {
7886 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8843 foreach (var part in parts)
7887 res += partRes; 8844 {
8845 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8846 res += partRes;
8847 }
8848 }
8849 if (avatars.Count > 0)
8850 {
8851 foreach (ScenePresence avatar in avatars)
8852 {
8853 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8854 res += avaRes;
8855 }
7888 } 8856 }
8857 return res;
8858 }
8859
8860 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8861 {
8862 // avatars case
8863 // replies as SL wiki
8864
8865 LSL_List res = new LSL_List();
8866// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8867 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8868
8869 int idx = 0;
8870 while (idx < rules.Length)
8871 {
8872 int code = (int)rules.GetLSLIntegerItem(idx++);
8873 int remain = rules.Length - idx;
8874
8875 switch (code)
8876 {
8877 case (int)ScriptBaseClass.PRIM_MATERIAL:
8878 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8879 break;
8880
8881 case (int)ScriptBaseClass.PRIM_PHYSICS:
8882 res.Add(new LSL_Integer(0));
8883 break;
8884
8885 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8886 res.Add(new LSL_Integer(0));
8887 break;
8888
8889 case (int)ScriptBaseClass.PRIM_PHANTOM:
8890 res.Add(new LSL_Integer(0));
8891 break;
8892
8893 case (int)ScriptBaseClass.PRIM_POSITION:
8894
8895 Vector3 pos = avatar.OffsetPosition;
8896
8897 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8898 pos -= sitOffset;
8899
8900 if( sitPart != null)
8901 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8902
8903 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8904 break;
8905
8906 case (int)ScriptBaseClass.PRIM_SIZE:
8907 // as in llGetAgentSize above
8908 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8909 break;
8910
8911 case (int)ScriptBaseClass.PRIM_ROTATION:
8912 Quaternion rot = avatar.Rotation;
8913 if (sitPart != null)
8914 {
8915 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8916 }
7889 8917
8918 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8919 break;
8920
8921 case (int)ScriptBaseClass.PRIM_TYPE:
8922 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8923 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8924 res.Add(new LSL_Vector(0f,1.0f,0f));
8925 res.Add(new LSL_Float(0.0f));
8926 res.Add(new LSL_Vector(0, 0, 0));
8927 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8928 res.Add(new LSL_Vector(0, 0, 0));
8929 break;
8930
8931 case (int)ScriptBaseClass.PRIM_TEXTURE:
8932 if (remain < 1)
8933 return res;
8934
8935 int face = (int)rules.GetLSLIntegerItem(idx++);
8936 if (face == ScriptBaseClass.ALL_SIDES)
8937 {
8938 for (face = 0; face < 21; face++)
8939 {
8940 res.Add(new LSL_String(""));
8941 res.Add(new LSL_Vector(0,0,0));
8942 res.Add(new LSL_Vector(0,0,0));
8943 res.Add(new LSL_Float(0.0));
8944 }
8945 }
8946 else
8947 {
8948 if (face >= 0 && face < 21)
8949 {
8950 res.Add(new LSL_String(""));
8951 res.Add(new LSL_Vector(0,0,0));
8952 res.Add(new LSL_Vector(0,0,0));
8953 res.Add(new LSL_Float(0.0));
8954 }
8955 }
8956 break;
8957
8958 case (int)ScriptBaseClass.PRIM_COLOR:
8959 if (remain < 1)
8960 return res;
8961
8962 face = (int)rules.GetLSLIntegerItem(idx++);
8963
8964 if (face == ScriptBaseClass.ALL_SIDES)
8965 {
8966 for (face = 0; face < 21; face++)
8967 {
8968 res.Add(new LSL_Vector(0,0,0));
8969 res.Add(new LSL_Float(0));
8970 }
8971 }
8972 else
8973 {
8974 res.Add(new LSL_Vector(0,0,0));
8975 res.Add(new LSL_Float(0));
8976 }
8977 break;
8978
8979 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8980 if (remain < 1)
8981 return res;
8982 face = (int)rules.GetLSLIntegerItem(idx++);
8983
8984 if (face == ScriptBaseClass.ALL_SIDES)
8985 {
8986 for (face = 0; face < 21; face++)
8987 {
8988 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8989 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8990 }
8991 }
8992 else
8993 {
8994 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8995 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8996 }
8997 break;
8998
8999 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9000 if (remain < 1)
9001 return res;
9002 face = (int)rules.GetLSLIntegerItem(idx++);
9003
9004 if (face == ScriptBaseClass.ALL_SIDES)
9005 {
9006 for (face = 0; face < 21; face++)
9007 {
9008 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9009 }
9010 }
9011 else
9012 {
9013 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9014 }
9015 break;
9016
9017 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9018 res.Add(new LSL_Integer(0));
9019 res.Add(new LSL_Integer(0));// softness
9020 res.Add(new LSL_Float(0.0f)); // gravity
9021 res.Add(new LSL_Float(0.0f)); // friction
9022 res.Add(new LSL_Float(0.0f)); // wind
9023 res.Add(new LSL_Float(0.0f)); // tension
9024 res.Add(new LSL_Vector(0f,0f,0f));
9025 break;
9026
9027 case (int)ScriptBaseClass.PRIM_TEXGEN:
9028 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9029 if (remain < 1)
9030 return res;
9031 face = (int)rules.GetLSLIntegerItem(idx++);
9032
9033 if (face == ScriptBaseClass.ALL_SIDES)
9034 {
9035 for (face = 0; face < 21; face++)
9036 {
9037 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9038 }
9039 }
9040 else
9041 {
9042 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9043 }
9044 break;
9045
9046 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9047 res.Add(new LSL_Integer(0));
9048 res.Add(new LSL_Vector(0f,0f,0f));
9049 res.Add(new LSL_Float(0f)); // intensity
9050 res.Add(new LSL_Float(0f)); // radius
9051 res.Add(new LSL_Float(0f)); // falloff
9052 break;
9053
9054 case (int)ScriptBaseClass.PRIM_GLOW:
9055 if (remain < 1)
9056 return res;
9057 face = (int)rules.GetLSLIntegerItem(idx++);
9058
9059 if (face == ScriptBaseClass.ALL_SIDES)
9060 {
9061 for (face = 0; face < 21; face++)
9062 {
9063 res.Add(new LSL_Float(0f));
9064 }
9065 }
9066 else
9067 {
9068 res.Add(new LSL_Float(0f));
9069 }
9070 break;
9071
9072 case (int)ScriptBaseClass.PRIM_TEXT:
9073 res.Add(new LSL_String(""));
9074 res.Add(new LSL_Vector(0f,0f,0f));
9075 res.Add(new LSL_Float(1.0f));
9076 break;
9077
9078 case (int)ScriptBaseClass.PRIM_NAME:
9079 res.Add(new LSL_String(avatar.Name));
9080 break;
9081
9082 case (int)ScriptBaseClass.PRIM_DESC:
9083 res.Add(new LSL_String(""));
9084 break;
9085
9086 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9087 Quaternion lrot = avatar.Rotation;
9088
9089 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9090 {
9091 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9092 }
9093 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9094 break;
9095
9096 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9097 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9098 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9099 lpos -= lsitOffset;
9100
9101 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9102 {
9103 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9104 }
9105 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9106 break;
9107
9108 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9109 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9110 return res;
9111 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9112 LSL_List new_rules = rules.GetSublist(idx, -1);
9113
9114 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9115 return res;
9116 }
9117 }
7890 return res; 9118 return res;
7891 } 9119 }
7892 9120
@@ -7930,13 +9158,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7930 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9158 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7931 part.AbsolutePosition.Y, 9159 part.AbsolutePosition.Y,
7932 part.AbsolutePosition.Z); 9160 part.AbsolutePosition.Z);
7933 // For some reason, the part.AbsolutePosition.* values do not change if the
7934 // linkset is rotated; they always reflect the child prim's world position
7935 // as though the linkset is unrotated. This is incompatible behavior with SL's
7936 // implementation, so will break scripts imported from there (not to mention it
7937 // makes it more difficult to determine a child prim's actual inworld position).
7938 if (part.ParentID != 0)
7939 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7940 res.Add(v); 9161 res.Add(v);
7941 break; 9162 break;
7942 9163
@@ -8107,56 +9328,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8107 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9328 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8108 if (remain < 1) 9329 if (remain < 1)
8109 return res; 9330 return res;
8110 9331 face = (int)rules.GetLSLIntegerItem(idx++);
8111 face=(int)rules.GetLSLIntegerItem(idx++);
8112 9332
8113 tex = part.Shape.Textures; 9333 tex = part.Shape.Textures;
9334 int shiny;
8114 if (face == ScriptBaseClass.ALL_SIDES) 9335 if (face == ScriptBaseClass.ALL_SIDES)
8115 { 9336 {
8116 for (face = 0; face < GetNumberOfSides(part); face++) 9337 for (face = 0; face < GetNumberOfSides(part); face++)
8117 { 9338 {
8118 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9339 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8119 // Convert Shininess to PRIM_SHINY_* 9340 if (shinyness == Shininess.High)
8120 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9341 {
8121 // PRIM_BUMP_* 9342 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8122 res.Add(new LSL_Integer((int)texface.Bump)); 9343 }
9344 else if (shinyness == Shininess.Medium)
9345 {
9346 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9347 }
9348 else if (shinyness == Shininess.Low)
9349 {
9350 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9351 }
9352 else
9353 {
9354 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9355 }
9356 res.Add(new LSL_Integer(shiny));
9357 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8123 } 9358 }
8124 } 9359 }
8125 else 9360 else
8126 { 9361 {
8127 if (face >= 0 && face < GetNumberOfSides(part)) 9362 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9363 if (shinyness == Shininess.High)
8128 { 9364 {
8129 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9365 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8130 // Convert Shininess to PRIM_SHINY_* 9366 }
8131 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9367 else if (shinyness == Shininess.Medium)
8132 // PRIM_BUMP_* 9368 {
8133 res.Add(new LSL_Integer((int)texface.Bump)); 9369 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9370 }
9371 else if (shinyness == Shininess.Low)
9372 {
9373 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8134 } 9374 }
9375 else
9376 {
9377 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9378 }
9379 res.Add(new LSL_Integer(shiny));
9380 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8135 } 9381 }
8136 break; 9382 break;
8137 9383
8138 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9384 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8139 if (remain < 1) 9385 if (remain < 1)
8140 return res; 9386 return res;
8141 9387 face = (int)rules.GetLSLIntegerItem(idx++);
8142 face=(int)rules.GetLSLIntegerItem(idx++);
8143 9388
8144 tex = part.Shape.Textures; 9389 tex = part.Shape.Textures;
9390 int fullbright;
8145 if (face == ScriptBaseClass.ALL_SIDES) 9391 if (face == ScriptBaseClass.ALL_SIDES)
8146 { 9392 {
8147 for (face = 0; face < GetNumberOfSides(part); face++) 9393 for (face = 0; face < GetNumberOfSides(part); face++)
8148 { 9394 {
8149 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9395 if (tex.GetFace((uint)face).Fullbright == true)
8150 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9396 {
9397 fullbright = ScriptBaseClass.TRUE;
9398 }
9399 else
9400 {
9401 fullbright = ScriptBaseClass.FALSE;
9402 }
9403 res.Add(new LSL_Integer(fullbright));
8151 } 9404 }
8152 } 9405 }
8153 else 9406 else
8154 { 9407 {
8155 if (face >= 0 && face < GetNumberOfSides(part)) 9408 if (tex.GetFace((uint)face).Fullbright == true)
8156 { 9409 {
8157 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9410 fullbright = ScriptBaseClass.TRUE;
8158 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8159 } 9411 }
9412 else
9413 {
9414 fullbright = ScriptBaseClass.FALSE;
9415 }
9416 res.Add(new LSL_Integer(fullbright));
8160 } 9417 }
8161 break; 9418 break;
8162 9419
@@ -8178,27 +9435,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8178 break; 9435 break;
8179 9436
8180 case (int)ScriptBaseClass.PRIM_TEXGEN: 9437 case (int)ScriptBaseClass.PRIM_TEXGEN:
9438 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8181 if (remain < 1) 9439 if (remain < 1)
8182 return res; 9440 return res;
8183 9441 face = (int)rules.GetLSLIntegerItem(idx++);
8184 face=(int)rules.GetLSLIntegerItem(idx++);
8185 9442
8186 tex = part.Shape.Textures; 9443 tex = part.Shape.Textures;
8187 if (face == ScriptBaseClass.ALL_SIDES) 9444 if (face == ScriptBaseClass.ALL_SIDES)
8188 { 9445 {
8189 for (face = 0; face < GetNumberOfSides(part); face++) 9446 for (face = 0; face < GetNumberOfSides(part); face++)
8190 { 9447 {
8191 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9448 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8192 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9449 {
8193 res.Add(new LSL_Integer((uint)texgen >> 1)); 9450 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9451 }
9452 else
9453 {
9454 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9455 }
8194 } 9456 }
8195 } 9457 }
8196 else 9458 else
8197 { 9459 {
8198 if (face >= 0 && face < GetNumberOfSides(part)) 9460 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8199 { 9461 {
8200 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9462 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8201 res.Add(new LSL_Integer((uint)texgen >> 1)); 9463 }
9464 else
9465 {
9466 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8202 } 9467 }
8203 } 9468 }
8204 break; 9469 break;
@@ -8221,25 +9486,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8221 case (int)ScriptBaseClass.PRIM_GLOW: 9486 case (int)ScriptBaseClass.PRIM_GLOW:
8222 if (remain < 1) 9487 if (remain < 1)
8223 return res; 9488 return res;
8224 9489 face = (int)rules.GetLSLIntegerItem(idx++);
8225 face=(int)rules.GetLSLIntegerItem(idx++);
8226 9490
8227 tex = part.Shape.Textures; 9491 tex = part.Shape.Textures;
9492 float primglow;
8228 if (face == ScriptBaseClass.ALL_SIDES) 9493 if (face == ScriptBaseClass.ALL_SIDES)
8229 { 9494 {
8230 for (face = 0; face < GetNumberOfSides(part); face++) 9495 for (face = 0; face < GetNumberOfSides(part); face++)
8231 { 9496 {
8232 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9497 primglow = tex.GetFace((uint)face).Glow;
8233 res.Add(new LSL_Float(texface.Glow)); 9498 res.Add(new LSL_Float(primglow));
8234 } 9499 }
8235 } 9500 }
8236 else 9501 else
8237 { 9502 {
8238 if (face >= 0 && face < GetNumberOfSides(part)) 9503 primglow = tex.GetFace((uint)face).Glow;
8239 { 9504 res.Add(new LSL_Float(primglow));
8240 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8241 res.Add(new LSL_Float(texface.Glow));
8242 }
8243 } 9505 }
8244 break; 9506 break;
8245 9507
@@ -8251,18 +9513,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8251 textColor.B)); 9513 textColor.B));
8252 res.Add(new LSL_Float(textColor.A)); 9514 res.Add(new LSL_Float(textColor.A));
8253 break; 9515 break;
9516
8254 case (int)ScriptBaseClass.PRIM_NAME: 9517 case (int)ScriptBaseClass.PRIM_NAME:
8255 res.Add(new LSL_String(part.Name)); 9518 res.Add(new LSL_String(part.Name));
8256 break; 9519 break;
9520
8257 case (int)ScriptBaseClass.PRIM_DESC: 9521 case (int)ScriptBaseClass.PRIM_DESC:
8258 res.Add(new LSL_String(part.Description)); 9522 res.Add(new LSL_String(part.Description));
8259 break; 9523 break;
9524
8260 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9525 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8261 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9526 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8262 break; 9527 break;
9528
8263 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9529 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8264 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9530 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8265 break; 9531 break;
9532
9533 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9534 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9535 return res;
9536 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9537 LSL_List new_rules = rules.GetSublist(idx, -1);
9538 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9539 res += tres;
9540 return res;
8266 } 9541 }
8267 } 9542 }
8268 return res; 9543 return res;
@@ -8855,8 +10130,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8855 // The function returns an ordered list 10130 // The function returns an ordered list
8856 // representing the tokens found in the supplied 10131 // representing the tokens found in the supplied
8857 // sources string. If two successive tokenizers 10132 // sources string. If two successive tokenizers
8858 // are encountered, then a NULL entry is added 10133 // are encountered, then a null-string entry is
8859 // to the list. 10134 // added to the list.
8860 // 10135 //
8861 // It is a precondition that the source and 10136 // It is a precondition that the source and
8862 // toekizer lisst are non-null. If they are null, 10137 // toekizer lisst are non-null. If they are null,
@@ -8864,7 +10139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8864 // while their lengths are being determined. 10139 // while their lengths are being determined.
8865 // 10140 //
8866 // A small amount of working memoryis required 10141 // A small amount of working memoryis required
8867 // of approximately 8*#tokenizers. 10142 // of approximately 8*#tokenizers + 8*srcstrlen.
8868 // 10143 //
8869 // There are many ways in which this function 10144 // There are many ways in which this function
8870 // can be implemented, this implementation is 10145 // can be implemented, this implementation is
@@ -8880,155 +10155,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8880 // and eliminates redundant tokenizers as soon 10155 // and eliminates redundant tokenizers as soon
8881 // as is possible. 10156 // as is possible.
8882 // 10157 //
8883 // The implementation tries to avoid any copying 10158 // The implementation tries to minimize temporary
8884 // of arrays or other objects. 10159 // garbage generation.
8885 // </remarks> 10160 // </remarks>
8886 10161
8887 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10162 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8888 { 10163 {
8889 int beginning = 0; 10164 return ParseString2List(src, separators, spacers, true);
8890 int srclen = src.Length; 10165 }
8891 int seplen = separators.Length;
8892 object[] separray = separators.Data;
8893 int spclen = spacers.Length;
8894 object[] spcarray = spacers.Data;
8895 int mlen = seplen+spclen;
8896
8897 int[] offset = new int[mlen+1];
8898 bool[] active = new bool[mlen];
8899
8900 int best;
8901 int j;
8902
8903 // Initial capacity reduces resize cost
8904 10166
8905 LSL_List tokens = new LSL_List(); 10167 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10168 {
10169 int srclen = src.Length;
10170 int seplen = separators.Length;
10171 object[] separray = separators.Data;
10172 int spclen = spacers.Length;
10173 object[] spcarray = spacers.Data;
10174 int dellen = 0;
10175 string[] delarray = new string[seplen+spclen];
8906 10176
8907 // All entries are initially valid 10177 int outlen = 0;
10178 string[] outarray = new string[srclen*2+1];
8908 10179
8909 for (int i = 0; i < mlen; i++) 10180 int i, j;
8910 active[i] = true; 10181 string d;
8911 10182
8912 offset[mlen] = srclen; 10183 m_host.AddScriptLPS(1);
8913 10184
8914 while (beginning < srclen) 10185 /*
10186 * Convert separator and spacer lists to C# strings.
10187 * Also filter out null strings so we don't hang.
10188 */
10189 for (i = 0; i < seplen; i ++)
8915 { 10190 {
10191 d = separray[i].ToString();
10192 if (d.Length > 0)
10193 {
10194 delarray[dellen++] = d;
10195 }
10196 }
10197 seplen = dellen;
8916 10198
8917 best = mlen; // as bad as it gets 10199 for (i = 0; i < spclen; i ++)
10200 {
10201 d = spcarray[i].ToString();
10202 if (d.Length > 0)
10203 {
10204 delarray[dellen++] = d;
10205 }
10206 }
8918 10207
8919 // Scan for separators 10208 /*
10209 * Scan through source string from beginning to end.
10210 */
10211 for (i = 0;;)
10212 {
8920 10213
8921 for (j = 0; j < seplen; j++) 10214 /*
10215 * Find earliest delimeter in src starting at i (if any).
10216 */
10217 int earliestDel = -1;
10218 int earliestSrc = srclen;
10219 string earliestStr = null;
10220 for (j = 0; j < dellen; j ++)
8922 { 10221 {
8923 if (separray[j].ToString() == String.Empty) 10222 d = delarray[j];
8924 active[j] = false; 10223 if (d != null)
8925
8926 if (active[j])
8927 { 10224 {
8928 // scan all of the markers 10225 int index = src.IndexOf(d, i);
8929 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10226 if (index < 0)
8930 { 10227 {
8931 // not present at all 10228 delarray[j] = null; // delim nowhere in src, don't check it anymore
8932 active[j] = false;
8933 } 10229 }
8934 else 10230 else if (index < earliestSrc)
8935 { 10231 {
8936 // present and correct 10232 earliestSrc = index; // where delimeter starts in source string
8937 if (offset[j] < offset[best]) 10233 earliestDel = j; // where delimeter is in delarray[]
8938 { 10234 earliestStr = d; // the delimeter string from delarray[]
8939 // closest so far 10235 if (index == i) break; // can't do any better than found at beg of string
8940 best = j;
8941 if (offset[best] == beginning)
8942 break;
8943 }
8944 } 10236 }
8945 } 10237 }
8946 } 10238 }
8947 10239
8948 // Scan for spacers 10240 /*
8949 10241 * Output source string starting at i through start of earliest delimeter.
8950 if (offset[best] != beginning) 10242 */
10243 if (keepNulls || (earliestSrc > i))
8951 { 10244 {
8952 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10245 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8953 {
8954 if (spcarray[j-seplen].ToString() == String.Empty)
8955 active[j] = false;
8956
8957 if (active[j])
8958 {
8959 // scan all of the markers
8960 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8961 {
8962 // not present at all
8963 active[j] = false;
8964 }
8965 else
8966 {
8967 // present and correct
8968 if (offset[j] < offset[best])
8969 {
8970 // closest so far
8971 best = j;
8972 }
8973 }
8974 }
8975 }
8976 } 10246 }
8977 10247
8978 // This is the normal exit from the scanning loop 10248 /*
10249 * If no delimeter found at or after i, we're done scanning.
10250 */
10251 if (earliestDel < 0) break;
8979 10252
8980 if (best == mlen) 10253 /*
10254 * If delimeter was a spacer, output the spacer.
10255 */
10256 if (earliestDel >= seplen)
8981 { 10257 {
8982 // no markers were found on this pass 10258 outarray[outlen++] = earliestStr;
8983 // so we're pretty much done
8984 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8985 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8986 break;
8987 } 10259 }
8988 10260
8989 // Otherwise we just add the newly delimited token 10261 /*
8990 // and recalculate where the search should continue. 10262 * Look at rest of src string following delimeter.
8991 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10263 */
8992 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10264 i = earliestSrc + earliestStr.Length;
8993
8994 if (best < seplen)
8995 {
8996 beginning = offset[best] + (separray[best].ToString()).Length;
8997 }
8998 else
8999 {
9000 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9001 string str = spcarray[best - seplen].ToString();
9002 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9003 tokens.Add(new LSL_String(str));
9004 }
9005 } 10265 }
9006 10266
9007 // This an awkward an not very intuitive boundary case. If the 10267 /*
9008 // last substring is a tokenizer, then there is an implied trailing 10268 * Make up an exact-sized output array suitable for an LSL_List object.
9009 // null list entry. Hopefully the single comparison will not be too 10269 */
9010 // arduous. Alternatively the 'break' could be replced with a return 10270 object[] outlist = new object[outlen];
9011 // but that's shabby programming. 10271 for (i = 0; i < outlen; i ++)
9012
9013 if ((beginning == srclen) && (keepNulls))
9014 { 10272 {
9015 if (srclen != 0) 10273 outlist[i] = new LSL_String(outarray[i]);
9016 tokens.Add(new LSL_String(""));
9017 } 10274 }
9018 10275 return new LSL_List(outlist);
9019 return tokens;
9020 }
9021
9022 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9023 {
9024 m_host.AddScriptLPS(1);
9025 return this.ParseString(src, separators, spacers, false);
9026 }
9027
9028 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9029 {
9030 m_host.AddScriptLPS(1);
9031 return this.ParseString(src, separators, spacers, true);
9032 } 10276 }
9033 10277
9034 public LSL_Integer llGetObjectPermMask(int mask) 10278 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9123,6 +10367,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9123 case 4: 10367 case 4:
9124 return (int)item.NextPermissions; 10368 return (int)item.NextPermissions;
9125 } 10369 }
10370 m_host.TaskInventory.LockItemsForRead(false);
9126 10371
9127 return -1; 10372 return -1;
9128 } 10373 }
@@ -9313,9 +10558,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9313 { 10558 {
9314 try 10559 try
9315 { 10560 {
10561 /*
9316 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10562 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9317 if (obj != null) 10563 if (obj != null)
9318 return (double)obj.GetMass(); 10564 return (double)obj.GetMass();
10565 */
10566 // return total object mass
10567 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10568 if (obj != null)
10569 return obj.GetMass();
10570
9319 // the object is null so the key is for an avatar 10571 // the object is null so the key is for an avatar
9320 ScenePresence avatar = World.GetScenePresence(key); 10572 ScenePresence avatar = World.GetScenePresence(key);
9321 if (avatar != null) 10573 if (avatar != null)
@@ -9335,7 +10587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9335 } 10587 }
9336 10588
9337 /// <summary> 10589 /// <summary>
9338 /// illListReplaceList removes the sub-list defined by the inclusive indices 10590 /// llListReplaceList removes the sub-list defined by the inclusive indices
9339 /// start and end and inserts the src list in its place. The inclusive 10591 /// start and end and inserts the src list in its place. The inclusive
9340 /// nature of the indices means that at least one element must be deleted 10592 /// nature of the indices means that at least one element must be deleted
9341 /// if the indices are within the bounds of the existing list. I.e. 2,2 10593 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9392,16 +10644,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9392 // based upon end. Note that if end exceeds the upper 10644 // based upon end. Note that if end exceeds the upper
9393 // bound in this case, the entire destination list 10645 // bound in this case, the entire destination list
9394 // is removed. 10646 // is removed.
9395 else 10647 else if (start == 0)
9396 { 10648 {
9397 if (end + 1 < dest.Length) 10649 if (end + 1 < dest.Length)
9398 {
9399 return src + dest.GetSublist(end + 1, -1); 10650 return src + dest.GetSublist(end + 1, -1);
9400 }
9401 else 10651 else
9402 {
9403 return src; 10652 return src;
9404 } 10653 }
10654 else // Start < 0
10655 {
10656 if (end + 1 < dest.Length)
10657 return dest.GetSublist(end + 1, -1);
10658 else
10659 return new LSL_List();
9405 } 10660 }
9406 } 10661 }
9407 // Finally, if start > end, we strip away a prefix and 10662 // Finally, if start > end, we strip away a prefix and
@@ -9452,17 +10707,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9452 int width = 0; 10707 int width = 0;
9453 int height = 0; 10708 int height = 0;
9454 10709
9455 ParcelMediaCommandEnum? commandToSend = null; 10710 uint commandToSend = 0;
9456 float time = 0.0f; // default is from start 10711 float time = 0.0f; // default is from start
9457 10712
9458 ScenePresence presence = null; 10713 ScenePresence presence = null;
9459 10714
9460 for (int i = 0; i < commandList.Data.Length; i++) 10715 for (int i = 0; i < commandList.Data.Length; i++)
9461 { 10716 {
9462 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10717 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9463 switch (command) 10718 switch (command)
9464 { 10719 {
9465 case ParcelMediaCommandEnum.Agent: 10720 case (uint)ParcelMediaCommandEnum.Agent:
9466 // we send only to one agent 10721 // we send only to one agent
9467 if ((i + 1) < commandList.Length) 10722 if ((i + 1) < commandList.Length)
9468 { 10723 {
@@ -9479,25 +10734,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9479 } 10734 }
9480 break; 10735 break;
9481 10736
9482 case ParcelMediaCommandEnum.Loop: 10737 case (uint)ParcelMediaCommandEnum.Loop:
9483 loop = 1; 10738 loop = 1;
9484 commandToSend = command; 10739 commandToSend = command;
9485 update = true; //need to send the media update packet to set looping 10740 update = true; //need to send the media update packet to set looping
9486 break; 10741 break;
9487 10742
9488 case ParcelMediaCommandEnum.Play: 10743 case (uint)ParcelMediaCommandEnum.Play:
9489 loop = 0; 10744 loop = 0;
9490 commandToSend = command; 10745 commandToSend = command;
9491 update = true; //need to send the media update packet to make sure it doesn't loop 10746 update = true; //need to send the media update packet to make sure it doesn't loop
9492 break; 10747 break;
9493 10748
9494 case ParcelMediaCommandEnum.Pause: 10749 case (uint)ParcelMediaCommandEnum.Pause:
9495 case ParcelMediaCommandEnum.Stop: 10750 case (uint)ParcelMediaCommandEnum.Stop:
9496 case ParcelMediaCommandEnum.Unload: 10751 case (uint)ParcelMediaCommandEnum.Unload:
9497 commandToSend = command; 10752 commandToSend = command;
9498 break; 10753 break;
9499 10754
9500 case ParcelMediaCommandEnum.Url: 10755 case (uint)ParcelMediaCommandEnum.Url:
9501 if ((i + 1) < commandList.Length) 10756 if ((i + 1) < commandList.Length)
9502 { 10757 {
9503 if (commandList.Data[i + 1] is LSL_String) 10758 if (commandList.Data[i + 1] is LSL_String)
@@ -9510,7 +10765,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9510 } 10765 }
9511 break; 10766 break;
9512 10767
9513 case ParcelMediaCommandEnum.Texture: 10768 case (uint)ParcelMediaCommandEnum.Texture:
9514 if ((i + 1) < commandList.Length) 10769 if ((i + 1) < commandList.Length)
9515 { 10770 {
9516 if (commandList.Data[i + 1] is LSL_String) 10771 if (commandList.Data[i + 1] is LSL_String)
@@ -9523,7 +10778,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9523 } 10778 }
9524 break; 10779 break;
9525 10780
9526 case ParcelMediaCommandEnum.Time: 10781 case (uint)ParcelMediaCommandEnum.Time:
9527 if ((i + 1) < commandList.Length) 10782 if ((i + 1) < commandList.Length)
9528 { 10783 {
9529 if (commandList.Data[i + 1] is LSL_Float) 10784 if (commandList.Data[i + 1] is LSL_Float)
@@ -9535,7 +10790,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9535 } 10790 }
9536 break; 10791 break;
9537 10792
9538 case ParcelMediaCommandEnum.AutoAlign: 10793 case (uint)ParcelMediaCommandEnum.AutoAlign:
9539 if ((i + 1) < commandList.Length) 10794 if ((i + 1) < commandList.Length)
9540 { 10795 {
9541 if (commandList.Data[i + 1] is LSL_Integer) 10796 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9549,7 +10804,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9549 } 10804 }
9550 break; 10805 break;
9551 10806
9552 case ParcelMediaCommandEnum.Type: 10807 case (uint)ParcelMediaCommandEnum.Type:
9553 if ((i + 1) < commandList.Length) 10808 if ((i + 1) < commandList.Length)
9554 { 10809 {
9555 if (commandList.Data[i + 1] is LSL_String) 10810 if (commandList.Data[i + 1] is LSL_String)
@@ -9562,7 +10817,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9562 } 10817 }
9563 break; 10818 break;
9564 10819
9565 case ParcelMediaCommandEnum.Desc: 10820 case (uint)ParcelMediaCommandEnum.Desc:
9566 if ((i + 1) < commandList.Length) 10821 if ((i + 1) < commandList.Length)
9567 { 10822 {
9568 if (commandList.Data[i + 1] is LSL_String) 10823 if (commandList.Data[i + 1] is LSL_String)
@@ -9575,7 +10830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9575 } 10830 }
9576 break; 10831 break;
9577 10832
9578 case ParcelMediaCommandEnum.Size: 10833 case (uint)ParcelMediaCommandEnum.Size:
9579 if ((i + 2) < commandList.Length) 10834 if ((i + 2) < commandList.Length)
9580 { 10835 {
9581 if (commandList.Data[i + 1] is LSL_Integer) 10836 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9645,7 +10900,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9645 } 10900 }
9646 } 10901 }
9647 10902
9648 if (commandToSend != null) 10903 if (commandToSend != 0)
9649 { 10904 {
9650 // the commandList contained a start/stop/... command, too 10905 // the commandList contained a start/stop/... command, too
9651 if (presence == null) 10906 if (presence == null)
@@ -9682,7 +10937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9682 10937
9683 if (aList.Data[i] != null) 10938 if (aList.Data[i] != null)
9684 { 10939 {
9685 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10940 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9686 { 10941 {
9687 case ParcelMediaCommandEnum.Url: 10942 case ParcelMediaCommandEnum.Url:
9688 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10943 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9739,15 +10994,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9739 10994
9740 if (quick_pay_buttons.Data.Length < 4) 10995 if (quick_pay_buttons.Data.Length < 4)
9741 { 10996 {
9742 LSLError("List must have at least 4 elements"); 10997 int x;
9743 return; 10998 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10999 {
11000 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
11001 }
9744 } 11002 }
9745 m_host.ParentGroup.RootPart.PayPrice[0]=price; 11003 int[] nPrice = new int[5];
9746 11004 nPrice[0] = price;
9747 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 11005 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9748 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11006 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9749 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11007 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9750 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11008 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11009 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9751 m_host.ParentGroup.HasGroupChanged = true; 11010 m_host.ParentGroup.HasGroupChanged = true;
9752 } 11011 }
9753 11012
@@ -9764,7 +11023,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9764 return new LSL_Vector(); 11023 return new LSL_Vector();
9765 } 11024 }
9766 11025
9767 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11026// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11027 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9768 if (presence != null) 11028 if (presence != null)
9769 { 11029 {
9770 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11030 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9786,7 +11046,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9786 return new LSL_Rotation(); 11046 return new LSL_Rotation();
9787 } 11047 }
9788 11048
9789 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11049// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11050 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9790 if (presence != null) 11051 if (presence != null)
9791 { 11052 {
9792 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11053 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9846,8 +11107,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9846 { 11107 {
9847 m_host.AddScriptLPS(1); 11108 m_host.AddScriptLPS(1);
9848 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11109 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9849 if (detectedParams == null) return; // only works on the first detected avatar 11110 if (detectedParams == null)
9850 11111 {
11112 if (m_host.ParentGroup.IsAttachment == true)
11113 {
11114 detectedParams = new DetectParams();
11115 detectedParams.Key = m_host.OwnerID;
11116 }
11117 else
11118 {
11119 return;
11120 }
11121 }
11122
9851 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11123 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9852 if (avatar != null) 11124 if (avatar != null)
9853 { 11125 {
@@ -9855,6 +11127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9855 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11127 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9856 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11128 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9857 } 11129 }
11130
9858 ScriptSleep(1000); 11131 ScriptSleep(1000);
9859 } 11132 }
9860 11133
@@ -9978,12 +11251,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9978 11251
9979 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11252 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9980 object[] data = rules.Data; 11253 object[] data = rules.Data;
9981 for (int i = 0; i < data.Length; ++i) { 11254 for (int i = 0; i < data.Length; ++i)
11255 {
9982 int type = Convert.ToInt32(data[i++].ToString()); 11256 int type = Convert.ToInt32(data[i++].ToString());
9983 if (i >= data.Length) break; // odd number of entries => ignore the last 11257 if (i >= data.Length) break; // odd number of entries => ignore the last
9984 11258
9985 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11259 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9986 switch (type) { 11260 switch (type)
11261 {
9987 case ScriptBaseClass.CAMERA_FOCUS: 11262 case ScriptBaseClass.CAMERA_FOCUS:
9988 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11263 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9989 case ScriptBaseClass.CAMERA_POSITION: 11264 case ScriptBaseClass.CAMERA_POSITION:
@@ -10089,19 +11364,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10089 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11364 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10090 { 11365 {
10091 m_host.AddScriptLPS(1); 11366 m_host.AddScriptLPS(1);
10092 string ret = String.Empty; 11367
10093 string src1 = llBase64ToString(str1); 11368 if (str1 == String.Empty)
10094 string src2 = llBase64ToString(str2); 11369 return String.Empty;
10095 int c = 0; 11370 if (str2 == String.Empty)
10096 for (int i = 0; i < src1.Length; i++) 11371 return str1;
11372
11373 int len = str2.Length;
11374 if ((len % 4) != 0) // LL is EVIL!!!!
11375 {
11376 while (str2.EndsWith("="))
11377 str2 = str2.Substring(0, str2.Length - 1);
11378
11379 len = str2.Length;
11380 int mod = len % 4;
11381
11382 if (mod == 1)
11383 str2 = str2.Substring(0, str2.Length - 1);
11384 else if (mod == 2)
11385 str2 += "==";
11386 else if (mod == 3)
11387 str2 += "=";
11388 }
11389
11390 byte[] data1;
11391 byte[] data2;
11392 try
11393 {
11394 data1 = Convert.FromBase64String(str1);
11395 data2 = Convert.FromBase64String(str2);
11396 }
11397 catch (Exception)
10097 { 11398 {
10098 ret += (char) (src1[i] ^ src2[c]); 11399 return new LSL_String(String.Empty);
11400 }
10099 11401
10100 c++; 11402 byte[] d2 = new Byte[data1.Length];
10101 if (c >= src2.Length) 11403 int pos = 0;
10102 c = 0; 11404
11405 if (data1.Length <= data2.Length)
11406 {
11407 Array.Copy(data2, 0, d2, 0, data1.Length);
10103 } 11408 }
10104 return llStringToBase64(ret); 11409 else
11410 {
11411 while (pos < data1.Length)
11412 {
11413 len = data1.Length - pos;
11414 if (len > data2.Length)
11415 len = data2.Length;
11416
11417 Array.Copy(data2, 0, d2, pos, len);
11418 pos += len;
11419 }
11420 }
11421
11422 for (pos = 0 ; pos < data1.Length ; pos++ )
11423 data1[pos] ^= d2[pos];
11424
11425 return Convert.ToBase64String(data1);
10105 } 11426 }
10106 11427
10107 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11428 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10154,16 +11475,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10154 if (userAgent != null) 11475 if (userAgent != null)
10155 httpHeaders["User-Agent"] = userAgent; 11476 httpHeaders["User-Agent"] = userAgent;
10156 11477
11478 // See if the URL contains any header hacks
11479 string[] urlParts = url.Split(new char[] {'\n'});
11480 if (urlParts.Length > 1)
11481 {
11482 // Iterate the passed headers and parse them
11483 for (int i = 1 ; i < urlParts.Length ; i++ )
11484 {
11485 // The rest of those would be added to the body in SL.
11486 // Let's not do that.
11487 if (urlParts[i] == String.Empty)
11488 break;
11489
11490 // See if this could be a valid header
11491 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11492 if (headerParts.Length != 2)
11493 continue;
11494
11495 string headerName = headerParts[0].Trim();
11496 string headerValue = headerParts[1].Trim();
11497
11498 // Filter out headers that could be used to abuse
11499 // another system or cloak the request
11500 if (headerName.ToLower() == "x-secondlife-shard" ||
11501 headerName.ToLower() == "x-secondlife-object-name" ||
11502 headerName.ToLower() == "x-secondlife-object-key" ||
11503 headerName.ToLower() == "x-secondlife-region" ||
11504 headerName.ToLower() == "x-secondlife-local-position" ||
11505 headerName.ToLower() == "x-secondlife-local-velocity" ||
11506 headerName.ToLower() == "x-secondlife-local-rotation" ||
11507 headerName.ToLower() == "x-secondlife-owner-name" ||
11508 headerName.ToLower() == "x-secondlife-owner-key" ||
11509 headerName.ToLower() == "connection" ||
11510 headerName.ToLower() == "content-length" ||
11511 headerName.ToLower() == "from" ||
11512 headerName.ToLower() == "host" ||
11513 headerName.ToLower() == "proxy-authorization" ||
11514 headerName.ToLower() == "referer" ||
11515 headerName.ToLower() == "trailer" ||
11516 headerName.ToLower() == "transfer-encoding" ||
11517 headerName.ToLower() == "via" ||
11518 headerName.ToLower() == "authorization")
11519 continue;
11520
11521 httpHeaders[headerName] = headerValue;
11522 }
11523
11524 // Finally, strip any protocol specifier from the URL
11525 url = urlParts[0].Trim();
11526 int idx = url.IndexOf(" HTTP/");
11527 if (idx != -1)
11528 url = url.Substring(0, idx);
11529 }
11530
10157 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11531 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10158 Regex r = new Regex(authregex); 11532 Regex r = new Regex(authregex);
10159 int[] gnums = r.GetGroupNumbers(); 11533 int[] gnums = r.GetGroupNumbers();
10160 Match m = r.Match(url); 11534 Match m = r.Match(url);
10161 if (m.Success) { 11535 if (m.Success)
10162 for (int i = 1; i < gnums.Length; i++) { 11536 {
11537 for (int i = 1; i < gnums.Length; i++)
11538 {
10163 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11539 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10164 //CaptureCollection cc = g.Captures; 11540 //CaptureCollection cc = g.Captures;
10165 } 11541 }
10166 if (m.Groups.Count == 5) { 11542 if (m.Groups.Count == 5)
11543 {
10167 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11544 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10168 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11545 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10169 } 11546 }
@@ -10366,6 +11743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10366 11743
10367 LSL_List ret = new LSL_List(); 11744 LSL_List ret = new LSL_List();
10368 UUID key = new UUID(); 11745 UUID key = new UUID();
11746
11747
10369 if (UUID.TryParse(id, out key)) 11748 if (UUID.TryParse(id, out key))
10370 { 11749 {
10371 ScenePresence av = World.GetScenePresence(key); 11750 ScenePresence av = World.GetScenePresence(key);
@@ -10383,13 +11762,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10383 ret.Add(new LSL_String("")); 11762 ret.Add(new LSL_String(""));
10384 break; 11763 break;
10385 case ScriptBaseClass.OBJECT_POS: 11764 case ScriptBaseClass.OBJECT_POS:
10386 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11765 Vector3 avpos;
11766
11767 if (av.ParentID != 0 && av.ParentPart != null)
11768 {
11769 avpos = av.OffsetPosition;
11770
11771 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11772 avpos -= sitOffset;
11773
11774 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11775 }
11776 else
11777 avpos = av.AbsolutePosition;
11778
11779 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10387 break; 11780 break;
10388 case ScriptBaseClass.OBJECT_ROT: 11781 case ScriptBaseClass.OBJECT_ROT:
10389 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11782 Quaternion avrot = av.Rotation;
11783 if (av.ParentID != 0 && av.ParentPart != null)
11784 {
11785 avrot = av.ParentPart.GetWorldRotation() * avrot;
11786 }
11787 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10390 break; 11788 break;
10391 case ScriptBaseClass.OBJECT_VELOCITY: 11789 case ScriptBaseClass.OBJECT_VELOCITY:
10392 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11790 Vector3 avvel = av.Velocity;
11791 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10393 break; 11792 break;
10394 case ScriptBaseClass.OBJECT_OWNER: 11793 case ScriptBaseClass.OBJECT_OWNER:
10395 ret.Add(new LSL_String(id)); 11794 ret.Add(new LSL_String(id));
@@ -10445,11 +11844,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10445 case ScriptBaseClass.OBJECT_NAME: 11844 case ScriptBaseClass.OBJECT_NAME:
10446 ret.Add(new LSL_String(obj.Name)); 11845 ret.Add(new LSL_String(obj.Name));
10447 break; 11846 break;
10448 case ScriptBaseClass.OBJECT_DESC: 11847 case ScriptBaseClass.OBJECT_DESC:
10449 ret.Add(new LSL_String(obj.Description)); 11848 ret.Add(new LSL_String(obj.Description));
10450 break; 11849 break;
10451 case ScriptBaseClass.OBJECT_POS: 11850 case ScriptBaseClass.OBJECT_POS:
10452 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11851 Vector3 opos = obj.AbsolutePosition;
11852 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10453 break; 11853 break;
10454 case ScriptBaseClass.OBJECT_ROT: 11854 case ScriptBaseClass.OBJECT_ROT:
10455 { 11855 {
@@ -10465,7 +11865,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10465 } 11865 }
10466 break; 11866 break;
10467 case ScriptBaseClass.OBJECT_VELOCITY: 11867 case ScriptBaseClass.OBJECT_VELOCITY:
10468 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11868 Vector3 ovel = obj.Velocity;
11869 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10469 break; 11870 break;
10470 case ScriptBaseClass.OBJECT_OWNER: 11871 case ScriptBaseClass.OBJECT_OWNER:
10471 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11872 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10499,9 +11900,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10499 // The value returned in SL for normal prims is prim count 11900 // The value returned in SL for normal prims is prim count
10500 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11901 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10501 break; 11902 break;
10502 // The following 3 costs I have intentionaly coded to return zero. They are part of 11903
10503 // "Land Impact" calculations. These calculations are probably not applicable 11904 // costs below may need to be diferent for root parts, need to check
10504 // to OpenSim and are not yet complete in SL
10505 case ScriptBaseClass.OBJECT_SERVER_COST: 11905 case ScriptBaseClass.OBJECT_SERVER_COST:
10506 // The linden calculation is here 11906 // The linden calculation is here
10507 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11907 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10509,16 +11909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10509 ret.Add(new LSL_Float(0)); 11909 ret.Add(new LSL_Float(0));
10510 break; 11910 break;
10511 case ScriptBaseClass.OBJECT_STREAMING_COST: 11911 case ScriptBaseClass.OBJECT_STREAMING_COST:
10512 // The linden calculation is here 11912 // The value returned in SL for normal prims is prim count * 0.06
10513 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11913 ret.Add(new LSL_Float(obj.StreamingCost));
10514 // The value returned in SL for normal prims looks like the prim count * 0.06
10515 ret.Add(new LSL_Float(0));
10516 break; 11914 break;
10517 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11915 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10518 // The linden calculation is here 11916 // The value returned in SL for normal prims is prim count
10519 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11917 ret.Add(new LSL_Float(obj.PhysicsCost));
10520 // The value returned in SL for normal prims looks like the prim count
10521 ret.Add(new LSL_Float(0));
10522 break; 11918 break;
10523 default: 11919 default:
10524 // Invalid or unhandled constant. 11920 // Invalid or unhandled constant.
@@ -10707,15 +12103,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10707 return GetLinkPrimitiveParams(obj, rules); 12103 return GetLinkPrimitiveParams(obj, rules);
10708 } 12104 }
10709 12105
10710 public void print(string str) 12106 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10711 { 12107 {
10712 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12108 List<SceneObjectPart> parts = GetLinkParts(link);
10713 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12109 if (parts.Count < 1)
10714 if (ossl != null) 12110 return 0;
10715 { 12111
10716 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12112 return GetNumberOfSides(parts[0]);
10717 m_log.Info("LSL print():" + str);
10718 }
10719 } 12113 }
10720 12114
10721 private string Name2Username(string name) 12115 private string Name2Username(string name)
@@ -10760,7 +12154,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10760 12154
10761 return rq.ToString(); 12155 return rq.ToString();
10762 } 12156 }
10763 12157/*
12158 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12159 {
12160 m_SayShoutCount = 0;
12161 }
12162*/
10764 private struct Tri 12163 private struct Tri
10765 { 12164 {
10766 public Vector3 p1; 12165 public Vector3 p1;
@@ -10900,9 +12299,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10900 12299
10901 ContactResult result = new ContactResult (); 12300 ContactResult result = new ContactResult ();
10902 result.ConsumerID = group.LocalId; 12301 result.ConsumerID = group.LocalId;
10903 result.Depth = intersection.distance; 12302// result.Depth = intersection.distance;
10904 result.Normal = intersection.normal; 12303 result.Normal = intersection.normal;
10905 result.Pos = intersection.ipoint; 12304 result.Pos = intersection.ipoint;
12305 result.Depth = Vector3.Mag(rayStart - result.Pos);
10906 12306
10907 contacts.Add(result); 12307 contacts.Add(result);
10908 }); 12308 });
@@ -11035,6 +12435,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11035 12435
11036 return contacts[0]; 12436 return contacts[0];
11037 } 12437 }
12438/*
12439 // not done:
12440 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12441 {
12442 ContactResult[] contacts = null;
12443 World.ForEachSOG(delegate(SceneObjectGroup group)
12444 {
12445 if (m_host.ParentGroup == group)
12446 return;
12447
12448 if (group.IsAttachment)
12449 return;
12450
12451 if(group.RootPart.PhysActor != null)
12452 return;
12453
12454 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12455 });
12456 return contacts;
12457 }
12458*/
11038 12459
11039 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12460 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11040 { 12461 {
@@ -11076,32 +12497,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11076 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12497 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11077 12498
11078 12499
11079 if (checkTerrain) 12500 if (World.SuportsRayCastFiltered())
11080 { 12501 {
11081 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12502 if (dist == 0)
11082 if (groundContact != null) 12503 return list;
11083 results.Add((ContactResult)groundContact);
11084 }
11085 12504
11086 if (checkAgents) 12505 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11087 { 12506 if (checkTerrain)
11088 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12507 rayfilter |= RayFilterFlags.land;
11089 foreach (ContactResult r in agentHits) 12508// if (checkAgents)
11090 results.Add(r); 12509// rayfilter |= RayFilterFlags.agent;
11091 } 12510 if (checkPhysical)
12511 rayfilter |= RayFilterFlags.physical;
12512 if (checkNonPhysical)
12513 rayfilter |= RayFilterFlags.nonphysical;
12514 if (detectPhantom)
12515 rayfilter |= RayFilterFlags.LSLPhanton;
12516
12517 Vector3 direction = dir * ( 1/dist);
12518
12519 if(rayfilter == 0)
12520 {
12521 list.Add(new LSL_Integer(0));
12522 return list;
12523 }
11092 12524
11093 if (checkPhysical || checkNonPhysical || detectPhantom) 12525 // get some more contacts to sort ???
12526 int physcount = 4 * count;
12527 if (physcount > 20)
12528 physcount = 20;
12529
12530 object physresults;
12531 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12532
12533 if (physresults == null)
12534 {
12535 list.Add(new LSL_Integer(-3)); // timeout error
12536 return list;
12537 }
12538
12539 results = (List<ContactResult>)physresults;
12540
12541 // for now physics doesn't detect sitted avatars so do it outside physics
12542 if (checkAgents)
12543 {
12544 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12545 foreach (ContactResult r in agentHits)
12546 results.Add(r);
12547 }
12548
12549 // TODO: Replace this with a better solution. ObjectIntersection can only
12550 // detect nonphysical phantoms. They are detected by virtue of being
12551 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12552 // physicsl phantoms as done by the physics scene
12553 // We don't want anything else but phantoms here.
12554 if (detectPhantom)
12555 {
12556 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12557 foreach (ContactResult r in objectHits)
12558 results.Add(r);
12559 }
12560 }
12561 else
11094 { 12562 {
11095 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12563 if (checkTerrain)
11096 foreach (ContactResult r in objectHits) 12564 {
11097 results.Add(r); 12565 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12566 if (groundContact != null)
12567 results.Add((ContactResult)groundContact);
12568 }
12569
12570 if (checkAgents)
12571 {
12572 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12573 foreach (ContactResult r in agentHits)
12574 results.Add(r);
12575 }
12576
12577 if (checkPhysical || checkNonPhysical || detectPhantom)
12578 {
12579 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12580 foreach (ContactResult r in objectHits)
12581 results.Add(r);
12582 }
11098 } 12583 }
11099 12584
11100 results.Sort(delegate(ContactResult a, ContactResult b) 12585 results.Sort(delegate(ContactResult a, ContactResult b)
11101 { 12586 {
11102 return a.Depth.CompareTo(b.Depth); 12587 return a.Depth.CompareTo(b.Depth);
11103 }); 12588 });
11104 12589
11105 int values = 0; 12590 int values = 0;
11106 SceneObjectGroup thisgrp = m_host.ParentGroup; 12591 SceneObjectGroup thisgrp = m_host.ParentGroup;
11107 12592
@@ -11194,7 +12679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11194 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12679 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11195 if (!isAccount) return 0; 12680 if (!isAccount) return 0;
11196 if (estate.HasAccess(id)) return 1; 12681 if (estate.HasAccess(id)) return 1;
11197 if (estate.IsBanned(id)) 12682 if (estate.IsBanned(id, World.GetUserFlags(id)))
11198 estate.RemoveBan(id); 12683 estate.RemoveBan(id);
11199 estate.AddEstateUser(id); 12684 estate.AddEstateUser(id);
11200 break; 12685 break;
@@ -11213,14 +12698,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11213 break; 12698 break;
11214 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12699 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11215 if (!isAccount) return 0; 12700 if (!isAccount) return 0;
11216 if (estate.IsBanned(id)) return 1; 12701 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11217 EstateBan ban = new EstateBan(); 12702 EstateBan ban = new EstateBan();
11218 ban.EstateID = estate.EstateID; 12703 ban.EstateID = estate.EstateID;
11219 ban.BannedUserID = id; 12704 ban.BannedUserID = id;
11220 estate.AddBan(ban); 12705 estate.AddBan(ban);
11221 break; 12706 break;
11222 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12707 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11223 if (!isAccount || !estate.IsBanned(id)) return 0; 12708 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11224 estate.RemoveBan(id); 12709 estate.RemoveBan(id);
11225 break; 12710 break;
11226 default: return 0; 12711 default: return 0;
@@ -11249,7 +12734,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11249 return 16384; 12734 return 16384;
11250 } 12735 }
11251 12736
11252 public LSL_Integer llGetUsedMemory() 12737 public virtual LSL_Integer llGetUsedMemory()
11253 { 12738 {
11254 m_host.AddScriptLPS(1); 12739 m_host.AddScriptLPS(1);
11255 // The value returned for LSO scripts in SL 12740 // The value returned for LSO scripts in SL
@@ -11277,7 +12762,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11277 public void llSetSoundQueueing(int queue) 12762 public void llSetSoundQueueing(int queue)
11278 { 12763 {
11279 m_host.AddScriptLPS(1); 12764 m_host.AddScriptLPS(1);
11280 NotImplemented("llSetSoundQueueing");
11281 } 12765 }
11282 12766
11283 public void llCollisionSprite(string impact_sprite) 12767 public void llCollisionSprite(string impact_sprite)
@@ -11289,10 +12773,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11289 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12773 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11290 { 12774 {
11291 m_host.AddScriptLPS(1); 12775 m_host.AddScriptLPS(1);
11292 NotImplemented("llGodLikeRezObject"); 12776
12777 if (!World.Permissions.IsGod(m_host.OwnerID))
12778 NotImplemented("llGodLikeRezObject");
12779
12780 AssetBase rezAsset = World.AssetService.Get(inventory);
12781 if (rezAsset == null)
12782 {
12783 llSay(0, "Asset not found");
12784 return;
12785 }
12786
12787 SceneObjectGroup group = null;
12788
12789 try
12790 {
12791 string xmlData = Utils.BytesToString(rezAsset.Data);
12792 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12793 }
12794 catch
12795 {
12796 llSay(0, "Asset not found");
12797 return;
12798 }
12799
12800 if (group == null)
12801 {
12802 llSay(0, "Asset not found");
12803 return;
12804 }
12805
12806 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12807 group.RootPart.AttachOffset = group.AbsolutePosition;
12808
12809 group.ResetIDs();
12810
12811 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12812 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12813 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12814 group.ScheduleGroupForFullUpdate();
12815
12816 // objects rezzed with this method are die_at_edge by default.
12817 group.RootPart.SetDieAtEdge(true);
12818
12819 group.ResumeScripts();
12820
12821 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12822 "object_rez", new Object[] {
12823 new LSL_String(
12824 group.RootPart.UUID.ToString()) },
12825 new DetectParams[0]));
12826 }
12827
12828 public LSL_String llTransferLindenDollars(string destination, int amount)
12829 {
12830 UUID txn = UUID.Random();
12831
12832 Util.FireAndForget(delegate(object x)
12833 {
12834 int replycode = 0;
12835 string replydata = destination + "," + amount.ToString();
12836
12837 try
12838 {
12839 TaskInventoryItem item = m_item;
12840 if (item == null)
12841 {
12842 replydata = "SERVICE_ERROR";
12843 return;
12844 }
12845
12846 m_host.AddScriptLPS(1);
12847
12848 if (item.PermsGranter == UUID.Zero)
12849 {
12850 replydata = "MISSING_PERMISSION_DEBIT";
12851 return;
12852 }
12853
12854 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12855 {
12856 replydata = "MISSING_PERMISSION_DEBIT";
12857 return;
12858 }
12859
12860 UUID toID = new UUID();
12861
12862 if (!UUID.TryParse(destination, out toID))
12863 {
12864 replydata = "INVALID_AGENT";
12865 return;
12866 }
12867
12868 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12869
12870 if (money == null)
12871 {
12872 replydata = "TRANSFERS_DISABLED";
12873 return;
12874 }
12875
12876 bool result = money.ObjectGiveMoney(
12877 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12878
12879 if (result)
12880 {
12881 replycode = 1;
12882 return;
12883 }
12884
12885 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12886 }
12887 finally
12888 {
12889 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12890 "transaction_result", new Object[] {
12891 new LSL_String(txn.ToString()),
12892 new LSL_Integer(replycode),
12893 new LSL_String(replydata) },
12894 new DetectParams[0]));
12895 }
12896 });
12897
12898 return txn.ToString();
11293 } 12899 }
11294 12900
11295 #endregion 12901 #endregion
12902
12903 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12904 {
12905 SceneObjectGroup group = m_host.ParentGroup;
12906
12907 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12908 return;
12909 if (group.IsAttachment)
12910 return;
12911
12912 if (frames.Data.Length > 0) // We are getting a new motion
12913 {
12914 if (group.RootPart.KeyframeMotion != null)
12915 group.RootPart.KeyframeMotion.Stop();
12916 group.RootPart.KeyframeMotion = null;
12917
12918 int idx = 0;
12919
12920 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12921 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12922
12923 while (idx < options.Data.Length)
12924 {
12925 int option = (int)options.GetLSLIntegerItem(idx++);
12926 int remain = options.Data.Length - idx;
12927
12928 switch (option)
12929 {
12930 case ScriptBaseClass.KFM_MODE:
12931 if (remain < 1)
12932 break;
12933 int modeval = (int)options.GetLSLIntegerItem(idx++);
12934 switch(modeval)
12935 {
12936 case ScriptBaseClass.KFM_FORWARD:
12937 mode = KeyframeMotion.PlayMode.Forward;
12938 break;
12939 case ScriptBaseClass.KFM_REVERSE:
12940 mode = KeyframeMotion.PlayMode.Reverse;
12941 break;
12942 case ScriptBaseClass.KFM_LOOP:
12943 mode = KeyframeMotion.PlayMode.Loop;
12944 break;
12945 case ScriptBaseClass.KFM_PING_PONG:
12946 mode = KeyframeMotion.PlayMode.PingPong;
12947 break;
12948 }
12949 break;
12950 case ScriptBaseClass.KFM_DATA:
12951 if (remain < 1)
12952 break;
12953 int dataval = (int)options.GetLSLIntegerItem(idx++);
12954 data = (KeyframeMotion.DataFormat)dataval;
12955 break;
12956 }
12957 }
12958
12959 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12960
12961 idx = 0;
12962
12963 int elemLength = 2;
12964 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12965 elemLength = 3;
12966
12967 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12968 while (idx < frames.Data.Length)
12969 {
12970 int remain = frames.Data.Length - idx;
12971
12972 if (remain < elemLength)
12973 break;
12974
12975 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12976 frame.Position = null;
12977 frame.Rotation = null;
12978
12979 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12980 {
12981 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12982 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12983 }
12984 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12985 {
12986 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12987 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12988 }
12989
12990 float tempf = (float)frames.GetLSLFloatItem(idx++);
12991 frame.TimeMS = (int)(tempf * 1000.0f);
12992
12993 keyframes.Add(frame);
12994 }
12995
12996 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12997 group.RootPart.KeyframeMotion.Start();
12998 }
12999 else
13000 {
13001 if (group.RootPart.KeyframeMotion == null)
13002 return;
13003
13004 if (options.Data.Length == 0)
13005 {
13006 group.RootPart.KeyframeMotion.Stop();
13007 return;
13008 }
13009
13010 int code = (int)options.GetLSLIntegerItem(0);
13011
13012 int idx = 0;
13013
13014 while (idx < options.Data.Length)
13015 {
13016 int option = (int)options.GetLSLIntegerItem(idx++);
13017 int remain = options.Data.Length - idx;
13018
13019 switch (option)
13020 {
13021 case ScriptBaseClass.KFM_COMMAND:
13022 int cmd = (int)options.GetLSLIntegerItem(idx++);
13023 switch (cmd)
13024 {
13025 case ScriptBaseClass.KFM_CMD_PLAY:
13026 group.RootPart.KeyframeMotion.Start();
13027 break;
13028 case ScriptBaseClass.KFM_CMD_STOP:
13029 group.RootPart.KeyframeMotion.Stop();
13030 break;
13031 case ScriptBaseClass.KFM_CMD_PAUSE:
13032 group.RootPart.KeyframeMotion.Pause();
13033 break;
13034 }
13035 break;
13036 }
13037 }
13038 }
13039 }
11296 } 13040 }
11297 13041
11298 public class NotecardCache 13042 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 bcd1a6f..0bb933c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -916,18 +925,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
916 if (target != null) 925 if (target != null)
917 { 926 {
918 UUID animID=UUID.Zero; 927 UUID animID=UUID.Zero;
919 lock (m_host.TaskInventory) 928 m_host.TaskInventory.LockItemsForRead(true);
929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
920 { 930 {
921 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 931 if (inv.Value.Name == animation)
922 { 932 {
923 if (inv.Value.Name == animation) 933 if (inv.Value.Type == (int)AssetType.Animation)
924 { 934 animID = inv.Value.AssetID;
925 if (inv.Value.Type == (int)AssetType.Animation) 935 continue;
926 animID = inv.Value.AssetID;
927 continue;
928 }
929 } 936 }
930 } 937 }
938 m_host.TaskInventory.LockItemsForRead(false);
931 if (animID == UUID.Zero) 939 if (animID == UUID.Zero)
932 target.Animator.AddAnimation(animation, m_host.UUID); 940 target.Animator.AddAnimation(animation, m_host.UUID);
933 else 941 else
@@ -968,6 +976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
968 else 976 else
969 animID = UUID.Zero; 977 animID = UUID.Zero;
970 } 978 }
979 m_host.TaskInventory.LockItemsForRead(false);
971 980
972 if (animID == UUID.Zero) 981 if (animID == UUID.Zero)
973 target.Animator.RemoveAnimation(animation); 982 target.Animator.RemoveAnimation(animation);
@@ -1801,6 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1801 1810
1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1811 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1803 { 1812 {
1813 m_host.TaskInventory.LockItemsForRead(true);
1804 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1814 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1805 { 1815 {
1806 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1816 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1808,6 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 assetID = item.AssetID; 1818 assetID = item.AssetID;
1809 } 1819 }
1810 } 1820 }
1821 m_host.TaskInventory.LockItemsForRead(false);
1811 } 1822 }
1812 1823
1813 if (assetID == UUID.Zero) 1824 if (assetID == UUID.Zero)
@@ -2279,7 +2290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2279 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2290 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2280 m_host.AddScriptLPS(1); 2291 m_host.AddScriptLPS(1);
2281 2292
2282 return NpcCreate(firstname, lastname, position, notecard, false, false); 2293 return NpcCreate(firstname, lastname, position, notecard, true, false);
2283 } 2294 }
2284 2295
2285 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2296 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2290,24 +2301,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2290 return NpcCreate( 2301 return NpcCreate(
2291 firstname, lastname, position, notecard, 2302 firstname, lastname, position, notecard,
2292 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2303 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2293 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2304 false);
2305// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2294 } 2306 }
2295 2307
2296 private LSL_Key NpcCreate( 2308 private LSL_Key NpcCreate(
2297 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2309 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2298 { 2310 {
2311 if (!owned)
2312 OSSLError("Unowned NPCs are unsupported");
2313
2314 string groupTitle = String.Empty;
2315
2316 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2317 return new LSL_Key(UUID.Zero.ToString());
2318
2319 if (firstname != String.Empty || lastname != String.Empty)
2320 {
2321 if (firstname != "Shown outfit:")
2322 groupTitle = "- NPC -";
2323 }
2324
2299 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2325 INPCModule module = World.RequestModuleInterface<INPCModule>();
2300 if (module != null) 2326 if (module != null)
2301 { 2327 {
2302 AvatarAppearance appearance = null; 2328 AvatarAppearance appearance = null;
2303 2329
2304 UUID id; 2330// UUID id;
2305 if (UUID.TryParse(notecard, out id)) 2331// if (UUID.TryParse(notecard, out id))
2306 { 2332// {
2307 ScenePresence clonePresence = World.GetScenePresence(id); 2333// ScenePresence clonePresence = World.GetScenePresence(id);
2308 if (clonePresence != null) 2334// if (clonePresence != null)
2309 appearance = clonePresence.Appearance; 2335// appearance = clonePresence.Appearance;
2310 } 2336// }
2311 2337
2312 if (appearance == null) 2338 if (appearance == null)
2313 { 2339 {
@@ -2335,6 +2361,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2335 World, 2361 World,
2336 appearance); 2362 appearance);
2337 2363
2364 ScenePresence sp;
2365 if (World.TryGetScenePresence(x, out sp))
2366 {
2367 sp.Grouptitle = groupTitle;
2368 sp.SendAvatarDataToAllAgents();
2369 }
2338 return new LSL_Key(x.ToString()); 2370 return new LSL_Key(x.ToString());
2339 } 2371 }
2340 2372
@@ -2626,16 +2658,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2626 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2658 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2627 m_host.AddScriptLPS(1); 2659 m_host.AddScriptLPS(1);
2628 2660
2629 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2661 ManualResetEvent ev = new ManualResetEvent(false);
2630 if (module != null)
2631 {
2632 UUID npcId = new UUID(npc.m_string);
2633 2662
2634 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2663 Util.FireAndForget(delegate(object x) {
2635 return; 2664 try
2665 {
2666 INPCModule module = World.RequestModuleInterface<INPCModule>();
2667 if (module != null)
2668 {
2669 UUID npcId = new UUID(npc.m_string);
2636 2670
2637 module.DeleteNPC(npcId, World); 2671 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2638 } 2672 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2673 {
2674 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2675 return;
2676 }
2677
2678 module.DeleteNPC(npcId, World);
2679 }
2680 }
2681 finally
2682 {
2683 ev.Set();
2684 }
2685 });
2686 ev.WaitOne();
2639 } 2687 }
2640 2688
2641 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2689 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3323,4 +3371,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3323 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString()); 3371 return new LSL_Key(m_host.ParentGroup.FromPartID.ToString());
3324 } 3372 }
3325 } 3373 }
3326} \ No newline at end of file 3374}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index a626be8..678f9d5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -70,7 +70,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
70 private const int AGENT = 1; 70 private const int AGENT = 1;
71 private const int AGENT_BY_USERNAME = 0x10; 71 private const int AGENT_BY_USERNAME = 0x10;
72 private const int NPC = 0x20; 72 private const int NPC = 0x20;
73 private const int OS_NPC = 0x01000000;
74 private const int ACTIVE = 2; 73 private const int ACTIVE = 2;
75 private const int PASSIVE = 4; 74 private const int PASSIVE = 4;
76 private const int SCRIPTED = 8; 75 private const int SCRIPTED = 8;
@@ -235,7 +234,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
235 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 234 List<SensedEntity> sensedEntities = new List<SensedEntity>();
236 235
237 // Is the sensor type is AGENT and not SCRIPTED then include agents 236 // Is the sensor type is AGENT and not SCRIPTED then include agents
238 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 237 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
239 { 238 {
240 sensedEntities.AddRange(doAgentSensor(ts)); 239 sensedEntities.AddRange(doAgentSensor(ts));
241 } 240 }
@@ -334,7 +333,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
334 float dy; 333 float dy;
335 float dz; 334 float dz;
336 335
337 Quaternion q = SensePoint.GetWorldRotation(); 336// Quaternion q = SensePoint.RotationOffset;
337 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
338 if (SensePoint.ParentGroup.IsAttachment) 338 if (SensePoint.ParentGroup.IsAttachment)
339 { 339 {
340 // In attachments, rotate the sensor cone with the 340 // In attachments, rotate the sensor cone with the
@@ -348,7 +348,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
348 // Position of a sensor in a child prim attached to an avatar 348 // Position of a sensor in a child prim attached to an avatar
349 // will be still wrong. 349 // will be still wrong.
350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 350 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
351 q = avatar.Rotation * q; 351 fromRegionPos = avatar.AbsolutePosition;
352 q = avatar.Rotation;
352 } 353 }
353 354
354 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 355 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -476,7 +477,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
476 // Position of a sensor in a child prim attached to an avatar 477 // Position of a sensor in a child prim attached to an avatar
477 // will be still wrong. 478 // will be still wrong.
478 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 479 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
479 q = avatar.Rotation * q; 480 if (avatar == null)
481 return sensedEntities;
482 fromRegionPos = avatar.AbsolutePosition;
483 q = avatar.Rotation;
480 } 484 }
481 485
482 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -492,7 +496,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
492// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
493// presence.Name, presence.PresenceType, ts.name, ts.type); 497// presence.Name, presence.PresenceType, ts.name, ts.type);
494 498
495 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 499 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
496 { 500 {
497 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
498 if (npcData == null || !npcData.SenseAsAgent) 502 if (npcData == null || !npcData.SenseAsAgent)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 3fb463b..af35258 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,11 +358,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
361 void llSetPrimURL(string url); 365 void llSetPrimURL(string url);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 void llSetRemoteScriptAccessPin(int pin); 366 void llSetRemoteScriptAccessPin(int pin);
364 void llSetRot(LSL_Rotation rot); 367 void llSetRot(LSL_Rotation rot);
365 void llSetScale(LSL_Vector scale); 368 void llSetScale(LSL_Vector scale);
@@ -379,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
379 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
380 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
381 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
382 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
383 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
384 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -422,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
422 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
423 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
424 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
425 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
426 431
427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
428 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
429 } 435 }
430} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 1f000a3..8c34ed3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index c3eada0..a08cc42 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;
@@ -283,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
284 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
285 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
286 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
287 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
288 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -587,6 +588,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
587 public const int PRIM_MEDIA_PERM_OWNER = 1; 588 public const int PRIM_MEDIA_PERM_OWNER = 1;
588 public const int PRIM_MEDIA_PERM_GROUP = 2; 589 public const int PRIM_MEDIA_PERM_GROUP = 2;
589 public const int PRIM_MEDIA_PERM_ANYONE = 4; 590 public const int PRIM_MEDIA_PERM_ANYONE = 4;
591
592 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
593 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
594 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
595 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
596
597 public const int PRIM_PHYSICS_MATERIAL = 31;
598 public const int DENSITY = 1;
599 public const int FRICTION = 2;
600 public const int RESTITUTION = 4;
601 public const int GRAVITY_MULTIPLIER = 8;
590 602
591 // extra constants for llSetPrimMediaParams 603 // extra constants for llSetPrimMediaParams
592 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 604 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -659,6 +671,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
659 671
660 public static readonly LSLInteger RCERR_UNKNOWN = -1; 672 public static readonly LSLInteger RCERR_UNKNOWN = -1;
661 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 673 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
662 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 674 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
675
676 public const int KFM_MODE = 1;
677 public const int KFM_LOOP = 1;
678 public const int KFM_REVERSE = 3;
679 public const int KFM_FORWARD = 0;
680 public const int KFM_PING_PONG = 2;
681 public const int KFM_DATA = 2;
682 public const int KFM_TRANSLATION = 2;
683 public const int KFM_ROTATION = 1;
684 public const int KFM_COMMAND = 0;
685 public const int KFM_CMD_PLAY = 0;
686 public const int KFM_CMD_STOP = 1;
687 public const int KFM_CMD_PAUSE = 2;
663 } 688 }
664} 689}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c457880..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1618,11 +1640,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPrimURL(url); 1640 m_LSL_Functions.llSetPrimURL(url);
1619 } 1641 }
1620 1642
1621 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1622 {
1623 return m_LSL_Functions.llSetRegionPos(pos);
1624 }
1625
1626 public void llSetRemoteScriptAccessPin(int pin) 1643 public void llSetRemoteScriptAccessPin(int pin)
1627 { 1644 {
1628 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1645 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1718,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1718 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1719 } 1736 }
1720 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1721 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1722 { 1744 {
1723 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1968,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1968 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1969 } 1991 }
1970 1992
1971 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1972 { 2004 {
1973 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1974 } 2006 }
1975 } 2007 }
1976} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 0108f44..9e5fb24 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -102,6 +103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 Type = 0; 103 Type = 0;
103 Velocity = new LSL_Types.Vector3(); 104 Velocity = new LSL_Types.Vector3();
104 initializeSurfaceTouch(); 105 initializeSurfaceTouch();
106 Country = String.Empty;
105 } 107 }
106 108
107 public UUID Key; 109 public UUID Key;
@@ -133,6 +135,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
133 private int touchFace; 135 private int touchFace;
134 public int TouchFace { get { return touchFace; } } 136 public int TouchFace { get { return touchFace; } }
135 137
138 public string Country;
139
136 // This can be done in two places including the constructor 140 // This can be done in two places including the constructor
137 // so be carefull what gets added here 141 // so be carefull what gets added here
138 private void initializeSurfaceTouch() 142 private void initializeSurfaceTouch()
@@ -180,6 +184,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
180 return; 184 return;
181 185
182 Name = presence.Firstname + " " + presence.Lastname; 186 Name = presence.Firstname + " " + presence.Lastname;
187 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
188 if (account != null)
189 Country = account.UserCountry;
190
183 Owner = Key; 191 Owner = Key;
184 Position = new LSL_Types.Vector3( 192 Position = new LSL_Types.Vector3(
185 presence.AbsolutePosition.X, 193 presence.AbsolutePosition.X,
@@ -195,22 +203,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
195 presence.Velocity.Y, 203 presence.Velocity.Y,
196 presence.Velocity.Z); 204 presence.Velocity.Z);
197 205
198 if (presence.PresenceType != PresenceType.Npc) 206 Type = 0x01; // Avatar
199 { 207 if (presence.PresenceType == PresenceType.Npc)
200 Type = AGENT; 208 Type = 0x20;
201 } 209
202 else 210 // Cope Impl. We don't use OS_NPC.
203 { 211 //if (presence.PresenceType != PresenceType.Npc)
204 Type = OS_NPC; 212 //{
205 213 // Type = AGENT;
206 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 214 //}
207 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 215 //else
208 216 //{
209 if (npcData.SenseAsAgent) 217 // Type = OS_NPC;
210 { 218
211 Type |= AGENT; 219 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
212 } 220 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
213 } 221
222 // if (npcData.SenseAsAgent)
223 // {
224 // Type |= AGENT;
225 // }
226 //}
214 227
215 if (presence.Velocity != Vector3.Zero) 228 if (presence.Velocity != Vector3.Zero)
216 Type |= ACTIVE; 229 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 5793cc9..771db0c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -219,13 +220,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
219 220
220 if (part != null) 221 if (part != null)
221 { 222 {
222 lock (part.TaskInventory) 223 part.TaskInventory.LockItemsForRead(true);
224 if (part.TaskInventory.ContainsKey(ItemID))
223 { 225 {
224 if (part.TaskInventory.ContainsKey(ItemID)) 226 ScriptTask = part.TaskInventory[ItemID];
225 {
226 ScriptTask = part.TaskInventory[ItemID];
227 }
228 } 227 }
228 part.TaskInventory.LockItemsForRead(false);
229 } 229 }
230 230
231 ApiManager am = new ApiManager(); 231 ApiManager am = new ApiManager();
@@ -417,14 +417,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
417 { 417 {
418 int permsMask; 418 int permsMask;
419 UUID permsGranter; 419 UUID permsGranter;
420 lock (part.TaskInventory) 420 part.TaskInventory.LockItemsForRead(true);
421 if (!part.TaskInventory.ContainsKey(ItemID))
421 { 422 {
422 if (!part.TaskInventory.ContainsKey(ItemID)) 423 part.TaskInventory.LockItemsForRead(false);
423 return; 424 return;
424
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 } 425 }
426 permsGranter = part.TaskInventory[ItemID].PermsGranter;
427 permsMask = part.TaskInventory[ItemID].PermsMask;
428 part.TaskInventory.LockItemsForRead(false);
428 429
429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 430 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
430 { 431 {
@@ -552,6 +553,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
552 return true; 553 return true;
553 } 554 }
554 555
556 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
555 public void SetState(string state) 557 public void SetState(string state)
556 { 558 {
557 if (state == State) 559 if (state == State)
@@ -563,7 +565,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
563 new DetectParams[0])); 565 new DetectParams[0]));
564 PostEvent(new EventParams("state_entry", new Object[0], 566 PostEvent(new EventParams("state_entry", new Object[0],
565 new DetectParams[0])); 567 new DetectParams[0]));
566 568
567 throw new EventAbortException(); 569 throw new EventAbortException();
568 } 570 }
569 571
@@ -653,45 +655,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
653 /// <returns></returns> 655 /// <returns></returns>
654 public object EventProcessor() 656 public object EventProcessor()
655 { 657 {
658 EventParams data = null;
656 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 659 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
657 if (!Running) 660 if (!Running)
658 return 0; 661 return 0;
659 662
660 lock (m_Script)
661 {
662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 663// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
663 664
664 if (Suspended) 665 if (Suspended)
665 return 0; 666 return 0;
666
667 EventParams data = null;
668 667
669 lock (EventQueue) 668 lock (EventQueue)
669 {
670 data = (EventParams) EventQueue.Dequeue();
671 if (data == null) // Shouldn't happen
670 { 672 {
671 data = (EventParams)EventQueue.Dequeue(); 673 if (EventQueue.Count > 0 && Running && !ShuttingDown)
672 if (data == null) // Shouldn't happen
673 { 674 {
674 if (EventQueue.Count > 0 && Running && !ShuttingDown) 675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
675 {
676 m_CurrentWorkItem = Engine.QueueEventHandler(this);
677 }
678 else
679 {
680 m_CurrentWorkItem = null;
681 }
682 return 0;
683 } 676 }
684 677 else
685 if (data.EventName == "timer")
686 m_TimerQueued = false;
687 if (data.EventName == "control")
688 { 678 {
689 if (m_ControlEventsInQueue > 0) 679 m_CurrentWorkItem = null;
690 m_ControlEventsInQueue--;
691 } 680 }
692 if (data.EventName == "collision") 681 return 0;
693 m_CollisionInQueue = false;
694 } 682 }
683
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 {
688 if (m_ControlEventsInQueue > 0)
689 m_ControlEventsInQueue--;
690 }
691 if (data.EventName == "collision")
692 m_CollisionInQueue = false;
693 }
694
695 lock(m_Script)
696 {
695 697
696// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 698// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
697 699
@@ -846,6 +848,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
846 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 848 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
847 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 849 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
848 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 850 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
851 part.CollisionSound = UUID.Zero;
849 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 852 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
850 EventQueue.Clear(); 853 EventQueue.Clear();
851 m_Script.ResetVars(); 854 m_Script.ResetVars();
@@ -860,6 +863,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 863 new Object[0], new DetectParams[0]));
861 } 864 }
862 865
866 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 867 public void ApiResetScript()
864 { 868 {
865 // bool running = Running; 869 // bool running = Running;
@@ -871,6 +875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
871 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 875 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
872 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 876 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
873 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 877 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
878 part.CollisionSound = UUID.Zero;
874 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 879 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
875 880
876 EventQueue.Clear(); 881 EventQueue.Clear();
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 2dba029..f6cb7df 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,52 +644,57 @@ 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 // 659 instance.SaveState(assembly);
589 if (m_Assemblies.ContainsKey(instance.AssetID)) 660 }
590 {
591 string assembly = m_Assemblies[instance.AssetID];
592 instance.SaveState(assembly);
593 }
594 661
595 // Clear the event queue and abort the instance thread 662 // Clear the event queue and abort the instance thread
596 // 663 //
597 instance.ClearQueue(); 664 instance.ClearQueue();
598 instance.Stop(0); 665 instance.Stop(0);
599 666
600 // Release events, timer, etc 667 // Release events, timer, etc
601 // 668 //
602 instance.DestroyScriptInstance(); 669 instance.DestroyScriptInstance();
603 670
604 // Unload scripts and app domains. 671 // Unload scripts and app domains
605 // Must be done explicitly because they have infinite 672 // Must be done explicitly because they have infinite
606 // lifetime. 673 // lifetime
607 // However, don't bother to do this if the simulator is shutting 674 //
608 // down since it takes a long time with many scripts. 675// if (!m_SimulatorShuttingDown)
609 if (!m_SimulatorShuttingDown) 676 {
677 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
678 if (m_DomainScripts[instance.AppDomain].Count == 0)
610 { 679 {
611 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 680 m_DomainScripts.Remove(instance.AppDomain);
612 if (m_DomainScripts[instance.AppDomain].Count == 0) 681 UnloadAppDomain(instance.AppDomain);
613 {
614 m_DomainScripts.Remove(instance.AppDomain);
615 UnloadAppDomain(instance.AppDomain);
616 }
617 } 682 }
618 } 683 }
619 684
620 m_Scripts.Clear(); 685// m_Scripts.Clear();
621 m_PrimObjects.Clear(); 686// m_PrimObjects.Clear();
622 m_Assemblies.Clear(); 687// m_Assemblies.Clear();
623 m_DomainScripts.Clear(); 688// m_DomainScripts.Clear();
624 } 689 }
690 lockScriptsForRead(false);
691 lockScriptsForWrite(true);
692 m_Scripts.Clear();
693 lockScriptsForWrite(false);
694 m_PrimObjects.Clear();
695 m_Assemblies.Clear();
696 m_DomainScripts.Clear();
697
625 lock (m_ScriptEngines) 698 lock (m_ScriptEngines)
626 { 699 {
627 m_ScriptEngines.Remove(this); 700 m_ScriptEngines.Remove(this);
@@ -690,22 +763,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
690 763
691 List<IScriptInstance> instances = new List<IScriptInstance>(); 764 List<IScriptInstance> instances = new List<IScriptInstance>();
692 765
693 lock (m_Scripts) 766 lockScriptsForRead(true);
694 { 767 foreach (IScriptInstance instance in m_Scripts.Values)
695 foreach (IScriptInstance instance in m_Scripts.Values)
696 instances.Add(instance); 768 instances.Add(instance);
697 } 769 lockScriptsForRead(false);
698 770
699 foreach (IScriptInstance i in instances) 771 foreach (IScriptInstance i in instances)
700 { 772 {
701 string assembly = String.Empty; 773 string assembly = String.Empty;
702 774
703 lock (m_Scripts) 775
704 {
705 if (!m_Assemblies.ContainsKey(i.AssetID)) 776 if (!m_Assemblies.ContainsKey(i.AssetID))
706 continue; 777 continue;
707 assembly = m_Assemblies[i.AssetID]; 778 assembly = m_Assemblies[i.AssetID];
708 } 779
709 780
710 i.SaveState(assembly); 781 i.SaveState(assembly);
711 } 782 }
@@ -1092,96 +1163,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1092 } 1163 }
1093 1164
1094 ScriptInstance instance = null; 1165 ScriptInstance instance = null;
1095 lock (m_Scripts) 1166 // Create the object record
1167 lockScriptsForRead(true);
1168 if ((!m_Scripts.ContainsKey(itemID)) ||
1169 (m_Scripts[itemID].AssetID != assetID))
1096 { 1170 {
1097 // Create the object record 1171 lockScriptsForRead(false);
1098 if ((!m_Scripts.ContainsKey(itemID)) ||
1099 (m_Scripts[itemID].AssetID != assetID))
1100 {
1101 UUID appDomain = assetID;
1102 1172
1103 if (part.ParentGroup.IsAttachment) 1173 UUID appDomain = assetID;
1104 appDomain = part.ParentGroup.RootPart.UUID;
1105 1174
1106 if (!m_AppDomains.ContainsKey(appDomain)) 1175 if (part.ParentGroup.IsAttachment)
1107 { 1176 appDomain = part.ParentGroup.RootPart.UUID;
1108 try
1109 {
1110 AppDomainSetup appSetup = new AppDomainSetup();
1111 appSetup.PrivateBinPath = Path.Combine(
1112 m_ScriptEnginesPath,
1113 m_Scene.RegionInfo.RegionID.ToString());
1114 1177
1115 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1178 if (!m_AppDomains.ContainsKey(appDomain))
1116 Evidence evidence = new Evidence(baseEvidence); 1179 {
1180 try
1181 {
1182 AppDomainSetup appSetup = new AppDomainSetup();
1183 appSetup.PrivateBinPath = Path.Combine(
1184 m_ScriptEnginesPath,
1185 m_Scene.RegionInfo.RegionID.ToString());
1117 1186
1118 AppDomain sandbox; 1187 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1119 if (m_AppDomainLoading) 1188 Evidence evidence = new Evidence(baseEvidence);
1120 {
1121 sandbox = AppDomain.CreateDomain(
1122 m_Scene.RegionInfo.RegionID.ToString(),
1123 evidence, appSetup);
1124 sandbox.AssemblyResolve +=
1125 new ResolveEventHandler(
1126 AssemblyResolver.OnAssemblyResolve);
1127 }
1128 else
1129 {
1130 sandbox = AppDomain.CurrentDomain;
1131 }
1132
1133 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1134 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1135 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1136 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1137 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1138 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1139 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1140
1141 m_AppDomains[appDomain] = sandbox;
1142 1189
1143 m_DomainScripts[appDomain] = new List<UUID>(); 1190 AppDomain sandbox;
1191 if (m_AppDomainLoading)
1192 {
1193 sandbox = AppDomain.CreateDomain(
1194 m_Scene.RegionInfo.RegionID.ToString(),
1195 evidence, appSetup);
1196 m_AppDomains[appDomain].AssemblyResolve +=
1197 new ResolveEventHandler(
1198 AssemblyResolver.OnAssemblyResolve);
1144 } 1199 }
1145 catch (Exception e) 1200 else
1146 { 1201 {
1147 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1202 sandbox = AppDomain.CurrentDomain;
1148 m_ScriptErrorMessage += "Exception creating app domain:\n";
1149 m_ScriptFailCount++;
1150 lock (m_AddingAssemblies)
1151 {
1152 m_AddingAssemblies[assembly]--;
1153 }
1154 return false;
1155 } 1203 }
1156 }
1157 m_DomainScripts[appDomain].Add(itemID);
1158
1159 instance = new ScriptInstance(this, part,
1160 itemID, assetID, assembly,
1161 m_AppDomains[appDomain],
1162 part.ParentGroup.RootPart.Name,
1163 item.Name, startParam, postOnRez,
1164 stateSource, m_MaxScriptQueue);
1165
1166// if (DebugLevel >= 1)
1167 m_log.DebugFormat(
1168 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1169 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1170 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1171 1204
1172 if (presence != null) 1205 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1206 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1207 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1208 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1209 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1210 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1211 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1212
1213 m_AppDomains[appDomain] = sandbox;
1214
1215 m_DomainScripts[appDomain] = new List<UUID>();
1216 }
1217 catch (Exception e)
1173 { 1218 {
1174 ShowScriptSaveResponse(item.OwnerID, 1219 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1175 assetID, "Compile successful", true); 1220 m_ScriptErrorMessage += "Exception creating app domain:\n";
1221 m_ScriptFailCount++;
1222 lock (m_AddingAssemblies)
1223 {
1224 m_AddingAssemblies[assembly]--;
1225 }
1226 return false;
1176 } 1227 }
1228 }
1229 m_DomainScripts[appDomain].Add(itemID);
1230
1231 instance = new ScriptInstance(this, part,
1232 itemID, assetID, assembly,
1233 m_AppDomains[appDomain],
1234 part.ParentGroup.RootPart.Name,
1235 item.Name, startParam, postOnRez,
1236 stateSource, m_MaxScriptQueue);
1237
1238 m_log.DebugFormat(
1239 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1240 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1241 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1177 1242
1178 instance.AppDomain = appDomain; 1243 if (presence != null)
1179 instance.LineMap = linemap; 1244 {
1180 1245 ShowScriptSaveResponse(item.OwnerID,
1181 m_Scripts[itemID] = instance; 1246 assetID, "Compile successful", true);
1182 } 1247 }
1183 }
1184 1248
1249 instance.AppDomain = appDomain;
1250 instance.LineMap = linemap;
1251 lockScriptsForWrite(true);
1252 m_Scripts[itemID] = instance;
1253 lockScriptsForWrite(false);
1254 }
1255 else
1256 {
1257 lockScriptsForRead(false);
1258 }
1185 lock (m_PrimObjects) 1259 lock (m_PrimObjects)
1186 { 1260 {
1187 if (!m_PrimObjects.ContainsKey(localID)) 1261 if (!m_PrimObjects.ContainsKey(localID))
@@ -1199,7 +1273,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1199 m_AddingAssemblies[assembly]--; 1273 m_AddingAssemblies[assembly]--;
1200 } 1274 }
1201 1275
1202 if (instance != null) 1276 if (instance!=null)
1203 instance.Init(); 1277 instance.Init();
1204 1278
1205 bool runIt; 1279 bool runIt;
@@ -1222,18 +1296,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1222 m_CompileDict.Remove(itemID); 1296 m_CompileDict.Remove(itemID);
1223 } 1297 }
1224 1298
1225 IScriptInstance instance = null; 1299 lockScriptsForRead(true);
1226 1300 // Do we even have it?
1227 lock (m_Scripts) 1301 if (!m_Scripts.ContainsKey(itemID))
1228 { 1302 {
1229 // Do we even have it? 1303 // Do we even have it?
1230 if (!m_Scripts.ContainsKey(itemID)) 1304 if (!m_Scripts.ContainsKey(itemID))
1231 return; 1305 return;
1232 1306
1233 instance = m_Scripts[itemID]; 1307 lockScriptsForRead(false);
1308 lockScriptsForWrite(true);
1234 m_Scripts.Remove(itemID); 1309 m_Scripts.Remove(itemID);
1310 lockScriptsForWrite(false);
1311
1312 return;
1235 } 1313 }
1314
1236 1315
1316 IScriptInstance instance=m_Scripts[itemID];
1317 lockScriptsForRead(false);
1318 lockScriptsForWrite(true);
1319 m_Scripts.Remove(itemID);
1320 lockScriptsForWrite(false);
1237 instance.ClearQueue(); 1321 instance.ClearQueue();
1238 1322
1239 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1323 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1272,8 +1356,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1272 1356
1273 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1357 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1274 if (handlerObjectRemoved != null) 1358 if (handlerObjectRemoved != null)
1275 handlerObjectRemoved(instance.ObjectID); 1359 {
1360 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1361 handlerObjectRemoved(part.UUID);
1362 }
1276 1363
1364 CleanAssemblies();
1365
1277 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1366 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1278 if (handlerScriptRemoved != null) 1367 if (handlerScriptRemoved != null)
1279 handlerScriptRemoved(itemID); 1368 handlerScriptRemoved(itemID);
@@ -1534,12 +1623,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1534 private IScriptInstance GetInstance(UUID itemID) 1623 private IScriptInstance GetInstance(UUID itemID)
1535 { 1624 {
1536 IScriptInstance instance; 1625 IScriptInstance instance;
1537 lock (m_Scripts) 1626 lockScriptsForRead(true);
1627 if (!m_Scripts.ContainsKey(itemID))
1538 { 1628 {
1539 if (!m_Scripts.ContainsKey(itemID)) 1629 lockScriptsForRead(false);
1540 return null; 1630 return null;
1541 instance = m_Scripts[itemID];
1542 } 1631 }
1632 instance = m_Scripts[itemID];
1633 lockScriptsForRead(false);
1543 return instance; 1634 return instance;
1544 } 1635 }
1545 1636
@@ -1563,6 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1563 return false; 1654 return false;
1564 } 1655 }
1565 1656
1657 [DebuggerNonUserCode]
1566 public void ApiResetScript(UUID itemID) 1658 public void ApiResetScript(UUID itemID)
1567 { 1659 {
1568 IScriptInstance instance = GetInstance(itemID); 1660 IScriptInstance instance = GetInstance(itemID);
@@ -1624,6 +1716,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1624 return UUID.Zero; 1716 return UUID.Zero;
1625 } 1717 }
1626 1718
1719 [DebuggerNonUserCode]
1627 public void SetState(UUID itemID, string newState) 1720 public void SetState(UUID itemID, string newState)
1628 { 1721 {
1629 IScriptInstance instance = GetInstance(itemID); 1722 IScriptInstance instance = GetInstance(itemID);
@@ -1646,11 +1739,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1646 1739
1647 List<IScriptInstance> instances = new List<IScriptInstance>(); 1740 List<IScriptInstance> instances = new List<IScriptInstance>();
1648 1741
1649 lock (m_Scripts) 1742 lockScriptsForRead(true);
1650 { 1743 foreach (IScriptInstance instance in m_Scripts.Values)
1651 foreach (IScriptInstance instance in m_Scripts.Values)
1652 instances.Add(instance); 1744 instances.Add(instance);
1653 } 1745 lockScriptsForRead(false);
1654 1746
1655 foreach (IScriptInstance i in instances) 1747 foreach (IScriptInstance i in instances)
1656 { 1748 {