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 1287709..54cb214 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, false); 3349 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
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)
@@ -5014,7 +5432,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5014 else if (src.Data[index] is LSL_Float) 5432 else if (src.Data[index] is LSL_Float)
5015 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5433 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5016 else if (src.Data[index] is LSL_String) 5434 else if (src.Data[index] is LSL_String)
5017 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5435 {
5436 string str = ((LSL_String) src.Data[index]).m_string;
5437 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5438 if (m != Match.Empty)
5439 {
5440 str = m.Value;
5441 double d = 0.0;
5442 if (!Double.TryParse(str, out d))
5443 return 0.0;
5444
5445 return d;
5446 }
5447 return 0.0;
5448 }
5018 return Convert.ToDouble(src.Data[index]); 5449 return Convert.ToDouble(src.Data[index]);
5019 } 5450 }
5020 catch (FormatException) 5451 catch (FormatException)
@@ -5324,7 +5755,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5324 } 5755 }
5325 } 5756 }
5326 } 5757 }
5327 else { 5758 else
5759 {
5328 object[] array = new object[src.Length]; 5760 object[] array = new object[src.Length];
5329 Array.Copy(src.Data, 0, array, 0, src.Length); 5761 Array.Copy(src.Data, 0, array, 0, src.Length);
5330 result = new LSL_List(array); 5762 result = new LSL_List(array);
@@ -5431,7 +5863,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5431 public LSL_Integer llGetRegionAgentCount() 5863 public LSL_Integer llGetRegionAgentCount()
5432 { 5864 {
5433 m_host.AddScriptLPS(1); 5865 m_host.AddScriptLPS(1);
5434 return new LSL_Integer(World.GetRootAgentCount()); 5866
5867 int count = 0;
5868 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5869 count++;
5870 });
5871
5872 return new LSL_Integer(count);
5435 } 5873 }
5436 5874
5437 public LSL_Vector llGetRegionCorner() 5875 public LSL_Vector llGetRegionCorner()
@@ -5711,6 +6149,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5711 flags |= ScriptBaseClass.AGENT_SITTING; 6149 flags |= ScriptBaseClass.AGENT_SITTING;
5712 } 6150 }
5713 6151
6152 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6153 {
6154 flags |= ScriptBaseClass.AGENT_MALE;
6155 }
6156
5714 return flags; 6157 return flags;
5715 } 6158 }
5716 6159
@@ -5857,10 +6300,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5857 m_host.AddScriptLPS(1); 6300 m_host.AddScriptLPS(1);
5858 6301
5859 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6302 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5860 6303 if (parts.Count > 0)
5861 foreach (var part in parts)
5862 { 6304 {
5863 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6305 try
6306 {
6307 parts[0].ParentGroup.areUpdatesSuspended = true;
6308 foreach (var part in parts)
6309 {
6310 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6311 }
6312 }
6313 finally
6314 {
6315 parts[0].ParentGroup.areUpdatesSuspended = false;
6316 }
5864 } 6317 }
5865 } 6318 }
5866 6319
@@ -5912,13 +6365,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5912 6365
5913 if (m_host.OwnerID == land.LandData.OwnerID) 6366 if (m_host.OwnerID == land.LandData.OwnerID)
5914 { 6367 {
5915 World.TeleportClientHome(agentID, presence.ControllingClient); 6368 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6369 presence.TeleportWithMomentum(pos, null);
6370 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5916 } 6371 }
5917 } 6372 }
5918 } 6373 }
5919 ScriptSleep(5000); 6374 ScriptSleep(5000);
5920 } 6375 }
5921 6376
6377 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6378 {
6379 return ParseString2List(str, separators, in_spacers, false);
6380 }
6381
5922 public LSL_Integer llOverMyLand(string id) 6382 public LSL_Integer llOverMyLand(string id)
5923 { 6383 {
5924 m_host.AddScriptLPS(1); 6384 m_host.AddScriptLPS(1);
@@ -5977,20 +6437,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5977 return agentSize; 6437 return agentSize;
5978 } 6438 }
5979 6439
5980 public LSL_Integer llSameGroup(string agent) 6440 public LSL_Integer llSameGroup(string id)
5981 { 6441 {
5982 m_host.AddScriptLPS(1); 6442 m_host.AddScriptLPS(1);
5983 UUID agentId = new UUID(); 6443 UUID uuid = new UUID();
5984 if (!UUID.TryParse(agent, out agentId)) 6444 if (!UUID.TryParse(id, out uuid))
5985 return new LSL_Integer(0); 6445 return new LSL_Integer(0);
5986 ScenePresence presence = World.GetScenePresence(agentId); 6446
5987 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6447 // Check if it's a group key
5988 return new LSL_Integer(0); 6448 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5989 IClientAPI client = presence.ControllingClient;
5990 if (m_host.GroupID == client.ActiveGroupId)
5991 return new LSL_Integer(1); 6449 return new LSL_Integer(1);
5992 else 6450
6451 // We got passed a UUID.Zero
6452 if (uuid == UUID.Zero)
5993 return new LSL_Integer(0); 6453 return new LSL_Integer(0);
6454
6455 // Handle the case where id names an avatar
6456 ScenePresence presence = World.GetScenePresence(uuid);
6457 if (presence != null)
6458 {
6459 if (presence.IsChildAgent)
6460 return new LSL_Integer(0);
6461
6462 IClientAPI client = presence.ControllingClient;
6463 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6464 return new LSL_Integer(1);
6465
6466 return new LSL_Integer(0);
6467 }
6468
6469 // Handle object case
6470 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6471 if (part != null)
6472 {
6473 // This will handle both deed and non-deed and also the no
6474 // group case
6475 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6476 return new LSL_Integer(1);
6477
6478 return new LSL_Integer(0);
6479 }
6480
6481 return new LSL_Integer(0);
5994 } 6482 }
5995 6483
5996 public void llUnSit(string id) 6484 public void llUnSit(string id)
@@ -6119,7 +6607,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6119 return m_host.ParentGroup.AttachmentPoint; 6607 return m_host.ParentGroup.AttachmentPoint;
6120 } 6608 }
6121 6609
6122 public LSL_Integer llGetFreeMemory() 6610 public virtual LSL_Integer llGetFreeMemory()
6123 { 6611 {
6124 m_host.AddScriptLPS(1); 6612 m_host.AddScriptLPS(1);
6125 // Make scripts designed for LSO happy 6613 // Make scripts designed for LSO happy
@@ -6236,7 +6724,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6236 SetParticleSystem(m_host, rules); 6724 SetParticleSystem(m_host, rules);
6237 } 6725 }
6238 6726
6239 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6727 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6728 {
6240 6729
6241 6730
6242 if (rules.Length == 0) 6731 if (rules.Length == 0)
@@ -6553,7 +7042,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6553 { 7042 {
6554 // LSL quaternions can normalize to 0, normal Quaternions can't. 7043 // LSL quaternions can normalize to 0, normal Quaternions can't.
6555 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 7044 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6556 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 7045 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6557 7046
6558 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 7047 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6559 part.SitTargetOrientation = Rot2Quaternion(rot); 7048 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6710,13 +7199,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6710 UUID av = new UUID(); 7199 UUID av = new UUID();
6711 if (!UUID.TryParse(avatar,out av)) 7200 if (!UUID.TryParse(avatar,out av))
6712 { 7201 {
6713 LSLError("First parameter to llDialog needs to be a key"); 7202 //LSLError("First parameter to llDialog needs to be a key");
6714 return; 7203 return;
6715 } 7204 }
6716 if (buttons.Length < 1) 7205 if (buttons.Length < 1)
6717 { 7206 {
6718 LSLError("No less than 1 button can be shown"); 7207 buttons.Add("OK");
6719 return;
6720 } 7208 }
6721 if (buttons.Length > 12) 7209 if (buttons.Length > 12)
6722 { 7210 {
@@ -6733,7 +7221,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6733 } 7221 }
6734 if (buttons.Data[i].ToString().Length > 24) 7222 if (buttons.Data[i].ToString().Length > 24)
6735 { 7223 {
6736 LSLError("button label cannot be longer than 24 characters"); 7224 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6737 return; 7225 return;
6738 } 7226 }
6739 buts[i] = buttons.Data[i].ToString(); 7227 buts[i] = buttons.Data[i].ToString();
@@ -6800,9 +7288,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6800 return; 7288 return;
6801 } 7289 }
6802 7290
6803 // the rest of the permission checks are done in RezScript, so check the pin there as well 7291 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6804 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7292 if (dest != null)
7293 {
7294 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7295 {
7296 // the rest of the permission checks are done in RezScript, so check the pin there as well
7297 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6805 7298
7299 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7300 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7301 }
7302 }
6806 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7303 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6807 ScriptSleep(3000); 7304 ScriptSleep(3000);
6808 } 7305 }
@@ -6865,19 +7362,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6865 public LSL_String llMD5String(string src, int nonce) 7362 public LSL_String llMD5String(string src, int nonce)
6866 { 7363 {
6867 m_host.AddScriptLPS(1); 7364 m_host.AddScriptLPS(1);
6868 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7365 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6869 } 7366 }
6870 7367
6871 public LSL_String llSHA1String(string src) 7368 public LSL_String llSHA1String(string src)
6872 { 7369 {
6873 m_host.AddScriptLPS(1); 7370 m_host.AddScriptLPS(1);
6874 return Util.SHA1Hash(src).ToLower(); 7371 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6875 } 7372 }
6876 7373
6877 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7374 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6878 { 7375 {
6879 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7376 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6880 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7377 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7378 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7379 return shapeBlock;
6881 7380
6882 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7381 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6883 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7382 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6982,6 +7481,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6982 // Prim type box, cylinder and prism. 7481 // Prim type box, cylinder and prism.
6983 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) 7482 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)
6984 { 7483 {
7484 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7485 return;
7486
6985 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7487 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6986 ObjectShapePacket.ObjectDataBlock shapeBlock; 7488 ObjectShapePacket.ObjectDataBlock shapeBlock;
6987 7489
@@ -7035,6 +7537,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7035 // Prim type sphere. 7537 // Prim type sphere.
7036 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7538 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7037 { 7539 {
7540 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7541 return;
7542
7038 ObjectShapePacket.ObjectDataBlock shapeBlock; 7543 ObjectShapePacket.ObjectDataBlock shapeBlock;
7039 7544
7040 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7545 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7076,6 +7581,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7076 // Prim type torus, tube and ring. 7581 // Prim type torus, tube and ring.
7077 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) 7582 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)
7078 { 7583 {
7584 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7585 return;
7586
7079 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7587 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7080 ObjectShapePacket.ObjectDataBlock shapeBlock; 7588 ObjectShapePacket.ObjectDataBlock shapeBlock;
7081 7589
@@ -7211,6 +7719,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7211 // Prim type sculpt. 7719 // Prim type sculpt.
7212 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7720 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7213 { 7721 {
7722 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7723 return;
7724
7214 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7725 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7215 UUID sculptId; 7726 UUID sculptId;
7216 7727
@@ -7235,7 +7746,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7235 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7746 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7236 { 7747 {
7237 // default 7748 // default
7238 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7749 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7239 } 7750 }
7240 7751
7241 part.Shape.SetSculptProperties((byte)type, sculptId); 7752 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7251,34 +7762,298 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7251 ScriptSleep(200); 7762 ScriptSleep(200);
7252 } 7763 }
7253 7764
7254 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7765 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7255 { 7766 {
7256 m_host.AddScriptLPS(1); 7767 m_host.AddScriptLPS(1);
7257 7768
7258 setLinkPrimParams(linknumber, rules); 7769 setLinkPrimParams(linknumber, rules);
7770 }
7771
7772 private void setLinkPrimParams(int linknumber, LSL_List rules)
7773 {
7774 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7775 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7776 if (parts.Count>0)
7777 {
7778 try
7779 {
7780 parts[0].ParentGroup.areUpdatesSuspended = true;
7781 foreach (SceneObjectPart part in parts)
7782 SetPrimParams(part, rules);
7783 }
7784 finally
7785 {
7786 parts[0].ParentGroup.areUpdatesSuspended = false;
7787 }
7788 }
7789 if (avatars.Count > 0)
7790 {
7791 foreach (ScenePresence avatar in avatars)
7792 SetPrimParams(avatar, rules);
7793 }
7794 }
7259 7795
7796 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7797 float material_density, float material_friction,
7798 float material_restitution, float material_gravity_modifier)
7799 {
7800 ExtraPhysicsData physdata = new ExtraPhysicsData();
7801 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7802 physdata.Density = part.Density;
7803 physdata.Friction = part.Friction;
7804 physdata.Bounce = part.Bounciness;
7805 physdata.GravitationModifier = part.GravityModifier;
7806
7807 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7808 physdata.Density = material_density;
7809 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7810 physdata.Friction = material_friction;
7811 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7812 physdata.Bounce = material_restitution;
7813 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7814 physdata.GravitationModifier = material_gravity_modifier;
7815
7816 part.UpdateExtraPhysics(physdata);
7817 }
7818
7819 public void llSetPhysicsMaterial(int material_bits,
7820 float material_gravity_modifier, float material_restitution,
7821 float material_friction, float material_density)
7822 {
7823 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7824 }
7825
7826 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7827 {
7828 llSetLinkPrimitiveParamsFast(linknumber, rules);
7260 ScriptSleep(200); 7829 ScriptSleep(200);
7261 } 7830 }
7262 7831
7263 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7832 // vector up using libomv (c&p from sop )
7833 // vector up rotated by r
7834 private Vector3 Zrot(Quaternion r)
7264 { 7835 {
7265 m_host.AddScriptLPS(1); 7836 double x, y, z, m;
7266 7837
7267 setLinkPrimParams(linknumber, rules); 7838 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7839 if (Math.Abs(1.0 - m) > 0.000001)
7840 {
7841 m = 1.0 / Math.Sqrt(m);
7842 r.X *= (float)m;
7843 r.Y *= (float)m;
7844 r.Z *= (float)m;
7845 r.W *= (float)m;
7846 }
7847
7848 x = 2 * (r.X * r.Z + r.Y * r.W);
7849 y = 2 * (-r.X * r.W + r.Y * r.Z);
7850 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7851
7852 return new Vector3((float)x, (float)y, (float)z);
7268 } 7853 }
7269 7854
7270 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7855 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7271 { 7856 {
7272 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7857 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7273 7858
7274 foreach (SceneObjectPart part in parts) 7859 int idx = 0;
7275 SetPrimParams(part, rules); 7860
7861 bool positionChanged = false;
7862 Vector3 finalPos = Vector3.Zero;
7863
7864 try
7865 {
7866 while (idx < rules.Length)
7867 {
7868 int code = rules.GetLSLIntegerItem(idx++);
7869
7870 int remain = rules.Length - idx;
7871
7872 switch (code)
7873 {
7874 case (int)ScriptBaseClass.PRIM_POSITION:
7875 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7876 {
7877 if (remain < 1)
7878 return;
7879
7880 LSL_Vector v;
7881 v = rules.GetVector3Item(idx++);
7882
7883 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7884 if (part == null)
7885 break;
7886
7887 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7888 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7889 if (part.LinkNum > 1)
7890 {
7891 localRot = GetPartLocalRot(part);
7892 localPos = GetPartLocalPos(part);
7893 }
7894
7895 v -= localPos;
7896 v /= localRot;
7897
7898 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7899
7900 v = v + 2 * sitOffset;
7901
7902 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7903 av.SendAvatarDataToAllAgents();
7904
7905 }
7906 break;
7907
7908 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7909 case (int)ScriptBaseClass.PRIM_ROTATION:
7910 {
7911 if (remain < 1)
7912 return;
7913
7914 LSL_Rotation r;
7915 r = rules.GetQuaternionItem(idx++);
7916
7917 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7918 if (part == null)
7919 break;
7920
7921 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7922 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7923
7924 if (part.LinkNum > 1)
7925 localRot = GetPartLocalRot(part);
7926
7927 r = r * llGetRootRotation() / localRot;
7928 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7929 av.SendAvatarDataToAllAgents();
7930 }
7931 break;
7932
7933 // parse rest doing nothing but number of parameters error check
7934 case (int)ScriptBaseClass.PRIM_SIZE:
7935 case (int)ScriptBaseClass.PRIM_MATERIAL:
7936 case (int)ScriptBaseClass.PRIM_PHANTOM:
7937 case (int)ScriptBaseClass.PRIM_PHYSICS:
7938 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7939 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7940 case (int)ScriptBaseClass.PRIM_NAME:
7941 case (int)ScriptBaseClass.PRIM_DESC:
7942 if (remain < 1)
7943 return;
7944 idx++;
7945 break;
7946
7947 case (int)ScriptBaseClass.PRIM_GLOW:
7948 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7949 case (int)ScriptBaseClass.PRIM_TEXGEN:
7950 if (remain < 2)
7951 return;
7952 idx += 2;
7953 break;
7954
7955 case (int)ScriptBaseClass.PRIM_TYPE:
7956 if (remain < 3)
7957 return;
7958 code = (int)rules.GetLSLIntegerItem(idx++);
7959 remain = rules.Length - idx;
7960 switch (code)
7961 {
7962 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7963 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7964 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7965 if (remain < 6)
7966 return;
7967 idx += 6;
7968 break;
7969
7970 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7971 if (remain < 5)
7972 return;
7973 idx += 5;
7974 break;
7975
7976 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7977 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7978 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7979 if (remain < 11)
7980 return;
7981 idx += 11;
7982 break;
7983
7984 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7985 if (remain < 2)
7986 return;
7987 idx += 2;
7988 break;
7989 }
7990 break;
7991
7992 case (int)ScriptBaseClass.PRIM_COLOR:
7993 case (int)ScriptBaseClass.PRIM_TEXT:
7994 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7995 case (int)ScriptBaseClass.PRIM_OMEGA:
7996 if (remain < 3)
7997 return;
7998 idx += 3;
7999 break;
8000
8001 case (int)ScriptBaseClass.PRIM_TEXTURE:
8002 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8003 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8004 if (remain < 5)
8005 return;
8006 idx += 5;
8007 break;
8008
8009 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8010 if (remain < 7)
8011 return;
8012
8013 idx += 7;
8014 break;
8015
8016 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8017 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8018 return;
8019
8020 if (positionChanged)
8021 {
8022 positionChanged = false;
8023 av.OffsetPosition = finalPos;
8024// av.SendAvatarDataToAllAgents();
8025 av.SendTerseUpdateToAllClients();
8026 }
8027
8028 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
8029 LSL_List new_rules = rules.GetSublist(idx, -1);
8030 setLinkPrimParams((int)new_linknumber, new_rules);
8031 return;
8032 }
8033 }
8034 }
8035
8036 finally
8037 {
8038 if (positionChanged)
8039 {
8040 av.OffsetPosition = finalPos;
8041// av.SendAvatarDataToAllAgents();
8042 av.SendTerseUpdateToAllClients();
8043 positionChanged = false;
8044 }
8045 }
7276 } 8046 }
7277 8047
7278 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 8048 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7279 { 8049 {
8050 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8051 return;
8052
7280 int idx = 0; 8053 int idx = 0;
7281 8054
8055 SceneObjectGroup parentgrp = part.ParentGroup;
8056
7282 bool positionChanged = false; 8057 bool positionChanged = false;
7283 LSL_Vector currentPosition = GetPartLocalPos(part); 8058 LSL_Vector currentPosition = GetPartLocalPos(part);
7284 8059
@@ -7301,8 +8076,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7301 return; 8076 return;
7302 8077
7303 v=rules.GetVector3Item(idx++); 8078 v=rules.GetVector3Item(idx++);
7304 positionChanged = true;
7305 currentPosition = GetSetPosTarget(part, v, currentPosition); 8079 currentPosition = GetSetPosTarget(part, v, currentPosition);
8080 positionChanged = true;
7306 8081
7307 break; 8082 break;
7308 case (int)ScriptBaseClass.PRIM_SIZE: 8083 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7318,8 +8093,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7318 return; 8093 return;
7319 8094
7320 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8095 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8096 SceneObjectPart rootPart = parentgrp.RootPart;
7321 // try to let this work as in SL... 8097 // try to let this work as in SL...
7322 if (part.ParentID == 0) 8098 if (rootPart == part)
7323 { 8099 {
7324 // special case: If we are root, rotate complete SOG to new rotation 8100 // special case: If we are root, rotate complete SOG to new rotation
7325 SetRot(part, Rot2Quaternion(q)); 8101 SetRot(part, Rot2Quaternion(q));
@@ -7327,7 +8103,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7327 else 8103 else
7328 { 8104 {
7329 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8105 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7330 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8106 // sounds like sl bug that we need to replicate
7331 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8107 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7332 } 8108 }
7333 8109
@@ -7580,7 +8356,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7580 return; 8356 return;
7581 8357
7582 string ph = rules.Data[idx++].ToString(); 8358 string ph = rules.Data[idx++].ToString();
7583 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8359 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7584 8360
7585 break; 8361 break;
7586 8362
@@ -7598,12 +8374,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7598 part.ScriptSetPhysicsStatus(physics); 8374 part.ScriptSetPhysicsStatus(physics);
7599 break; 8375 break;
7600 8376
8377 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8378 if (remain < 1)
8379 return;
8380
8381 int shape_type = rules.GetLSLIntegerItem(idx++);
8382
8383 ExtraPhysicsData physdata = new ExtraPhysicsData();
8384 physdata.Density = part.Density;
8385 physdata.Bounce = part.Bounciness;
8386 physdata.GravitationModifier = part.GravityModifier;
8387 physdata.PhysShapeType = (PhysShapeType)shape_type;
8388
8389 part.UpdateExtraPhysics(physdata);
8390
8391 break;
8392
8393 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8394 if (remain < 5)
8395 return;
8396
8397 int material_bits = rules.GetLSLIntegerItem(idx++);
8398 float material_density = (float)rules.GetLSLFloatItem(idx++);
8399 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8400 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8401 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8402
8403 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8404
8405 break;
8406
7601 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8407 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7602 if (remain < 1) 8408 if (remain < 1)
7603 return; 8409 return;
7604 string temp = rules.Data[idx++].ToString(); 8410 string temp = rules.Data[idx++].ToString();
7605 8411
7606 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8412 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7607 8413
7608 break; 8414 break;
7609 8415
@@ -7642,6 +8448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7642 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8448 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7643 if (remain < 1) 8449 if (remain < 1)
7644 return; 8450 return;
8451
7645 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8452 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7646 SetRot(part, Rot2Quaternion(lr)); 8453 SetRot(part, Rot2Quaternion(lr));
7647 break; 8454 break;
@@ -7653,13 +8460,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7653 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8460 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7654 TargetOmega(part, axis, (double)spinrate, (double)gain); 8461 TargetOmega(part, axis, (double)spinrate, (double)gain);
7655 break; 8462 break;
8463
7656 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8464 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7657 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8465 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7658 return; 8466 return;
8467
8468 // do a pending position change before jumping to other part/avatar
8469 if (positionChanged)
8470 {
8471 positionChanged = false;
8472 if (parentgrp == null)
8473 return;
8474
8475 if (parentgrp.RootPart == part)
8476 {
8477
8478 Util.FireAndForget(delegate(object x)
8479 {
8480 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8481 });
8482 }
8483 else
8484 {
8485 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8486 parentgrp.HasGroupChanged = true;
8487 parentgrp.ScheduleGroupForTerseUpdate();
8488 }
8489 }
8490
7659 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8491 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7660 LSL_List new_rules = rules.GetSublist(idx, -1); 8492 LSL_List new_rules = rules.GetSublist(idx, -1);
7661 setLinkPrimParams((int)new_linknumber, new_rules); 8493 setLinkPrimParams((int)new_linknumber, new_rules);
7662
7663 return; 8494 return;
7664 } 8495 }
7665 } 8496 }
@@ -7671,7 +8502,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7671 if (part.ParentGroup.RootPart == part) 8502 if (part.ParentGroup.RootPart == part)
7672 { 8503 {
7673 SceneObjectGroup parent = part.ParentGroup; 8504 SceneObjectGroup parent = part.ParentGroup;
7674 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8505 Util.FireAndForget(delegate(object x) {
8506 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8507 });
7675 } 8508 }
7676 else 8509 else
7677 { 8510 {
@@ -7715,10 +8548,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7715 8548
7716 public LSL_String llXorBase64Strings(string str1, string str2) 8549 public LSL_String llXorBase64Strings(string str1, string str2)
7717 { 8550 {
7718 m_host.AddScriptLPS(1); 8551 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7719 Deprecated("llXorBase64Strings"); 8552
7720 ScriptSleep(300); 8553 ScriptSleep(300);
7721 return String.Empty; 8554 m_host.AddScriptLPS(1);
8555
8556 if (str1 == String.Empty)
8557 return String.Empty;
8558 if (str2 == String.Empty)
8559 return str1;
8560
8561 int len = str2.Length;
8562 if ((len % 4) != 0) // LL is EVIL!!!!
8563 {
8564 while (str2.EndsWith("="))
8565 str2 = str2.Substring(0, str2.Length - 1);
8566
8567 len = str2.Length;
8568 int mod = len % 4;
8569
8570 if (mod == 1)
8571 str2 = str2.Substring(0, str2.Length - 1);
8572 else if (mod == 2)
8573 str2 += "==";
8574 else if (mod == 3)
8575 str2 += "=";
8576 }
8577
8578 byte[] data1;
8579 byte[] data2;
8580 try
8581 {
8582 data1 = Convert.FromBase64String(str1);
8583 data2 = Convert.FromBase64String(str2);
8584 }
8585 catch (Exception)
8586 {
8587 return new LSL_String(String.Empty);
8588 }
8589
8590 // For cases where the decoded length of s2 is greater
8591 // than the decoded length of s1, simply perform a normal
8592 // decode and XOR
8593 //
8594 if (data2.Length >= data1.Length)
8595 {
8596 for (int pos = 0 ; pos < data1.Length ; pos++ )
8597 data1[pos] ^= data2[pos];
8598
8599 return Convert.ToBase64String(data1);
8600 }
8601
8602 // Remove padding
8603 while (str1.EndsWith("="))
8604 str1 = str1.Substring(0, str1.Length - 1);
8605 while (str2.EndsWith("="))
8606 str2 = str2.Substring(0, str2.Length - 1);
8607
8608 byte[] d1 = new byte[str1.Length];
8609 byte[] d2 = new byte[str2.Length];
8610
8611 for (int i = 0 ; i < str1.Length ; i++)
8612 {
8613 int idx = b64.IndexOf(str1.Substring(i, 1));
8614 if (idx == -1)
8615 idx = 0;
8616 d1[i] = (byte)idx;
8617 }
8618
8619 for (int i = 0 ; i < str2.Length ; i++)
8620 {
8621 int idx = b64.IndexOf(str2.Substring(i, 1));
8622 if (idx == -1)
8623 idx = 0;
8624 d2[i] = (byte)idx;
8625 }
8626
8627 string output = String.Empty;
8628
8629 for (int pos = 0 ; pos < d1.Length ; pos++)
8630 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8631
8632 while (output.Length % 3 > 0)
8633 output += "=";
8634
8635 return output;
7722 } 8636 }
7723 8637
7724 public void llRemoteDataSetRegion() 8638 public void llRemoteDataSetRegion()
@@ -7842,13 +8756,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7842 public LSL_Integer llGetNumberOfPrims() 8756 public LSL_Integer llGetNumberOfPrims()
7843 { 8757 {
7844 m_host.AddScriptLPS(1); 8758 m_host.AddScriptLPS(1);
7845 int avatarCount = 0; 8759 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7846 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8760
7847 {
7848 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7849 avatarCount++;
7850 });
7851
7852 return m_host.ParentGroup.PrimCount + avatarCount; 8761 return m_host.ParentGroup.PrimCount + avatarCount;
7853 } 8762 }
7854 8763
@@ -7864,55 +8773,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7864 m_host.AddScriptLPS(1); 8773 m_host.AddScriptLPS(1);
7865 UUID objID = UUID.Zero; 8774 UUID objID = UUID.Zero;
7866 LSL_List result = new LSL_List(); 8775 LSL_List result = new LSL_List();
8776
8777 // If the ID is not valid, return null result
7867 if (!UUID.TryParse(obj, out objID)) 8778 if (!UUID.TryParse(obj, out objID))
7868 { 8779 {
7869 result.Add(new LSL_Vector()); 8780 result.Add(new LSL_Vector());
7870 result.Add(new LSL_Vector()); 8781 result.Add(new LSL_Vector());
7871 return result; 8782 return result;
7872 } 8783 }
8784
8785 // Check if this is an attached prim. If so, replace
8786 // the UUID with the avatar UUID and report it's bounding box
8787 SceneObjectPart part = World.GetSceneObjectPart(objID);
8788 if (part != null && part.ParentGroup.IsAttachment)
8789 objID = part.ParentGroup.AttachedAvatar;
8790
8791 // Find out if this is an avatar ID. If so, return it's box
7873 ScenePresence presence = World.GetScenePresence(objID); 8792 ScenePresence presence = World.GetScenePresence(objID);
7874 if (presence != null) 8793 if (presence != null)
7875 { 8794 {
7876 if (presence.ParentID == 0) // not sat on an object 8795 // As per LSL Wiki, there is no difference between sitting
8796 // and standing avatar since server 1.36
8797 LSL_Vector lower;
8798 LSL_Vector upper;
8799 if (presence.Animator.Animations.DefaultAnimation.AnimID
8800 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7877 { 8801 {
7878 LSL_Vector lower; 8802 // This is for ground sitting avatars
7879 LSL_Vector upper; 8803 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7880 if (presence.Animator.Animations.DefaultAnimation.AnimID 8804 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7881 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8805 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7882 {
7883 // This is for ground sitting avatars
7884 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7885 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7886 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7887 }
7888 else
7889 {
7890 // This is for standing/flying avatars
7891 float height = presence.Appearance.AvatarHeight / 2.0f;
7892 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7893 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7894 }
7895 result.Add(lower);
7896 result.Add(upper);
7897 return result;
7898 } 8806 }
7899 else 8807 else
7900 { 8808 {
7901 // sitting on an object so we need the bounding box of that 8809 // This is for standing/flying avatars
7902 // which should include the avatar so set the UUID to the 8810 float height = presence.Appearance.AvatarHeight / 2.0f;
7903 // UUID of the object the avatar is sat on and allow it to fall through 8811 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7904 // to processing an object 8812 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7905 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7906 objID = p.UUID;
7907 } 8813 }
8814
8815 // Adjust to the documented error offsets (see LSL Wiki)
8816 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8817 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8818
8819 if (lower.x > upper.x)
8820 lower.x = upper.x;
8821 if (lower.y > upper.y)
8822 lower.y = upper.y;
8823 if (lower.z > upper.z)
8824 lower.z = upper.z;
8825
8826 result.Add(lower);
8827 result.Add(upper);
8828 return result;
7908 } 8829 }
7909 SceneObjectPart part = World.GetSceneObjectPart(objID); 8830
8831 part = World.GetSceneObjectPart(objID);
7910 // Currently only works for single prims without a sitting avatar 8832 // Currently only works for single prims without a sitting avatar
7911 if (part != null) 8833 if (part != null)
7912 { 8834 {
7913 Vector3 halfSize = part.Scale / 2.0f; 8835 float minX;
7914 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8836 float maxX;
7915 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8837 float minY;
8838 float maxY;
8839 float minZ;
8840 float maxZ;
8841
8842 // This BBox is in sim coordinates, with the offset being
8843 // a contained point.
8844 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8845 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8846
8847 minX -= offsets[0].X;
8848 maxX -= offsets[0].X;
8849 minY -= offsets[0].Y;
8850 maxY -= offsets[0].Y;
8851 minZ -= offsets[0].Z;
8852 maxZ -= offsets[0].Z;
8853
8854 LSL_Vector lower;
8855 LSL_Vector upper;
8856
8857 // Adjust to the documented error offsets (see LSL Wiki)
8858 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8859 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8860
8861 if (lower.x > upper.x)
8862 lower.x = upper.x;
8863 if (lower.y > upper.y)
8864 lower.y = upper.y;
8865 if (lower.z > upper.z)
8866 lower.z = upper.z;
8867
7916 result.Add(lower); 8868 result.Add(lower);
7917 result.Add(upper); 8869 result.Add(upper);
7918 return result; 8870 return result;
@@ -7926,7 +8878,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7926 8878
7927 public LSL_Vector llGetGeometricCenter() 8879 public LSL_Vector llGetGeometricCenter()
7928 { 8880 {
7929 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8881 Vector3 tmp = m_host.GetGeometricCenter();
8882 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7930 } 8883 }
7931 8884
7932 public LSL_List llGetPrimitiveParams(LSL_List rules) 8885 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7939,16 +8892,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7939 { 8892 {
7940 m_host.AddScriptLPS(1); 8893 m_host.AddScriptLPS(1);
7941 8894
8895 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8896 // keep other options as before
8897
7942 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8898 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8899 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7943 8900
7944 LSL_List res = new LSL_List(); 8901 LSL_List res = new LSL_List();
7945 8902
7946 foreach (var part in parts) 8903 if (parts.Count > 0)
7947 { 8904 {
7948 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8905 foreach (var part in parts)
7949 res += partRes; 8906 {
8907 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8908 res += partRes;
8909 }
8910 }
8911 if (avatars.Count > 0)
8912 {
8913 foreach (ScenePresence avatar in avatars)
8914 {
8915 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8916 res += avaRes;
8917 }
7950 } 8918 }
8919 return res;
8920 }
8921
8922 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8923 {
8924 // avatars case
8925 // replies as SL wiki
8926
8927 LSL_List res = new LSL_List();
8928// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8929 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8930
8931 int idx = 0;
8932 while (idx < rules.Length)
8933 {
8934 int code = (int)rules.GetLSLIntegerItem(idx++);
8935 int remain = rules.Length - idx;
8936
8937 switch (code)
8938 {
8939 case (int)ScriptBaseClass.PRIM_MATERIAL:
8940 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8941 break;
8942
8943 case (int)ScriptBaseClass.PRIM_PHYSICS:
8944 res.Add(new LSL_Integer(0));
8945 break;
8946
8947 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8948 res.Add(new LSL_Integer(0));
8949 break;
8950
8951 case (int)ScriptBaseClass.PRIM_PHANTOM:
8952 res.Add(new LSL_Integer(0));
8953 break;
8954
8955 case (int)ScriptBaseClass.PRIM_POSITION:
8956
8957 Vector3 pos = avatar.OffsetPosition;
8958
8959 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8960 pos -= sitOffset;
8961
8962 if( sitPart != null)
8963 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8964
8965 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8966 break;
8967
8968 case (int)ScriptBaseClass.PRIM_SIZE:
8969 // as in llGetAgentSize above
8970 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8971 break;
8972
8973 case (int)ScriptBaseClass.PRIM_ROTATION:
8974 Quaternion rot = avatar.Rotation;
8975 if (sitPart != null)
8976 {
8977 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8978 }
7951 8979
8980 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8981 break;
8982
8983 case (int)ScriptBaseClass.PRIM_TYPE:
8984 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8985 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8986 res.Add(new LSL_Vector(0f,1.0f,0f));
8987 res.Add(new LSL_Float(0.0f));
8988 res.Add(new LSL_Vector(0, 0, 0));
8989 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8990 res.Add(new LSL_Vector(0, 0, 0));
8991 break;
8992
8993 case (int)ScriptBaseClass.PRIM_TEXTURE:
8994 if (remain < 1)
8995 return res;
8996
8997 int face = (int)rules.GetLSLIntegerItem(idx++);
8998 if (face == ScriptBaseClass.ALL_SIDES)
8999 {
9000 for (face = 0; face < 21; face++)
9001 {
9002 res.Add(new LSL_String(""));
9003 res.Add(new LSL_Vector(0,0,0));
9004 res.Add(new LSL_Vector(0,0,0));
9005 res.Add(new LSL_Float(0.0));
9006 }
9007 }
9008 else
9009 {
9010 if (face >= 0 && face < 21)
9011 {
9012 res.Add(new LSL_String(""));
9013 res.Add(new LSL_Vector(0,0,0));
9014 res.Add(new LSL_Vector(0,0,0));
9015 res.Add(new LSL_Float(0.0));
9016 }
9017 }
9018 break;
9019
9020 case (int)ScriptBaseClass.PRIM_COLOR:
9021 if (remain < 1)
9022 return res;
9023
9024 face = (int)rules.GetLSLIntegerItem(idx++);
9025
9026 if (face == ScriptBaseClass.ALL_SIDES)
9027 {
9028 for (face = 0; face < 21; face++)
9029 {
9030 res.Add(new LSL_Vector(0,0,0));
9031 res.Add(new LSL_Float(0));
9032 }
9033 }
9034 else
9035 {
9036 res.Add(new LSL_Vector(0,0,0));
9037 res.Add(new LSL_Float(0));
9038 }
9039 break;
9040
9041 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
9042 if (remain < 1)
9043 return res;
9044 face = (int)rules.GetLSLIntegerItem(idx++);
9045
9046 if (face == ScriptBaseClass.ALL_SIDES)
9047 {
9048 for (face = 0; face < 21; face++)
9049 {
9050 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9051 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9052 }
9053 }
9054 else
9055 {
9056 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
9057 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
9058 }
9059 break;
9060
9061 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
9062 if (remain < 1)
9063 return res;
9064 face = (int)rules.GetLSLIntegerItem(idx++);
9065
9066 if (face == ScriptBaseClass.ALL_SIDES)
9067 {
9068 for (face = 0; face < 21; face++)
9069 {
9070 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9071 }
9072 }
9073 else
9074 {
9075 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9076 }
9077 break;
9078
9079 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9080 res.Add(new LSL_Integer(0));
9081 res.Add(new LSL_Integer(0));// softness
9082 res.Add(new LSL_Float(0.0f)); // gravity
9083 res.Add(new LSL_Float(0.0f)); // friction
9084 res.Add(new LSL_Float(0.0f)); // wind
9085 res.Add(new LSL_Float(0.0f)); // tension
9086 res.Add(new LSL_Vector(0f,0f,0f));
9087 break;
9088
9089 case (int)ScriptBaseClass.PRIM_TEXGEN:
9090 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9091 if (remain < 1)
9092 return res;
9093 face = (int)rules.GetLSLIntegerItem(idx++);
9094
9095 if (face == ScriptBaseClass.ALL_SIDES)
9096 {
9097 for (face = 0; face < 21; face++)
9098 {
9099 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9100 }
9101 }
9102 else
9103 {
9104 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9105 }
9106 break;
9107
9108 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9109 res.Add(new LSL_Integer(0));
9110 res.Add(new LSL_Vector(0f,0f,0f));
9111 res.Add(new LSL_Float(0f)); // intensity
9112 res.Add(new LSL_Float(0f)); // radius
9113 res.Add(new LSL_Float(0f)); // falloff
9114 break;
9115
9116 case (int)ScriptBaseClass.PRIM_GLOW:
9117 if (remain < 1)
9118 return res;
9119 face = (int)rules.GetLSLIntegerItem(idx++);
9120
9121 if (face == ScriptBaseClass.ALL_SIDES)
9122 {
9123 for (face = 0; face < 21; face++)
9124 {
9125 res.Add(new LSL_Float(0f));
9126 }
9127 }
9128 else
9129 {
9130 res.Add(new LSL_Float(0f));
9131 }
9132 break;
9133
9134 case (int)ScriptBaseClass.PRIM_TEXT:
9135 res.Add(new LSL_String(""));
9136 res.Add(new LSL_Vector(0f,0f,0f));
9137 res.Add(new LSL_Float(1.0f));
9138 break;
9139
9140 case (int)ScriptBaseClass.PRIM_NAME:
9141 res.Add(new LSL_String(avatar.Name));
9142 break;
9143
9144 case (int)ScriptBaseClass.PRIM_DESC:
9145 res.Add(new LSL_String(""));
9146 break;
9147
9148 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9149 Quaternion lrot = avatar.Rotation;
9150
9151 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9152 {
9153 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9154 }
9155 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9156 break;
9157
9158 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9159 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9160 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9161 lpos -= lsitOffset;
9162
9163 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9164 {
9165 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9166 }
9167 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9168 break;
9169
9170 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9171 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9172 return res;
9173 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9174 LSL_List new_rules = rules.GetSublist(idx, -1);
9175
9176 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9177 return res;
9178 }
9179 }
7952 return res; 9180 return res;
7953 } 9181 }
7954 9182
@@ -7992,13 +9220,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7992 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9220 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7993 part.AbsolutePosition.Y, 9221 part.AbsolutePosition.Y,
7994 part.AbsolutePosition.Z); 9222 part.AbsolutePosition.Z);
7995 // For some reason, the part.AbsolutePosition.* values do not change if the
7996 // linkset is rotated; they always reflect the child prim's world position
7997 // as though the linkset is unrotated. This is incompatible behavior with SL's
7998 // implementation, so will break scripts imported from there (not to mention it
7999 // makes it more difficult to determine a child prim's actual inworld position).
8000 if (part.ParentID != 0)
8001 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8002 res.Add(v); 9223 res.Add(v);
8003 break; 9224 break;
8004 9225
@@ -8169,56 +9390,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8169 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9390 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8170 if (remain < 1) 9391 if (remain < 1)
8171 return res; 9392 return res;
8172 9393 face = (int)rules.GetLSLIntegerItem(idx++);
8173 face=(int)rules.GetLSLIntegerItem(idx++);
8174 9394
8175 tex = part.Shape.Textures; 9395 tex = part.Shape.Textures;
9396 int shiny;
8176 if (face == ScriptBaseClass.ALL_SIDES) 9397 if (face == ScriptBaseClass.ALL_SIDES)
8177 { 9398 {
8178 for (face = 0; face < GetNumberOfSides(part); face++) 9399 for (face = 0; face < GetNumberOfSides(part); face++)
8179 { 9400 {
8180 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9401 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8181 // Convert Shininess to PRIM_SHINY_* 9402 if (shinyness == Shininess.High)
8182 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9403 {
8183 // PRIM_BUMP_* 9404 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8184 res.Add(new LSL_Integer((int)texface.Bump)); 9405 }
9406 else if (shinyness == Shininess.Medium)
9407 {
9408 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9409 }
9410 else if (shinyness == Shininess.Low)
9411 {
9412 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9413 }
9414 else
9415 {
9416 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9417 }
9418 res.Add(new LSL_Integer(shiny));
9419 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8185 } 9420 }
8186 } 9421 }
8187 else 9422 else
8188 { 9423 {
8189 if (face >= 0 && face < GetNumberOfSides(part)) 9424 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9425 if (shinyness == Shininess.High)
8190 { 9426 {
8191 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9427 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8192 // Convert Shininess to PRIM_SHINY_* 9428 }
8193 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9429 else if (shinyness == Shininess.Medium)
8194 // PRIM_BUMP_* 9430 {
8195 res.Add(new LSL_Integer((int)texface.Bump)); 9431 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9432 }
9433 else if (shinyness == Shininess.Low)
9434 {
9435 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8196 } 9436 }
9437 else
9438 {
9439 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9440 }
9441 res.Add(new LSL_Integer(shiny));
9442 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8197 } 9443 }
8198 break; 9444 break;
8199 9445
8200 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9446 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8201 if (remain < 1) 9447 if (remain < 1)
8202 return res; 9448 return res;
8203 9449 face = (int)rules.GetLSLIntegerItem(idx++);
8204 face=(int)rules.GetLSLIntegerItem(idx++);
8205 9450
8206 tex = part.Shape.Textures; 9451 tex = part.Shape.Textures;
9452 int fullbright;
8207 if (face == ScriptBaseClass.ALL_SIDES) 9453 if (face == ScriptBaseClass.ALL_SIDES)
8208 { 9454 {
8209 for (face = 0; face < GetNumberOfSides(part); face++) 9455 for (face = 0; face < GetNumberOfSides(part); face++)
8210 { 9456 {
8211 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9457 if (tex.GetFace((uint)face).Fullbright == true)
8212 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9458 {
9459 fullbright = ScriptBaseClass.TRUE;
9460 }
9461 else
9462 {
9463 fullbright = ScriptBaseClass.FALSE;
9464 }
9465 res.Add(new LSL_Integer(fullbright));
8213 } 9466 }
8214 } 9467 }
8215 else 9468 else
8216 { 9469 {
8217 if (face >= 0 && face < GetNumberOfSides(part)) 9470 if (tex.GetFace((uint)face).Fullbright == true)
8218 { 9471 {
8219 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9472 fullbright = ScriptBaseClass.TRUE;
8220 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8221 } 9473 }
9474 else
9475 {
9476 fullbright = ScriptBaseClass.FALSE;
9477 }
9478 res.Add(new LSL_Integer(fullbright));
8222 } 9479 }
8223 break; 9480 break;
8224 9481
@@ -8240,27 +9497,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8240 break; 9497 break;
8241 9498
8242 case (int)ScriptBaseClass.PRIM_TEXGEN: 9499 case (int)ScriptBaseClass.PRIM_TEXGEN:
9500 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8243 if (remain < 1) 9501 if (remain < 1)
8244 return res; 9502 return res;
8245 9503 face = (int)rules.GetLSLIntegerItem(idx++);
8246 face=(int)rules.GetLSLIntegerItem(idx++);
8247 9504
8248 tex = part.Shape.Textures; 9505 tex = part.Shape.Textures;
8249 if (face == ScriptBaseClass.ALL_SIDES) 9506 if (face == ScriptBaseClass.ALL_SIDES)
8250 { 9507 {
8251 for (face = 0; face < GetNumberOfSides(part); face++) 9508 for (face = 0; face < GetNumberOfSides(part); face++)
8252 { 9509 {
8253 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9510 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8254 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9511 {
8255 res.Add(new LSL_Integer((uint)texgen >> 1)); 9512 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9513 }
9514 else
9515 {
9516 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9517 }
8256 } 9518 }
8257 } 9519 }
8258 else 9520 else
8259 { 9521 {
8260 if (face >= 0 && face < GetNumberOfSides(part)) 9522 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8261 { 9523 {
8262 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9524 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8263 res.Add(new LSL_Integer((uint)texgen >> 1)); 9525 }
9526 else
9527 {
9528 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8264 } 9529 }
8265 } 9530 }
8266 break; 9531 break;
@@ -8283,25 +9548,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8283 case (int)ScriptBaseClass.PRIM_GLOW: 9548 case (int)ScriptBaseClass.PRIM_GLOW:
8284 if (remain < 1) 9549 if (remain < 1)
8285 return res; 9550 return res;
8286 9551 face = (int)rules.GetLSLIntegerItem(idx++);
8287 face=(int)rules.GetLSLIntegerItem(idx++);
8288 9552
8289 tex = part.Shape.Textures; 9553 tex = part.Shape.Textures;
9554 float primglow;
8290 if (face == ScriptBaseClass.ALL_SIDES) 9555 if (face == ScriptBaseClass.ALL_SIDES)
8291 { 9556 {
8292 for (face = 0; face < GetNumberOfSides(part); face++) 9557 for (face = 0; face < GetNumberOfSides(part); face++)
8293 { 9558 {
8294 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9559 primglow = tex.GetFace((uint)face).Glow;
8295 res.Add(new LSL_Float(texface.Glow)); 9560 res.Add(new LSL_Float(primglow));
8296 } 9561 }
8297 } 9562 }
8298 else 9563 else
8299 { 9564 {
8300 if (face >= 0 && face < GetNumberOfSides(part)) 9565 primglow = tex.GetFace((uint)face).Glow;
8301 { 9566 res.Add(new LSL_Float(primglow));
8302 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8303 res.Add(new LSL_Float(texface.Glow));
8304 }
8305 } 9567 }
8306 break; 9568 break;
8307 9569
@@ -8313,18 +9575,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8313 textColor.B)); 9575 textColor.B));
8314 res.Add(new LSL_Float(textColor.A)); 9576 res.Add(new LSL_Float(textColor.A));
8315 break; 9577 break;
9578
8316 case (int)ScriptBaseClass.PRIM_NAME: 9579 case (int)ScriptBaseClass.PRIM_NAME:
8317 res.Add(new LSL_String(part.Name)); 9580 res.Add(new LSL_String(part.Name));
8318 break; 9581 break;
9582
8319 case (int)ScriptBaseClass.PRIM_DESC: 9583 case (int)ScriptBaseClass.PRIM_DESC:
8320 res.Add(new LSL_String(part.Description)); 9584 res.Add(new LSL_String(part.Description));
8321 break; 9585 break;
9586
8322 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9587 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8323 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9588 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8324 break; 9589 break;
9590
8325 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9591 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8326 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9592 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8327 break; 9593 break;
9594
9595 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9596 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9597 return res;
9598 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9599 LSL_List new_rules = rules.GetSublist(idx, -1);
9600 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9601 res += tres;
9602 return res;
8328 } 9603 }
8329 } 9604 }
8330 return res; 9605 return res;
@@ -8917,8 +10192,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8917 // The function returns an ordered list 10192 // The function returns an ordered list
8918 // representing the tokens found in the supplied 10193 // representing the tokens found in the supplied
8919 // sources string. If two successive tokenizers 10194 // sources string. If two successive tokenizers
8920 // are encountered, then a NULL entry is added 10195 // are encountered, then a null-string entry is
8921 // to the list. 10196 // added to the list.
8922 // 10197 //
8923 // It is a precondition that the source and 10198 // It is a precondition that the source and
8924 // toekizer lisst are non-null. If they are null, 10199 // toekizer lisst are non-null. If they are null,
@@ -8926,7 +10201,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8926 // while their lengths are being determined. 10201 // while their lengths are being determined.
8927 // 10202 //
8928 // A small amount of working memoryis required 10203 // A small amount of working memoryis required
8929 // of approximately 8*#tokenizers. 10204 // of approximately 8*#tokenizers + 8*srcstrlen.
8930 // 10205 //
8931 // There are many ways in which this function 10206 // There are many ways in which this function
8932 // can be implemented, this implementation is 10207 // can be implemented, this implementation is
@@ -8942,155 +10217,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8942 // and eliminates redundant tokenizers as soon 10217 // and eliminates redundant tokenizers as soon
8943 // as is possible. 10218 // as is possible.
8944 // 10219 //
8945 // The implementation tries to avoid any copying 10220 // The implementation tries to minimize temporary
8946 // of arrays or other objects. 10221 // garbage generation.
8947 // </remarks> 10222 // </remarks>
8948 10223
8949 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10224 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8950 { 10225 {
8951 int beginning = 0; 10226 return ParseString2List(src, separators, spacers, true);
8952 int srclen = src.Length; 10227 }
8953 int seplen = separators.Length;
8954 object[] separray = separators.Data;
8955 int spclen = spacers.Length;
8956 object[] spcarray = spacers.Data;
8957 int mlen = seplen+spclen;
8958
8959 int[] offset = new int[mlen+1];
8960 bool[] active = new bool[mlen];
8961
8962 int best;
8963 int j;
8964
8965 // Initial capacity reduces resize cost
8966 10228
8967 LSL_List tokens = new LSL_List(); 10229 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10230 {
10231 int srclen = src.Length;
10232 int seplen = separators.Length;
10233 object[] separray = separators.Data;
10234 int spclen = spacers.Length;
10235 object[] spcarray = spacers.Data;
10236 int dellen = 0;
10237 string[] delarray = new string[seplen+spclen];
8968 10238
8969 // All entries are initially valid 10239 int outlen = 0;
10240 string[] outarray = new string[srclen*2+1];
8970 10241
8971 for (int i = 0; i < mlen; i++) 10242 int i, j;
8972 active[i] = true; 10243 string d;
8973 10244
8974 offset[mlen] = srclen; 10245 m_host.AddScriptLPS(1);
8975 10246
8976 while (beginning < srclen) 10247 /*
10248 * Convert separator and spacer lists to C# strings.
10249 * Also filter out null strings so we don't hang.
10250 */
10251 for (i = 0; i < seplen; i ++)
8977 { 10252 {
10253 d = separray[i].ToString();
10254 if (d.Length > 0)
10255 {
10256 delarray[dellen++] = d;
10257 }
10258 }
10259 seplen = dellen;
8978 10260
8979 best = mlen; // as bad as it gets 10261 for (i = 0; i < spclen; i ++)
10262 {
10263 d = spcarray[i].ToString();
10264 if (d.Length > 0)
10265 {
10266 delarray[dellen++] = d;
10267 }
10268 }
8980 10269
8981 // Scan for separators 10270 /*
10271 * Scan through source string from beginning to end.
10272 */
10273 for (i = 0;;)
10274 {
8982 10275
8983 for (j = 0; j < seplen; j++) 10276 /*
10277 * Find earliest delimeter in src starting at i (if any).
10278 */
10279 int earliestDel = -1;
10280 int earliestSrc = srclen;
10281 string earliestStr = null;
10282 for (j = 0; j < dellen; j ++)
8984 { 10283 {
8985 if (separray[j].ToString() == String.Empty) 10284 d = delarray[j];
8986 active[j] = false; 10285 if (d != null)
8987
8988 if (active[j])
8989 { 10286 {
8990 // scan all of the markers 10287 int index = src.IndexOf(d, i);
8991 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10288 if (index < 0)
8992 { 10289 {
8993 // not present at all 10290 delarray[j] = null; // delim nowhere in src, don't check it anymore
8994 active[j] = false;
8995 } 10291 }
8996 else 10292 else if (index < earliestSrc)
8997 { 10293 {
8998 // present and correct 10294 earliestSrc = index; // where delimeter starts in source string
8999 if (offset[j] < offset[best]) 10295 earliestDel = j; // where delimeter is in delarray[]
9000 { 10296 earliestStr = d; // the delimeter string from delarray[]
9001 // closest so far 10297 if (index == i) break; // can't do any better than found at beg of string
9002 best = j;
9003 if (offset[best] == beginning)
9004 break;
9005 }
9006 } 10298 }
9007 } 10299 }
9008 } 10300 }
9009 10301
9010 // Scan for spacers 10302 /*
9011 10303 * Output source string starting at i through start of earliest delimeter.
9012 if (offset[best] != beginning) 10304 */
10305 if (keepNulls || (earliestSrc > i))
9013 { 10306 {
9014 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10307 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9015 {
9016 if (spcarray[j-seplen].ToString() == String.Empty)
9017 active[j] = false;
9018
9019 if (active[j])
9020 {
9021 // scan all of the markers
9022 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9023 {
9024 // not present at all
9025 active[j] = false;
9026 }
9027 else
9028 {
9029 // present and correct
9030 if (offset[j] < offset[best])
9031 {
9032 // closest so far
9033 best = j;
9034 }
9035 }
9036 }
9037 }
9038 } 10308 }
9039 10309
9040 // This is the normal exit from the scanning loop 10310 /*
10311 * If no delimeter found at or after i, we're done scanning.
10312 */
10313 if (earliestDel < 0) break;
9041 10314
9042 if (best == mlen) 10315 /*
10316 * If delimeter was a spacer, output the spacer.
10317 */
10318 if (earliestDel >= seplen)
9043 { 10319 {
9044 // no markers were found on this pass 10320 outarray[outlen++] = earliestStr;
9045 // so we're pretty much done
9046 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9047 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9048 break;
9049 } 10321 }
9050 10322
9051 // Otherwise we just add the newly delimited token 10323 /*
9052 // and recalculate where the search should continue. 10324 * Look at rest of src string following delimeter.
9053 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10325 */
9054 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10326 i = earliestSrc + earliestStr.Length;
9055
9056 if (best < seplen)
9057 {
9058 beginning = offset[best] + (separray[best].ToString()).Length;
9059 }
9060 else
9061 {
9062 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9063 string str = spcarray[best - seplen].ToString();
9064 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9065 tokens.Add(new LSL_String(str));
9066 }
9067 } 10327 }
9068 10328
9069 // This an awkward an not very intuitive boundary case. If the 10329 /*
9070 // last substring is a tokenizer, then there is an implied trailing 10330 * Make up an exact-sized output array suitable for an LSL_List object.
9071 // null list entry. Hopefully the single comparison will not be too 10331 */
9072 // arduous. Alternatively the 'break' could be replced with a return 10332 object[] outlist = new object[outlen];
9073 // but that's shabby programming. 10333 for (i = 0; i < outlen; i ++)
9074
9075 if ((beginning == srclen) && (keepNulls))
9076 { 10334 {
9077 if (srclen != 0) 10335 outlist[i] = new LSL_String(outarray[i]);
9078 tokens.Add(new LSL_String(""));
9079 } 10336 }
9080 10337 return new LSL_List(outlist);
9081 return tokens;
9082 }
9083
9084 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9085 {
9086 m_host.AddScriptLPS(1);
9087 return this.ParseString(src, separators, spacers, false);
9088 }
9089
9090 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9091 {
9092 m_host.AddScriptLPS(1);
9093 return this.ParseString(src, separators, spacers, true);
9094 } 10338 }
9095 10339
9096 public LSL_Integer llGetObjectPermMask(int mask) 10340 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9185,6 +10429,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9185 case 4: 10429 case 4:
9186 return (int)item.NextPermissions; 10430 return (int)item.NextPermissions;
9187 } 10431 }
10432 m_host.TaskInventory.LockItemsForRead(false);
9188 10433
9189 return -1; 10434 return -1;
9190 } 10435 }
@@ -9375,9 +10620,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9375 { 10620 {
9376 try 10621 try
9377 { 10622 {
10623 /*
9378 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10624 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9379 if (obj != null) 10625 if (obj != null)
9380 return (double)obj.GetMass(); 10626 return (double)obj.GetMass();
10627 */
10628 // return total object mass
10629 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10630 if (obj != null)
10631 return obj.GetMass();
10632
9381 // the object is null so the key is for an avatar 10633 // the object is null so the key is for an avatar
9382 ScenePresence avatar = World.GetScenePresence(key); 10634 ScenePresence avatar = World.GetScenePresence(key);
9383 if (avatar != null) 10635 if (avatar != null)
@@ -9397,7 +10649,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9397 } 10649 }
9398 10650
9399 /// <summary> 10651 /// <summary>
9400 /// illListReplaceList removes the sub-list defined by the inclusive indices 10652 /// llListReplaceList removes the sub-list defined by the inclusive indices
9401 /// start and end and inserts the src list in its place. The inclusive 10653 /// start and end and inserts the src list in its place. The inclusive
9402 /// nature of the indices means that at least one element must be deleted 10654 /// nature of the indices means that at least one element must be deleted
9403 /// if the indices are within the bounds of the existing list. I.e. 2,2 10655 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9454,16 +10706,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9454 // based upon end. Note that if end exceeds the upper 10706 // based upon end. Note that if end exceeds the upper
9455 // bound in this case, the entire destination list 10707 // bound in this case, the entire destination list
9456 // is removed. 10708 // is removed.
9457 else 10709 else if (start == 0)
9458 { 10710 {
9459 if (end + 1 < dest.Length) 10711 if (end + 1 < dest.Length)
9460 {
9461 return src + dest.GetSublist(end + 1, -1); 10712 return src + dest.GetSublist(end + 1, -1);
9462 }
9463 else 10713 else
9464 {
9465 return src; 10714 return src;
9466 } 10715 }
10716 else // Start < 0
10717 {
10718 if (end + 1 < dest.Length)
10719 return dest.GetSublist(end + 1, -1);
10720 else
10721 return new LSL_List();
9467 } 10722 }
9468 } 10723 }
9469 // Finally, if start > end, we strip away a prefix and 10724 // Finally, if start > end, we strip away a prefix and
@@ -9514,17 +10769,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9514 int width = 0; 10769 int width = 0;
9515 int height = 0; 10770 int height = 0;
9516 10771
9517 ParcelMediaCommandEnum? commandToSend = null; 10772 uint commandToSend = 0;
9518 float time = 0.0f; // default is from start 10773 float time = 0.0f; // default is from start
9519 10774
9520 ScenePresence presence = null; 10775 ScenePresence presence = null;
9521 10776
9522 for (int i = 0; i < commandList.Data.Length; i++) 10777 for (int i = 0; i < commandList.Data.Length; i++)
9523 { 10778 {
9524 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10779 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9525 switch (command) 10780 switch (command)
9526 { 10781 {
9527 case ParcelMediaCommandEnum.Agent: 10782 case (uint)ParcelMediaCommandEnum.Agent:
9528 // we send only to one agent 10783 // we send only to one agent
9529 if ((i + 1) < commandList.Length) 10784 if ((i + 1) < commandList.Length)
9530 { 10785 {
@@ -9541,25 +10796,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9541 } 10796 }
9542 break; 10797 break;
9543 10798
9544 case ParcelMediaCommandEnum.Loop: 10799 case (uint)ParcelMediaCommandEnum.Loop:
9545 loop = 1; 10800 loop = 1;
9546 commandToSend = command; 10801 commandToSend = command;
9547 update = true; //need to send the media update packet to set looping 10802 update = true; //need to send the media update packet to set looping
9548 break; 10803 break;
9549 10804
9550 case ParcelMediaCommandEnum.Play: 10805 case (uint)ParcelMediaCommandEnum.Play:
9551 loop = 0; 10806 loop = 0;
9552 commandToSend = command; 10807 commandToSend = command;
9553 update = true; //need to send the media update packet to make sure it doesn't loop 10808 update = true; //need to send the media update packet to make sure it doesn't loop
9554 break; 10809 break;
9555 10810
9556 case ParcelMediaCommandEnum.Pause: 10811 case (uint)ParcelMediaCommandEnum.Pause:
9557 case ParcelMediaCommandEnum.Stop: 10812 case (uint)ParcelMediaCommandEnum.Stop:
9558 case ParcelMediaCommandEnum.Unload: 10813 case (uint)ParcelMediaCommandEnum.Unload:
9559 commandToSend = command; 10814 commandToSend = command;
9560 break; 10815 break;
9561 10816
9562 case ParcelMediaCommandEnum.Url: 10817 case (uint)ParcelMediaCommandEnum.Url:
9563 if ((i + 1) < commandList.Length) 10818 if ((i + 1) < commandList.Length)
9564 { 10819 {
9565 if (commandList.Data[i + 1] is LSL_String) 10820 if (commandList.Data[i + 1] is LSL_String)
@@ -9572,7 +10827,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 } 10827 }
9573 break; 10828 break;
9574 10829
9575 case ParcelMediaCommandEnum.Texture: 10830 case (uint)ParcelMediaCommandEnum.Texture:
9576 if ((i + 1) < commandList.Length) 10831 if ((i + 1) < commandList.Length)
9577 { 10832 {
9578 if (commandList.Data[i + 1] is LSL_String) 10833 if (commandList.Data[i + 1] is LSL_String)
@@ -9585,7 +10840,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9585 } 10840 }
9586 break; 10841 break;
9587 10842
9588 case ParcelMediaCommandEnum.Time: 10843 case (uint)ParcelMediaCommandEnum.Time:
9589 if ((i + 1) < commandList.Length) 10844 if ((i + 1) < commandList.Length)
9590 { 10845 {
9591 if (commandList.Data[i + 1] is LSL_Float) 10846 if (commandList.Data[i + 1] is LSL_Float)
@@ -9597,7 +10852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9597 } 10852 }
9598 break; 10853 break;
9599 10854
9600 case ParcelMediaCommandEnum.AutoAlign: 10855 case (uint)ParcelMediaCommandEnum.AutoAlign:
9601 if ((i + 1) < commandList.Length) 10856 if ((i + 1) < commandList.Length)
9602 { 10857 {
9603 if (commandList.Data[i + 1] is LSL_Integer) 10858 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9611,7 +10866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9611 } 10866 }
9612 break; 10867 break;
9613 10868
9614 case ParcelMediaCommandEnum.Type: 10869 case (uint)ParcelMediaCommandEnum.Type:
9615 if ((i + 1) < commandList.Length) 10870 if ((i + 1) < commandList.Length)
9616 { 10871 {
9617 if (commandList.Data[i + 1] is LSL_String) 10872 if (commandList.Data[i + 1] is LSL_String)
@@ -9624,7 +10879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9624 } 10879 }
9625 break; 10880 break;
9626 10881
9627 case ParcelMediaCommandEnum.Desc: 10882 case (uint)ParcelMediaCommandEnum.Desc:
9628 if ((i + 1) < commandList.Length) 10883 if ((i + 1) < commandList.Length)
9629 { 10884 {
9630 if (commandList.Data[i + 1] is LSL_String) 10885 if (commandList.Data[i + 1] is LSL_String)
@@ -9637,7 +10892,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9637 } 10892 }
9638 break; 10893 break;
9639 10894
9640 case ParcelMediaCommandEnum.Size: 10895 case (uint)ParcelMediaCommandEnum.Size:
9641 if ((i + 2) < commandList.Length) 10896 if ((i + 2) < commandList.Length)
9642 { 10897 {
9643 if (commandList.Data[i + 1] is LSL_Integer) 10898 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9707,7 +10962,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9707 } 10962 }
9708 } 10963 }
9709 10964
9710 if (commandToSend != null) 10965 if (commandToSend != 0)
9711 { 10966 {
9712 // the commandList contained a start/stop/... command, too 10967 // the commandList contained a start/stop/... command, too
9713 if (presence == null) 10968 if (presence == null)
@@ -9744,7 +10999,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9744 10999
9745 if (aList.Data[i] != null) 11000 if (aList.Data[i] != null)
9746 { 11001 {
9747 switch ((ParcelMediaCommandEnum) aList.Data[i]) 11002 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9748 { 11003 {
9749 case ParcelMediaCommandEnum.Url: 11004 case ParcelMediaCommandEnum.Url:
9750 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 11005 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9801,15 +11056,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9801 11056
9802 if (quick_pay_buttons.Data.Length < 4) 11057 if (quick_pay_buttons.Data.Length < 4)
9803 { 11058 {
9804 LSLError("List must have at least 4 elements"); 11059 int x;
9805 return; 11060 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
11061 {
11062 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
11063 }
9806 } 11064 }
9807 m_host.ParentGroup.RootPart.PayPrice[0]=price; 11065 int[] nPrice = new int[5];
9808 11066 nPrice[0] = price;
9809 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 11067 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9810 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11068 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9811 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11069 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9812 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11070 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11071 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9813 m_host.ParentGroup.HasGroupChanged = true; 11072 m_host.ParentGroup.HasGroupChanged = true;
9814 } 11073 }
9815 11074
@@ -9826,7 +11085,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9826 return new LSL_Vector(); 11085 return new LSL_Vector();
9827 } 11086 }
9828 11087
9829 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11088// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11089 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9830 if (presence != null) 11090 if (presence != null)
9831 { 11091 {
9832 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11092 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9848,7 +11108,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9848 return new LSL_Rotation(); 11108 return new LSL_Rotation();
9849 } 11109 }
9850 11110
9851 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11111// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11112 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9852 if (presence != null) 11113 if (presence != null)
9853 { 11114 {
9854 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11115 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9908,8 +11169,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9908 { 11169 {
9909 m_host.AddScriptLPS(1); 11170 m_host.AddScriptLPS(1);
9910 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11171 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9911 if (detectedParams == null) return; // only works on the first detected avatar 11172 if (detectedParams == null)
9912 11173 {
11174 if (m_host.ParentGroup.IsAttachment == true)
11175 {
11176 detectedParams = new DetectParams();
11177 detectedParams.Key = m_host.OwnerID;
11178 }
11179 else
11180 {
11181 return;
11182 }
11183 }
11184
9913 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11185 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9914 if (avatar != null) 11186 if (avatar != null)
9915 { 11187 {
@@ -9917,6 +11189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9917 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11189 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9918 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11190 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9919 } 11191 }
11192
9920 ScriptSleep(1000); 11193 ScriptSleep(1000);
9921 } 11194 }
9922 11195
@@ -10040,12 +11313,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10040 11313
10041 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11314 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10042 object[] data = rules.Data; 11315 object[] data = rules.Data;
10043 for (int i = 0; i < data.Length; ++i) { 11316 for (int i = 0; i < data.Length; ++i)
11317 {
10044 int type = Convert.ToInt32(data[i++].ToString()); 11318 int type = Convert.ToInt32(data[i++].ToString());
10045 if (i >= data.Length) break; // odd number of entries => ignore the last 11319 if (i >= data.Length) break; // odd number of entries => ignore the last
10046 11320
10047 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11321 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10048 switch (type) { 11322 switch (type)
11323 {
10049 case ScriptBaseClass.CAMERA_FOCUS: 11324 case ScriptBaseClass.CAMERA_FOCUS:
10050 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11325 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10051 case ScriptBaseClass.CAMERA_POSITION: 11326 case ScriptBaseClass.CAMERA_POSITION:
@@ -10151,19 +11426,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10151 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11426 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10152 { 11427 {
10153 m_host.AddScriptLPS(1); 11428 m_host.AddScriptLPS(1);
10154 string ret = String.Empty; 11429
10155 string src1 = llBase64ToString(str1); 11430 if (str1 == String.Empty)
10156 string src2 = llBase64ToString(str2); 11431 return String.Empty;
10157 int c = 0; 11432 if (str2 == String.Empty)
10158 for (int i = 0; i < src1.Length; i++) 11433 return str1;
11434
11435 int len = str2.Length;
11436 if ((len % 4) != 0) // LL is EVIL!!!!
11437 {
11438 while (str2.EndsWith("="))
11439 str2 = str2.Substring(0, str2.Length - 1);
11440
11441 len = str2.Length;
11442 int mod = len % 4;
11443
11444 if (mod == 1)
11445 str2 = str2.Substring(0, str2.Length - 1);
11446 else if (mod == 2)
11447 str2 += "==";
11448 else if (mod == 3)
11449 str2 += "=";
11450 }
11451
11452 byte[] data1;
11453 byte[] data2;
11454 try
11455 {
11456 data1 = Convert.FromBase64String(str1);
11457 data2 = Convert.FromBase64String(str2);
11458 }
11459 catch (Exception)
10159 { 11460 {
10160 ret += (char) (src1[i] ^ src2[c]); 11461 return new LSL_String(String.Empty);
11462 }
10161 11463
10162 c++; 11464 byte[] d2 = new Byte[data1.Length];
10163 if (c >= src2.Length) 11465 int pos = 0;
10164 c = 0; 11466
11467 if (data1.Length <= data2.Length)
11468 {
11469 Array.Copy(data2, 0, d2, 0, data1.Length);
10165 } 11470 }
10166 return llStringToBase64(ret); 11471 else
11472 {
11473 while (pos < data1.Length)
11474 {
11475 len = data1.Length - pos;
11476 if (len > data2.Length)
11477 len = data2.Length;
11478
11479 Array.Copy(data2, 0, d2, pos, len);
11480 pos += len;
11481 }
11482 }
11483
11484 for (pos = 0 ; pos < data1.Length ; pos++ )
11485 data1[pos] ^= d2[pos];
11486
11487 return Convert.ToBase64String(data1);
10167 } 11488 }
10168 11489
10169 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11490 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10216,16 +11537,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10216 if (userAgent != null) 11537 if (userAgent != null)
10217 httpHeaders["User-Agent"] = userAgent; 11538 httpHeaders["User-Agent"] = userAgent;
10218 11539
11540 // See if the URL contains any header hacks
11541 string[] urlParts = url.Split(new char[] {'\n'});
11542 if (urlParts.Length > 1)
11543 {
11544 // Iterate the passed headers and parse them
11545 for (int i = 1 ; i < urlParts.Length ; i++ )
11546 {
11547 // The rest of those would be added to the body in SL.
11548 // Let's not do that.
11549 if (urlParts[i] == String.Empty)
11550 break;
11551
11552 // See if this could be a valid header
11553 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11554 if (headerParts.Length != 2)
11555 continue;
11556
11557 string headerName = headerParts[0].Trim();
11558 string headerValue = headerParts[1].Trim();
11559
11560 // Filter out headers that could be used to abuse
11561 // another system or cloak the request
11562 if (headerName.ToLower() == "x-secondlife-shard" ||
11563 headerName.ToLower() == "x-secondlife-object-name" ||
11564 headerName.ToLower() == "x-secondlife-object-key" ||
11565 headerName.ToLower() == "x-secondlife-region" ||
11566 headerName.ToLower() == "x-secondlife-local-position" ||
11567 headerName.ToLower() == "x-secondlife-local-velocity" ||
11568 headerName.ToLower() == "x-secondlife-local-rotation" ||
11569 headerName.ToLower() == "x-secondlife-owner-name" ||
11570 headerName.ToLower() == "x-secondlife-owner-key" ||
11571 headerName.ToLower() == "connection" ||
11572 headerName.ToLower() == "content-length" ||
11573 headerName.ToLower() == "from" ||
11574 headerName.ToLower() == "host" ||
11575 headerName.ToLower() == "proxy-authorization" ||
11576 headerName.ToLower() == "referer" ||
11577 headerName.ToLower() == "trailer" ||
11578 headerName.ToLower() == "transfer-encoding" ||
11579 headerName.ToLower() == "via" ||
11580 headerName.ToLower() == "authorization")
11581 continue;
11582
11583 httpHeaders[headerName] = headerValue;
11584 }
11585
11586 // Finally, strip any protocol specifier from the URL
11587 url = urlParts[0].Trim();
11588 int idx = url.IndexOf(" HTTP/");
11589 if (idx != -1)
11590 url = url.Substring(0, idx);
11591 }
11592
10219 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11593 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10220 Regex r = new Regex(authregex); 11594 Regex r = new Regex(authregex);
10221 int[] gnums = r.GetGroupNumbers(); 11595 int[] gnums = r.GetGroupNumbers();
10222 Match m = r.Match(url); 11596 Match m = r.Match(url);
10223 if (m.Success) { 11597 if (m.Success)
10224 for (int i = 1; i < gnums.Length; i++) { 11598 {
11599 for (int i = 1; i < gnums.Length; i++)
11600 {
10225 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11601 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10226 //CaptureCollection cc = g.Captures; 11602 //CaptureCollection cc = g.Captures;
10227 } 11603 }
10228 if (m.Groups.Count == 5) { 11604 if (m.Groups.Count == 5)
11605 {
10229 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11606 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10230 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11607 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10231 } 11608 }
@@ -10428,6 +11805,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10428 11805
10429 LSL_List ret = new LSL_List(); 11806 LSL_List ret = new LSL_List();
10430 UUID key = new UUID(); 11807 UUID key = new UUID();
11808
11809
10431 if (UUID.TryParse(id, out key)) 11810 if (UUID.TryParse(id, out key))
10432 { 11811 {
10433 ScenePresence av = World.GetScenePresence(key); 11812 ScenePresence av = World.GetScenePresence(key);
@@ -10445,13 +11824,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10445 ret.Add(new LSL_String("")); 11824 ret.Add(new LSL_String(""));
10446 break; 11825 break;
10447 case ScriptBaseClass.OBJECT_POS: 11826 case ScriptBaseClass.OBJECT_POS:
10448 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11827 Vector3 avpos;
11828
11829 if (av.ParentID != 0 && av.ParentPart != null)
11830 {
11831 avpos = av.OffsetPosition;
11832
11833 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11834 avpos -= sitOffset;
11835
11836 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11837 }
11838 else
11839 avpos = av.AbsolutePosition;
11840
11841 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10449 break; 11842 break;
10450 case ScriptBaseClass.OBJECT_ROT: 11843 case ScriptBaseClass.OBJECT_ROT:
10451 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11844 Quaternion avrot = av.Rotation;
11845 if (av.ParentID != 0 && av.ParentPart != null)
11846 {
11847 avrot = av.ParentPart.GetWorldRotation() * avrot;
11848 }
11849 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10452 break; 11850 break;
10453 case ScriptBaseClass.OBJECT_VELOCITY: 11851 case ScriptBaseClass.OBJECT_VELOCITY:
10454 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11852 Vector3 avvel = av.Velocity;
11853 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10455 break; 11854 break;
10456 case ScriptBaseClass.OBJECT_OWNER: 11855 case ScriptBaseClass.OBJECT_OWNER:
10457 ret.Add(new LSL_String(id)); 11856 ret.Add(new LSL_String(id));
@@ -10507,11 +11906,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10507 case ScriptBaseClass.OBJECT_NAME: 11906 case ScriptBaseClass.OBJECT_NAME:
10508 ret.Add(new LSL_String(obj.Name)); 11907 ret.Add(new LSL_String(obj.Name));
10509 break; 11908 break;
10510 case ScriptBaseClass.OBJECT_DESC: 11909 case ScriptBaseClass.OBJECT_DESC:
10511 ret.Add(new LSL_String(obj.Description)); 11910 ret.Add(new LSL_String(obj.Description));
10512 break; 11911 break;
10513 case ScriptBaseClass.OBJECT_POS: 11912 case ScriptBaseClass.OBJECT_POS:
10514 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11913 Vector3 opos = obj.AbsolutePosition;
11914 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10515 break; 11915 break;
10516 case ScriptBaseClass.OBJECT_ROT: 11916 case ScriptBaseClass.OBJECT_ROT:
10517 { 11917 {
@@ -10527,7 +11927,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10527 } 11927 }
10528 break; 11928 break;
10529 case ScriptBaseClass.OBJECT_VELOCITY: 11929 case ScriptBaseClass.OBJECT_VELOCITY:
10530 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11930 Vector3 ovel = obj.Velocity;
11931 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10531 break; 11932 break;
10532 case ScriptBaseClass.OBJECT_OWNER: 11933 case ScriptBaseClass.OBJECT_OWNER:
10533 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11934 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10561,9 +11962,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10561 // The value returned in SL for normal prims is prim count 11962 // The value returned in SL for normal prims is prim count
10562 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11963 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10563 break; 11964 break;
10564 // The following 3 costs I have intentionaly coded to return zero. They are part of 11965
10565 // "Land Impact" calculations. These calculations are probably not applicable 11966 // costs below may need to be diferent for root parts, need to check
10566 // to OpenSim and are not yet complete in SL
10567 case ScriptBaseClass.OBJECT_SERVER_COST: 11967 case ScriptBaseClass.OBJECT_SERVER_COST:
10568 // The linden calculation is here 11968 // The linden calculation is here
10569 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11969 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10571,16 +11971,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10571 ret.Add(new LSL_Float(0)); 11971 ret.Add(new LSL_Float(0));
10572 break; 11972 break;
10573 case ScriptBaseClass.OBJECT_STREAMING_COST: 11973 case ScriptBaseClass.OBJECT_STREAMING_COST:
10574 // The linden calculation is here 11974 // The value returned in SL for normal prims is prim count * 0.06
10575 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11975 ret.Add(new LSL_Float(obj.StreamingCost));
10576 // The value returned in SL for normal prims looks like the prim count * 0.06
10577 ret.Add(new LSL_Float(0));
10578 break; 11976 break;
10579 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11977 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10580 // The linden calculation is here 11978 // The value returned in SL for normal prims is prim count
10581 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11979 ret.Add(new LSL_Float(obj.PhysicsCost));
10582 // The value returned in SL for normal prims looks like the prim count
10583 ret.Add(new LSL_Float(0));
10584 break; 11980 break;
10585 default: 11981 default:
10586 // Invalid or unhandled constant. 11982 // Invalid or unhandled constant.
@@ -10769,15 +12165,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10769 return GetLinkPrimitiveParams(obj, rules); 12165 return GetLinkPrimitiveParams(obj, rules);
10770 } 12166 }
10771 12167
10772 public void print(string str) 12168 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10773 { 12169 {
10774 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12170 List<SceneObjectPart> parts = GetLinkParts(link);
10775 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12171 if (parts.Count < 1)
10776 if (ossl != null) 12172 return 0;
10777 { 12173
10778 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12174 return GetNumberOfSides(parts[0]);
10779 m_log.Info("LSL print():" + str);
10780 }
10781 } 12175 }
10782 12176
10783 private string Name2Username(string name) 12177 private string Name2Username(string name)
@@ -10822,7 +12216,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10822 12216
10823 return rq.ToString(); 12217 return rq.ToString();
10824 } 12218 }
10825 12219/*
12220 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12221 {
12222 m_SayShoutCount = 0;
12223 }
12224*/
10826 private struct Tri 12225 private struct Tri
10827 { 12226 {
10828 public Vector3 p1; 12227 public Vector3 p1;
@@ -10962,9 +12361,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10962 12361
10963 ContactResult result = new ContactResult (); 12362 ContactResult result = new ContactResult ();
10964 result.ConsumerID = group.LocalId; 12363 result.ConsumerID = group.LocalId;
10965 result.Depth = intersection.distance; 12364// result.Depth = intersection.distance;
10966 result.Normal = intersection.normal; 12365 result.Normal = intersection.normal;
10967 result.Pos = intersection.ipoint; 12366 result.Pos = intersection.ipoint;
12367 result.Depth = Vector3.Mag(rayStart - result.Pos);
10968 12368
10969 contacts.Add(result); 12369 contacts.Add(result);
10970 }); 12370 });
@@ -11097,6 +12497,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11097 12497
11098 return contacts[0]; 12498 return contacts[0];
11099 } 12499 }
12500/*
12501 // not done:
12502 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12503 {
12504 ContactResult[] contacts = null;
12505 World.ForEachSOG(delegate(SceneObjectGroup group)
12506 {
12507 if (m_host.ParentGroup == group)
12508 return;
12509
12510 if (group.IsAttachment)
12511 return;
12512
12513 if(group.RootPart.PhysActor != null)
12514 return;
12515
12516 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12517 });
12518 return contacts;
12519 }
12520*/
11100 12521
11101 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12522 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11102 { 12523 {
@@ -11138,32 +12559,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11138 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12559 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11139 12560
11140 12561
11141 if (checkTerrain) 12562 if (World.SuportsRayCastFiltered())
11142 { 12563 {
11143 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12564 if (dist == 0)
11144 if (groundContact != null) 12565 return list;
11145 results.Add((ContactResult)groundContact);
11146 }
11147 12566
11148 if (checkAgents) 12567 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11149 { 12568 if (checkTerrain)
11150 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12569 rayfilter |= RayFilterFlags.land;
11151 foreach (ContactResult r in agentHits) 12570// if (checkAgents)
11152 results.Add(r); 12571// rayfilter |= RayFilterFlags.agent;
11153 } 12572 if (checkPhysical)
12573 rayfilter |= RayFilterFlags.physical;
12574 if (checkNonPhysical)
12575 rayfilter |= RayFilterFlags.nonphysical;
12576 if (detectPhantom)
12577 rayfilter |= RayFilterFlags.LSLPhanton;
12578
12579 Vector3 direction = dir * ( 1/dist);
12580
12581 if(rayfilter == 0)
12582 {
12583 list.Add(new LSL_Integer(0));
12584 return list;
12585 }
11154 12586
11155 if (checkPhysical || checkNonPhysical || detectPhantom) 12587 // get some more contacts to sort ???
12588 int physcount = 4 * count;
12589 if (physcount > 20)
12590 physcount = 20;
12591
12592 object physresults;
12593 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12594
12595 if (physresults == null)
12596 {
12597 list.Add(new LSL_Integer(-3)); // timeout error
12598 return list;
12599 }
12600
12601 results = (List<ContactResult>)physresults;
12602
12603 // for now physics doesn't detect sitted avatars so do it outside physics
12604 if (checkAgents)
12605 {
12606 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12607 foreach (ContactResult r in agentHits)
12608 results.Add(r);
12609 }
12610
12611 // TODO: Replace this with a better solution. ObjectIntersection can only
12612 // detect nonphysical phantoms. They are detected by virtue of being
12613 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12614 // physicsl phantoms as done by the physics scene
12615 // We don't want anything else but phantoms here.
12616 if (detectPhantom)
12617 {
12618 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12619 foreach (ContactResult r in objectHits)
12620 results.Add(r);
12621 }
12622 }
12623 else
11156 { 12624 {
11157 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12625 if (checkTerrain)
11158 foreach (ContactResult r in objectHits) 12626 {
11159 results.Add(r); 12627 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12628 if (groundContact != null)
12629 results.Add((ContactResult)groundContact);
12630 }
12631
12632 if (checkAgents)
12633 {
12634 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12635 foreach (ContactResult r in agentHits)
12636 results.Add(r);
12637 }
12638
12639 if (checkPhysical || checkNonPhysical || detectPhantom)
12640 {
12641 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12642 foreach (ContactResult r in objectHits)
12643 results.Add(r);
12644 }
11160 } 12645 }
11161 12646
11162 results.Sort(delegate(ContactResult a, ContactResult b) 12647 results.Sort(delegate(ContactResult a, ContactResult b)
11163 { 12648 {
11164 return a.Depth.CompareTo(b.Depth); 12649 return a.Depth.CompareTo(b.Depth);
11165 }); 12650 });
11166 12651
11167 int values = 0; 12652 int values = 0;
11168 SceneObjectGroup thisgrp = m_host.ParentGroup; 12653 SceneObjectGroup thisgrp = m_host.ParentGroup;
11169 12654
@@ -11256,7 +12741,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11256 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12741 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11257 if (!isAccount) return 0; 12742 if (!isAccount) return 0;
11258 if (estate.HasAccess(id)) return 1; 12743 if (estate.HasAccess(id)) return 1;
11259 if (estate.IsBanned(id)) 12744 if (estate.IsBanned(id, World.GetUserFlags(id)))
11260 estate.RemoveBan(id); 12745 estate.RemoveBan(id);
11261 estate.AddEstateUser(id); 12746 estate.AddEstateUser(id);
11262 break; 12747 break;
@@ -11275,14 +12760,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11275 break; 12760 break;
11276 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12761 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11277 if (!isAccount) return 0; 12762 if (!isAccount) return 0;
11278 if (estate.IsBanned(id)) return 1; 12763 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11279 EstateBan ban = new EstateBan(); 12764 EstateBan ban = new EstateBan();
11280 ban.EstateID = estate.EstateID; 12765 ban.EstateID = estate.EstateID;
11281 ban.BannedUserID = id; 12766 ban.BannedUserID = id;
11282 estate.AddBan(ban); 12767 estate.AddBan(ban);
11283 break; 12768 break;
11284 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12769 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11285 if (!isAccount || !estate.IsBanned(id)) return 0; 12770 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11286 estate.RemoveBan(id); 12771 estate.RemoveBan(id);
11287 break; 12772 break;
11288 default: return 0; 12773 default: return 0;
@@ -11311,7 +12796,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11311 return 16384; 12796 return 16384;
11312 } 12797 }
11313 12798
11314 public LSL_Integer llGetUsedMemory() 12799 public virtual LSL_Integer llGetUsedMemory()
11315 { 12800 {
11316 m_host.AddScriptLPS(1); 12801 m_host.AddScriptLPS(1);
11317 // The value returned for LSO scripts in SL 12802 // The value returned for LSO scripts in SL
@@ -11339,7 +12824,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11339 public void llSetSoundQueueing(int queue) 12824 public void llSetSoundQueueing(int queue)
11340 { 12825 {
11341 m_host.AddScriptLPS(1); 12826 m_host.AddScriptLPS(1);
11342 NotImplemented("llSetSoundQueueing");
11343 } 12827 }
11344 12828
11345 public void llCollisionSprite(string impact_sprite) 12829 public void llCollisionSprite(string impact_sprite)
@@ -11351,10 +12835,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11351 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12835 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11352 { 12836 {
11353 m_host.AddScriptLPS(1); 12837 m_host.AddScriptLPS(1);
11354 NotImplemented("llGodLikeRezObject"); 12838
12839 if (!World.Permissions.IsGod(m_host.OwnerID))
12840 NotImplemented("llGodLikeRezObject");
12841
12842 AssetBase rezAsset = World.AssetService.Get(inventory);
12843 if (rezAsset == null)
12844 {
12845 llSay(0, "Asset not found");
12846 return;
12847 }
12848
12849 SceneObjectGroup group = null;
12850
12851 try
12852 {
12853 string xmlData = Utils.BytesToString(rezAsset.Data);
12854 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12855 }
12856 catch
12857 {
12858 llSay(0, "Asset not found");
12859 return;
12860 }
12861
12862 if (group == null)
12863 {
12864 llSay(0, "Asset not found");
12865 return;
12866 }
12867
12868 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12869 group.RootPart.AttachOffset = group.AbsolutePosition;
12870
12871 group.ResetIDs();
12872
12873 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12874 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12875 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12876 group.ScheduleGroupForFullUpdate();
12877
12878 // objects rezzed with this method are die_at_edge by default.
12879 group.RootPart.SetDieAtEdge(true);
12880
12881 group.ResumeScripts();
12882
12883 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12884 "object_rez", new Object[] {
12885 new LSL_String(
12886 group.RootPart.UUID.ToString()) },
12887 new DetectParams[0]));
12888 }
12889
12890 public LSL_String llTransferLindenDollars(string destination, int amount)
12891 {
12892 UUID txn = UUID.Random();
12893
12894 Util.FireAndForget(delegate(object x)
12895 {
12896 int replycode = 0;
12897 string replydata = destination + "," + amount.ToString();
12898
12899 try
12900 {
12901 TaskInventoryItem item = m_item;
12902 if (item == null)
12903 {
12904 replydata = "SERVICE_ERROR";
12905 return;
12906 }
12907
12908 m_host.AddScriptLPS(1);
12909
12910 if (item.PermsGranter == UUID.Zero)
12911 {
12912 replydata = "MISSING_PERMISSION_DEBIT";
12913 return;
12914 }
12915
12916 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12917 {
12918 replydata = "MISSING_PERMISSION_DEBIT";
12919 return;
12920 }
12921
12922 UUID toID = new UUID();
12923
12924 if (!UUID.TryParse(destination, out toID))
12925 {
12926 replydata = "INVALID_AGENT";
12927 return;
12928 }
12929
12930 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12931
12932 if (money == null)
12933 {
12934 replydata = "TRANSFERS_DISABLED";
12935 return;
12936 }
12937
12938 bool result = money.ObjectGiveMoney(
12939 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12940
12941 if (result)
12942 {
12943 replycode = 1;
12944 return;
12945 }
12946
12947 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12948 }
12949 finally
12950 {
12951 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12952 "transaction_result", new Object[] {
12953 new LSL_String(txn.ToString()),
12954 new LSL_Integer(replycode),
12955 new LSL_String(replydata) },
12956 new DetectParams[0]));
12957 }
12958 });
12959
12960 return txn.ToString();
11355 } 12961 }
11356 12962
11357 #endregion 12963 #endregion
12964
12965 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12966 {
12967 SceneObjectGroup group = m_host.ParentGroup;
12968
12969 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12970 return;
12971 if (group.IsAttachment)
12972 return;
12973
12974 if (frames.Data.Length > 0) // We are getting a new motion
12975 {
12976 if (group.RootPart.KeyframeMotion != null)
12977 group.RootPart.KeyframeMotion.Stop();
12978 group.RootPart.KeyframeMotion = null;
12979
12980 int idx = 0;
12981
12982 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12983 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12984
12985 while (idx < options.Data.Length)
12986 {
12987 int option = (int)options.GetLSLIntegerItem(idx++);
12988 int remain = options.Data.Length - idx;
12989
12990 switch (option)
12991 {
12992 case ScriptBaseClass.KFM_MODE:
12993 if (remain < 1)
12994 break;
12995 int modeval = (int)options.GetLSLIntegerItem(idx++);
12996 switch(modeval)
12997 {
12998 case ScriptBaseClass.KFM_FORWARD:
12999 mode = KeyframeMotion.PlayMode.Forward;
13000 break;
13001 case ScriptBaseClass.KFM_REVERSE:
13002 mode = KeyframeMotion.PlayMode.Reverse;
13003 break;
13004 case ScriptBaseClass.KFM_LOOP:
13005 mode = KeyframeMotion.PlayMode.Loop;
13006 break;
13007 case ScriptBaseClass.KFM_PING_PONG:
13008 mode = KeyframeMotion.PlayMode.PingPong;
13009 break;
13010 }
13011 break;
13012 case ScriptBaseClass.KFM_DATA:
13013 if (remain < 1)
13014 break;
13015 int dataval = (int)options.GetLSLIntegerItem(idx++);
13016 data = (KeyframeMotion.DataFormat)dataval;
13017 break;
13018 }
13019 }
13020
13021 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
13022
13023 idx = 0;
13024
13025 int elemLength = 2;
13026 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
13027 elemLength = 3;
13028
13029 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
13030 while (idx < frames.Data.Length)
13031 {
13032 int remain = frames.Data.Length - idx;
13033
13034 if (remain < elemLength)
13035 break;
13036
13037 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
13038 frame.Position = null;
13039 frame.Rotation = null;
13040
13041 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
13042 {
13043 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
13044 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
13045 }
13046 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
13047 {
13048 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
13049 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
13050 }
13051
13052 float tempf = (float)frames.GetLSLFloatItem(idx++);
13053 frame.TimeMS = (int)(tempf * 1000.0f);
13054
13055 keyframes.Add(frame);
13056 }
13057
13058 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
13059 group.RootPart.KeyframeMotion.Start();
13060 }
13061 else
13062 {
13063 if (group.RootPart.KeyframeMotion == null)
13064 return;
13065
13066 if (options.Data.Length == 0)
13067 {
13068 group.RootPart.KeyframeMotion.Stop();
13069 return;
13070 }
13071
13072 int code = (int)options.GetLSLIntegerItem(0);
13073
13074 int idx = 0;
13075
13076 while (idx < options.Data.Length)
13077 {
13078 int option = (int)options.GetLSLIntegerItem(idx++);
13079 int remain = options.Data.Length - idx;
13080
13081 switch (option)
13082 {
13083 case ScriptBaseClass.KFM_COMMAND:
13084 int cmd = (int)options.GetLSLIntegerItem(idx++);
13085 switch (cmd)
13086 {
13087 case ScriptBaseClass.KFM_CMD_PLAY:
13088 group.RootPart.KeyframeMotion.Start();
13089 break;
13090 case ScriptBaseClass.KFM_CMD_STOP:
13091 group.RootPart.KeyframeMotion.Stop();
13092 break;
13093 case ScriptBaseClass.KFM_CMD_PAUSE:
13094 group.RootPart.KeyframeMotion.Pause();
13095 break;
13096 }
13097 break;
13098 }
13099 }
13100 }
13101 }
11358 } 13102 }
11359 13103
11360 public class NotecardCache 13104 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 {