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 c3b1f3d..ce1c364 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);
@@ -236,9 +279,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 279 }
237 } 280 }
238 281
282 public List<ScenePresence> GetLinkAvatars(int linkType)
283 {
284 List<ScenePresence> ret = new List<ScenePresence>();
285 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
286 return ret;
287
288 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
289
290 switch (linkType)
291 {
292 case ScriptBaseClass.LINK_SET:
293 return avs;
294
295 case ScriptBaseClass.LINK_ROOT:
296 return ret;
297
298 case ScriptBaseClass.LINK_ALL_OTHERS:
299 return avs;
300
301 case ScriptBaseClass.LINK_ALL_CHILDREN:
302 return avs;
303
304 case ScriptBaseClass.LINK_THIS:
305 return ret;
306
307 default:
308 if (linkType < 0)
309 return ret;
310
311 int partCount = m_host.ParentGroup.GetPartCount();
312
313 if (linkType <= partCount)
314 {
315 return ret;
316 }
317 else
318 {
319 linkType = linkType - partCount;
320 if (linkType > avs.Count)
321 {
322 return ret;
323 }
324 else
325 {
326 ret.Add(avs[linkType-1]);
327 return ret;
328 }
329 }
330 }
331 }
332
239 public List<SceneObjectPart> GetLinkParts(int linkType) 333 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 334 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 335 List<SceneObjectPart> ret = new List<SceneObjectPart>();
336 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
337 return ret;
242 ret.Add(m_host); 338 ret.Add(m_host);
243 339
244 switch (linkType) 340 switch (linkType)
@@ -437,31 +533,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
437 533
438 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 534 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
439 535
440 /// <summary> 536 // Utility function for llRot2Euler
441 /// Convert an LSL rotation to a Euler vector. 537
442 /// </summary> 538 // normalize an angle between -PI and PI (-180 to +180 degrees)
443 /// <remarks> 539 protected double NormalizeAngle(double angle)
444 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
445 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
446 /// </remarks>
447 /// <param name="r"></param>
448 /// <returns></returns>
449 public LSL_Vector llRot2Euler(LSL_Rotation r)
450 { 540 {
451 m_host.AddScriptLPS(1); 541 if (angle > -Math.PI && angle < Math.PI)
542 return angle;
452 543
453 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 544 int numPis = (int)(Math.PI / angle);
454 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 545 double remainder = angle - Math.PI * numPis;
455 if (m == 0.0) return new LSL_Vector(); 546 if (numPis % 2 == 1)
456 double x = Math.Atan2(-v.y, v.z); 547 return Math.PI - angle;
457 double sin = v.x / m; 548 return remainder;
458 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 549 }
459 double y = Math.Asin(sin);
460 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
461 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)));
462 double z = Math.Atan2(v.y, v.x);
463 550
464 return new LSL_Vector(x, y, z); 551 public LSL_Vector llRot2Euler(LSL_Rotation q1)
552 {
553 m_host.AddScriptLPS(1);
554 LSL_Vector eul = new LSL_Vector();
555
556 double sqw = q1.s*q1.s;
557 double sqx = q1.x*q1.x;
558 double sqy = q1.z*q1.z;
559 double sqz = q1.y*q1.y;
560 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
561 double test = q1.x*q1.z + q1.y*q1.s;
562 if (test > 0.4999*unit) { // singularity at north pole
563 eul.z = 2 * Math.Atan2(q1.x,q1.s);
564 eul.y = Math.PI/2;
565 eul.x = 0;
566 return eul;
567 }
568 if (test < -0.4999*unit) { // singularity at south 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 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
575 eul.y = Math.Asin(2*test/unit);
576 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
577 return eul;
465 } 578 }
466 579
467 /* From wiki: 580 /* From wiki:
@@ -514,18 +627,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
514 m_host.AddScriptLPS(1); 627 m_host.AddScriptLPS(1);
515 628
516 double x,y,z,s; 629 double x,y,z,s;
517 630 v.x *= 0.5;
518 double c1 = Math.Cos(v.x * 0.5); 631 v.y *= 0.5;
519 double c2 = Math.Cos(v.y * 0.5); 632 v.z *= 0.5;
520 double c3 = Math.Cos(v.z * 0.5); 633 double c1 = Math.Cos(v.x);
521 double s1 = Math.Sin(v.x * 0.5); 634 double c2 = Math.Cos(v.y);
522 double s2 = Math.Sin(v.y * 0.5); 635 double c1c2 = c1 * c2;
523 double s3 = Math.Sin(v.z * 0.5); 636 double s1 = Math.Sin(v.x);
524 637 double s2 = Math.Sin(v.y);
525 x = s1 * c2 * c3 + c1 * s2 * s3; 638 double s1s2 = s1 * s2;
526 y = c1 * s2 * c3 - s1 * c2 * s3; 639 double c1s2 = c1 * s2;
527 z = s1 * s2 * c3 + c1 * c2 * s3; 640 double s1c2 = s1 * c2;
528 s = c1 * c2 * c3 - s1 * s2 * s3; 641 double c3 = Math.Cos(v.z);
642 double s3 = Math.Sin(v.z);
643
644 x = s1c2 * c3 + c1s2 * s3;
645 y = c1s2 * c3 - s1c2 * s3;
646 z = s1s2 * c3 + c1c2 * s3;
647 s = c1c2 * c3 - s1s2 * s3;
529 648
530 return new LSL_Rotation(x, y, z, s); 649 return new LSL_Rotation(x, y, z, s);
531 } 650 }
@@ -663,77 +782,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
663 { 782 {
664 //A and B should both be normalized 783 //A and B should both be normalized
665 m_host.AddScriptLPS(1); 784 m_host.AddScriptLPS(1);
666 LSL_Rotation rotBetween; 785 /* This method is more accurate than the SL one, and thus causes problems
667 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 786 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
668 // continue calculation. 787
669 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 788 double dotProduct = LSL_Vector.Dot(a, b);
789 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
790 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
791 double angle = Math.Acos(dotProduct / magProduct);
792 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
793 double s = Math.Sin(angle / 2);
794
795 double x = axis.x * s;
796 double y = axis.y * s;
797 double z = axis.z * s;
798 double w = Math.Cos(angle / 2);
799
800 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
801 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
802
803 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
804 */
805
806 // This method mimics the 180 errors found in SL
807 // See www.euclideanspace.com... angleBetween
808 LSL_Vector vec_a = a;
809 LSL_Vector vec_b = b;
810
811 // Eliminate zero length
812 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
813 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
814 if (vec_a_mag < 0.00001 ||
815 vec_b_mag < 0.00001)
670 { 816 {
671 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 817 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
672 } 818 }
673 else 819
820 // Normalize
821 vec_a = llVecNorm(vec_a);
822 vec_b = llVecNorm(vec_b);
823
824 // Calculate axis and rotation angle
825 LSL_Vector axis = vec_a % vec_b;
826 LSL_Float cos_theta = vec_a * vec_b;
827
828 // Check if parallel
829 if (cos_theta > 0.99999)
674 { 830 {
675 a = LSL_Vector.Norm(a); 831 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
676 b = LSL_Vector.Norm(b); 832 }
677 double dotProduct = LSL_Vector.Dot(a, b); 833
678 // There are two degenerate cases possible. These are for vectors 180 or 834 // Check if anti-parallel
679 // 0 degrees apart. These have to be detected and handled individually. 835 else if (cos_theta < -0.99999)
680 // 836 {
681 // Check for vectors 180 degrees apart. 837 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
682 // A dot product of -1 would mean the angle between vectors is 180 degrees. 838 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
683 if (dotProduct < -0.9999999f) 839 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
684 { 840 }
685 // First assume X axis is orthogonal to the vectors. 841 else // other rotation
686 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 842 {
687 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 843 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
688 // Check for near zero vector. A very small non-zero number here will create 844 axis = llVecNorm(axis);
689 // a rotation in an undesired direction. 845 double x, y, z, s, t;
690 if (LSL_Vector.Mag(orthoVector) > 0.0001) 846 s = Math.Cos(theta);
691 { 847 t = Math.Sin(theta);
692 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 848 x = axis.x * t;
693 } 849 y = axis.y * t;
694 // If the magnitude of the vector was near zero, then assume the X axis is not 850 z = axis.z * t;
695 // orthogonal and use the Z axis instead. 851 return new LSL_Rotation(x,y,z,s);
696 else
697 {
698 // Set 180 z rotation.
699 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
700 }
701 }
702 // Check for parallel vectors.
703 // A dot product of 1 would mean the angle between vectors is 0 degrees.
704 else if (dotProduct > 0.9999999f)
705 {
706 // Set zero rotation.
707 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
708 }
709 else
710 {
711 // All special checks have been performed so get the axis of rotation.
712 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
713 // Quarternion s value is the length of the unit vector + dot product.
714 double qs = 1.0 + dotProduct;
715 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
716 // Normalize the rotation.
717 double mag = LSL_Rotation.Mag(rotBetween);
718 // We shouldn't have to worry about a divide by zero here. The qs value will be
719 // non-zero because we already know if we're here, then the dotProduct is not -1 so
720 // qs will not be zero. Also, we've already handled the input vectors being zero so the
721 // crossProduct vector should also not be zero.
722 rotBetween.x = rotBetween.x / mag;
723 rotBetween.y = rotBetween.y / mag;
724 rotBetween.z = rotBetween.z / mag;
725 rotBetween.s = rotBetween.s / mag;
726 // Check for undefined values and set zero rotation if any found. This code might not actually be required
727 // any longer since zero vectors are checked for at the top.
728 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
729 {
730 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
731 }
732 }
733 } 852 }
734 return rotBetween;
735 } 853 }
736 854
737 public void llWhisper(int channelID, string text) 855 public void llWhisper(int channelID, string text)
738 { 856 {
739 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
@@ -749,10 +867,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
749 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 867 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
750 } 868 }
751 869
870 private void CheckSayShoutTime()
871 {
872 DateTime now = DateTime.UtcNow;
873 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
874 {
875 m_lastSayShoutCheck = now;
876 m_SayShoutCount = 0;
877 }
878 else
879 m_SayShoutCount++;
880 }
881
752 public void llSay(int channelID, string text) 882 public void llSay(int channelID, string text)
753 { 883 {
754 m_host.AddScriptLPS(1); 884 m_host.AddScriptLPS(1);
755 885
886 if (channelID == 0)
887// m_SayShoutCount++;
888 CheckSayShoutTime();
889
890 if (m_SayShoutCount >= 11)
891 ScriptSleep(2000);
892
756 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 893 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
757 { 894 {
758 Console.WriteLine(text); 895 Console.WriteLine(text);
@@ -775,6 +912,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
775 { 912 {
776 m_host.AddScriptLPS(1); 913 m_host.AddScriptLPS(1);
777 914
915 if (channelID == 0)
916// m_SayShoutCount++;
917 CheckSayShoutTime();
918
919 if (m_SayShoutCount >= 11)
920 ScriptSleep(2000);
921
778 if (text.Length > 1023) 922 if (text.Length > 1023)
779 text = text.Substring(0, 1023); 923 text = text.Substring(0, 1023);
780 924
@@ -806,22 +950,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
806 950
807 public void llRegionSayTo(string target, int channel, string msg) 951 public void llRegionSayTo(string target, int channel, string msg)
808 { 952 {
953 string error = String.Empty;
954
809 if (msg.Length > 1023) 955 if (msg.Length > 1023)
810 msg = msg.Substring(0, 1023); 956 msg = msg.Substring(0, 1023);
811 957
812 m_host.AddScriptLPS(1); 958 m_host.AddScriptLPS(1);
813 959
814 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
815 {
816 return;
817 }
818
819 UUID TargetID; 960 UUID TargetID;
820 UUID.TryParse(target, out TargetID); 961 UUID.TryParse(target, out TargetID);
821 962
822 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 963 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
823 if (wComm != null) 964 if (wComm != null)
824 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 965 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
966 LSLError(error);
825 } 967 }
826 968
827 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 969 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1077,10 +1219,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1077 return detectedParams.TouchUV; 1219 return detectedParams.TouchUV;
1078 } 1220 }
1079 1221
1222 [DebuggerNonUserCode]
1080 public virtual void llDie() 1223 public virtual void llDie()
1081 { 1224 {
1082 m_host.AddScriptLPS(1); 1225 m_host.AddScriptLPS(1);
1083 throw new SelfDeleteException(); 1226 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1084 } 1227 }
1085 1228
1086 public LSL_Float llGround(LSL_Vector offset) 1229 public LSL_Float llGround(LSL_Vector offset)
@@ -1153,6 +1296,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1153 1296
1154 public void llSetStatus(int status, int value) 1297 public void llSetStatus(int status, int value)
1155 { 1298 {
1299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1300 return;
1156 m_host.AddScriptLPS(1); 1301 m_host.AddScriptLPS(1);
1157 1302
1158 int statusrotationaxis = 0; 1303 int statusrotationaxis = 0;
@@ -1176,6 +1321,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1176 if (!allow) 1321 if (!allow)
1177 return; 1322 return;
1178 1323
1324 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1325 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1326 return;
1327
1179 m_host.ScriptSetPhysicsStatus(true); 1328 m_host.ScriptSetPhysicsStatus(true);
1180 } 1329 }
1181 else 1330 else
@@ -1385,6 +1534,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1385 { 1534 {
1386 m_host.AddScriptLPS(1); 1535 m_host.AddScriptLPS(1);
1387 1536
1537 SetColor(m_host, color, face);
1538 }
1539
1540 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1541 {
1542 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1543 return;
1544
1545 Primitive.TextureEntry tex = part.Shape.Textures;
1546 Color4 texcolor;
1547 if (face >= 0 && face < GetNumberOfSides(part))
1548 {
1549 texcolor = tex.CreateFace((uint)face).RGBA;
1550 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1551 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1552 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1553 tex.FaceTextures[face].RGBA = texcolor;
1554 part.UpdateTextureEntry(tex.GetBytes());
1555 return;
1556 }
1557 else if (face == ScriptBaseClass.ALL_SIDES)
1558 {
1559 for (uint i = 0; i < GetNumberOfSides(part); i++)
1560 {
1561 if (tex.FaceTextures[i] != null)
1562 {
1563 texcolor = tex.FaceTextures[i].RGBA;
1564 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1565 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1566 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1567 tex.FaceTextures[i].RGBA = texcolor;
1568 }
1569 texcolor = tex.DefaultTexture.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.DefaultTexture.RGBA = texcolor;
1574 }
1575 part.UpdateTextureEntry(tex.GetBytes());
1576 return;
1577 }
1578
1388 if (face == ScriptBaseClass.ALL_SIDES) 1579 if (face == ScriptBaseClass.ALL_SIDES)
1389 face = SceneObjectPart.ALL_SIDES; 1580 face = SceneObjectPart.ALL_SIDES;
1390 1581
@@ -1393,6 +1584,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1393 1584
1394 public void SetTexGen(SceneObjectPart part, int face,int style) 1585 public void SetTexGen(SceneObjectPart part, int face,int style)
1395 { 1586 {
1587 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1588 return;
1589
1396 Primitive.TextureEntry tex = part.Shape.Textures; 1590 Primitive.TextureEntry tex = part.Shape.Textures;
1397 MappingType textype; 1591 MappingType textype;
1398 textype = MappingType.Default; 1592 textype = MappingType.Default;
@@ -1423,6 +1617,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1617
1424 public void SetGlow(SceneObjectPart part, int face, float glow) 1618 public void SetGlow(SceneObjectPart part, int face, float glow)
1425 { 1619 {
1620 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return;
1622
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1623 Primitive.TextureEntry tex = part.Shape.Textures;
1427 if (face >= 0 && face < GetNumberOfSides(part)) 1624 if (face >= 0 && face < GetNumberOfSides(part))
1428 { 1625 {
@@ -1448,6 +1645,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1645
1449 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1646 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1450 { 1647 {
1648 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return;
1451 1650
1452 Shininess sval = new Shininess(); 1651 Shininess sval = new Shininess();
1453 1652
@@ -1498,6 +1697,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1498 1697
1499 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1698 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1500 { 1699 {
1700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1701 return;
1702
1501 Primitive.TextureEntry tex = part.Shape.Textures; 1703 Primitive.TextureEntry tex = part.Shape.Textures;
1502 if (face >= 0 && face < GetNumberOfSides(part)) 1704 if (face >= 0 && face < GetNumberOfSides(part))
1503 { 1705 {
@@ -1558,13 +1760,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1558 m_host.AddScriptLPS(1); 1760 m_host.AddScriptLPS(1);
1559 1761
1560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1762 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1561 1763 if (parts.Count > 0)
1562 foreach (SceneObjectPart part in parts) 1764 {
1563 SetAlpha(part, alpha, face); 1765 try
1766 {
1767 parts[0].ParentGroup.areUpdatesSuspended = true;
1768 foreach (SceneObjectPart part in parts)
1769 SetAlpha(part, alpha, face);
1770 }
1771 finally
1772 {
1773 parts[0].ParentGroup.areUpdatesSuspended = false;
1774 }
1775 }
1564 } 1776 }
1565 1777
1566 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1778 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1567 { 1779 {
1780 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1781 return;
1782
1568 Primitive.TextureEntry tex = part.Shape.Textures; 1783 Primitive.TextureEntry tex = part.Shape.Textures;
1569 Color4 texcolor; 1784 Color4 texcolor;
1570 if (face >= 0 && face < GetNumberOfSides(part)) 1785 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1617,7 +1832,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1617 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1832 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1618 float wind, float tension, LSL_Vector Force) 1833 float wind, float tension, LSL_Vector Force)
1619 { 1834 {
1620 if (part == null) 1835 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return; 1836 return;
1622 1837
1623 if (flexi) 1838 if (flexi)
@@ -1651,7 +1866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1651 /// <param name="falloff"></param> 1866 /// <param name="falloff"></param>
1652 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1867 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1653 { 1868 {
1654 if (part == null) 1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1655 return; 1870 return;
1656 1871
1657 if (light) 1872 if (light)
@@ -1684,11 +1899,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1684 Primitive.TextureEntry tex = part.Shape.Textures; 1899 Primitive.TextureEntry tex = part.Shape.Textures;
1685 Color4 texcolor; 1900 Color4 texcolor;
1686 LSL_Vector rgb = new LSL_Vector(); 1901 LSL_Vector rgb = new LSL_Vector();
1902 int nsides = GetNumberOfSides(part);
1903
1687 if (face == ScriptBaseClass.ALL_SIDES) 1904 if (face == ScriptBaseClass.ALL_SIDES)
1688 { 1905 {
1689 int i; 1906 int i;
1690 1907 for (i = 0; i < nsides; i++)
1691 for (i = 0 ; i < GetNumberOfSides(part); i++)
1692 { 1908 {
1693 texcolor = tex.GetFace((uint)i).RGBA; 1909 texcolor = tex.GetFace((uint)i).RGBA;
1694 rgb.x += texcolor.R; 1910 rgb.x += texcolor.R;
@@ -1696,14 +1912,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1696 rgb.z += texcolor.B; 1912 rgb.z += texcolor.B;
1697 } 1913 }
1698 1914
1699 rgb.x /= (float)GetNumberOfSides(part); 1915 float invnsides = 1.0f / (float)nsides;
1700 rgb.y /= (float)GetNumberOfSides(part); 1916
1701 rgb.z /= (float)GetNumberOfSides(part); 1917 rgb.x *= invnsides;
1918 rgb.y *= invnsides;
1919 rgb.z *= invnsides;
1702 1920
1703 return rgb; 1921 return rgb;
1704 } 1922 }
1705 1923 if (face >= 0 && face < nsides)
1706 if (face >= 0 && face < GetNumberOfSides(part))
1707 { 1924 {
1708 texcolor = tex.GetFace((uint)face).RGBA; 1925 texcolor = tex.GetFace((uint)face).RGBA;
1709 rgb.x = texcolor.R; 1926 rgb.x = texcolor.R;
@@ -1730,15 +1947,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1730 m_host.AddScriptLPS(1); 1947 m_host.AddScriptLPS(1);
1731 1948
1732 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1949 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1733 1950 if (parts.Count > 0)
1734 foreach (SceneObjectPart part in parts) 1951 {
1735 SetTexture(part, texture, face); 1952 try
1736 1953 {
1954 parts[0].ParentGroup.areUpdatesSuspended = true;
1955 foreach (SceneObjectPart part in parts)
1956 SetTexture(part, texture, face);
1957 }
1958 finally
1959 {
1960 parts[0].ParentGroup.areUpdatesSuspended = false;
1961 }
1962 }
1737 ScriptSleep(200); 1963 ScriptSleep(200);
1738 } 1964 }
1739 1965
1740 protected void SetTexture(SceneObjectPart part, string texture, int face) 1966 protected void SetTexture(SceneObjectPart part, string texture, int face)
1741 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1742 UUID textureID = new UUID(); 1971 UUID textureID = new UUID();
1743 1972
1744 textureID = InventoryKey(texture, (int)AssetType.Texture); 1973 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1783,6 +2012,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1783 2012
1784 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2013 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1785 { 2014 {
2015 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2016 return;
2017
1786 Primitive.TextureEntry tex = part.Shape.Textures; 2018 Primitive.TextureEntry tex = part.Shape.Textures;
1787 if (face >= 0 && face < GetNumberOfSides(part)) 2019 if (face >= 0 && face < GetNumberOfSides(part))
1788 { 2020 {
@@ -1819,6 +2051,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 2051
1820 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2052 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1821 { 2053 {
2054 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2055 return;
2056
1822 Primitive.TextureEntry tex = part.Shape.Textures; 2057 Primitive.TextureEntry tex = part.Shape.Textures;
1823 if (face >= 0 && face < GetNumberOfSides(part)) 2058 if (face >= 0 && face < GetNumberOfSides(part))
1824 { 2059 {
@@ -1855,6 +2090,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1855 2090
1856 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2091 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1857 { 2092 {
2093 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2094 return;
2095
1858 Primitive.TextureEntry tex = part.Shape.Textures; 2096 Primitive.TextureEntry tex = part.Shape.Textures;
1859 if (face >= 0 && face < GetNumberOfSides(part)) 2097 if (face >= 0 && face < GetNumberOfSides(part))
1860 { 2098 {
@@ -1975,7 +2213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1975 2213
1976 bool sameParcel = here.GlobalID == there.GlobalID; 2214 bool sameParcel = here.GlobalID == there.GlobalID;
1977 2215
1978 if (!sameParcel && !World.Permissions.CanRezObject(m_host.ParentGroup.PrimCount, m_host.ParentGroup.OwnerID, new Vector3((float)pos.x, (float)pos.y, (float)pos.z))) 2216 if (!sameParcel && !World.Permissions.CanObjectEntry(m_host.UUID, false, new Vector3((float)pos.x, (float)pos.y, (float)pos.z)))
1979 { 2217 {
1980 return 0; 2218 return 0;
1981 } 2219 }
@@ -2024,24 +2262,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2262 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2025 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2263 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2026 { 2264 {
2027 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2265 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2266 return;
2267
2028 LSL_Vector currentPos = GetPartLocalPos(part); 2268 LSL_Vector currentPos = GetPartLocalPos(part);
2269 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2029 2270
2030 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2031 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2032 2271
2033 if (part.ParentGroup.RootPart == part) 2272 if (part.ParentGroup.RootPart == part)
2034 { 2273 {
2035 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2036 targetPos.z = ground;
2037 SceneObjectGroup parent = part.ParentGroup; 2274 SceneObjectGroup parent = part.ParentGroup;
2038 LSL_Vector real_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2275 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2039 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2276 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2277 return;
2278 Util.FireAndForget(delegate(object x) {
2279 parent.UpdateGroupPosition(dest);
2280 });
2040 } 2281 }
2041 else 2282 else
2042 { 2283 {
2043 LSL_Vector rel_vec = !adjust ? targetPos : SetPosAdjust(currentPos, targetPos); 2284 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2044 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2045 SceneObjectGroup parent = part.ParentGroup; 2285 SceneObjectGroup parent = part.ParentGroup;
2046 parent.HasGroupChanged = true; 2286 parent.HasGroupChanged = true;
2047 parent.ScheduleGroupForTerseUpdate(); 2287 parent.ScheduleGroupForTerseUpdate();
@@ -2074,17 +2314,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2074 else 2314 else
2075 { 2315 {
2076 if (part.ParentGroup.IsAttachment) 2316 if (part.ParentGroup.IsAttachment)
2077 {
2078 pos = part.AttachedPos; 2317 pos = part.AttachedPos;
2079 }
2080 else 2318 else
2081 {
2082 pos = part.AbsolutePosition; 2319 pos = part.AbsolutePosition;
2083 }
2084 } 2320 }
2085 2321
2086// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2087
2088 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2322 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2089 } 2323 }
2090 2324
@@ -2093,18 +2327,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2093 m_host.AddScriptLPS(1); 2327 m_host.AddScriptLPS(1);
2094 2328
2095 // try to let this work as in SL... 2329 // try to let this work as in SL...
2096 if (m_host.ParentID == 0) 2330 if (m_host.LinkNum < 2)
2097 { 2331 {
2098 // special case: If we are root, rotate complete SOG to new rotation 2332 // Special case: If we are root, rotate complete SOG to new
2333 // rotation.
2334 // We are root if the link number is 0 (single prim) or 1
2335 // (root prim). ParentID may be nonzero in attachments and
2336 // using it would cause attachments and HUDs to rotate
2337 // to the wrong positions.
2338
2099 SetRot(m_host, Rot2Quaternion(rot)); 2339 SetRot(m_host, Rot2Quaternion(rot));
2100 } 2340 }
2101 else 2341 else
2102 { 2342 {
2103 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2343 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2104 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2344 SceneObjectPart rootPart;
2105 if (rootPart != null) // better safe than sorry 2345 if (m_host.ParentGroup != null) // better safe than sorry
2106 { 2346 {
2107 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2347 rootPart = m_host.ParentGroup.RootPart;
2348 if (rootPart != null)
2349 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2108 } 2350 }
2109 } 2351 }
2110 2352
@@ -2114,31 +2356,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2114 public void llSetLocalRot(LSL_Rotation rot) 2356 public void llSetLocalRot(LSL_Rotation rot)
2115 { 2357 {
2116 m_host.AddScriptLPS(1); 2358 m_host.AddScriptLPS(1);
2359
2117 SetRot(m_host, Rot2Quaternion(rot)); 2360 SetRot(m_host, Rot2Quaternion(rot));
2118 ScriptSleep(200); 2361 ScriptSleep(200);
2119 } 2362 }
2120 2363
2121 protected void SetRot(SceneObjectPart part, Quaternion rot) 2364 protected void SetRot(SceneObjectPart part, Quaternion rot)
2122 { 2365 {
2123 part.UpdateRotation(rot); 2366 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2124 // Update rotation does not move the object in the physics scene if it's a linkset. 2367 return;
2125 2368
2126//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2369 bool isroot = (part == part.ParentGroup.RootPart);
2127// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2370 bool isphys;
2128 2371
2129 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2130 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2131 // It's perfectly okay when the object is not an active physical body though.
2132 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2133 // but only if the object is not physial and active. This is important for rotating doors.
2134 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2135 // scene
2136 PhysicsActor pa = part.PhysActor; 2372 PhysicsActor pa = part.PhysActor;
2137 2373
2138 if (pa != null && !pa.IsPhysical) 2374 // keep using physactor ideia of isphysical
2375 // it should be SOP ideia of that
2376 // not much of a issue with ubitODE
2377 if (pa != null && pa.IsPhysical)
2378 isphys = true;
2379 else
2380 isphys = false;
2381
2382 // SL doesn't let scripts rotate root of physical linksets
2383 if (isroot && isphys)
2384 return;
2385
2386 part.UpdateRotation(rot);
2387
2388 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2389 // so do a nasty update of parts positions if is a root part rotation
2390 if (isroot && pa != null) // with if above implies non physical root part
2139 { 2391 {
2140 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2392 part.ParentGroup.ResetChildPrimPhysicsPositions();
2141 } 2393 }
2394 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2395 {
2396 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2397 if (sittingavas.Count > 0)
2398 {
2399 foreach (ScenePresence av in sittingavas)
2400 {
2401 if (isroot || part.LocalId == av.ParentID)
2402 av.SendTerseUpdateToAllClients();
2403 }
2404 }
2405 }
2142 } 2406 }
2143 2407
2144 /// <summary> 2408 /// <summary>
@@ -2186,8 +2450,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2186 2450
2187 public LSL_Rotation llGetLocalRot() 2451 public LSL_Rotation llGetLocalRot()
2188 { 2452 {
2453 return GetPartLocalRot(m_host);
2454 }
2455
2456 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2457 {
2189 m_host.AddScriptLPS(1); 2458 m_host.AddScriptLPS(1);
2190 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2459 Quaternion rot = part.RotationOffset;
2460 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2191 } 2461 }
2192 2462
2193 public void llSetForce(LSL_Vector force, int local) 2463 public void llSetForce(LSL_Vector force, int local)
@@ -2271,16 +2541,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 m_host.ApplyImpulse(v, local != 0); 2541 m_host.ApplyImpulse(v, local != 0);
2272 } 2542 }
2273 2543
2544
2274 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2545 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2275 { 2546 {
2276 m_host.AddScriptLPS(1); 2547 m_host.AddScriptLPS(1);
2277 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2548 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2278 } 2549 }
2279 2550
2280 public void llSetTorque(LSL_Vector torque, int local) 2551 public void llSetTorque(LSL_Vector torque, int local)
2281 { 2552 {
2282 m_host.AddScriptLPS(1); 2553 m_host.AddScriptLPS(1);
2283 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2554 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2284 } 2555 }
2285 2556
2286 public LSL_Vector llGetTorque() 2557 public LSL_Vector llGetTorque()
@@ -2297,20 +2568,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 llSetTorque(torque, local); 2568 llSetTorque(torque, local);
2298 } 2569 }
2299 2570
2571 public void llSetVelocity(LSL_Vector vel, int local)
2572 {
2573 m_host.AddScriptLPS(1);
2574 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2575 }
2576
2300 public LSL_Vector llGetVel() 2577 public LSL_Vector llGetVel()
2301 { 2578 {
2302 m_host.AddScriptLPS(1); 2579 m_host.AddScriptLPS(1);
2303 2580
2304 Vector3 vel; 2581 Vector3 vel = Vector3.Zero;
2305 2582
2306 if (m_host.ParentGroup.IsAttachment) 2583 if (m_host.ParentGroup.IsAttachment)
2307 { 2584 {
2308 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2585 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2309 vel = avatar.Velocity; 2586 if (avatar != null)
2587 vel = avatar.Velocity;
2310 } 2588 }
2311 else 2589 else
2312 { 2590 {
2313 vel = m_host.Velocity; 2591 vel = m_host.ParentGroup.RootPart.Velocity;
2314 } 2592 }
2315 2593
2316 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2594 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2322,10 +2600,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2322 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2600 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2323 } 2601 }
2324 2602
2603 public void llSetAngularVelocity(LSL_Vector avel, int local)
2604 {
2605 m_host.AddScriptLPS(1);
2606 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2607 }
2608
2325 public LSL_Vector llGetOmega() 2609 public LSL_Vector llGetOmega()
2326 { 2610 {
2327 m_host.AddScriptLPS(1); 2611 m_host.AddScriptLPS(1);
2328 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2612 Vector3 avel = m_host.AngularVelocity;
2613 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2329 } 2614 }
2330 2615
2331 public LSL_Float llGetTimeOfDay() 2616 public LSL_Float llGetTimeOfDay()
@@ -2854,16 +3139,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2854 new_group.RootPart.UUID.ToString()) }, 3139 new_group.RootPart.UUID.ToString()) },
2855 new DetectParams[0])); 3140 new DetectParams[0]));
2856 3141
2857 float groupmass = new_group.GetMass(); 3142 // do recoil
3143 SceneObjectGroup hostgrp = m_host.ParentGroup;
3144 if (hostgrp == null)
3145 return;
3146
3147 if (hostgrp.IsAttachment) // don't recoil avatars
3148 return;
2858 3149
2859 PhysicsActor pa = new_group.RootPart.PhysActor; 3150 PhysicsActor pa = new_group.RootPart.PhysActor;
2860 3151
2861 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3152 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2862 { 3153 {
2863 //Recoil. 3154 float groupmass = new_group.GetMass();
2864 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3155 llvel *= -groupmass;
3156 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2865 } 3157 }
2866 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3158 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3159 return;
3160
2867 }); 3161 });
2868 3162
2869 //ScriptSleep((int)((groupmass * velmag) / 10)); 3163 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2878,35 +3172,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 public void llLookAt(LSL_Vector target, double strength, double damping) 3172 public void llLookAt(LSL_Vector target, double strength, double damping)
2879 { 3173 {
2880 m_host.AddScriptLPS(1); 3174 m_host.AddScriptLPS(1);
2881 // Determine where we are looking from
2882 LSL_Vector from = llGetPos();
2883 3175
2884 // Work out the normalised vector from the source to the target 3176 // Get the normalized vector to the target
2885 LSL_Vector delta = llVecNorm(target - from); 3177 LSL_Vector d1 = llVecNorm(target - llGetPos());
2886 LSL_Vector angle = new LSL_Vector(0,0,0);
2887 3178
2888 // Calculate the yaw 3179 // Get the bearing (yaw)
2889 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3180 LSL_Vector a1 = new LSL_Vector(0,0,0);
2890 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3181 a1.z = llAtan2(d1.y, d1.x);
2891 3182
2892 // Calculate pitch 3183 // Get the elevation (pitch)
2893 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3184 LSL_Vector a2 = new LSL_Vector(0,0,0);
3185 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2894 3186
2895 // we need to convert from a vector describing 3187 LSL_Rotation r1 = llEuler2Rot(a1);
2896 // the angles of rotation in radians into rotation value 3188 LSL_Rotation r2 = llEuler2Rot(a2);
2897 LSL_Rotation rot = llEuler2Rot(angle); 3189 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2898
2899 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2900 // set the rotation of the object, copy that behavior
2901 PhysicsActor pa = m_host.PhysActor;
2902 3190
2903 if (strength == 0 || pa == null || !pa.IsPhysical) 3191 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2904 { 3192 {
2905 llSetRot(rot); 3193 // Do nothing if either value is 0 (this has been checked in SL)
3194 if (strength <= 0.0 || damping <= 0.0)
3195 return;
3196
3197 llSetRot(r3 * r2 * r1);
2906 } 3198 }
2907 else 3199 else
2908 { 3200 {
2909 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3201 if (strength == 0)
3202 {
3203 llSetRot(r3 * r2 * r1);
3204 return;
3205 }
3206
3207 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2910 } 3208 }
2911 } 3209 }
2912 3210
@@ -2952,17 +3250,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2952 } 3250 }
2953 else 3251 else
2954 { 3252 {
2955 if (m_host.IsRoot) 3253 // new SL always returns object mass
2956 { 3254// if (m_host.IsRoot)
3255// {
2957 return m_host.ParentGroup.GetMass(); 3256 return m_host.ParentGroup.GetMass();
2958 } 3257// }
2959 else 3258// else
2960 { 3259// {
2961 return m_host.GetMass(); 3260// return m_host.GetMass();
2962 } 3261// }
2963 } 3262 }
2964 } 3263 }
2965 3264
3265
3266 public LSL_Float llGetMassMKS()
3267 {
3268 return 100f * llGetMass();
3269 }
3270
2966 public void llCollisionFilter(string name, string id, int accept) 3271 public void llCollisionFilter(string name, string id, int accept)
2967 { 3272 {
2968 m_host.AddScriptLPS(1); 3273 m_host.AddScriptLPS(1);
@@ -3010,8 +3315,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3010 { 3315 {
3011 // Unregister controls from Presence 3316 // Unregister controls from Presence
3012 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3317 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3013 // Remove Take Control permission.
3014 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3015 } 3318 }
3016 } 3319 }
3017 } 3320 }
@@ -3037,7 +3340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3340 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3038 3341
3039 if (attachmentsModule != null) 3342 if (attachmentsModule != null)
3040 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3343 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
3041 else 3344 else
3042 return false; 3345 return false;
3043 } 3346 }
@@ -3067,9 +3370,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3067 { 3370 {
3068 m_host.AddScriptLPS(1); 3371 m_host.AddScriptLPS(1);
3069 3372
3070// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3071// return;
3072
3073 if (m_item.PermsGranter != m_host.OwnerID) 3373 if (m_item.PermsGranter != m_host.OwnerID)
3074 return; 3374 return;
3075 3375
@@ -3112,6 +3412,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 3412
3113 public void llInstantMessage(string user, string message) 3413 public void llInstantMessage(string user, string message)
3114 { 3414 {
3415 UUID result;
3416 if (!UUID.TryParse(user, out result))
3417 {
3418 ShoutError("An invalid key was passed to llInstantMessage");
3419 ScriptSleep(2000);
3420 return;
3421 }
3422
3423
3115 m_host.AddScriptLPS(1); 3424 m_host.AddScriptLPS(1);
3116 3425
3117 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3426 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3126,14 +3435,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3126 UUID friendTransactionID = UUID.Random(); 3435 UUID friendTransactionID = UUID.Random();
3127 3436
3128 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3437 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3129 3438
3130 GridInstantMessage msg = new GridInstantMessage(); 3439 GridInstantMessage msg = new GridInstantMessage();
3131 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3440 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3132 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3441 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3133 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3442 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3134// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3443// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3135// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3444// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3136 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3445// DateTime dt = DateTime.UtcNow;
3446//
3447// // Ticks from UtcNow, but make it look like local. Evil, huh?
3448// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3449//
3450// try
3451// {
3452// // Convert that to the PST timezone
3453// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3454// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3455// }
3456// catch
3457// {
3458// // No logging here, as it could be VERY spammy
3459// }
3460//
3461// // And make it look local again to fool the unix time util
3462// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3463
3464 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3465
3137 //if (client != null) 3466 //if (client != null)
3138 //{ 3467 //{
3139 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3468 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3147,12 +3476,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3147 msg.message = message.Substring(0, 1024); 3476 msg.message = message.Substring(0, 1024);
3148 else 3477 else
3149 msg.message = message; 3478 msg.message = message;
3150 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3479 msg.dialog = (byte)19; // MessageFromObject
3151 msg.fromGroup = false;// fromGroup; 3480 msg.fromGroup = false;// fromGroup;
3152 msg.offline = (byte)0; //offline; 3481 msg.offline = (byte)0; //offline;
3153 msg.ParentEstateID = 0; //ParentEstateID; 3482 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3154 msg.Position = new Vector3(m_host.AbsolutePosition); 3483 msg.Position = new Vector3(m_host.AbsolutePosition);
3155 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3484 msg.RegionID = World.RegionInfo.RegionID.Guid;
3156 msg.binaryBucket 3485 msg.binaryBucket
3157 = Util.StringToBytes256( 3486 = Util.StringToBytes256(
3158 "{0}/{1}/{2}/{3}", 3487 "{0}/{1}/{2}/{3}",
@@ -3180,7 +3509,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 } 3509 }
3181 3510
3182 emailModule.SendEmail(m_host.UUID, address, subject, message); 3511 emailModule.SendEmail(m_host.UUID, address, subject, message);
3183 llSleep(EMAIL_PAUSE_TIME); 3512 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3184 } 3513 }
3185 3514
3186 public void llGetNextEmail(string address, string subject) 3515 public void llGetNextEmail(string address, string subject)
@@ -3424,15 +3753,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3424 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3753 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3425 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3754 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3426 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3755 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3756 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3427 ScriptBaseClass.PERMISSION_ATTACH; 3757 ScriptBaseClass.PERMISSION_ATTACH;
3428 3758
3429 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3759 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3430 { 3760 {
3431 lock (m_host.TaskInventory) 3761 m_host.TaskInventory.LockItemsForWrite(true);
3432 { 3762 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3433 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3763 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3434 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3764 m_host.TaskInventory.LockItemsForWrite(false);
3435 }
3436 3765
3437 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3766 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3438 "run_time_permissions", new Object[] { 3767 "run_time_permissions", new Object[] {
@@ -3442,28 +3771,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3442 return; 3771 return;
3443 } 3772 }
3444 } 3773 }
3445 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3774 else
3446 { 3775 {
3447 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3776 bool sitting = false;
3448 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3777 if (m_host.SitTargetAvatar == agentID)
3449 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3778 {
3450 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3779 sitting = true;
3451 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3780 }
3781 else
3782 {
3783 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3784 {
3785 if (p.SitTargetAvatar == agentID)
3786 sitting = true;
3787 }
3788 }
3452 3789
3453 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3790 if (sitting)
3454 { 3791 {
3455 lock (m_host.TaskInventory) 3792 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3793 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3794 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3795 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3796 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3797
3798 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3456 { 3799 {
3800 m_host.TaskInventory.LockItemsForWrite(true);
3457 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3801 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3458 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3802 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3459 } 3803 m_host.TaskInventory.LockItemsForWrite(false);
3460 3804
3461 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3805 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3806 "run_time_permissions", new Object[] {
3463 new LSL_Integer(perm) }, 3807 new LSL_Integer(perm) },
3464 new DetectParams[0])); 3808 new DetectParams[0]));
3465 3809
3466 return; 3810 return;
3811 }
3467 } 3812 }
3468 } 3813 }
3469 3814
@@ -3500,11 +3845,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3500 3845
3501 if (!m_waitingForScriptAnswer) 3846 if (!m_waitingForScriptAnswer)
3502 { 3847 {
3503 lock (m_host.TaskInventory) 3848 m_host.TaskInventory.LockItemsForWrite(true);
3504 { 3849 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3505 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3850 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3506 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3851 m_host.TaskInventory.LockItemsForWrite(false);
3507 }
3508 3852
3509 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3853 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3510 m_waitingForScriptAnswer=true; 3854 m_waitingForScriptAnswer=true;
@@ -3533,14 +3877,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3877 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3534 llReleaseControls(); 3878 llReleaseControls();
3535 3879
3536 lock (m_host.TaskInventory) 3880 m_host.TaskInventory.LockItemsForWrite(true);
3537 { 3881 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3538 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3882 m_host.TaskInventory.LockItemsForWrite(false);
3539 } 3883
3540 3884 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3541 m_ScriptEngine.PostScriptEvent( 3885 "run_time_permissions", new Object[] {
3542 m_item.ItemID, 3886 new LSL_Integer(answer) },
3543 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3887 new DetectParams[0]));
3544 } 3888 }
3545 3889
3546 public LSL_String llGetPermissionsKey() 3890 public LSL_String llGetPermissionsKey()
@@ -3579,14 +3923,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3923 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3924 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3925 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3926 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3927 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3928 try
3929 {
3930 parts[0].ParentGroup.areUpdatesSuspended = true;
3931 foreach (SceneObjectPart part in parts)
3932 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3933 }
3934 finally
3935 {
3936 parts[0].ParentGroup.areUpdatesSuspended = false;
3937 }
3938 }
3585 } 3939 }
3586 3940
3587 public void llCreateLink(string target, int parent) 3941 public void llCreateLink(string target, int parent)
3588 { 3942 {
3589 m_host.AddScriptLPS(1); 3943 m_host.AddScriptLPS(1);
3944
3590 UUID targetID; 3945 UUID targetID;
3591 3946
3592 if (!UUID.TryParse(target, out targetID)) 3947 if (!UUID.TryParse(target, out targetID))
@@ -3692,10 +4047,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3692 // Restructuring Multiple Prims. 4047 // Restructuring Multiple Prims.
3693 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4048 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3694 parts.Remove(parentPrim.RootPart); 4049 parts.Remove(parentPrim.RootPart);
3695 foreach (SceneObjectPart part in parts) 4050 if (parts.Count > 0)
3696 { 4051 {
3697 parentPrim.DelinkFromGroup(part.LocalId, true); 4052 try
4053 {
4054 parts[0].ParentGroup.areUpdatesSuspended = true;
4055 foreach (SceneObjectPart part in parts)
4056 {
4057 parentPrim.DelinkFromGroup(part.LocalId, true);
4058 }
4059 }
4060 finally
4061 {
4062 parts[0].ParentGroup.areUpdatesSuspended = false;
4063 }
3698 } 4064 }
4065
3699 parentPrim.HasGroupChanged = true; 4066 parentPrim.HasGroupChanged = true;
3700 parentPrim.ScheduleGroupForFullUpdate(); 4067 parentPrim.ScheduleGroupForFullUpdate();
3701 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4068 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3704,12 +4071,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3704 { 4071 {
3705 SceneObjectPart newRoot = parts[0]; 4072 SceneObjectPart newRoot = parts[0];
3706 parts.Remove(newRoot); 4073 parts.Remove(newRoot);
3707 foreach (SceneObjectPart part in parts) 4074
4075 try
3708 { 4076 {
3709 // Required for linking 4077 parts[0].ParentGroup.areUpdatesSuspended = true;
3710 part.ClearUpdateSchedule(); 4078 foreach (SceneObjectPart part in parts)
3711 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4079 {
4080 part.ClearUpdateSchedule();
4081 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4082 }
3712 } 4083 }
4084 finally
4085 {
4086 parts[0].ParentGroup.areUpdatesSuspended = false;
4087 }
4088
4089
3713 newRoot.ParentGroup.HasGroupChanged = true; 4090 newRoot.ParentGroup.HasGroupChanged = true;
3714 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4091 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3715 } 4092 }
@@ -3729,6 +4106,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3729 public void llBreakAllLinks() 4106 public void llBreakAllLinks()
3730 { 4107 {
3731 m_host.AddScriptLPS(1); 4108 m_host.AddScriptLPS(1);
4109
4110 TaskInventoryItem item = m_item;
4111
4112 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4113 && !m_automaticLinkPermission)
4114 {
4115 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4116 return;
4117 }
4118
3732 SceneObjectGroup parentPrim = m_host.ParentGroup; 4119 SceneObjectGroup parentPrim = m_host.ParentGroup;
3733 if (parentPrim.AttachmentPoint != 0) 4120 if (parentPrim.AttachmentPoint != 0)
3734 return; // Fail silently if attached 4121 return; // Fail silently if attached
@@ -3748,25 +4135,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3748 public LSL_String llGetLinkKey(int linknum) 4135 public LSL_String llGetLinkKey(int linknum)
3749 { 4136 {
3750 m_host.AddScriptLPS(1); 4137 m_host.AddScriptLPS(1);
3751 List<UUID> keytable = new List<UUID>();
3752 // parse for sitting avatare-uuids
3753 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3754 {
3755 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3756 keytable.Add(presence.UUID);
3757 });
3758
3759 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3760 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3761 {
3762 return keytable[totalprims - linknum].ToString();
3763 }
3764
3765 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3766 {
3767 return m_host.UUID.ToString();
3768 }
3769
3770 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4138 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3771 if (part != null) 4139 if (part != null)
3772 { 4140 {
@@ -3774,6 +4142,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3774 } 4142 }
3775 else 4143 else
3776 { 4144 {
4145 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4146 {
4147 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4148
4149 if (linknum < 0)
4150 return UUID.Zero.ToString();
4151
4152 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4153 if (avatars.Count > linknum)
4154 {
4155 return avatars[linknum].UUID.ToString();
4156 }
4157 }
3777 return UUID.Zero.ToString(); 4158 return UUID.Zero.ToString();
3778 } 4159 }
3779 } 4160 }
@@ -3873,17 +4254,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3873 m_host.AddScriptLPS(1); 4254 m_host.AddScriptLPS(1);
3874 int count = 0; 4255 int count = 0;
3875 4256
3876 lock (m_host.TaskInventory) 4257 m_host.TaskInventory.LockItemsForRead(true);
4258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3877 { 4259 {
3878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4260 if (inv.Value.Type == type || type == -1)
3879 { 4261 {
3880 if (inv.Value.Type == type || type == -1) 4262 count = count + 1;
3881 {
3882 count = count + 1;
3883 }
3884 } 4263 }
3885 } 4264 }
3886 4265
4266 m_host.TaskInventory.LockItemsForRead(false);
3887 return count; 4267 return count;
3888 } 4268 }
3889 4269
@@ -3892,16 +4272,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3892 m_host.AddScriptLPS(1); 4272 m_host.AddScriptLPS(1);
3893 ArrayList keys = new ArrayList(); 4273 ArrayList keys = new ArrayList();
3894 4274
3895 lock (m_host.TaskInventory) 4275 m_host.TaskInventory.LockItemsForRead(true);
4276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3896 { 4277 {
3897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4278 if (inv.Value.Type == type || type == -1)
3898 { 4279 {
3899 if (inv.Value.Type == type || type == -1) 4280 keys.Add(inv.Value.Name);
3900 {
3901 keys.Add(inv.Value.Name);
3902 }
3903 } 4281 }
3904 } 4282 }
4283 m_host.TaskInventory.LockItemsForRead(false);
3905 4284
3906 if (keys.Count == 0) 4285 if (keys.Count == 0)
3907 { 4286 {
@@ -3939,7 +4318,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3939 if (item == null) 4318 if (item == null)
3940 { 4319 {
3941 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4320 llSay(0, String.Format("Could not find object '{0}'", inventory));
3942 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4321 return;
4322// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3943 } 4323 }
3944 4324
3945 UUID objId = item.ItemID; 4325 UUID objId = item.ItemID;
@@ -3967,33 +4347,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3967 return; 4347 return;
3968 } 4348 }
3969 } 4349 }
4350
3970 // destination is an avatar 4351 // destination is an avatar
3971 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4352 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3972 4353
3973 if (agentItem == null) 4354 if (agentItem == null)
3974 return; 4355 return;
3975 4356
3976 if (m_TransferModule != null) 4357 byte[] bucket = new byte[1];
3977 { 4358 bucket[0] = (byte)item.Type;
3978 byte[] bucket = new byte[] { (byte)item.Type }; 4359 //byte[] objBytes = agentItem.ID.GetBytes();
4360 //Array.Copy(objBytes, 0, bucket, 1, 16);
3979 4361
3980 GridInstantMessage msg = new GridInstantMessage(World, 4362 GridInstantMessage msg = new GridInstantMessage(World,
3981 m_host.UUID, m_host.Name + ", an object owned by " + 4363 m_host.OwnerID, m_host.Name, destId,
3982 resolveName(m_host.OwnerID) + ",", destId, 4364 (byte)InstantMessageDialog.TaskInventoryOffered,
3983 (byte)InstantMessageDialog.TaskInventoryOffered, 4365 false, item.Name+". "+m_host.Name+" is located at "+
3984 false, item.Name + "\n" + m_host.Name + " is located at " + 4366 World.RegionInfo.RegionName+" "+
3985 World.RegionInfo.RegionName+" "+ 4367 m_host.AbsolutePosition.ToString(),
3986 m_host.AbsolutePosition.ToString(), 4368 agentItem.ID, true, m_host.AbsolutePosition,
3987 agentItem.ID, true, m_host.AbsolutePosition, 4369 bucket);
3988 bucket);
3989 4370
3990 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4371 ScenePresence sp;
3991 }
3992 4372
4373 if (World.TryGetScenePresence(destId, out sp))
4374 {
4375 sp.ControllingClient.SendInstantMessage(msg);
4376 }
4377 else
4378 {
4379 if (m_TransferModule != null)
4380 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4381 }
4382
4383 //This delay should only occur when giving inventory to avatars.
3993 ScriptSleep(3000); 4384 ScriptSleep(3000);
3994 } 4385 }
3995 } 4386 }
3996 4387
4388 [DebuggerNonUserCode]
3997 public void llRemoveInventory(string name) 4389 public void llRemoveInventory(string name)
3998 { 4390 {
3999 m_host.AddScriptLPS(1); 4391 m_host.AddScriptLPS(1);
@@ -4039,109 +4431,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4039 { 4431 {
4040 m_host.AddScriptLPS(1); 4432 m_host.AddScriptLPS(1);
4041 4433
4042 UUID uuid = (UUID)id; 4434 UUID uuid;
4043 PresenceInfo pinfo = null; 4435 if (UUID.TryParse(id, out uuid))
4044 UserAccount account;
4045
4046 UserInfoCacheEntry ce;
4047 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4048 { 4436 {
4049 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4437 PresenceInfo pinfo = null;
4050 if (account == null) 4438 UserAccount account;
4439
4440 UserInfoCacheEntry ce;
4441 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4051 { 4442 {
4052 m_userInfoCache[uuid] = null; // Cache negative 4443 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4053 return UUID.Zero.ToString(); 4444 if (account == null)
4054 } 4445 {
4446 m_userInfoCache[uuid] = null; // Cache negative
4447 return UUID.Zero.ToString();
4448 }
4055 4449
4056 4450
4057 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4451 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4058 if (pinfos != null && pinfos.Length > 0) 4452 if (pinfos != null && pinfos.Length > 0)
4059 {
4060 foreach (PresenceInfo p in pinfos)
4061 { 4453 {
4062 if (p.RegionID != UUID.Zero) 4454 foreach (PresenceInfo p in pinfos)
4063 { 4455 {
4064 pinfo = p; 4456 if (p.RegionID != UUID.Zero)
4457 {
4458 pinfo = p;
4459 }
4065 } 4460 }
4066 } 4461 }
4067 }
4068 4462
4069 ce = new UserInfoCacheEntry(); 4463 ce = new UserInfoCacheEntry();
4070 ce.time = Util.EnvironmentTickCount(); 4464 ce.time = Util.EnvironmentTickCount();
4071 ce.account = account; 4465 ce.account = account;
4072 ce.pinfo = pinfo; 4466 ce.pinfo = pinfo;
4073 } 4467 m_userInfoCache[uuid] = ce;
4074 else 4468 }
4075 { 4469 else
4076 if (ce == null) 4470 {
4077 return UUID.Zero.ToString(); 4471 if (ce == null)
4472 return UUID.Zero.ToString();
4078 4473
4079 account = ce.account; 4474 account = ce.account;
4080 pinfo = ce.pinfo; 4475 pinfo = ce.pinfo;
4081 } 4476 }
4082 4477
4083 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4478 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4084 {
4085 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4086 if (pinfos != null && pinfos.Length > 0)
4087 { 4479 {
4088 foreach (PresenceInfo p in pinfos) 4480 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4481 if (pinfos != null && pinfos.Length > 0)
4089 { 4482 {
4090 if (p.RegionID != UUID.Zero) 4483 foreach (PresenceInfo p in pinfos)
4091 { 4484 {
4092 pinfo = p; 4485 if (p.RegionID != UUID.Zero)
4486 {
4487 pinfo = p;
4488 }
4093 } 4489 }
4094 } 4490 }
4095 } 4491 else
4096 else 4492 pinfo = null;
4097 pinfo = null;
4098 4493
4099 ce.time = Util.EnvironmentTickCount(); 4494 ce.time = Util.EnvironmentTickCount();
4100 ce.pinfo = pinfo; 4495 ce.pinfo = pinfo;
4101 } 4496 }
4102 4497
4103 string reply = String.Empty; 4498 string reply = String.Empty;
4104 4499
4105 switch (data) 4500 switch (data)
4106 { 4501 {
4107 case 1: // DATA_ONLINE (0|1) 4502 case 1: // DATA_ONLINE (0|1)
4108 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4503 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4109 reply = "1"; 4504 reply = "1";
4110 else 4505 else
4111 reply = "0"; 4506 reply = "0";
4112 break; 4507 break;
4113 case 2: // DATA_NAME (First Last) 4508 case 2: // DATA_NAME (First Last)
4114 reply = account.FirstName + " " + account.LastName; 4509 reply = account.FirstName + " " + account.LastName;
4115 break; 4510 break;
4116 case 3: // DATA_BORN (YYYY-MM-DD) 4511 case 3: // DATA_BORN (YYYY-MM-DD)
4117 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4512 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4118 born = born.AddSeconds(account.Created); 4513 born = born.AddSeconds(account.Created);
4119 reply = born.ToString("yyyy-MM-dd"); 4514 reply = born.ToString("yyyy-MM-dd");
4120 break; 4515 break;
4121 case 4: // DATA_RATING (0,0,0,0,0,0) 4516 case 4: // DATA_RATING (0,0,0,0,0,0)
4122 reply = "0,0,0,0,0,0"; 4517 reply = "0,0,0,0,0,0";
4123 break; 4518 break;
4124 case 7: // DATA_USERLEVEL (integer) 4519 case 8: // DATA_PAYINFO (0|1|2|3)
4125 reply = account.UserLevel.ToString(); 4520 reply = "0";
4126 break; 4521 break;
4127 case 8: // DATA_PAYINFO (0|1|2|3) 4522 default:
4128 reply = "0"; 4523 return UUID.Zero.ToString(); // Raise no event
4129 break; 4524 }
4130 default:
4131 return UUID.Zero.ToString(); // Raise no event
4132 }
4133 4525
4134 UUID rq = UUID.Random(); 4526 UUID rq = UUID.Random();
4135 4527
4136 UUID tid = AsyncCommands. 4528 UUID tid = AsyncCommands.
4137 DataserverPlugin.RegisterRequest(m_host.LocalId, 4529 DataserverPlugin.RegisterRequest(m_host.LocalId,
4138 m_item.ItemID, rq.ToString()); 4530 m_item.ItemID, rq.ToString());
4139 4531
4140 AsyncCommands. 4532 AsyncCommands.
4141 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4533 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4142 4534
4143 ScriptSleep(100); 4535 ScriptSleep(100);
4144 return tid.ToString(); 4536 return tid.ToString();
4537 }
4538 else
4539 {
4540 ShoutError("Invalid UUID passed to llRequestAgentData.");
4541 }
4542 return "";
4145 } 4543 }
4146 4544
4147 public LSL_String llRequestInventoryData(string name) 4545 public LSL_String llRequestInventoryData(string name)
@@ -4198,13 +4596,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4198 if (UUID.TryParse(agent, out agentId)) 4596 if (UUID.TryParse(agent, out agentId))
4199 { 4597 {
4200 ScenePresence presence = World.GetScenePresence(agentId); 4598 ScenePresence presence = World.GetScenePresence(agentId);
4201 if (presence != null) 4599 if (presence != null && presence.PresenceType != PresenceType.Npc)
4202 { 4600 {
4601 // agent must not be a god
4602 if (presence.UserLevel >= 200) return;
4603
4203 // agent must be over the owners land 4604 // agent must be over the owners land
4204 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4605 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4205 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4606 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4206 { 4607 {
4207 World.TeleportClientHome(agentId, presence.ControllingClient); 4608 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4609 {
4610 // They can't be teleported home for some reason
4611 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4612 if (regionInfo != null)
4613 {
4614 World.RequestTeleportLocation(
4615 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4616 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4617 }
4618 }
4208 } 4619 }
4209 } 4620 }
4210 } 4621 }
@@ -4316,7 +4727,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4316 UUID av = new UUID(); 4727 UUID av = new UUID();
4317 if (!UUID.TryParse(agent,out av)) 4728 if (!UUID.TryParse(agent,out av))
4318 { 4729 {
4319 LSLError("First parameter to llDialog needs to be a key"); 4730 //LSLError("First parameter to llDialog needs to be a key");
4320 return; 4731 return;
4321 } 4732 }
4322 4733
@@ -4348,7 +4759,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4348 public void llCollisionSound(string impact_sound, double impact_volume) 4759 public void llCollisionSound(string impact_sound, double impact_volume)
4349 { 4760 {
4350 m_host.AddScriptLPS(1); 4761 m_host.AddScriptLPS(1);
4351 4762
4763 if(impact_sound == "")
4764 {
4765 m_host.CollisionSoundVolume = (float)impact_volume;
4766 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4767 m_host.CollisionSoundType = 0;
4768 return;
4769 }
4352 // TODO: Parameter check logic required. 4770 // TODO: Parameter check logic required.
4353 UUID soundId = UUID.Zero; 4771 UUID soundId = UUID.Zero;
4354 if (!UUID.TryParse(impact_sound, out soundId)) 4772 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4361,6 +4779,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4361 4779
4362 m_host.CollisionSound = soundId; 4780 m_host.CollisionSound = soundId;
4363 m_host.CollisionSoundVolume = (float)impact_volume; 4781 m_host.CollisionSoundVolume = (float)impact_volume;
4782 m_host.CollisionSoundType = 1;
4364 } 4783 }
4365 4784
4366 public LSL_String llGetAnimation(string id) 4785 public LSL_String llGetAnimation(string id)
@@ -4374,14 +4793,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4374 4793
4375 if (m_host.RegionHandle == presence.RegionHandle) 4794 if (m_host.RegionHandle == presence.RegionHandle)
4376 { 4795 {
4377 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4378
4379 if (presence != null) 4796 if (presence != null)
4380 { 4797 {
4381 AnimationSet currentAnims = presence.Animator.Animations; 4798 if (presence.SitGround)
4382 string currentAnimationState = String.Empty; 4799 return "Sitting on Ground";
4383 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4800 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4384 return currentAnimationState; 4801 return "Sitting";
4802
4803 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4804 string lslMovementAnimation;
4805
4806 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4807 return lslMovementAnimation;
4385 } 4808 }
4386 } 4809 }
4387 4810
@@ -4528,7 +4951,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4528 { 4951 {
4529 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4952 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4530 float distance_term = distance * distance * distance; // Script Energy 4953 float distance_term = distance * distance * distance; // Script Energy
4531 float pusher_mass = m_host.GetMass(); 4954 // use total object mass and not part
4955 float pusher_mass = m_host.ParentGroup.GetMass();
4532 4956
4533 float PUSH_ATTENUATION_DISTANCE = 17f; 4957 float PUSH_ATTENUATION_DISTANCE = 17f;
4534 float PUSH_ATTENUATION_SCALE = 5f; 4958 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4778,6 +5202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4778 { 5202 {
4779 return item.AssetID.ToString(); 5203 return item.AssetID.ToString();
4780 } 5204 }
5205 m_host.TaskInventory.LockItemsForRead(false);
4781 5206
4782 return UUID.Zero.ToString(); 5207 return UUID.Zero.ToString();
4783 } 5208 }
@@ -4911,7 +5336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4911 public LSL_Vector llGetCenterOfMass() 5336 public LSL_Vector llGetCenterOfMass()
4912 { 5337 {
4913 m_host.AddScriptLPS(1); 5338 m_host.AddScriptLPS(1);
4914 Vector3 center = m_host.GetGeometricCenter(); 5339 Vector3 center = m_host.GetCenterOfMass();
4915 return new LSL_Vector(center.X,center.Y,center.Z); 5340 return new LSL_Vector(center.X,center.Y,center.Z);
4916 } 5341 }
4917 5342
@@ -4930,14 +5355,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 { 5355 {
4931 m_host.AddScriptLPS(1); 5356 m_host.AddScriptLPS(1);
4932 5357
4933 if (src == null) 5358 return src.Length;
4934 {
4935 return 0;
4936 }
4937 else
4938 {
4939 return src.Length;
4940 }
4941 } 5359 }
4942 5360
4943 public LSL_Integer llList2Integer(LSL_List src, int index) 5361 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4983,7 +5401,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4983 else if (src.Data[index] is LSL_Float) 5401 else if (src.Data[index] is LSL_Float)
4984 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5402 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4985 else if (src.Data[index] is LSL_String) 5403 else if (src.Data[index] is LSL_String)
4986 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5404 {
5405 string str = ((LSL_String) src.Data[index]).m_string;
5406 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5407 if (m != Match.Empty)
5408 {
5409 str = m.Value;
5410 double d = 0.0;
5411 if (!Double.TryParse(str, out d))
5412 return 0.0;
5413
5414 return d;
5415 }
5416 return 0.0;
5417 }
4987 return Convert.ToDouble(src.Data[index]); 5418 return Convert.ToDouble(src.Data[index]);
4988 } 5419 }
4989 catch (FormatException) 5420 catch (FormatException)
@@ -5256,7 +5687,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5256 } 5687 }
5257 } 5688 }
5258 } 5689 }
5259 else { 5690 else
5691 {
5260 object[] array = new object[src.Length]; 5692 object[] array = new object[src.Length];
5261 Array.Copy(src.Data, 0, array, 0, src.Length); 5693 Array.Copy(src.Data, 0, array, 0, src.Length);
5262 result = new LSL_List(array); 5694 result = new LSL_List(array);
@@ -5363,7 +5795,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5363 public LSL_Integer llGetRegionAgentCount() 5795 public LSL_Integer llGetRegionAgentCount()
5364 { 5796 {
5365 m_host.AddScriptLPS(1); 5797 m_host.AddScriptLPS(1);
5366 return new LSL_Integer(World.GetRootAgentCount()); 5798
5799 int count = 0;
5800 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5801 count++;
5802 });
5803
5804 return new LSL_Integer(count);
5367 } 5805 }
5368 5806
5369 public LSL_Vector llGetRegionCorner() 5807 public LSL_Vector llGetRegionCorner()
@@ -5643,6 +6081,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5643 flags |= ScriptBaseClass.AGENT_SITTING; 6081 flags |= ScriptBaseClass.AGENT_SITTING;
5644 } 6082 }
5645 6083
6084 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6085 {
6086 flags |= ScriptBaseClass.AGENT_MALE;
6087 }
6088
5646 return flags; 6089 return flags;
5647 } 6090 }
5648 6091
@@ -5789,10 +6232,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5789 m_host.AddScriptLPS(1); 6232 m_host.AddScriptLPS(1);
5790 6233
5791 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6234 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5792 6235 if (parts.Count > 0)
5793 foreach (var part in parts)
5794 { 6236 {
5795 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6237 try
6238 {
6239 parts[0].ParentGroup.areUpdatesSuspended = true;
6240 foreach (var part in parts)
6241 {
6242 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6243 }
6244 }
6245 finally
6246 {
6247 parts[0].ParentGroup.areUpdatesSuspended = false;
6248 }
5796 } 6249 }
5797 } 6250 }
5798 6251
@@ -5844,13 +6297,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5844 6297
5845 if (m_host.OwnerID == land.LandData.OwnerID) 6298 if (m_host.OwnerID == land.LandData.OwnerID)
5846 { 6299 {
5847 World.TeleportClientHome(agentID, presence.ControllingClient); 6300 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6301 presence.TeleportWithMomentum(pos, null);
6302 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5848 } 6303 }
5849 } 6304 }
5850 } 6305 }
5851 ScriptSleep(5000); 6306 ScriptSleep(5000);
5852 } 6307 }
5853 6308
6309 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6310 {
6311 return ParseString2List(str, separators, in_spacers, false);
6312 }
6313
5854 public LSL_Integer llOverMyLand(string id) 6314 public LSL_Integer llOverMyLand(string id)
5855 { 6315 {
5856 m_host.AddScriptLPS(1); 6316 m_host.AddScriptLPS(1);
@@ -5909,20 +6369,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5909 return agentSize; 6369 return agentSize;
5910 } 6370 }
5911 6371
5912 public LSL_Integer llSameGroup(string agent) 6372 public LSL_Integer llSameGroup(string id)
5913 { 6373 {
5914 m_host.AddScriptLPS(1); 6374 m_host.AddScriptLPS(1);
5915 UUID agentId = new UUID(); 6375 UUID uuid = new UUID();
5916 if (!UUID.TryParse(agent, out agentId)) 6376 if (!UUID.TryParse(id, out uuid))
5917 return new LSL_Integer(0); 6377 return new LSL_Integer(0);
5918 ScenePresence presence = World.GetScenePresence(agentId); 6378
5919 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6379 // Check if it's a group key
5920 return new LSL_Integer(0); 6380 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5921 IClientAPI client = presence.ControllingClient;
5922 if (m_host.GroupID == client.ActiveGroupId)
5923 return new LSL_Integer(1); 6381 return new LSL_Integer(1);
5924 else 6382
6383 // We got passed a UUID.Zero
6384 if (uuid == UUID.Zero)
5925 return new LSL_Integer(0); 6385 return new LSL_Integer(0);
6386
6387 // Handle the case where id names an avatar
6388 ScenePresence presence = World.GetScenePresence(uuid);
6389 if (presence != null)
6390 {
6391 if (presence.IsChildAgent)
6392 return new LSL_Integer(0);
6393
6394 IClientAPI client = presence.ControllingClient;
6395 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6396 return new LSL_Integer(1);
6397
6398 return new LSL_Integer(0);
6399 }
6400
6401 // Handle object case
6402 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6403 if (part != null)
6404 {
6405 // This will handle both deed and non-deed and also the no
6406 // group case
6407 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6408 return new LSL_Integer(1);
6409
6410 return new LSL_Integer(0);
6411 }
6412
6413 return new LSL_Integer(0);
5926 } 6414 }
5927 6415
5928 public void llUnSit(string id) 6416 public void llUnSit(string id)
@@ -6051,7 +6539,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6051 return m_host.ParentGroup.AttachmentPoint; 6539 return m_host.ParentGroup.AttachmentPoint;
6052 } 6540 }
6053 6541
6054 public LSL_Integer llGetFreeMemory() 6542 public virtual LSL_Integer llGetFreeMemory()
6055 { 6543 {
6056 m_host.AddScriptLPS(1); 6544 m_host.AddScriptLPS(1);
6057 // Make scripts designed for LSO happy 6545 // Make scripts designed for LSO happy
@@ -6168,7 +6656,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6168 SetParticleSystem(m_host, rules); 6656 SetParticleSystem(m_host, rules);
6169 } 6657 }
6170 6658
6171 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6659 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6660 {
6172 6661
6173 6662
6174 if (rules.Length == 0) 6663 if (rules.Length == 0)
@@ -6485,7 +6974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6485 { 6974 {
6486 // LSL quaternions can normalize to 0, normal Quaternions can't. 6975 // LSL quaternions can normalize to 0, normal Quaternions can't.
6487 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6976 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6488 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6977 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6489 6978
6490 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6979 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6491 part.SitTargetOrientation = Rot2Quaternion(rot); 6980 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6642,13 +7131,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6642 UUID av = new UUID(); 7131 UUID av = new UUID();
6643 if (!UUID.TryParse(avatar,out av)) 7132 if (!UUID.TryParse(avatar,out av))
6644 { 7133 {
6645 LSLError("First parameter to llDialog needs to be a key"); 7134 //LSLError("First parameter to llDialog needs to be a key");
6646 return; 7135 return;
6647 } 7136 }
6648 if (buttons.Length < 1) 7137 if (buttons.Length < 1)
6649 { 7138 {
6650 LSLError("No less than 1 button can be shown"); 7139 buttons.Add("OK");
6651 return;
6652 } 7140 }
6653 if (buttons.Length > 12) 7141 if (buttons.Length > 12)
6654 { 7142 {
@@ -6665,7 +7153,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6665 } 7153 }
6666 if (buttons.Data[i].ToString().Length > 24) 7154 if (buttons.Data[i].ToString().Length > 24)
6667 { 7155 {
6668 LSLError("button label cannot be longer than 24 characters"); 7156 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6669 return; 7157 return;
6670 } 7158 }
6671 buts[i] = buttons.Data[i].ToString(); 7159 buts[i] = buttons.Data[i].ToString();
@@ -6732,9 +7220,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6732 return; 7220 return;
6733 } 7221 }
6734 7222
6735 // the rest of the permission checks are done in RezScript, so check the pin there as well 7223 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6736 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7224 if (dest != null)
7225 {
7226 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7227 {
7228 // the rest of the permission checks are done in RezScript, so check the pin there as well
7229 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6737 7230
7231 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7232 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7233 }
7234 }
6738 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7235 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6739 ScriptSleep(3000); 7236 ScriptSleep(3000);
6740 } 7237 }
@@ -6797,19 +7294,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6797 public LSL_String llMD5String(string src, int nonce) 7294 public LSL_String llMD5String(string src, int nonce)
6798 { 7295 {
6799 m_host.AddScriptLPS(1); 7296 m_host.AddScriptLPS(1);
6800 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7297 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6801 } 7298 }
6802 7299
6803 public LSL_String llSHA1String(string src) 7300 public LSL_String llSHA1String(string src)
6804 { 7301 {
6805 m_host.AddScriptLPS(1); 7302 m_host.AddScriptLPS(1);
6806 return Util.SHA1Hash(src).ToLower(); 7303 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6807 } 7304 }
6808 7305
6809 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7306 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6810 { 7307 {
6811 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7308 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6812 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7309 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7310 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7311 return shapeBlock;
6813 7312
6814 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7313 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6815 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7314 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6914,6 +7413,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6914 // Prim type box, cylinder and prism. 7413 // Prim type box, cylinder and prism.
6915 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) 7414 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)
6916 { 7415 {
7416 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7417 return;
7418
6917 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7419 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6918 ObjectShapePacket.ObjectDataBlock shapeBlock; 7420 ObjectShapePacket.ObjectDataBlock shapeBlock;
6919 7421
@@ -6967,6 +7469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6967 // Prim type sphere. 7469 // Prim type sphere.
6968 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7470 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6969 { 7471 {
7472 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7473 return;
7474
6970 ObjectShapePacket.ObjectDataBlock shapeBlock; 7475 ObjectShapePacket.ObjectDataBlock shapeBlock;
6971 7476
6972 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7477 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7008,6 +7513,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7008 // Prim type torus, tube and ring. 7513 // Prim type torus, tube and ring.
7009 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) 7514 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)
7010 { 7515 {
7516 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7517 return;
7518
7011 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7519 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7012 ObjectShapePacket.ObjectDataBlock shapeBlock; 7520 ObjectShapePacket.ObjectDataBlock shapeBlock;
7013 7521
@@ -7143,6 +7651,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7143 // Prim type sculpt. 7651 // Prim type sculpt.
7144 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7652 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7145 { 7653 {
7654 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7655 return;
7656
7146 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7657 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7147 UUID sculptId; 7658 UUID sculptId;
7148 7659
@@ -7167,7 +7678,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7167 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7678 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7168 { 7679 {
7169 // default 7680 // default
7170 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7681 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7171 } 7682 }
7172 7683
7173 part.Shape.SetSculptProperties((byte)type, sculptId); 7684 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7183,34 +7694,298 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7183 ScriptSleep(200); 7694 ScriptSleep(200);
7184 } 7695 }
7185 7696
7186 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7697 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7187 { 7698 {
7188 m_host.AddScriptLPS(1); 7699 m_host.AddScriptLPS(1);
7189 7700
7190 setLinkPrimParams(linknumber, rules); 7701 setLinkPrimParams(linknumber, rules);
7702 }
7703
7704 private void setLinkPrimParams(int linknumber, LSL_List rules)
7705 {
7706 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7707 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7708 if (parts.Count>0)
7709 {
7710 try
7711 {
7712 parts[0].ParentGroup.areUpdatesSuspended = true;
7713 foreach (SceneObjectPart part in parts)
7714 SetPrimParams(part, rules);
7715 }
7716 finally
7717 {
7718 parts[0].ParentGroup.areUpdatesSuspended = false;
7719 }
7720 }
7721 if (avatars.Count > 0)
7722 {
7723 foreach (ScenePresence avatar in avatars)
7724 SetPrimParams(avatar, rules);
7725 }
7726 }
7191 7727
7728 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7729 float material_density, float material_friction,
7730 float material_restitution, float material_gravity_modifier)
7731 {
7732 ExtraPhysicsData physdata = new ExtraPhysicsData();
7733 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7734 physdata.Density = part.Density;
7735 physdata.Friction = part.Friction;
7736 physdata.Bounce = part.Bounciness;
7737 physdata.GravitationModifier = part.GravityModifier;
7738
7739 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7740 physdata.Density = material_density;
7741 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7742 physdata.Friction = material_friction;
7743 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7744 physdata.Bounce = material_restitution;
7745 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7746 physdata.GravitationModifier = material_gravity_modifier;
7747
7748 part.UpdateExtraPhysics(physdata);
7749 }
7750
7751 public void llSetPhysicsMaterial(int material_bits,
7752 float material_gravity_modifier, float material_restitution,
7753 float material_friction, float material_density)
7754 {
7755 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7756 }
7757
7758 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7759 {
7760 llSetLinkPrimitiveParamsFast(linknumber, rules);
7192 ScriptSleep(200); 7761 ScriptSleep(200);
7193 } 7762 }
7194 7763
7195 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7764 // vector up using libomv (c&p from sop )
7765 // vector up rotated by r
7766 private Vector3 Zrot(Quaternion r)
7196 { 7767 {
7197 m_host.AddScriptLPS(1); 7768 double x, y, z, m;
7198 7769
7199 setLinkPrimParams(linknumber, rules); 7770 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7771 if (Math.Abs(1.0 - m) > 0.000001)
7772 {
7773 m = 1.0 / Math.Sqrt(m);
7774 r.X *= (float)m;
7775 r.Y *= (float)m;
7776 r.Z *= (float)m;
7777 r.W *= (float)m;
7778 }
7779
7780 x = 2 * (r.X * r.Z + r.Y * r.W);
7781 y = 2 * (-r.X * r.W + r.Y * r.Z);
7782 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7783
7784 return new Vector3((float)x, (float)y, (float)z);
7200 } 7785 }
7201 7786
7202 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7787 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7203 { 7788 {
7204 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7789 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7205 7790
7206 foreach (SceneObjectPart part in parts) 7791 int idx = 0;
7207 SetPrimParams(part, rules); 7792
7793 bool positionChanged = false;
7794 Vector3 finalPos = Vector3.Zero;
7795
7796 try
7797 {
7798 while (idx < rules.Length)
7799 {
7800 int code = rules.GetLSLIntegerItem(idx++);
7801
7802 int remain = rules.Length - idx;
7803
7804 switch (code)
7805 {
7806 case (int)ScriptBaseClass.PRIM_POSITION:
7807 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7808 {
7809 if (remain < 1)
7810 return;
7811
7812 LSL_Vector v;
7813 v = rules.GetVector3Item(idx++);
7814
7815 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7816 if (part == null)
7817 break;
7818
7819 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7820 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7821 if (part.LinkNum > 1)
7822 {
7823 localRot = GetPartLocalRot(part);
7824 localPos = GetPartLocalPos(part);
7825 }
7826
7827 v -= localPos;
7828 v /= localRot;
7829
7830 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7831
7832 v = v + 2 * sitOffset;
7833
7834 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7835 av.SendAvatarDataToAllAgents();
7836
7837 }
7838 break;
7839
7840 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7841 case (int)ScriptBaseClass.PRIM_ROTATION:
7842 {
7843 if (remain < 1)
7844 return;
7845
7846 LSL_Rotation r;
7847 r = rules.GetQuaternionItem(idx++);
7848
7849 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7850 if (part == null)
7851 break;
7852
7853 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7854 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7855
7856 if (part.LinkNum > 1)
7857 localRot = GetPartLocalRot(part);
7858
7859 r = r * llGetRootRotation() / localRot;
7860 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7861 av.SendAvatarDataToAllAgents();
7862 }
7863 break;
7864
7865 // parse rest doing nothing but number of parameters error check
7866 case (int)ScriptBaseClass.PRIM_SIZE:
7867 case (int)ScriptBaseClass.PRIM_MATERIAL:
7868 case (int)ScriptBaseClass.PRIM_PHANTOM:
7869 case (int)ScriptBaseClass.PRIM_PHYSICS:
7870 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7871 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7872 case (int)ScriptBaseClass.PRIM_NAME:
7873 case (int)ScriptBaseClass.PRIM_DESC:
7874 if (remain < 1)
7875 return;
7876 idx++;
7877 break;
7878
7879 case (int)ScriptBaseClass.PRIM_GLOW:
7880 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7881 case (int)ScriptBaseClass.PRIM_TEXGEN:
7882 if (remain < 2)
7883 return;
7884 idx += 2;
7885 break;
7886
7887 case (int)ScriptBaseClass.PRIM_TYPE:
7888 if (remain < 3)
7889 return;
7890 code = (int)rules.GetLSLIntegerItem(idx++);
7891 remain = rules.Length - idx;
7892 switch (code)
7893 {
7894 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7895 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7896 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7897 if (remain < 6)
7898 return;
7899 idx += 6;
7900 break;
7901
7902 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7903 if (remain < 5)
7904 return;
7905 idx += 5;
7906 break;
7907
7908 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7909 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7910 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7911 if (remain < 11)
7912 return;
7913 idx += 11;
7914 break;
7915
7916 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7917 if (remain < 2)
7918 return;
7919 idx += 2;
7920 break;
7921 }
7922 break;
7923
7924 case (int)ScriptBaseClass.PRIM_COLOR:
7925 case (int)ScriptBaseClass.PRIM_TEXT:
7926 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7927 case (int)ScriptBaseClass.PRIM_OMEGA:
7928 if (remain < 3)
7929 return;
7930 idx += 3;
7931 break;
7932
7933 case (int)ScriptBaseClass.PRIM_TEXTURE:
7934 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7935 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7936 if (remain < 5)
7937 return;
7938 idx += 5;
7939 break;
7940
7941 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7942 if (remain < 7)
7943 return;
7944
7945 idx += 7;
7946 break;
7947
7948 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7949 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7950 return;
7951
7952 if (positionChanged)
7953 {
7954 positionChanged = false;
7955 av.OffsetPosition = finalPos;
7956// av.SendAvatarDataToAllAgents();
7957 av.SendTerseUpdateToAllClients();
7958 }
7959
7960 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7961 LSL_List new_rules = rules.GetSublist(idx, -1);
7962 setLinkPrimParams((int)new_linknumber, new_rules);
7963 return;
7964 }
7965 }
7966 }
7967
7968 finally
7969 {
7970 if (positionChanged)
7971 {
7972 av.OffsetPosition = finalPos;
7973// av.SendAvatarDataToAllAgents();
7974 av.SendTerseUpdateToAllClients();
7975 positionChanged = false;
7976 }
7977 }
7208 } 7978 }
7209 7979
7210 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7980 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7211 { 7981 {
7982 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7983 return;
7984
7212 int idx = 0; 7985 int idx = 0;
7213 7986
7987 SceneObjectGroup parentgrp = part.ParentGroup;
7988
7214 bool positionChanged = false; 7989 bool positionChanged = false;
7215 LSL_Vector currentPosition = GetPartLocalPos(part); 7990 LSL_Vector currentPosition = GetPartLocalPos(part);
7216 7991
@@ -7233,8 +8008,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7233 return; 8008 return;
7234 8009
7235 v=rules.GetVector3Item(idx++); 8010 v=rules.GetVector3Item(idx++);
7236 positionChanged = true;
7237 currentPosition = GetSetPosTarget(part, v, currentPosition); 8011 currentPosition = GetSetPosTarget(part, v, currentPosition);
8012 positionChanged = true;
7238 8013
7239 break; 8014 break;
7240 case (int)ScriptBaseClass.PRIM_SIZE: 8015 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7250,8 +8025,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7250 return; 8025 return;
7251 8026
7252 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8027 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8028 SceneObjectPart rootPart = parentgrp.RootPart;
7253 // try to let this work as in SL... 8029 // try to let this work as in SL...
7254 if (part.ParentID == 0) 8030 if (rootPart == part)
7255 { 8031 {
7256 // special case: If we are root, rotate complete SOG to new rotation 8032 // special case: If we are root, rotate complete SOG to new rotation
7257 SetRot(part, Rot2Quaternion(q)); 8033 SetRot(part, Rot2Quaternion(q));
@@ -7259,7 +8035,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7259 else 8035 else
7260 { 8036 {
7261 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8037 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7262 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8038 // sounds like sl bug that we need to replicate
7263 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8039 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7264 } 8040 }
7265 8041
@@ -7512,7 +8288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7512 return; 8288 return;
7513 8289
7514 string ph = rules.Data[idx++].ToString(); 8290 string ph = rules.Data[idx++].ToString();
7515 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8291 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7516 8292
7517 break; 8293 break;
7518 8294
@@ -7530,12 +8306,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7530 part.ScriptSetPhysicsStatus(physics); 8306 part.ScriptSetPhysicsStatus(physics);
7531 break; 8307 break;
7532 8308
8309 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8310 if (remain < 1)
8311 return;
8312
8313 int shape_type = rules.GetLSLIntegerItem(idx++);
8314
8315 ExtraPhysicsData physdata = new ExtraPhysicsData();
8316 physdata.Density = part.Density;
8317 physdata.Bounce = part.Bounciness;
8318 physdata.GravitationModifier = part.GravityModifier;
8319 physdata.PhysShapeType = (PhysShapeType)shape_type;
8320
8321 part.UpdateExtraPhysics(physdata);
8322
8323 break;
8324
8325 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8326 if (remain < 5)
8327 return;
8328
8329 int material_bits = rules.GetLSLIntegerItem(idx++);
8330 float material_density = (float)rules.GetLSLFloatItem(idx++);
8331 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8332 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8333 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8334
8335 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8336
8337 break;
8338
7533 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8339 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7534 if (remain < 1) 8340 if (remain < 1)
7535 return; 8341 return;
7536 string temp = rules.Data[idx++].ToString(); 8342 string temp = rules.Data[idx++].ToString();
7537 8343
7538 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8344 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7539 8345
7540 break; 8346 break;
7541 8347
@@ -7574,6 +8380,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7574 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8380 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7575 if (remain < 1) 8381 if (remain < 1)
7576 return; 8382 return;
8383
7577 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8384 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7578 SetRot(part, Rot2Quaternion(lr)); 8385 SetRot(part, Rot2Quaternion(lr));
7579 break; 8386 break;
@@ -7585,13 +8392,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7585 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8392 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7586 TargetOmega(part, axis, (double)spinrate, (double)gain); 8393 TargetOmega(part, axis, (double)spinrate, (double)gain);
7587 break; 8394 break;
8395
7588 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8396 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7589 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8397 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7590 return; 8398 return;
8399
8400 // do a pending position change before jumping to other part/avatar
8401 if (positionChanged)
8402 {
8403 positionChanged = false;
8404 if (parentgrp == null)
8405 return;
8406
8407 if (parentgrp.RootPart == part)
8408 {
8409
8410 Util.FireAndForget(delegate(object x)
8411 {
8412 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8413 });
8414 }
8415 else
8416 {
8417 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8418 parentgrp.HasGroupChanged = true;
8419 parentgrp.ScheduleGroupForTerseUpdate();
8420 }
8421 }
8422
7591 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8423 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7592 LSL_List new_rules = rules.GetSublist(idx, -1); 8424 LSL_List new_rules = rules.GetSublist(idx, -1);
7593 setLinkPrimParams((int)new_linknumber, new_rules); 8425 setLinkPrimParams((int)new_linknumber, new_rules);
7594
7595 return; 8426 return;
7596 } 8427 }
7597 } 8428 }
@@ -7603,7 +8434,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 if (part.ParentGroup.RootPart == part) 8434 if (part.ParentGroup.RootPart == part)
7604 { 8435 {
7605 SceneObjectGroup parent = part.ParentGroup; 8436 SceneObjectGroup parent = part.ParentGroup;
7606 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8437 Util.FireAndForget(delegate(object x) {
8438 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8439 });
7607 } 8440 }
7608 else 8441 else
7609 { 8442 {
@@ -7647,10 +8480,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7647 8480
7648 public LSL_String llXorBase64Strings(string str1, string str2) 8481 public LSL_String llXorBase64Strings(string str1, string str2)
7649 { 8482 {
7650 m_host.AddScriptLPS(1); 8483 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7651 Deprecated("llXorBase64Strings"); 8484
7652 ScriptSleep(300); 8485 ScriptSleep(300);
7653 return String.Empty; 8486 m_host.AddScriptLPS(1);
8487
8488 if (str1 == String.Empty)
8489 return String.Empty;
8490 if (str2 == String.Empty)
8491 return str1;
8492
8493 int len = str2.Length;
8494 if ((len % 4) != 0) // LL is EVIL!!!!
8495 {
8496 while (str2.EndsWith("="))
8497 str2 = str2.Substring(0, str2.Length - 1);
8498
8499 len = str2.Length;
8500 int mod = len % 4;
8501
8502 if (mod == 1)
8503 str2 = str2.Substring(0, str2.Length - 1);
8504 else if (mod == 2)
8505 str2 += "==";
8506 else if (mod == 3)
8507 str2 += "=";
8508 }
8509
8510 byte[] data1;
8511 byte[] data2;
8512 try
8513 {
8514 data1 = Convert.FromBase64String(str1);
8515 data2 = Convert.FromBase64String(str2);
8516 }
8517 catch (Exception)
8518 {
8519 return new LSL_String(String.Empty);
8520 }
8521
8522 // For cases where the decoded length of s2 is greater
8523 // than the decoded length of s1, simply perform a normal
8524 // decode and XOR
8525 //
8526 if (data2.Length >= data1.Length)
8527 {
8528 for (int pos = 0 ; pos < data1.Length ; pos++ )
8529 data1[pos] ^= data2[pos];
8530
8531 return Convert.ToBase64String(data1);
8532 }
8533
8534 // Remove padding
8535 while (str1.EndsWith("="))
8536 str1 = str1.Substring(0, str1.Length - 1);
8537 while (str2.EndsWith("="))
8538 str2 = str2.Substring(0, str2.Length - 1);
8539
8540 byte[] d1 = new byte[str1.Length];
8541 byte[] d2 = new byte[str2.Length];
8542
8543 for (int i = 0 ; i < str1.Length ; i++)
8544 {
8545 int idx = b64.IndexOf(str1.Substring(i, 1));
8546 if (idx == -1)
8547 idx = 0;
8548 d1[i] = (byte)idx;
8549 }
8550
8551 for (int i = 0 ; i < str2.Length ; i++)
8552 {
8553 int idx = b64.IndexOf(str2.Substring(i, 1));
8554 if (idx == -1)
8555 idx = 0;
8556 d2[i] = (byte)idx;
8557 }
8558
8559 string output = String.Empty;
8560
8561 for (int pos = 0 ; pos < d1.Length ; pos++)
8562 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8563
8564 while (output.Length % 3 > 0)
8565 output += "=";
8566
8567 return output;
7654 } 8568 }
7655 8569
7656 public void llRemoteDataSetRegion() 8570 public void llRemoteDataSetRegion()
@@ -7774,13 +8688,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7774 public LSL_Integer llGetNumberOfPrims() 8688 public LSL_Integer llGetNumberOfPrims()
7775 { 8689 {
7776 m_host.AddScriptLPS(1); 8690 m_host.AddScriptLPS(1);
7777 int avatarCount = 0; 8691 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7778 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8692
7779 {
7780 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7781 avatarCount++;
7782 });
7783
7784 return m_host.ParentGroup.PrimCount + avatarCount; 8693 return m_host.ParentGroup.PrimCount + avatarCount;
7785 } 8694 }
7786 8695
@@ -7796,55 +8705,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7796 m_host.AddScriptLPS(1); 8705 m_host.AddScriptLPS(1);
7797 UUID objID = UUID.Zero; 8706 UUID objID = UUID.Zero;
7798 LSL_List result = new LSL_List(); 8707 LSL_List result = new LSL_List();
8708
8709 // If the ID is not valid, return null result
7799 if (!UUID.TryParse(obj, out objID)) 8710 if (!UUID.TryParse(obj, out objID))
7800 { 8711 {
7801 result.Add(new LSL_Vector()); 8712 result.Add(new LSL_Vector());
7802 result.Add(new LSL_Vector()); 8713 result.Add(new LSL_Vector());
7803 return result; 8714 return result;
7804 } 8715 }
8716
8717 // Check if this is an attached prim. If so, replace
8718 // the UUID with the avatar UUID and report it's bounding box
8719 SceneObjectPart part = World.GetSceneObjectPart(objID);
8720 if (part != null && part.ParentGroup.IsAttachment)
8721 objID = part.ParentGroup.AttachedAvatar;
8722
8723 // Find out if this is an avatar ID. If so, return it's box
7805 ScenePresence presence = World.GetScenePresence(objID); 8724 ScenePresence presence = World.GetScenePresence(objID);
7806 if (presence != null) 8725 if (presence != null)
7807 { 8726 {
7808 if (presence.ParentID == 0) // not sat on an object 8727 // As per LSL Wiki, there is no difference between sitting
8728 // and standing avatar since server 1.36
8729 LSL_Vector lower;
8730 LSL_Vector upper;
8731 if (presence.Animator.Animations.DefaultAnimation.AnimID
8732 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7809 { 8733 {
7810 LSL_Vector lower; 8734 // This is for ground sitting avatars
7811 LSL_Vector upper; 8735 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7812 if (presence.Animator.Animations.DefaultAnimation.AnimID 8736 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7813 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8737 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7814 {
7815 // This is for ground sitting avatars
7816 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7817 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7818 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7819 }
7820 else
7821 {
7822 // This is for standing/flying avatars
7823 float height = presence.Appearance.AvatarHeight / 2.0f;
7824 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7825 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7826 }
7827 result.Add(lower);
7828 result.Add(upper);
7829 return result;
7830 } 8738 }
7831 else 8739 else
7832 { 8740 {
7833 // sitting on an object so we need the bounding box of that 8741 // This is for standing/flying avatars
7834 // which should include the avatar so set the UUID to the 8742 float height = presence.Appearance.AvatarHeight / 2.0f;
7835 // UUID of the object the avatar is sat on and allow it to fall through 8743 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7836 // to processing an object 8744 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7837 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7838 objID = p.UUID;
7839 } 8745 }
8746
8747 // Adjust to the documented error offsets (see LSL Wiki)
8748 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8749 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8750
8751 if (lower.x > upper.x)
8752 lower.x = upper.x;
8753 if (lower.y > upper.y)
8754 lower.y = upper.y;
8755 if (lower.z > upper.z)
8756 lower.z = upper.z;
8757
8758 result.Add(lower);
8759 result.Add(upper);
8760 return result;
7840 } 8761 }
7841 SceneObjectPart part = World.GetSceneObjectPart(objID); 8762
8763 part = World.GetSceneObjectPart(objID);
7842 // Currently only works for single prims without a sitting avatar 8764 // Currently only works for single prims without a sitting avatar
7843 if (part != null) 8765 if (part != null)
7844 { 8766 {
7845 Vector3 halfSize = part.Scale / 2.0f; 8767 float minX;
7846 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8768 float maxX;
7847 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8769 float minY;
8770 float maxY;
8771 float minZ;
8772 float maxZ;
8773
8774 // This BBox is in sim coordinates, with the offset being
8775 // a contained point.
8776 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8777 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8778
8779 minX -= offsets[0].X;
8780 maxX -= offsets[0].X;
8781 minY -= offsets[0].Y;
8782 maxY -= offsets[0].Y;
8783 minZ -= offsets[0].Z;
8784 maxZ -= offsets[0].Z;
8785
8786 LSL_Vector lower;
8787 LSL_Vector upper;
8788
8789 // Adjust to the documented error offsets (see LSL Wiki)
8790 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8791 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8792
8793 if (lower.x > upper.x)
8794 lower.x = upper.x;
8795 if (lower.y > upper.y)
8796 lower.y = upper.y;
8797 if (lower.z > upper.z)
8798 lower.z = upper.z;
8799
7848 result.Add(lower); 8800 result.Add(lower);
7849 result.Add(upper); 8801 result.Add(upper);
7850 return result; 8802 return result;
@@ -7858,7 +8810,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7858 8810
7859 public LSL_Vector llGetGeometricCenter() 8811 public LSL_Vector llGetGeometricCenter()
7860 { 8812 {
7861 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8813 Vector3 tmp = m_host.GetGeometricCenter();
8814 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7862 } 8815 }
7863 8816
7864 public LSL_List llGetPrimitiveParams(LSL_List rules) 8817 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7871,16 +8824,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7871 { 8824 {
7872 m_host.AddScriptLPS(1); 8825 m_host.AddScriptLPS(1);
7873 8826
8827 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8828 // keep other options as before
8829
7874 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8830 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8831 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7875 8832
7876 LSL_List res = new LSL_List(); 8833 LSL_List res = new LSL_List();
7877 8834
7878 foreach (var part in parts) 8835 if (parts.Count > 0)
7879 { 8836 {
7880 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8837 foreach (var part in parts)
7881 res += partRes; 8838 {
8839 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8840 res += partRes;
8841 }
8842 }
8843 if (avatars.Count > 0)
8844 {
8845 foreach (ScenePresence avatar in avatars)
8846 {
8847 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8848 res += avaRes;
8849 }
7882 } 8850 }
8851 return res;
8852 }
8853
8854 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8855 {
8856 // avatars case
8857 // replies as SL wiki
8858
8859 LSL_List res = new LSL_List();
8860// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8861 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8862
8863 int idx = 0;
8864 while (idx < rules.Length)
8865 {
8866 int code = (int)rules.GetLSLIntegerItem(idx++);
8867 int remain = rules.Length - idx;
8868
8869 switch (code)
8870 {
8871 case (int)ScriptBaseClass.PRIM_MATERIAL:
8872 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8873 break;
8874
8875 case (int)ScriptBaseClass.PRIM_PHYSICS:
8876 res.Add(new LSL_Integer(0));
8877 break;
8878
8879 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8880 res.Add(new LSL_Integer(0));
8881 break;
8882
8883 case (int)ScriptBaseClass.PRIM_PHANTOM:
8884 res.Add(new LSL_Integer(0));
8885 break;
8886
8887 case (int)ScriptBaseClass.PRIM_POSITION:
8888
8889 Vector3 pos = avatar.OffsetPosition;
8890
8891 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8892 pos -= sitOffset;
8893
8894 if( sitPart != null)
8895 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8896
8897 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8898 break;
8899
8900 case (int)ScriptBaseClass.PRIM_SIZE:
8901 // as in llGetAgentSize above
8902 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8903 break;
8904
8905 case (int)ScriptBaseClass.PRIM_ROTATION:
8906 Quaternion rot = avatar.Rotation;
8907 if (sitPart != null)
8908 {
8909 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8910 }
7883 8911
8912 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8913 break;
8914
8915 case (int)ScriptBaseClass.PRIM_TYPE:
8916 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8917 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8918 res.Add(new LSL_Vector(0f,1.0f,0f));
8919 res.Add(new LSL_Float(0.0f));
8920 res.Add(new LSL_Vector(0, 0, 0));
8921 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8922 res.Add(new LSL_Vector(0, 0, 0));
8923 break;
8924
8925 case (int)ScriptBaseClass.PRIM_TEXTURE:
8926 if (remain < 1)
8927 return res;
8928
8929 int face = (int)rules.GetLSLIntegerItem(idx++);
8930 if (face == ScriptBaseClass.ALL_SIDES)
8931 {
8932 for (face = 0; face < 21; face++)
8933 {
8934 res.Add(new LSL_String(""));
8935 res.Add(new LSL_Vector(0,0,0));
8936 res.Add(new LSL_Vector(0,0,0));
8937 res.Add(new LSL_Float(0.0));
8938 }
8939 }
8940 else
8941 {
8942 if (face >= 0 && face < 21)
8943 {
8944 res.Add(new LSL_String(""));
8945 res.Add(new LSL_Vector(0,0,0));
8946 res.Add(new LSL_Vector(0,0,0));
8947 res.Add(new LSL_Float(0.0));
8948 }
8949 }
8950 break;
8951
8952 case (int)ScriptBaseClass.PRIM_COLOR:
8953 if (remain < 1)
8954 return res;
8955
8956 face = (int)rules.GetLSLIntegerItem(idx++);
8957
8958 if (face == ScriptBaseClass.ALL_SIDES)
8959 {
8960 for (face = 0; face < 21; face++)
8961 {
8962 res.Add(new LSL_Vector(0,0,0));
8963 res.Add(new LSL_Float(0));
8964 }
8965 }
8966 else
8967 {
8968 res.Add(new LSL_Vector(0,0,0));
8969 res.Add(new LSL_Float(0));
8970 }
8971 break;
8972
8973 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8974 if (remain < 1)
8975 return res;
8976 face = (int)rules.GetLSLIntegerItem(idx++);
8977
8978 if (face == ScriptBaseClass.ALL_SIDES)
8979 {
8980 for (face = 0; face < 21; face++)
8981 {
8982 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8983 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8984 }
8985 }
8986 else
8987 {
8988 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8989 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8990 }
8991 break;
8992
8993 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8994 if (remain < 1)
8995 return res;
8996 face = (int)rules.GetLSLIntegerItem(idx++);
8997
8998 if (face == ScriptBaseClass.ALL_SIDES)
8999 {
9000 for (face = 0; face < 21; face++)
9001 {
9002 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9003 }
9004 }
9005 else
9006 {
9007 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
9008 }
9009 break;
9010
9011 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
9012 res.Add(new LSL_Integer(0));
9013 res.Add(new LSL_Integer(0));// softness
9014 res.Add(new LSL_Float(0.0f)); // gravity
9015 res.Add(new LSL_Float(0.0f)); // friction
9016 res.Add(new LSL_Float(0.0f)); // wind
9017 res.Add(new LSL_Float(0.0f)); // tension
9018 res.Add(new LSL_Vector(0f,0f,0f));
9019 break;
9020
9021 case (int)ScriptBaseClass.PRIM_TEXGEN:
9022 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
9023 if (remain < 1)
9024 return res;
9025 face = (int)rules.GetLSLIntegerItem(idx++);
9026
9027 if (face == ScriptBaseClass.ALL_SIDES)
9028 {
9029 for (face = 0; face < 21; face++)
9030 {
9031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9032 }
9033 }
9034 else
9035 {
9036 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9037 }
9038 break;
9039
9040 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9041 res.Add(new LSL_Integer(0));
9042 res.Add(new LSL_Vector(0f,0f,0f));
9043 res.Add(new LSL_Float(0f)); // intensity
9044 res.Add(new LSL_Float(0f)); // radius
9045 res.Add(new LSL_Float(0f)); // falloff
9046 break;
9047
9048 case (int)ScriptBaseClass.PRIM_GLOW:
9049 if (remain < 1)
9050 return res;
9051 face = (int)rules.GetLSLIntegerItem(idx++);
9052
9053 if (face == ScriptBaseClass.ALL_SIDES)
9054 {
9055 for (face = 0; face < 21; face++)
9056 {
9057 res.Add(new LSL_Float(0f));
9058 }
9059 }
9060 else
9061 {
9062 res.Add(new LSL_Float(0f));
9063 }
9064 break;
9065
9066 case (int)ScriptBaseClass.PRIM_TEXT:
9067 res.Add(new LSL_String(""));
9068 res.Add(new LSL_Vector(0f,0f,0f));
9069 res.Add(new LSL_Float(1.0f));
9070 break;
9071
9072 case (int)ScriptBaseClass.PRIM_NAME:
9073 res.Add(new LSL_String(avatar.Name));
9074 break;
9075
9076 case (int)ScriptBaseClass.PRIM_DESC:
9077 res.Add(new LSL_String(""));
9078 break;
9079
9080 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9081 Quaternion lrot = avatar.Rotation;
9082
9083 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9084 {
9085 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9086 }
9087 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9088 break;
9089
9090 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9091 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9092 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9093 lpos -= lsitOffset;
9094
9095 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9096 {
9097 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9098 }
9099 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9100 break;
9101
9102 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9103 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9104 return res;
9105 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9106 LSL_List new_rules = rules.GetSublist(idx, -1);
9107
9108 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9109 return res;
9110 }
9111 }
7884 return res; 9112 return res;
7885 } 9113 }
7886 9114
@@ -7924,13 +9152,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7924 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9152 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7925 part.AbsolutePosition.Y, 9153 part.AbsolutePosition.Y,
7926 part.AbsolutePosition.Z); 9154 part.AbsolutePosition.Z);
7927 // For some reason, the part.AbsolutePosition.* values do not change if the
7928 // linkset is rotated; they always reflect the child prim's world position
7929 // as though the linkset is unrotated. This is incompatible behavior with SL's
7930 // implementation, so will break scripts imported from there (not to mention it
7931 // makes it more difficult to determine a child prim's actual inworld position).
7932 if (part.ParentID != 0)
7933 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7934 res.Add(v); 9155 res.Add(v);
7935 break; 9156 break;
7936 9157
@@ -8101,56 +9322,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8101 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9322 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8102 if (remain < 1) 9323 if (remain < 1)
8103 return res; 9324 return res;
8104 9325 face = (int)rules.GetLSLIntegerItem(idx++);
8105 face=(int)rules.GetLSLIntegerItem(idx++);
8106 9326
8107 tex = part.Shape.Textures; 9327 tex = part.Shape.Textures;
9328 int shiny;
8108 if (face == ScriptBaseClass.ALL_SIDES) 9329 if (face == ScriptBaseClass.ALL_SIDES)
8109 { 9330 {
8110 for (face = 0; face < GetNumberOfSides(part); face++) 9331 for (face = 0; face < GetNumberOfSides(part); face++)
8111 { 9332 {
8112 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9333 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8113 // Convert Shininess to PRIM_SHINY_* 9334 if (shinyness == Shininess.High)
8114 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9335 {
8115 // PRIM_BUMP_* 9336 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8116 res.Add(new LSL_Integer((int)texface.Bump)); 9337 }
9338 else if (shinyness == Shininess.Medium)
9339 {
9340 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9341 }
9342 else if (shinyness == Shininess.Low)
9343 {
9344 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9345 }
9346 else
9347 {
9348 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9349 }
9350 res.Add(new LSL_Integer(shiny));
9351 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8117 } 9352 }
8118 } 9353 }
8119 else 9354 else
8120 { 9355 {
8121 if (face >= 0 && face < GetNumberOfSides(part)) 9356 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9357 if (shinyness == Shininess.High)
8122 { 9358 {
8123 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9359 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8124 // Convert Shininess to PRIM_SHINY_* 9360 }
8125 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9361 else if (shinyness == Shininess.Medium)
8126 // PRIM_BUMP_* 9362 {
8127 res.Add(new LSL_Integer((int)texface.Bump)); 9363 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9364 }
9365 else if (shinyness == Shininess.Low)
9366 {
9367 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8128 } 9368 }
9369 else
9370 {
9371 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9372 }
9373 res.Add(new LSL_Integer(shiny));
9374 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8129 } 9375 }
8130 break; 9376 break;
8131 9377
8132 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9378 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8133 if (remain < 1) 9379 if (remain < 1)
8134 return res; 9380 return res;
8135 9381 face = (int)rules.GetLSLIntegerItem(idx++);
8136 face=(int)rules.GetLSLIntegerItem(idx++);
8137 9382
8138 tex = part.Shape.Textures; 9383 tex = part.Shape.Textures;
9384 int fullbright;
8139 if (face == ScriptBaseClass.ALL_SIDES) 9385 if (face == ScriptBaseClass.ALL_SIDES)
8140 { 9386 {
8141 for (face = 0; face < GetNumberOfSides(part); face++) 9387 for (face = 0; face < GetNumberOfSides(part); face++)
8142 { 9388 {
8143 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9389 if (tex.GetFace((uint)face).Fullbright == true)
8144 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9390 {
9391 fullbright = ScriptBaseClass.TRUE;
9392 }
9393 else
9394 {
9395 fullbright = ScriptBaseClass.FALSE;
9396 }
9397 res.Add(new LSL_Integer(fullbright));
8145 } 9398 }
8146 } 9399 }
8147 else 9400 else
8148 { 9401 {
8149 if (face >= 0 && face < GetNumberOfSides(part)) 9402 if (tex.GetFace((uint)face).Fullbright == true)
8150 { 9403 {
8151 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9404 fullbright = ScriptBaseClass.TRUE;
8152 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8153 } 9405 }
9406 else
9407 {
9408 fullbright = ScriptBaseClass.FALSE;
9409 }
9410 res.Add(new LSL_Integer(fullbright));
8154 } 9411 }
8155 break; 9412 break;
8156 9413
@@ -8172,27 +9429,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8172 break; 9429 break;
8173 9430
8174 case (int)ScriptBaseClass.PRIM_TEXGEN: 9431 case (int)ScriptBaseClass.PRIM_TEXGEN:
9432 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8175 if (remain < 1) 9433 if (remain < 1)
8176 return res; 9434 return res;
8177 9435 face = (int)rules.GetLSLIntegerItem(idx++);
8178 face=(int)rules.GetLSLIntegerItem(idx++);
8179 9436
8180 tex = part.Shape.Textures; 9437 tex = part.Shape.Textures;
8181 if (face == ScriptBaseClass.ALL_SIDES) 9438 if (face == ScriptBaseClass.ALL_SIDES)
8182 { 9439 {
8183 for (face = 0; face < GetNumberOfSides(part); face++) 9440 for (face = 0; face < GetNumberOfSides(part); face++)
8184 { 9441 {
8185 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9442 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8186 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9443 {
8187 res.Add(new LSL_Integer((uint)texgen >> 1)); 9444 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9445 }
9446 else
9447 {
9448 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9449 }
8188 } 9450 }
8189 } 9451 }
8190 else 9452 else
8191 { 9453 {
8192 if (face >= 0 && face < GetNumberOfSides(part)) 9454 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8193 { 9455 {
8194 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9456 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8195 res.Add(new LSL_Integer((uint)texgen >> 1)); 9457 }
9458 else
9459 {
9460 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8196 } 9461 }
8197 } 9462 }
8198 break; 9463 break;
@@ -8215,25 +9480,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8215 case (int)ScriptBaseClass.PRIM_GLOW: 9480 case (int)ScriptBaseClass.PRIM_GLOW:
8216 if (remain < 1) 9481 if (remain < 1)
8217 return res; 9482 return res;
8218 9483 face = (int)rules.GetLSLIntegerItem(idx++);
8219 face=(int)rules.GetLSLIntegerItem(idx++);
8220 9484
8221 tex = part.Shape.Textures; 9485 tex = part.Shape.Textures;
9486 float primglow;
8222 if (face == ScriptBaseClass.ALL_SIDES) 9487 if (face == ScriptBaseClass.ALL_SIDES)
8223 { 9488 {
8224 for (face = 0; face < GetNumberOfSides(part); face++) 9489 for (face = 0; face < GetNumberOfSides(part); face++)
8225 { 9490 {
8226 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9491 primglow = tex.GetFace((uint)face).Glow;
8227 res.Add(new LSL_Float(texface.Glow)); 9492 res.Add(new LSL_Float(primglow));
8228 } 9493 }
8229 } 9494 }
8230 else 9495 else
8231 { 9496 {
8232 if (face >= 0 && face < GetNumberOfSides(part)) 9497 primglow = tex.GetFace((uint)face).Glow;
8233 { 9498 res.Add(new LSL_Float(primglow));
8234 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8235 res.Add(new LSL_Float(texface.Glow));
8236 }
8237 } 9499 }
8238 break; 9500 break;
8239 9501
@@ -8245,18 +9507,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8245 textColor.B)); 9507 textColor.B));
8246 res.Add(new LSL_Float(textColor.A)); 9508 res.Add(new LSL_Float(textColor.A));
8247 break; 9509 break;
9510
8248 case (int)ScriptBaseClass.PRIM_NAME: 9511 case (int)ScriptBaseClass.PRIM_NAME:
8249 res.Add(new LSL_String(part.Name)); 9512 res.Add(new LSL_String(part.Name));
8250 break; 9513 break;
9514
8251 case (int)ScriptBaseClass.PRIM_DESC: 9515 case (int)ScriptBaseClass.PRIM_DESC:
8252 res.Add(new LSL_String(part.Description)); 9516 res.Add(new LSL_String(part.Description));
8253 break; 9517 break;
9518
8254 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9519 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8255 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9520 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8256 break; 9521 break;
9522
8257 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9523 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8258 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9524 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8259 break; 9525 break;
9526
9527 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9528 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9529 return res;
9530 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9531 LSL_List new_rules = rules.GetSublist(idx, -1);
9532 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9533 res += tres;
9534 return res;
8260 } 9535 }
8261 } 9536 }
8262 return res; 9537 return res;
@@ -8849,8 +10124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8849 // The function returns an ordered list 10124 // The function returns an ordered list
8850 // representing the tokens found in the supplied 10125 // representing the tokens found in the supplied
8851 // sources string. If two successive tokenizers 10126 // sources string. If two successive tokenizers
8852 // are encountered, then a NULL entry is added 10127 // are encountered, then a null-string entry is
8853 // to the list. 10128 // added to the list.
8854 // 10129 //
8855 // It is a precondition that the source and 10130 // It is a precondition that the source and
8856 // toekizer lisst are non-null. If they are null, 10131 // toekizer lisst are non-null. If they are null,
@@ -8858,7 +10133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8858 // while their lengths are being determined. 10133 // while their lengths are being determined.
8859 // 10134 //
8860 // A small amount of working memoryis required 10135 // A small amount of working memoryis required
8861 // of approximately 8*#tokenizers. 10136 // of approximately 8*#tokenizers + 8*srcstrlen.
8862 // 10137 //
8863 // There are many ways in which this function 10138 // There are many ways in which this function
8864 // can be implemented, this implementation is 10139 // can be implemented, this implementation is
@@ -8874,155 +10149,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8874 // and eliminates redundant tokenizers as soon 10149 // and eliminates redundant tokenizers as soon
8875 // as is possible. 10150 // as is possible.
8876 // 10151 //
8877 // The implementation tries to avoid any copying 10152 // The implementation tries to minimize temporary
8878 // of arrays or other objects. 10153 // garbage generation.
8879 // </remarks> 10154 // </remarks>
8880 10155
8881 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10156 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8882 { 10157 {
8883 int beginning = 0; 10158 return ParseString2List(src, separators, spacers, true);
8884 int srclen = src.Length; 10159 }
8885 int seplen = separators.Length;
8886 object[] separray = separators.Data;
8887 int spclen = spacers.Length;
8888 object[] spcarray = spacers.Data;
8889 int mlen = seplen+spclen;
8890
8891 int[] offset = new int[mlen+1];
8892 bool[] active = new bool[mlen];
8893
8894 int best;
8895 int j;
8896
8897 // Initial capacity reduces resize cost
8898 10160
8899 LSL_List tokens = new LSL_List(); 10161 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10162 {
10163 int srclen = src.Length;
10164 int seplen = separators.Length;
10165 object[] separray = separators.Data;
10166 int spclen = spacers.Length;
10167 object[] spcarray = spacers.Data;
10168 int dellen = 0;
10169 string[] delarray = new string[seplen+spclen];
8900 10170
8901 // All entries are initially valid 10171 int outlen = 0;
10172 string[] outarray = new string[srclen*2+1];
8902 10173
8903 for (int i = 0; i < mlen; i++) 10174 int i, j;
8904 active[i] = true; 10175 string d;
8905 10176
8906 offset[mlen] = srclen; 10177 m_host.AddScriptLPS(1);
8907 10178
8908 while (beginning < srclen) 10179 /*
10180 * Convert separator and spacer lists to C# strings.
10181 * Also filter out null strings so we don't hang.
10182 */
10183 for (i = 0; i < seplen; i ++)
8909 { 10184 {
10185 d = separray[i].ToString();
10186 if (d.Length > 0)
10187 {
10188 delarray[dellen++] = d;
10189 }
10190 }
10191 seplen = dellen;
8910 10192
8911 best = mlen; // as bad as it gets 10193 for (i = 0; i < spclen; i ++)
10194 {
10195 d = spcarray[i].ToString();
10196 if (d.Length > 0)
10197 {
10198 delarray[dellen++] = d;
10199 }
10200 }
8912 10201
8913 // Scan for separators 10202 /*
10203 * Scan through source string from beginning to end.
10204 */
10205 for (i = 0;;)
10206 {
8914 10207
8915 for (j = 0; j < seplen; j++) 10208 /*
10209 * Find earliest delimeter in src starting at i (if any).
10210 */
10211 int earliestDel = -1;
10212 int earliestSrc = srclen;
10213 string earliestStr = null;
10214 for (j = 0; j < dellen; j ++)
8916 { 10215 {
8917 if (separray[j].ToString() == String.Empty) 10216 d = delarray[j];
8918 active[j] = false; 10217 if (d != null)
8919
8920 if (active[j])
8921 { 10218 {
8922 // scan all of the markers 10219 int index = src.IndexOf(d, i);
8923 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10220 if (index < 0)
8924 { 10221 {
8925 // not present at all 10222 delarray[j] = null; // delim nowhere in src, don't check it anymore
8926 active[j] = false;
8927 } 10223 }
8928 else 10224 else if (index < earliestSrc)
8929 { 10225 {
8930 // present and correct 10226 earliestSrc = index; // where delimeter starts in source string
8931 if (offset[j] < offset[best]) 10227 earliestDel = j; // where delimeter is in delarray[]
8932 { 10228 earliestStr = d; // the delimeter string from delarray[]
8933 // closest so far 10229 if (index == i) break; // can't do any better than found at beg of string
8934 best = j;
8935 if (offset[best] == beginning)
8936 break;
8937 }
8938 } 10230 }
8939 } 10231 }
8940 } 10232 }
8941 10233
8942 // Scan for spacers 10234 /*
8943 10235 * Output source string starting at i through start of earliest delimeter.
8944 if (offset[best] != beginning) 10236 */
10237 if (keepNulls || (earliestSrc > i))
8945 { 10238 {
8946 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10239 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8947 {
8948 if (spcarray[j-seplen].ToString() == String.Empty)
8949 active[j] = false;
8950
8951 if (active[j])
8952 {
8953 // scan all of the markers
8954 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8955 {
8956 // not present at all
8957 active[j] = false;
8958 }
8959 else
8960 {
8961 // present and correct
8962 if (offset[j] < offset[best])
8963 {
8964 // closest so far
8965 best = j;
8966 }
8967 }
8968 }
8969 }
8970 } 10240 }
8971 10241
8972 // This is the normal exit from the scanning loop 10242 /*
10243 * If no delimeter found at or after i, we're done scanning.
10244 */
10245 if (earliestDel < 0) break;
8973 10246
8974 if (best == mlen) 10247 /*
10248 * If delimeter was a spacer, output the spacer.
10249 */
10250 if (earliestDel >= seplen)
8975 { 10251 {
8976 // no markers were found on this pass 10252 outarray[outlen++] = earliestStr;
8977 // so we're pretty much done
8978 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8979 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8980 break;
8981 } 10253 }
8982 10254
8983 // Otherwise we just add the newly delimited token 10255 /*
8984 // and recalculate where the search should continue. 10256 * Look at rest of src string following delimeter.
8985 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10257 */
8986 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10258 i = earliestSrc + earliestStr.Length;
8987
8988 if (best < seplen)
8989 {
8990 beginning = offset[best] + (separray[best].ToString()).Length;
8991 }
8992 else
8993 {
8994 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8995 string str = spcarray[best - seplen].ToString();
8996 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8997 tokens.Add(new LSL_String(str));
8998 }
8999 } 10259 }
9000 10260
9001 // This an awkward an not very intuitive boundary case. If the 10261 /*
9002 // last substring is a tokenizer, then there is an implied trailing 10262 * Make up an exact-sized output array suitable for an LSL_List object.
9003 // null list entry. Hopefully the single comparison will not be too 10263 */
9004 // arduous. Alternatively the 'break' could be replced with a return 10264 object[] outlist = new object[outlen];
9005 // but that's shabby programming. 10265 for (i = 0; i < outlen; i ++)
9006
9007 if ((beginning == srclen) && (keepNulls))
9008 { 10266 {
9009 if (srclen != 0) 10267 outlist[i] = new LSL_String(outarray[i]);
9010 tokens.Add(new LSL_String(""));
9011 } 10268 }
9012 10269 return new LSL_List(outlist);
9013 return tokens;
9014 }
9015
9016 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9017 {
9018 m_host.AddScriptLPS(1);
9019 return this.ParseString(src, separators, spacers, false);
9020 }
9021
9022 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9023 {
9024 m_host.AddScriptLPS(1);
9025 return this.ParseString(src, separators, spacers, true);
9026 } 10270 }
9027 10271
9028 public LSL_Integer llGetObjectPermMask(int mask) 10272 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9117,6 +10361,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9117 case 4: 10361 case 4:
9118 return (int)item.NextPermissions; 10362 return (int)item.NextPermissions;
9119 } 10363 }
10364 m_host.TaskInventory.LockItemsForRead(false);
9120 10365
9121 return -1; 10366 return -1;
9122 } 10367 }
@@ -9307,9 +10552,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9307 { 10552 {
9308 try 10553 try
9309 { 10554 {
10555 /*
9310 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10556 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9311 if (obj != null) 10557 if (obj != null)
9312 return (double)obj.GetMass(); 10558 return (double)obj.GetMass();
10559 */
10560 // return total object mass
10561 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10562 if (obj != null)
10563 return obj.GetMass();
10564
9313 // the object is null so the key is for an avatar 10565 // the object is null so the key is for an avatar
9314 ScenePresence avatar = World.GetScenePresence(key); 10566 ScenePresence avatar = World.GetScenePresence(key);
9315 if (avatar != null) 10567 if (avatar != null)
@@ -9329,7 +10581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9329 } 10581 }
9330 10582
9331 /// <summary> 10583 /// <summary>
9332 /// illListReplaceList removes the sub-list defined by the inclusive indices 10584 /// llListReplaceList removes the sub-list defined by the inclusive indices
9333 /// start and end and inserts the src list in its place. The inclusive 10585 /// start and end and inserts the src list in its place. The inclusive
9334 /// nature of the indices means that at least one element must be deleted 10586 /// nature of the indices means that at least one element must be deleted
9335 /// if the indices are within the bounds of the existing list. I.e. 2,2 10587 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9386,16 +10638,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9386 // based upon end. Note that if end exceeds the upper 10638 // based upon end. Note that if end exceeds the upper
9387 // bound in this case, the entire destination list 10639 // bound in this case, the entire destination list
9388 // is removed. 10640 // is removed.
9389 else 10641 else if (start == 0)
9390 { 10642 {
9391 if (end + 1 < dest.Length) 10643 if (end + 1 < dest.Length)
9392 {
9393 return src + dest.GetSublist(end + 1, -1); 10644 return src + dest.GetSublist(end + 1, -1);
9394 }
9395 else 10645 else
9396 {
9397 return src; 10646 return src;
9398 } 10647 }
10648 else // Start < 0
10649 {
10650 if (end + 1 < dest.Length)
10651 return dest.GetSublist(end + 1, -1);
10652 else
10653 return new LSL_List();
9399 } 10654 }
9400 } 10655 }
9401 // Finally, if start > end, we strip away a prefix and 10656 // Finally, if start > end, we strip away a prefix and
@@ -9446,17 +10701,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9446 int width = 0; 10701 int width = 0;
9447 int height = 0; 10702 int height = 0;
9448 10703
9449 ParcelMediaCommandEnum? commandToSend = null; 10704 uint commandToSend = 0;
9450 float time = 0.0f; // default is from start 10705 float time = 0.0f; // default is from start
9451 10706
9452 ScenePresence presence = null; 10707 ScenePresence presence = null;
9453 10708
9454 for (int i = 0; i < commandList.Data.Length; i++) 10709 for (int i = 0; i < commandList.Data.Length; i++)
9455 { 10710 {
9456 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10711 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9457 switch (command) 10712 switch (command)
9458 { 10713 {
9459 case ParcelMediaCommandEnum.Agent: 10714 case (uint)ParcelMediaCommandEnum.Agent:
9460 // we send only to one agent 10715 // we send only to one agent
9461 if ((i + 1) < commandList.Length) 10716 if ((i + 1) < commandList.Length)
9462 { 10717 {
@@ -9473,25 +10728,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9473 } 10728 }
9474 break; 10729 break;
9475 10730
9476 case ParcelMediaCommandEnum.Loop: 10731 case (uint)ParcelMediaCommandEnum.Loop:
9477 loop = 1; 10732 loop = 1;
9478 commandToSend = command; 10733 commandToSend = command;
9479 update = true; //need to send the media update packet to set looping 10734 update = true; //need to send the media update packet to set looping
9480 break; 10735 break;
9481 10736
9482 case ParcelMediaCommandEnum.Play: 10737 case (uint)ParcelMediaCommandEnum.Play:
9483 loop = 0; 10738 loop = 0;
9484 commandToSend = command; 10739 commandToSend = command;
9485 update = true; //need to send the media update packet to make sure it doesn't loop 10740 update = true; //need to send the media update packet to make sure it doesn't loop
9486 break; 10741 break;
9487 10742
9488 case ParcelMediaCommandEnum.Pause: 10743 case (uint)ParcelMediaCommandEnum.Pause:
9489 case ParcelMediaCommandEnum.Stop: 10744 case (uint)ParcelMediaCommandEnum.Stop:
9490 case ParcelMediaCommandEnum.Unload: 10745 case (uint)ParcelMediaCommandEnum.Unload:
9491 commandToSend = command; 10746 commandToSend = command;
9492 break; 10747 break;
9493 10748
9494 case ParcelMediaCommandEnum.Url: 10749 case (uint)ParcelMediaCommandEnum.Url:
9495 if ((i + 1) < commandList.Length) 10750 if ((i + 1) < commandList.Length)
9496 { 10751 {
9497 if (commandList.Data[i + 1] is LSL_String) 10752 if (commandList.Data[i + 1] is LSL_String)
@@ -9504,7 +10759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9504 } 10759 }
9505 break; 10760 break;
9506 10761
9507 case ParcelMediaCommandEnum.Texture: 10762 case (uint)ParcelMediaCommandEnum.Texture:
9508 if ((i + 1) < commandList.Length) 10763 if ((i + 1) < commandList.Length)
9509 { 10764 {
9510 if (commandList.Data[i + 1] is LSL_String) 10765 if (commandList.Data[i + 1] is LSL_String)
@@ -9517,7 +10772,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9517 } 10772 }
9518 break; 10773 break;
9519 10774
9520 case ParcelMediaCommandEnum.Time: 10775 case (uint)ParcelMediaCommandEnum.Time:
9521 if ((i + 1) < commandList.Length) 10776 if ((i + 1) < commandList.Length)
9522 { 10777 {
9523 if (commandList.Data[i + 1] is LSL_Float) 10778 if (commandList.Data[i + 1] is LSL_Float)
@@ -9529,7 +10784,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9529 } 10784 }
9530 break; 10785 break;
9531 10786
9532 case ParcelMediaCommandEnum.AutoAlign: 10787 case (uint)ParcelMediaCommandEnum.AutoAlign:
9533 if ((i + 1) < commandList.Length) 10788 if ((i + 1) < commandList.Length)
9534 { 10789 {
9535 if (commandList.Data[i + 1] is LSL_Integer) 10790 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9543,7 +10798,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9543 } 10798 }
9544 break; 10799 break;
9545 10800
9546 case ParcelMediaCommandEnum.Type: 10801 case (uint)ParcelMediaCommandEnum.Type:
9547 if ((i + 1) < commandList.Length) 10802 if ((i + 1) < commandList.Length)
9548 { 10803 {
9549 if (commandList.Data[i + 1] is LSL_String) 10804 if (commandList.Data[i + 1] is LSL_String)
@@ -9556,7 +10811,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9556 } 10811 }
9557 break; 10812 break;
9558 10813
9559 case ParcelMediaCommandEnum.Desc: 10814 case (uint)ParcelMediaCommandEnum.Desc:
9560 if ((i + 1) < commandList.Length) 10815 if ((i + 1) < commandList.Length)
9561 { 10816 {
9562 if (commandList.Data[i + 1] is LSL_String) 10817 if (commandList.Data[i + 1] is LSL_String)
@@ -9569,7 +10824,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9569 } 10824 }
9570 break; 10825 break;
9571 10826
9572 case ParcelMediaCommandEnum.Size: 10827 case (uint)ParcelMediaCommandEnum.Size:
9573 if ((i + 2) < commandList.Length) 10828 if ((i + 2) < commandList.Length)
9574 { 10829 {
9575 if (commandList.Data[i + 1] is LSL_Integer) 10830 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9639,7 +10894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9639 } 10894 }
9640 } 10895 }
9641 10896
9642 if (commandToSend != null) 10897 if (commandToSend != 0)
9643 { 10898 {
9644 // the commandList contained a start/stop/... command, too 10899 // the commandList contained a start/stop/... command, too
9645 if (presence == null) 10900 if (presence == null)
@@ -9676,7 +10931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9676 10931
9677 if (aList.Data[i] != null) 10932 if (aList.Data[i] != null)
9678 { 10933 {
9679 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10934 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9680 { 10935 {
9681 case ParcelMediaCommandEnum.Url: 10936 case ParcelMediaCommandEnum.Url:
9682 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10937 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9733,15 +10988,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9733 10988
9734 if (quick_pay_buttons.Data.Length < 4) 10989 if (quick_pay_buttons.Data.Length < 4)
9735 { 10990 {
9736 LSLError("List must have at least 4 elements"); 10991 int x;
9737 return; 10992 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10993 {
10994 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10995 }
9738 } 10996 }
9739 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10997 int[] nPrice = new int[5];
9740 10998 nPrice[0] = price;
9741 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10999 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9742 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 11000 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9743 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 11001 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9744 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 11002 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
11003 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9745 m_host.ParentGroup.HasGroupChanged = true; 11004 m_host.ParentGroup.HasGroupChanged = true;
9746 } 11005 }
9747 11006
@@ -9758,7 +11017,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9758 return new LSL_Vector(); 11017 return new LSL_Vector();
9759 } 11018 }
9760 11019
9761 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11020// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11021 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9762 if (presence != null) 11022 if (presence != null)
9763 { 11023 {
9764 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 11024 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9780,7 +11040,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9780 return new LSL_Rotation(); 11040 return new LSL_Rotation();
9781 } 11041 }
9782 11042
9783 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11043// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11044 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9784 if (presence != null) 11045 if (presence != null)
9785 { 11046 {
9786 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11047 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9840,8 +11101,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9840 { 11101 {
9841 m_host.AddScriptLPS(1); 11102 m_host.AddScriptLPS(1);
9842 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11103 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9843 if (detectedParams == null) return; // only works on the first detected avatar 11104 if (detectedParams == null)
9844 11105 {
11106 if (m_host.ParentGroup.IsAttachment == true)
11107 {
11108 detectedParams = new DetectParams();
11109 detectedParams.Key = m_host.OwnerID;
11110 }
11111 else
11112 {
11113 return;
11114 }
11115 }
11116
9845 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11117 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9846 if (avatar != null) 11118 if (avatar != null)
9847 { 11119 {
@@ -9849,6 +11121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9849 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11121 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9850 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11122 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9851 } 11123 }
11124
9852 ScriptSleep(1000); 11125 ScriptSleep(1000);
9853 } 11126 }
9854 11127
@@ -9972,12 +11245,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9972 11245
9973 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11246 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9974 object[] data = rules.Data; 11247 object[] data = rules.Data;
9975 for (int i = 0; i < data.Length; ++i) { 11248 for (int i = 0; i < data.Length; ++i)
11249 {
9976 int type = Convert.ToInt32(data[i++].ToString()); 11250 int type = Convert.ToInt32(data[i++].ToString());
9977 if (i >= data.Length) break; // odd number of entries => ignore the last 11251 if (i >= data.Length) break; // odd number of entries => ignore the last
9978 11252
9979 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11253 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9980 switch (type) { 11254 switch (type)
11255 {
9981 case ScriptBaseClass.CAMERA_FOCUS: 11256 case ScriptBaseClass.CAMERA_FOCUS:
9982 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11257 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9983 case ScriptBaseClass.CAMERA_POSITION: 11258 case ScriptBaseClass.CAMERA_POSITION:
@@ -10083,19 +11358,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10083 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11358 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10084 { 11359 {
10085 m_host.AddScriptLPS(1); 11360 m_host.AddScriptLPS(1);
10086 string ret = String.Empty; 11361
10087 string src1 = llBase64ToString(str1); 11362 if (str1 == String.Empty)
10088 string src2 = llBase64ToString(str2); 11363 return String.Empty;
10089 int c = 0; 11364 if (str2 == String.Empty)
10090 for (int i = 0; i < src1.Length; i++) 11365 return str1;
11366
11367 int len = str2.Length;
11368 if ((len % 4) != 0) // LL is EVIL!!!!
11369 {
11370 while (str2.EndsWith("="))
11371 str2 = str2.Substring(0, str2.Length - 1);
11372
11373 len = str2.Length;
11374 int mod = len % 4;
11375
11376 if (mod == 1)
11377 str2 = str2.Substring(0, str2.Length - 1);
11378 else if (mod == 2)
11379 str2 += "==";
11380 else if (mod == 3)
11381 str2 += "=";
11382 }
11383
11384 byte[] data1;
11385 byte[] data2;
11386 try
11387 {
11388 data1 = Convert.FromBase64String(str1);
11389 data2 = Convert.FromBase64String(str2);
11390 }
11391 catch (Exception)
10091 { 11392 {
10092 ret += (char) (src1[i] ^ src2[c]); 11393 return new LSL_String(String.Empty);
11394 }
10093 11395
10094 c++; 11396 byte[] d2 = new Byte[data1.Length];
10095 if (c >= src2.Length) 11397 int pos = 0;
10096 c = 0; 11398
11399 if (data1.Length <= data2.Length)
11400 {
11401 Array.Copy(data2, 0, d2, 0, data1.Length);
10097 } 11402 }
10098 return llStringToBase64(ret); 11403 else
11404 {
11405 while (pos < data1.Length)
11406 {
11407 len = data1.Length - pos;
11408 if (len > data2.Length)
11409 len = data2.Length;
11410
11411 Array.Copy(data2, 0, d2, pos, len);
11412 pos += len;
11413 }
11414 }
11415
11416 for (pos = 0 ; pos < data1.Length ; pos++ )
11417 data1[pos] ^= d2[pos];
11418
11419 return Convert.ToBase64String(data1);
10099 } 11420 }
10100 11421
10101 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11422 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10148,16 +11469,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10148 if (userAgent != null) 11469 if (userAgent != null)
10149 httpHeaders["User-Agent"] = userAgent; 11470 httpHeaders["User-Agent"] = userAgent;
10150 11471
11472 // See if the URL contains any header hacks
11473 string[] urlParts = url.Split(new char[] {'\n'});
11474 if (urlParts.Length > 1)
11475 {
11476 // Iterate the passed headers and parse them
11477 for (int i = 1 ; i < urlParts.Length ; i++ )
11478 {
11479 // The rest of those would be added to the body in SL.
11480 // Let's not do that.
11481 if (urlParts[i] == String.Empty)
11482 break;
11483
11484 // See if this could be a valid header
11485 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11486 if (headerParts.Length != 2)
11487 continue;
11488
11489 string headerName = headerParts[0].Trim();
11490 string headerValue = headerParts[1].Trim();
11491
11492 // Filter out headers that could be used to abuse
11493 // another system or cloak the request
11494 if (headerName.ToLower() == "x-secondlife-shard" ||
11495 headerName.ToLower() == "x-secondlife-object-name" ||
11496 headerName.ToLower() == "x-secondlife-object-key" ||
11497 headerName.ToLower() == "x-secondlife-region" ||
11498 headerName.ToLower() == "x-secondlife-local-position" ||
11499 headerName.ToLower() == "x-secondlife-local-velocity" ||
11500 headerName.ToLower() == "x-secondlife-local-rotation" ||
11501 headerName.ToLower() == "x-secondlife-owner-name" ||
11502 headerName.ToLower() == "x-secondlife-owner-key" ||
11503 headerName.ToLower() == "connection" ||
11504 headerName.ToLower() == "content-length" ||
11505 headerName.ToLower() == "from" ||
11506 headerName.ToLower() == "host" ||
11507 headerName.ToLower() == "proxy-authorization" ||
11508 headerName.ToLower() == "referer" ||
11509 headerName.ToLower() == "trailer" ||
11510 headerName.ToLower() == "transfer-encoding" ||
11511 headerName.ToLower() == "via" ||
11512 headerName.ToLower() == "authorization")
11513 continue;
11514
11515 httpHeaders[headerName] = headerValue;
11516 }
11517
11518 // Finally, strip any protocol specifier from the URL
11519 url = urlParts[0].Trim();
11520 int idx = url.IndexOf(" HTTP/");
11521 if (idx != -1)
11522 url = url.Substring(0, idx);
11523 }
11524
10151 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11525 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10152 Regex r = new Regex(authregex); 11526 Regex r = new Regex(authregex);
10153 int[] gnums = r.GetGroupNumbers(); 11527 int[] gnums = r.GetGroupNumbers();
10154 Match m = r.Match(url); 11528 Match m = r.Match(url);
10155 if (m.Success) { 11529 if (m.Success)
10156 for (int i = 1; i < gnums.Length; i++) { 11530 {
11531 for (int i = 1; i < gnums.Length; i++)
11532 {
10157 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11533 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10158 //CaptureCollection cc = g.Captures; 11534 //CaptureCollection cc = g.Captures;
10159 } 11535 }
10160 if (m.Groups.Count == 5) { 11536 if (m.Groups.Count == 5)
11537 {
10161 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11538 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10162 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11539 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10163 } 11540 }
@@ -10360,6 +11737,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10360 11737
10361 LSL_List ret = new LSL_List(); 11738 LSL_List ret = new LSL_List();
10362 UUID key = new UUID(); 11739 UUID key = new UUID();
11740
11741
10363 if (UUID.TryParse(id, out key)) 11742 if (UUID.TryParse(id, out key))
10364 { 11743 {
10365 ScenePresence av = World.GetScenePresence(key); 11744 ScenePresence av = World.GetScenePresence(key);
@@ -10377,13 +11756,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10377 ret.Add(new LSL_String("")); 11756 ret.Add(new LSL_String(""));
10378 break; 11757 break;
10379 case ScriptBaseClass.OBJECT_POS: 11758 case ScriptBaseClass.OBJECT_POS:
10380 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11759 Vector3 avpos;
11760
11761 if (av.ParentID != 0 && av.ParentPart != null)
11762 {
11763 avpos = av.OffsetPosition;
11764
11765 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11766 avpos -= sitOffset;
11767
11768 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11769 }
11770 else
11771 avpos = av.AbsolutePosition;
11772
11773 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10381 break; 11774 break;
10382 case ScriptBaseClass.OBJECT_ROT: 11775 case ScriptBaseClass.OBJECT_ROT:
10383 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11776 Quaternion avrot = av.Rotation;
11777 if (av.ParentID != 0 && av.ParentPart != null)
11778 {
11779 avrot = av.ParentPart.GetWorldRotation() * avrot;
11780 }
11781 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10384 break; 11782 break;
10385 case ScriptBaseClass.OBJECT_VELOCITY: 11783 case ScriptBaseClass.OBJECT_VELOCITY:
10386 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11784 Vector3 avvel = av.Velocity;
11785 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10387 break; 11786 break;
10388 case ScriptBaseClass.OBJECT_OWNER: 11787 case ScriptBaseClass.OBJECT_OWNER:
10389 ret.Add(new LSL_String(id)); 11788 ret.Add(new LSL_String(id));
@@ -10439,11 +11838,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10439 case ScriptBaseClass.OBJECT_NAME: 11838 case ScriptBaseClass.OBJECT_NAME:
10440 ret.Add(new LSL_String(obj.Name)); 11839 ret.Add(new LSL_String(obj.Name));
10441 break; 11840 break;
10442 case ScriptBaseClass.OBJECT_DESC: 11841 case ScriptBaseClass.OBJECT_DESC:
10443 ret.Add(new LSL_String(obj.Description)); 11842 ret.Add(new LSL_String(obj.Description));
10444 break; 11843 break;
10445 case ScriptBaseClass.OBJECT_POS: 11844 case ScriptBaseClass.OBJECT_POS:
10446 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11845 Vector3 opos = obj.AbsolutePosition;
11846 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10447 break; 11847 break;
10448 case ScriptBaseClass.OBJECT_ROT: 11848 case ScriptBaseClass.OBJECT_ROT:
10449 { 11849 {
@@ -10459,7 +11859,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10459 } 11859 }
10460 break; 11860 break;
10461 case ScriptBaseClass.OBJECT_VELOCITY: 11861 case ScriptBaseClass.OBJECT_VELOCITY:
10462 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11862 Vector3 ovel = obj.Velocity;
11863 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10463 break; 11864 break;
10464 case ScriptBaseClass.OBJECT_OWNER: 11865 case ScriptBaseClass.OBJECT_OWNER:
10465 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11866 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10493,9 +11894,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10493 // The value returned in SL for normal prims is prim count 11894 // The value returned in SL for normal prims is prim count
10494 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11895 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10495 break; 11896 break;
10496 // The following 3 costs I have intentionaly coded to return zero. They are part of 11897
10497 // "Land Impact" calculations. These calculations are probably not applicable 11898 // costs below may need to be diferent for root parts, need to check
10498 // to OpenSim and are not yet complete in SL
10499 case ScriptBaseClass.OBJECT_SERVER_COST: 11899 case ScriptBaseClass.OBJECT_SERVER_COST:
10500 // The linden calculation is here 11900 // The linden calculation is here
10501 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11901 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10503,16 +11903,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10503 ret.Add(new LSL_Float(0)); 11903 ret.Add(new LSL_Float(0));
10504 break; 11904 break;
10505 case ScriptBaseClass.OBJECT_STREAMING_COST: 11905 case ScriptBaseClass.OBJECT_STREAMING_COST:
10506 // The linden calculation is here 11906 // The value returned in SL for normal prims is prim count * 0.06
10507 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11907 ret.Add(new LSL_Float(obj.StreamingCost));
10508 // The value returned in SL for normal prims looks like the prim count * 0.06
10509 ret.Add(new LSL_Float(0));
10510 break; 11908 break;
10511 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11909 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10512 // The linden calculation is here 11910 // The value returned in SL for normal prims is prim count
10513 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11911 ret.Add(new LSL_Float(obj.PhysicsCost));
10514 // The value returned in SL for normal prims looks like the prim count
10515 ret.Add(new LSL_Float(0));
10516 break; 11912 break;
10517 default: 11913 default:
10518 // Invalid or unhandled constant. 11914 // Invalid or unhandled constant.
@@ -10701,15 +12097,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10701 return GetLinkPrimitiveParams(obj, rules); 12097 return GetLinkPrimitiveParams(obj, rules);
10702 } 12098 }
10703 12099
10704 public void print(string str) 12100 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10705 { 12101 {
10706 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12102 List<SceneObjectPart> parts = GetLinkParts(link);
10707 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12103 if (parts.Count < 1)
10708 if (ossl != null) 12104 return 0;
10709 { 12105
10710 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12106 return GetNumberOfSides(parts[0]);
10711 m_log.Info("LSL print():" + str);
10712 }
10713 } 12107 }
10714 12108
10715 private string Name2Username(string name) 12109 private string Name2Username(string name)
@@ -10754,7 +12148,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10754 12148
10755 return rq.ToString(); 12149 return rq.ToString();
10756 } 12150 }
10757 12151/*
12152 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12153 {
12154 m_SayShoutCount = 0;
12155 }
12156*/
10758 private struct Tri 12157 private struct Tri
10759 { 12158 {
10760 public Vector3 p1; 12159 public Vector3 p1;
@@ -10894,9 +12293,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10894 12293
10895 ContactResult result = new ContactResult (); 12294 ContactResult result = new ContactResult ();
10896 result.ConsumerID = group.LocalId; 12295 result.ConsumerID = group.LocalId;
10897 result.Depth = intersection.distance; 12296// result.Depth = intersection.distance;
10898 result.Normal = intersection.normal; 12297 result.Normal = intersection.normal;
10899 result.Pos = intersection.ipoint; 12298 result.Pos = intersection.ipoint;
12299 result.Depth = Vector3.Mag(rayStart - result.Pos);
10900 12300
10901 contacts.Add(result); 12301 contacts.Add(result);
10902 }); 12302 });
@@ -11029,6 +12429,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11029 12429
11030 return contacts[0]; 12430 return contacts[0];
11031 } 12431 }
12432/*
12433 // not done:
12434 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12435 {
12436 ContactResult[] contacts = null;
12437 World.ForEachSOG(delegate(SceneObjectGroup group)
12438 {
12439 if (m_host.ParentGroup == group)
12440 return;
12441
12442 if (group.IsAttachment)
12443 return;
12444
12445 if(group.RootPart.PhysActor != null)
12446 return;
12447
12448 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12449 });
12450 return contacts;
12451 }
12452*/
11032 12453
11033 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12454 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11034 { 12455 {
@@ -11070,32 +12491,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11070 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12491 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11071 12492
11072 12493
11073 if (checkTerrain) 12494 if (World.SuportsRayCastFiltered())
11074 { 12495 {
11075 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12496 if (dist == 0)
11076 if (groundContact != null) 12497 return list;
11077 results.Add((ContactResult)groundContact);
11078 }
11079 12498
11080 if (checkAgents) 12499 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11081 { 12500 if (checkTerrain)
11082 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12501 rayfilter |= RayFilterFlags.land;
11083 foreach (ContactResult r in agentHits) 12502// if (checkAgents)
11084 results.Add(r); 12503// rayfilter |= RayFilterFlags.agent;
11085 } 12504 if (checkPhysical)
12505 rayfilter |= RayFilterFlags.physical;
12506 if (checkNonPhysical)
12507 rayfilter |= RayFilterFlags.nonphysical;
12508 if (detectPhantom)
12509 rayfilter |= RayFilterFlags.LSLPhanton;
12510
12511 Vector3 direction = dir * ( 1/dist);
12512
12513 if(rayfilter == 0)
12514 {
12515 list.Add(new LSL_Integer(0));
12516 return list;
12517 }
11086 12518
11087 if (checkPhysical || checkNonPhysical || detectPhantom) 12519 // get some more contacts to sort ???
12520 int physcount = 4 * count;
12521 if (physcount > 20)
12522 physcount = 20;
12523
12524 object physresults;
12525 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12526
12527 if (physresults == null)
12528 {
12529 list.Add(new LSL_Integer(-3)); // timeout error
12530 return list;
12531 }
12532
12533 results = (List<ContactResult>)physresults;
12534
12535 // for now physics doesn't detect sitted avatars so do it outside physics
12536 if (checkAgents)
12537 {
12538 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12539 foreach (ContactResult r in agentHits)
12540 results.Add(r);
12541 }
12542
12543 // TODO: Replace this with a better solution. ObjectIntersection can only
12544 // detect nonphysical phantoms. They are detected by virtue of being
12545 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12546 // physicsl phantoms as done by the physics scene
12547 // We don't want anything else but phantoms here.
12548 if (detectPhantom)
12549 {
12550 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12551 foreach (ContactResult r in objectHits)
12552 results.Add(r);
12553 }
12554 }
12555 else
11088 { 12556 {
11089 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12557 if (checkTerrain)
11090 foreach (ContactResult r in objectHits) 12558 {
11091 results.Add(r); 12559 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12560 if (groundContact != null)
12561 results.Add((ContactResult)groundContact);
12562 }
12563
12564 if (checkAgents)
12565 {
12566 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12567 foreach (ContactResult r in agentHits)
12568 results.Add(r);
12569 }
12570
12571 if (checkPhysical || checkNonPhysical || detectPhantom)
12572 {
12573 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12574 foreach (ContactResult r in objectHits)
12575 results.Add(r);
12576 }
11092 } 12577 }
11093 12578
11094 results.Sort(delegate(ContactResult a, ContactResult b) 12579 results.Sort(delegate(ContactResult a, ContactResult b)
11095 { 12580 {
11096 return a.Depth.CompareTo(b.Depth); 12581 return a.Depth.CompareTo(b.Depth);
11097 }); 12582 });
11098 12583
11099 int values = 0; 12584 int values = 0;
11100 SceneObjectGroup thisgrp = m_host.ParentGroup; 12585 SceneObjectGroup thisgrp = m_host.ParentGroup;
11101 12586
@@ -11188,7 +12673,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11188 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12673 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11189 if (!isAccount) return 0; 12674 if (!isAccount) return 0;
11190 if (estate.HasAccess(id)) return 1; 12675 if (estate.HasAccess(id)) return 1;
11191 if (estate.IsBanned(id)) 12676 if (estate.IsBanned(id, World.GetUserFlags(id)))
11192 estate.RemoveBan(id); 12677 estate.RemoveBan(id);
11193 estate.AddEstateUser(id); 12678 estate.AddEstateUser(id);
11194 break; 12679 break;
@@ -11207,14 +12692,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11207 break; 12692 break;
11208 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12693 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11209 if (!isAccount) return 0; 12694 if (!isAccount) return 0;
11210 if (estate.IsBanned(id)) return 1; 12695 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11211 EstateBan ban = new EstateBan(); 12696 EstateBan ban = new EstateBan();
11212 ban.EstateID = estate.EstateID; 12697 ban.EstateID = estate.EstateID;
11213 ban.BannedUserID = id; 12698 ban.BannedUserID = id;
11214 estate.AddBan(ban); 12699 estate.AddBan(ban);
11215 break; 12700 break;
11216 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12701 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11217 if (!isAccount || !estate.IsBanned(id)) return 0; 12702 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11218 estate.RemoveBan(id); 12703 estate.RemoveBan(id);
11219 break; 12704 break;
11220 default: return 0; 12705 default: return 0;
@@ -11243,7 +12728,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11243 return 16384; 12728 return 16384;
11244 } 12729 }
11245 12730
11246 public LSL_Integer llGetUsedMemory() 12731 public virtual LSL_Integer llGetUsedMemory()
11247 { 12732 {
11248 m_host.AddScriptLPS(1); 12733 m_host.AddScriptLPS(1);
11249 // The value returned for LSO scripts in SL 12734 // The value returned for LSO scripts in SL
@@ -11271,7 +12756,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11271 public void llSetSoundQueueing(int queue) 12756 public void llSetSoundQueueing(int queue)
11272 { 12757 {
11273 m_host.AddScriptLPS(1); 12758 m_host.AddScriptLPS(1);
11274 NotImplemented("llSetSoundQueueing");
11275 } 12759 }
11276 12760
11277 public void llCollisionSprite(string impact_sprite) 12761 public void llCollisionSprite(string impact_sprite)
@@ -11283,10 +12767,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11283 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12767 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11284 { 12768 {
11285 m_host.AddScriptLPS(1); 12769 m_host.AddScriptLPS(1);
11286 NotImplemented("llGodLikeRezObject"); 12770
12771 if (!World.Permissions.IsGod(m_host.OwnerID))
12772 NotImplemented("llGodLikeRezObject");
12773
12774 AssetBase rezAsset = World.AssetService.Get(inventory);
12775 if (rezAsset == null)
12776 {
12777 llSay(0, "Asset not found");
12778 return;
12779 }
12780
12781 SceneObjectGroup group = null;
12782
12783 try
12784 {
12785 string xmlData = Utils.BytesToString(rezAsset.Data);
12786 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12787 }
12788 catch
12789 {
12790 llSay(0, "Asset not found");
12791 return;
12792 }
12793
12794 if (group == null)
12795 {
12796 llSay(0, "Asset not found");
12797 return;
12798 }
12799
12800 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12801 group.RootPart.AttachOffset = group.AbsolutePosition;
12802
12803 group.ResetIDs();
12804
12805 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12806 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12807 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12808 group.ScheduleGroupForFullUpdate();
12809
12810 // objects rezzed with this method are die_at_edge by default.
12811 group.RootPart.SetDieAtEdge(true);
12812
12813 group.ResumeScripts();
12814
12815 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12816 "object_rez", new Object[] {
12817 new LSL_String(
12818 group.RootPart.UUID.ToString()) },
12819 new DetectParams[0]));
12820 }
12821
12822 public LSL_String llTransferLindenDollars(string destination, int amount)
12823 {
12824 UUID txn = UUID.Random();
12825
12826 Util.FireAndForget(delegate(object x)
12827 {
12828 int replycode = 0;
12829 string replydata = destination + "," + amount.ToString();
12830
12831 try
12832 {
12833 TaskInventoryItem item = m_item;
12834 if (item == null)
12835 {
12836 replydata = "SERVICE_ERROR";
12837 return;
12838 }
12839
12840 m_host.AddScriptLPS(1);
12841
12842 if (item.PermsGranter == UUID.Zero)
12843 {
12844 replydata = "MISSING_PERMISSION_DEBIT";
12845 return;
12846 }
12847
12848 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12849 {
12850 replydata = "MISSING_PERMISSION_DEBIT";
12851 return;
12852 }
12853
12854 UUID toID = new UUID();
12855
12856 if (!UUID.TryParse(destination, out toID))
12857 {
12858 replydata = "INVALID_AGENT";
12859 return;
12860 }
12861
12862 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12863
12864 if (money == null)
12865 {
12866 replydata = "TRANSFERS_DISABLED";
12867 return;
12868 }
12869
12870 bool result = money.ObjectGiveMoney(
12871 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12872
12873 if (result)
12874 {
12875 replycode = 1;
12876 return;
12877 }
12878
12879 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12880 }
12881 finally
12882 {
12883 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12884 "transaction_result", new Object[] {
12885 new LSL_String(txn.ToString()),
12886 new LSL_Integer(replycode),
12887 new LSL_String(replydata) },
12888 new DetectParams[0]));
12889 }
12890 });
12891
12892 return txn.ToString();
11287 } 12893 }
11288 12894
11289 #endregion 12895 #endregion
12896
12897 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12898 {
12899 SceneObjectGroup group = m_host.ParentGroup;
12900
12901 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12902 return;
12903 if (group.IsAttachment)
12904 return;
12905
12906 if (frames.Data.Length > 0) // We are getting a new motion
12907 {
12908 if (group.RootPart.KeyframeMotion != null)
12909 group.RootPart.KeyframeMotion.Stop();
12910 group.RootPart.KeyframeMotion = null;
12911
12912 int idx = 0;
12913
12914 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12915 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12916
12917 while (idx < options.Data.Length)
12918 {
12919 int option = (int)options.GetLSLIntegerItem(idx++);
12920 int remain = options.Data.Length - idx;
12921
12922 switch (option)
12923 {
12924 case ScriptBaseClass.KFM_MODE:
12925 if (remain < 1)
12926 break;
12927 int modeval = (int)options.GetLSLIntegerItem(idx++);
12928 switch(modeval)
12929 {
12930 case ScriptBaseClass.KFM_FORWARD:
12931 mode = KeyframeMotion.PlayMode.Forward;
12932 break;
12933 case ScriptBaseClass.KFM_REVERSE:
12934 mode = KeyframeMotion.PlayMode.Reverse;
12935 break;
12936 case ScriptBaseClass.KFM_LOOP:
12937 mode = KeyframeMotion.PlayMode.Loop;
12938 break;
12939 case ScriptBaseClass.KFM_PING_PONG:
12940 mode = KeyframeMotion.PlayMode.PingPong;
12941 break;
12942 }
12943 break;
12944 case ScriptBaseClass.KFM_DATA:
12945 if (remain < 1)
12946 break;
12947 int dataval = (int)options.GetLSLIntegerItem(idx++);
12948 data = (KeyframeMotion.DataFormat)dataval;
12949 break;
12950 }
12951 }
12952
12953 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12954
12955 idx = 0;
12956
12957 int elemLength = 2;
12958 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12959 elemLength = 3;
12960
12961 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12962 while (idx < frames.Data.Length)
12963 {
12964 int remain = frames.Data.Length - idx;
12965
12966 if (remain < elemLength)
12967 break;
12968
12969 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12970 frame.Position = null;
12971 frame.Rotation = null;
12972
12973 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12974 {
12975 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12976 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12977 }
12978 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12979 {
12980 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12981 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12982 }
12983
12984 float tempf = (float)frames.GetLSLFloatItem(idx++);
12985 frame.TimeMS = (int)(tempf * 1000.0f);
12986
12987 keyframes.Add(frame);
12988 }
12989
12990 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12991 group.RootPart.KeyframeMotion.Start();
12992 }
12993 else
12994 {
12995 if (group.RootPart.KeyframeMotion == null)
12996 return;
12997
12998 if (options.Data.Length == 0)
12999 {
13000 group.RootPart.KeyframeMotion.Stop();
13001 return;
13002 }
13003
13004 int code = (int)options.GetLSLIntegerItem(0);
13005
13006 int idx = 0;
13007
13008 while (idx < options.Data.Length)
13009 {
13010 int option = (int)options.GetLSLIntegerItem(idx++);
13011 int remain = options.Data.Length - idx;
13012
13013 switch (option)
13014 {
13015 case ScriptBaseClass.KFM_COMMAND:
13016 int cmd = (int)options.GetLSLIntegerItem(idx++);
13017 switch (cmd)
13018 {
13019 case ScriptBaseClass.KFM_CMD_PLAY:
13020 group.RootPart.KeyframeMotion.Start();
13021 break;
13022 case ScriptBaseClass.KFM_CMD_STOP:
13023 group.RootPart.KeyframeMotion.Stop();
13024 break;
13025 case ScriptBaseClass.KFM_CMD_PAUSE:
13026 group.RootPart.KeyframeMotion.Pause();
13027 break;
13028 }
13029 break;
13030 }
13031 }
13032 }
13033 }
11290 } 13034 }
11291 13035
11292 public class NotecardCache 13036 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 {